Hi guys,
I've attached 6 patches for some small fixes I made on the jackMidi branch that
also apply to trunk. The patches are against rev 381, and they are each
independent (no patch depends on the other). Here's a brief description of each:
001-scons-lists.patch
=====================
Scons doesn't work for me because it tries to run stuff like:
g++ -pipe -c " -O2 -Wall -DJACK_SUPPORT -foo" -I/usr/lib/baz ...
And I get an error that the file " -O2 -Wall -DJACK_SUPPORT -foo" doesn't exist.
Changing some of the strings to lists fixes this for me.
002-sampler-non-jack.patch
==========================
If JACK_SUPPORT is enabled, Sampler is always assuming that the audio output
porter is a JackOutput pointer. This patch checks before trudging.
003-lash-command-line.patch
===========================
This adds documentation for LASH's command line options to the H2 command line.
004-MidiInput-virtual-destructor.patch
======================================
MidiInput is supposed to be a base class that others derive from. This makes
its destructor virtual so that the destructors of the derived classes will be
called.
005-h2-exept-needs-qstring.patch
=================================
h2_exception.h needs the QString header.
006-jack-auto-rename.patch
==========================
jack_output.cpp had some code to detect if there was another JACK client using
our name... and rename ourselves accordingly. However, the JACK server will do
this for you automatically. I've replaced that code with the JACK support code.
Peace,
Gabriel
Peace,
Gabriel
diff --git a/Sconstruct b/Sconstruct
index 3290572..a29c2e1 100644
--- a/Sconstruct
+++ b/Sconstruct
@@ -42,39 +42,39 @@ def subdirsContaining( root, patterns ):
def get_platform_flags():
includes = []
- cppflags = ""
- ldflags = ""
+ cppflags = []
+ ldflags = []
if sys.platform == "linux2" or sys.platform == "darwin":
if debug:
- cppflags += " -Wall -g2 -ggdb -O0"
+ cppflags += ['-Wall', '-g2', '-ggdb', '-O0']
else:
- cppflags += " -O3 -fomit-frame-pointer -funroll-loops"
+ cppflags += ['-O3', '-fomit-frame-pointer', '-funroll-loops']
#cppflags += " %s" % get_optimized_flags( target_cpu )
- if alsa: cppflags += " -DALSA_SUPPORT"
- if jack: cppflags += " -DJACK_SUPPORT"
- if lash: cppflags += " -DLASH_SUPPORT"
- if portaudio: cppflags += " -DPORTAUDIO_SUPPORT"
- if portmidi: cppflags += " -DPORTMIDI_SUPPORT"
+ if alsa: cppflags.append('-DALSA_SUPPORT')
+ if jack: cppflags.append('-DJACK_SUPPORT')
+ if lash: cppflags.append('-DLASH_SUPPORT')
+ if lrdf: cppflags.append('-DLRDF_SUPPORT')
+ if portaudio: cppflags.append('-DPORTAUDIO_SUPPORT')
+ if portmidi: cppflags.append('-DPORTMIDI_SUPPORT')
- cppflags += " -DFLAC_SUPPORT"
- cppflags += " -DLADSPA_SUPPORT"
- cppflags += " -DLRDF_SUPPORT"
- cppflags += " -DOSS_SUPPORT"
+ cppflags.append('-DFLAC_SUPPORT')
+ cppflags.append('-DLADSPA_SUPPORT')
+ cppflags.append('-DOSS_SUPPORT')
includes.append( '/usr/lib/lash-1.0' )
- if libarchive: cppflags += " -DLIBARCHIVE_SUPPORT"
+ if libarchive: cppflags.append('-DLIBARCHIVE_SUPPORT')
includes.append( './' )
includes.append( 'gui/src/' )
includes.append( '3rdparty/install/include' )
if sys.platform == 'linux2':
- ldflags += " -lasound"
+ ldflags.append('-lasound')
elif sys.platform == 'darwin':
pass
@@ -202,7 +204,8 @@ def get_hydrogen_gui( lib_hydrogen ):
if lrdf: env.Append( LIBS = ["lrdf"] )
if flac: env.Append( LIBS = ["FLAC","FLAC++"] )
if lash: env.Append( LIBS = ["lash"])
- if jack: env.Append( LIBS = ["jack"])
+ if jack:
+ env.Append( LIBS = ["jack"])
if alsa: env.Append( LIBS = ["asound"])
if libarchive: env.Append( LIBS = ["archive"])
else: env.Append( LIBS = ["tar"])
diff --git a/libs/hydrogen/src/sampler/sampler.cpp b/libs/hydrogen/src/sampler/sampler.cpp
index 403be38..bb24ce4 100644
--- a/libs/hydrogen/src/sampler/sampler.cpp
+++ b/libs/hydrogen/src/sampler/sampler.cpp
@@ -95,12 +95,20 @@ void Sampler::process( uint32_t nFrames, Song* pSong )
#ifdef JACK_SUPPORT
- int numtracks = ( ( JackOutput* )__audio_output )->getNumTracks( );
-
- if ( __audio_output->has_track_outs() ) {
- for(int nTrack = 0; nTrack < numtracks; nTrack++) {
- memset( __track_out_L[nTrack], 0, ( ( JackOutput* )__audio_output )->getBufferSize( ) * sizeof( float ) );
- memset( __track_out_R[nTrack], 0, ( ( JackOutput* )__audio_output )->getBufferSize( ) * sizeof( float ) );
+ JackOutput* jao;
+ jao = dynamic_cast<JackOutput*>(__audio_output);
+ if (jao) {
+ int numtracks = jao->getNumTracks();
+
+ if ( jao->has_track_outs() ) {
+ for(int nTrack = 0; nTrack < numtracks; nTrack++) {
+ memset( __track_out_L[nTrack],
+ 0,
+ jao->getBufferSize( ) * sizeof( float ) );
+ memset( __track_out_R[nTrack],
+ 0,
+ jao->getBufferSize( ) * sizeof( float ) );
+ }
}
}
#endif // JACK_SUPPORT
@@ -398,14 +406,15 @@ int Sampler::__render_note_no_resample(
fVal_R = pNote->m_fLowPassFilterBuffer_R;
}
- if ( __audio_output->has_track_outs() ) {
#ifdef JACK_SUPPORT
+ if ( __audio_output->has_track_outs()
+ && dynamic_cast<JackOutput*>(__audio_output) ) {
assert( __track_out_L[ nInstrument ] );
assert( __track_out_R[ nInstrument ] );
__track_out_L[ nInstrument ][nBufferPos] += fVal_L * cost_track_L;
__track_out_R[ nInstrument ][nBufferPos] += fVal_R * cost_track_R;
-#endif
}
+#endif
fVal_L = fVal_L * cost_L;
fVal_R = fVal_R * cost_R;
@@ -568,14 +577,15 @@ int Sampler::__render_note_resample(
}
- if ( __audio_output->has_track_outs() ) {
#ifdef JACK_SUPPORT
+ if ( __audio_output->has_track_outs()
+ && dynamic_cast<JackOutput*>(__audio_output) ) {
assert( __track_out_L[ nInstrument ] );
assert( __track_out_R[ nInstrument ] );
__track_out_L[ nInstrument ][nBufferPos] += (fVal_L * cost_track_L);
__track_out_R[ nInstrument ][nBufferPos] += (fVal_R * cost_track_R);
-#endif
}
+#endif
fVal_L = fVal_L * cost_L;
fVal_R = fVal_R * cost_R;
@@ -723,11 +733,15 @@ void Sampler::makeTrackOutputQueues( )
INFOLOG( "Making Output Queues" );
#ifdef JACK_SUPPORT
- if ( __audio_output->has_track_outs() ) {
- for (int nTrack = 0; nTrack < ( ( JackOutput* )__audio_output )->getNumTracks( ); nTrack++) {
- __track_out_L[nTrack] = ( ( JackOutput* )__audio_output )->getTrackOut_L( nTrack );
+ JackOutput* jao = 0;
+ if (__audio_output && __audio_output->has_track_outs() ) {
+ jao = dynamic_cast<JackOutput*>(__audio_output);
+ }
+ if ( jao ) {
+ for (int nTrack = 0; nTrack < jao->getNumTracks( ); nTrack++) {
+ __track_out_L[nTrack] = jao->getTrackOut_L( nTrack );
assert( __track_out_L[ nTrack ] );
- __track_out_R[nTrack] = ( ( JackOutput* )__audio_output )->getTrackOut_R( nTrack );
+ __track_out_R[nTrack] = jao->getTrackOut_R( nTrack );
assert( __track_out_R[ nTrack ] );
}
}
diff --git a/gui/src/main.cpp b/gui/src/main.cpp
index f2552d9..c7649c6 100644
--- a/gui/src/main.cpp
+++ b/gui/src/main.cpp
@@ -358,6 +358,12 @@ void showUsage()
std::cout << "Usage: hydrogen [-v] [-h] -s file" << std::endl;
std::cout << " -d, --driver AUDIODRIVER - Use the selected audio driver (jack, alsa, oss)" << std::endl;
std::cout << " -s, --song FILE - Load a song (*.h2song) at startup" << std::endl;
+#ifdef LASH_SUPPORT
+ std::cout << " --lash-no-start-server - If LASH server not running, don't start" << endl
+ << " it (LASH 0.5.3 and later)." << std::endl;
+ std::cout << " --lash-no-autoresume - Tell LASH server not to assume I'm returning" << std::endl
+ << " from a crash." << std::endl;
+#endif
std::cout << " -n, --nosplash - Hide splash screen" << std::endl;
std::cout << " -V, --verbose - Print a lot of debugging info" << std::endl;
std::cout << " -v, --version - Show version info" << std::endl;
diff --git a/libs/hydrogen/include/hydrogen/IO/MidiInput.h b/libs/hydrogen/include/hydrogen/IO/MidiInput.h
index 60e6f71..e3bfb46 100644
--- a/libs/hydrogen/include/hydrogen/IO/MidiInput.h
+++ b/libs/hydrogen/include/hydrogen/IO/MidiInput.h
@@ -82,7 +86,7 @@ class MidiInput : public Object
{
public:
MidiInput( const QString class_name );
- ~MidiInput();
+ virtual ~MidiInput();
virtual void open() = 0;
virtual void close() = 0;
diff --git a/libs/hydrogen/include/hydrogen/h2_exception.h b/libs/hydrogen/include/hydrogen/h2_exception.h
index b7d2546..b8c7006 100644
--- a/libs/hydrogen/include/hydrogen/h2_exception.h
+++ b/libs/hydrogen/include/hydrogen/h2_exception.h
@@ -25,6 +25,7 @@
#include <string>
#include <stdexcept>
+#include <QString>
namespace H2Core
{
diff --git a/libs/hydrogen/src/IO/jack_output.cpp b/libs/hydrogen/src/IO/jack_output.cpp
index 6a12aad..64eef6c 100644
--- a/libs/hydrogen/src/IO/jack_output.cpp
+++ b/libs/hydrogen/src/IO/jack_output.cpp
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <cstdlib>
+#include <cassert>
#include <hydrogen/hydrogen.h>
#include <hydrogen/instrument.h>
#include <hydrogen/Song.h>
@@ -417,71 +418,90 @@ float* JackOutput::getTrackOut_R( unsigned nTrack )
}
-int JackOutput::init( unsigned nBufferSize )
-{
- UNUSED( nBufferSize );
-
- output_port_name_1 = Preferences::getInstance()->m_sJackPortName1;
- output_port_name_2 = Preferences::getInstance()->m_sJackPortName2;
+#define CLIENT_FAILURE(msg) { \
+ ERRORLOG("Could not connect to JACK server (" msg ")"); \
+ if (client) { \
+ ERRORLOG("...but JACK returned a non-null pointer?"); \
+ (client) = 0; \
+ } \
+ if (tries) ERRORLOG("...trying again."); \
+ }
-// test!!!
- if ( ( client = jack_client_open( "hydrogen", JackNullOption, NULL ) ) == NULL ) {
- WARNINGLOG( "Error: can't start JACK server" );
- return 3;
+#define CLIENT_SUCCESS(msg) { \
+ assert(client); \
+ INFOLOG(msg); \
+ tries = 0; \
}
- // check if another hydrogen instance is connected to jack
- if ( ( client = jack_client_new( "hydrogen-tmp" ) ) == 0 ) {
- WARNINGLOG( "Jack server not running?" );
- return 3;
- }
+int JackOutput::init( unsigned /*nBufferSize*/ )
+{
- std::vector<QString> clientList;
- const char **readports = jack_get_ports( client, NULL, NULL, JackPortIsOutput );
- int nPort = 0;
- while ( readports && readports[nPort] ) {
- QString sPort = readports[nPort];
- int nColonPos = sPort.indexOf( ":" );
- QString sClient = sPort.mid( 0, nColonPos );
- bool bClientExist = false;
- for ( int j = 0; j < ( int )clientList.size(); j++ ) {
- if ( sClient == clientList[ j ] ) {
- bClientExist = true;
- break;
- }
- }
- if ( !bClientExist ) {
- clientList.push_back( sClient );
- }
- nPort++;
- }
- jack_client_close( client );
-
- QString sClientName = "";
- for ( int nInstance = 1; nInstance < 16; nInstance++ ) {
-// sprintf( clientName, "Hydrogen-%d", nInstance );
- // sprintf( clientName, "Hydrogen-%d", getpid() );
- sClientName = QString( "Hydrogen-%1" ).arg( nInstance );
- bool bExist = false;
- for ( int i = 0; i < ( int )clientList.size(); i++ ) {
- if ( sClientName == clientList[ i ] ) {
- bExist = true;
- break;
+ output_port_name_1 = Preferences::getInstance()->m_sJackPortName1;
+ output_port_name_2 = Preferences::getInstance()->m_sJackPortName2;
+
+ QString sClientName = "Hydrogen";
+ jack_status_t status;
+ int tries = 2; // Sometimes jackd doesn't stop and start fast enough.
+ while ( tries > 0 ) {
+ --tries;
+ client = jack_client_open(
+ sClientName.toAscii(),
+ JackNullOption,
+ &status);
+ switch(status) {
+ case JackFailure:
+ CLIENT_FAILURE("unknown error");
+ break;
+ case JackInvalidOption:
+ CLIENT_FAILURE("invalid option");
+ break;
+ case JackNameNotUnique:
+ if (client) {
+ sClientName = jack_get_client_name(client);
+ CLIENT_SUCCESS(QString("Jack assigned the client name '%1'")
+ .arg(sClientName));
+ } else {
+ CLIENT_FAILURE("name not unique");
}
- }
- if ( !bExist ) {
break;
+ case JackServerStarted:
+ CLIENT_SUCCESS("JACK Server started for Hydrogen.");
+ break;
+ case JackServerFailed:
+ CLIENT_FAILURE("unable to connect");
+ break;
+ case JackServerError:
+ CLIENT_FAILURE("communication error");
+ break;
+ case JackNoSuchClient:
+ CLIENT_FAILURE("unknown client type");
+ break;
+ case JackLoadFailure:
+ CLIENT_FAILURE("can't load internal client");
+ break;
+ case JackInitFailure:
+ CLIENT_FAILURE("can't initialize client");
+ break;
+ case JackShmFailure:
+ CLIENT_FAILURE("unable to access shared memory");
+ break;
+ case JackVersionError:
+ CLIENT_FAILURE("client/server protocol version mismatch");
+ default:
+ if (status) {
+ ERRORLOG("Unknown status with JACK server.");
+ if (client) {
+ CLIENT_SUCCESS("Client pointer is *not* null..."
+ " assuming we're OK");
+ }
+ } else {
+ CLIENT_SUCCESS("Connected to JACK server");
+ }
}
}
-
- // try to become a client of the JACK server
- if ( ( client = jack_client_new( sClientName.toAscii() ) ) == 0 ) {
- ERRORLOG( "Jack server not running? (jack_client_new). Using " + sClientName + " as client name" );
- return 3;
- }
-
+ // Here, client should either be valid, or NULL.
jack_server_sampleRate = jack_get_sample_rate ( client );
jack_server_bufferSize = jack_get_buffer_size ( client );
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Hydrogen-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel