From e53722be36e68f07df8419deeb609ec3b2b80a9f Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Sat, 9 Jan 2010 10:13:07 +0000 Subject: See ChangeLog --- muse/ChangeLog | 10 +++ muse/muse/app.cpp | 139 ++++++++++++++++++++++++++++++++++------ muse/muse/audio.cpp | 6 +- muse/muse/driver/dummyaudio.cpp | 14 ++-- muse/muse/globals.cpp | 4 +- muse/muse/globals.h | 3 + muse/muse/midiseq.cpp | 5 +- 7 files changed, 153 insertions(+), 28 deletions(-) diff --git a/muse/ChangeLog b/muse/ChangeLog index 42bceab3..76a8b2bb 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,13 @@ +09.01.2010 + * Removed: Disabled watchdog thread. (T356) + - Tested OK (normally) without it, although behaviour needs to be tested if audio or midi thread + would stop unexpectedly. + * Changed/Fixed: Thread priorites: Added command line switches for audio (-P) and midi (-Y). (T356) + - Audio (-P) applies to dummy driver only. (Else audio priority is fixed by Jack). + - Also changed default settings so that no two threads have same priority. May fix problem reported + by user GB, concerning high midi latency. + * Added: Enable/disable LASH command line switch (-L), (if LASH support is compiled in). (T356) + - Helps prevent some issues like auto-starting Jack, or automatically routing midi to fluidsynth (observed). 07.01.2010 * Fixed: BUG ID: 2879426: *.med does not save meta event types. (T356) - Changed midievent.cpp MidiEventBase::write(). Now saves value A, B, C and sysex/meta data. Tested OK. diff --git a/muse/muse/app.cpp b/muse/muse/app.cpp index 53ff800f..d8fe90a8 100644 --- a/muse/muse/app.cpp +++ b/muse/muse/app.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -132,7 +133,7 @@ extern void initDSSI(); #ifdef HAVE_LASH #include -lash_client_t * lash_client; +lash_client_t * lash_client = 0; extern snd_seq_t * alsaSeq; #endif /* HAVE_LASH */ @@ -198,7 +199,7 @@ static void* watchdog(void*) rt_param.sched_priority = sched_get_priority_max(SCHED_FIFO); int rv = pthread_setschedparam(pthread_self(), SCHED_FIFO, &rt_param); if (rv != 0) - perror("3set realtime scheduler"); + perror("Set realtime scheduler"); int policy; if (pthread_getschedparam(pthread_self(), &policy, &rt_param)!= 0) { @@ -338,6 +339,8 @@ bool MusE::seqStart() if(debugMsg) printf("MusE::seqStart: getting audio driver realTimePriority:%d\n", realTimePriority); + // Disabled by Tim. p3.3.22 + /* if(realTimeScheduling) { // @@ -365,8 +368,19 @@ bool MusE::seqStart() pthread_attr_destroy(attributes); undoSetuid(); } + */ + + //int policy; + //if ((policy = sched_getscheduler (0)) < 0) { + // printf("Cannot get current client scheduler: %s\n", strerror(errno)); + // } + //if (policy != SCHED_FIFO) + // printf("midi thread %d _NOT_ running SCHED_FIFO\n", getpid()); + //audioState = AUDIO_RUNNING; + // Changed by Tim. p3.3.22 + /* //if(realTimePriority) if(realTimeScheduling) { @@ -383,11 +397,69 @@ bool MusE::seqStart() audioPrefetch->start(0); //audioWriteback->start(0); } - + */ + int pfprio = 0; + int midiprio = 0; + if(realTimeScheduling) + { + if(realTimePriority < 5) + printf("MusE: WARNING: Recommend setting audio realtime priority to at least 5!\n"); + if(realTimePriority == 1) + { + pfprio = 2; + midiprio = 3; + } + else + if(realTimePriority == 2) + { + pfprio = 1; + midiprio = 3; + } + else + if(realTimePriority == 3) + { + pfprio = 1; + midiprio = 2; + } + else + if(realTimePriority == 4) + { + pfprio = 1; + midiprio = 3; + } + else + if(realTimePriority == 5) + { + pfprio = 1; + midiprio = 3; + } + else + { + pfprio = realTimePriority - 5; + midiprio = realTimePriority - 2; + } + } + + if(midiRTPrioOverride > 0) + midiprio = midiRTPrioOverride; + + // FIXME FIXME: The realTimePriority of the Jack thread seems to always be 5 less than the value passed to jackd command. + //if(midiprio == realTimePriority) + // printf("MusE: WARNING: Midi realtime priority %d is the same as audio realtime priority %d. Try a different setting.\n", + // midiprio, realTimePriority); + //if(midiprio == pfprio) + // printf("MusE: WARNING: Midi realtime priority %d is the same as audio prefetch realtime priority %d. Try a different setting.\n", + // midiprio, pfprio); + + audioPrefetch->start(pfprio); + audioPrefetch->msgSeek(0, true); // force //midiSeqRunning = !midiSeq->start(realTimeScheduling ? realTimePriority : 0); - midiSeq->start(realTimeScheduling ? realTimePriority : 0); + // Changed by Tim. p3.3.22 + //midiSeq->start(realTimeScheduling ? realTimePriority : 0); + midiSeq->start(midiprio); + int counter=0; while (++counter) { if (counter > 10) { @@ -873,6 +945,15 @@ MusE::MusE(int argc, char** argv) : QMainWindow(0, "mainwindow") else if (realTimePriority > sched_get_priority_max(SCHED_FIFO)) realTimePriority = sched_get_priority_max(SCHED_FIFO); + // If we requested to force the midi thread priority... + if(midiRTPrioOverride > 0) + { + if (midiRTPrioOverride < sched_get_priority_min(SCHED_FIFO)) + midiRTPrioOverride = sched_get_priority_min(SCHED_FIFO); + else if (midiRTPrioOverride > sched_get_priority_max(SCHED_FIFO)) + midiRTPrioOverride = sched_get_priority_max(SCHED_FIFO); + } + // Changed by Tim. p3.3.17 //midiSeq = new MidiSeq(realTimeScheduling ? realTimePriority : 0, "Midi"); midiSeq = new MidiSeq("Midi"); @@ -1695,7 +1776,7 @@ void MusE::closeEvent(QCloseEvent*) #ifdef HAVE_LASH // Disconnect gracefully from LASH. - if(!lash_client) + if(lash_client) { if(debugMsg) printf("Muse: Disconnecting from LASH\n"); @@ -2185,7 +2266,8 @@ class MuseApplication : public QApplication { void setMuse(MusE* m) { muse = m; #ifdef HAVE_LASH - startTimer (300); + if(useLASH) + startTimer (300); #endif } @@ -2210,7 +2292,8 @@ class MuseApplication : public QApplication { #ifdef HAVE_LASH virtual void timerEvent (QTimerEvent * /* e */) { - muse->lash_idle_cb (); + if(useLASH) + muse->lash_idle_cb (); } #endif /* HAVE_LASH */ @@ -2233,6 +2316,8 @@ static void usage(const char* prog, const char* txt) fprintf(stderr, " -s debug mode: trace sync\n"); fprintf(stderr, " -a no audio\n"); //fprintf(stderr, " -P n set real time priority to n (default: 50)\n"); + fprintf(stderr, " -P n set audio driver real time priority to n (Dummy only, default 40. Else fixed by Jack.)\n"); + fprintf(stderr, " -Y n force midi real time priority to n (default: audio driver prio -2)\n"); fprintf(stderr, " -p don't load LADSPA plugins\n"); #ifdef ENABLE_PYTHON fprintf(stderr, " -y enable Python control support\n"); @@ -2242,6 +2327,9 @@ static void usage(const char* prog, const char* txt) #endif #ifdef DSSI_SUPPORT fprintf(stderr, " -I don't load DSSI plugins\n"); +#endif +#ifdef HAVE_LASH + fprintf(stderr, " -L don't use LASH\n"); #endif fprintf(stderr, "useful environment variables:\n"); fprintf(stderr, " MUSE override library and shared directories location\n"); @@ -2320,8 +2408,9 @@ int main(int argc, char* argv[]) museUserInstruments = museUser + QString("/muse_instruments"); #ifdef HAVE_LASH - lash_args_t * lash_args; - lash_args = lash_extract_args (&argc, &argv); + lash_args_t * lash_args = 0; + if(useLASH) + lash_args = lash_extract_args (&argc, &argv); #endif srand(time(0)); // initialize random number generator @@ -2350,13 +2439,16 @@ int main(int argc, char* argv[]) } int i; - QString optstr("ahvdDmMsP:py"); + QString optstr("ahvdDmMsP:Y:py"); #ifdef VST_SUPPORT optstr += QString("V"); #endif #ifdef DSSI_SUPPORT optstr += QString("I"); #endif +#ifdef HAVE_LASH + optstr += QString("L"); +#endif //#ifdef VST_SUPPORT // while ((i = getopt(argc, argv, "ahvdDmMsVP:py")) != EOF) { @@ -2379,10 +2471,12 @@ int main(int argc, char* argv[]) case 'm': midiInputTrace = true; break; case 'M': midiOutputTrace = true; break; case 's': debugSync = true; break; - //case 'P': realTimePriority = atoi(optarg); break; + case 'P': realTimePriority = atoi(optarg); break; + case 'Y': midiRTPrioOverride = atoi(optarg); break; case 'p': loadPlugins = false; break; case 'V': loadVST = false; break; case 'I': loadDSSI = false; break; + case 'L': useLASH = false; break; case 'y': usePythonBridge = true; break; case 'h': usage(argv[0], argv[1]); return -1; default: usage(argv[0], "bad argument"); return -1; @@ -2500,18 +2594,27 @@ int main(int argc, char* argv[]) muse = new MusE(argc, &argv[optind]); app.setMuse(muse); muse->setIcon(*museIcon); + // Added by Tim. p3.3.22 + if (!debugMode) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + perror("WARNING: Cannot lock memory:"); + } + muse->show(); muse->seqStart(); #ifdef HAVE_LASH { - int lash_flags = LASH_Config_File; - const char *muse_name = PACKAGE_NAME; - lash_client = lash_init (lash_args, muse_name, lash_flags, LASH_PROTOCOL(2,0)); - lash_alsa_client_id (lash_client, snd_seq_client_id (alsaSeq)); - if (!noAudio) { - char *jack_name = ((JackAudioDevice*)audioDevice)->getJackName(); - lash_jack_client_name (lash_client, jack_name); + if(useLASH) + { + int lash_flags = LASH_Config_File; + const char *muse_name = PACKAGE_NAME; + lash_client = lash_init (lash_args, muse_name, lash_flags, LASH_PROTOCOL(2,0)); + lash_alsa_client_id (lash_client, snd_seq_client_id (alsaSeq)); + if (!noAudio) { + char *jack_name = ((JackAudioDevice*)audioDevice)->getJackName(); + lash_jack_client_name (lash_client, jack_name); + } } } #endif /* HAVE_LASH */ diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp index 9a716054..153b5a2b 100644 --- a/muse/muse/audio.cpp +++ b/muse/muse/audio.cpp @@ -281,8 +281,10 @@ void Audio::shutdown() void Audio::process(unsigned frames) { - extern int watchAudio; - ++watchAudio; // make a simple watchdog happy + // Disabled by Tim. p3.3.22 +// extern int watchAudio; +// ++watchAudio; // make a simple watchdog happy + if (!checkAudioDevice()) return; if (msg) { processMsg(msg); diff --git a/muse/muse/driver/dummyaudio.cpp b/muse/muse/driver/dummyaudio.cpp index 1796d520..20750692 100644 --- a/muse/muse/driver/dummyaudio.cpp +++ b/muse/muse/driver/dummyaudio.cpp @@ -44,7 +44,7 @@ class DummyAudioDevice : public AudioDevice { // Changed by Tim. p3.3.15 //float buffer[1024]; float* buffer; - int realTimePriority; + int _realTimePriority; public: std::list cmdQueue; @@ -109,7 +109,8 @@ class DummyAudioDevice : public AudioDevice { return _framePos; } virtual bool isRealtime() { return realtimeFlag; } - virtual int realtimePriority() const { return 40; } + //virtual int realtimePriority() const { return 40; } + virtual int realtimePriority() const { return _realTimePriority; } virtual void startTransport() { if(DEBUG_DUMMY) printf("DummyAudioDevice::startTransport playPos=%d\n", playPos); @@ -284,7 +285,8 @@ static void* dummyLoop(void* ptr) #ifndef __APPLE__ doSetuid(); - if (realTimePriority) { + //if (realTimePriority) { + if (realTimeScheduling) { // // check if we really got realtime priviledges // @@ -364,10 +366,12 @@ static void* dummyLoop(void* ptr) //void DummyAudioDevice::start() void DummyAudioDevice::start(int priority) { - realTimePriority = priority; + //realTimePriority = priority; + _realTimePriority = priority; pthread_attr_t* attributes = 0; - if (priority) { + //if (priority) { + if (realTimeScheduling && priority > 0) { attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); pthread_attr_init(attributes); diff --git a/muse/muse/globals.cpp b/muse/muse/globals.cpp index b8e56b01..200ff453 100644 --- a/muse/muse/globals.cpp +++ b/muse/muse/globals.cpp @@ -84,11 +84,13 @@ bool debugMsg = false; bool midiInputTrace = false; bool midiOutputTrace = false; bool realTimeScheduling = false; -int realTimePriority = 80; +int realTimePriority = 40; // 80 +int midiRTPrioOverride = -1; bool loadPlugins = true; bool loadVST = true; bool loadDSSI = true; bool usePythonBridge = false; +bool useLASH = true; const char* midi_file_pattern[] = { "Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2)", diff --git a/muse/muse/globals.h b/muse/muse/globals.h index 7252cc06..4fb2254f 100644 --- a/muse/muse/globals.h +++ b/muse/muse/globals.h @@ -60,9 +60,12 @@ extern bool loadPlugins; extern bool loadVST; extern bool loadDSSI; extern bool usePythonBridge; +extern bool useLASH; extern bool realTimeScheduling; extern int realTimePriority; +extern int midiRTPrioOverride; + extern const char* midi_file_pattern[]; //!< File name pattern for midi files extern const char* med_file_pattern[]; //!< File name pattern for muse project files extern const char* image_file_pattern[]; //!< File name pattern for image files (gfx) diff --git a/muse/muse/midiseq.cpp b/muse/muse/midiseq.cpp index 4399a171..89b88804 100644 --- a/muse/muse/midiseq.cpp +++ b/muse/muse/midiseq.cpp @@ -505,8 +505,9 @@ void MidiSeq::midiTick(void* p, void*) void MidiSeq::processTimerTick() { - extern int watchMidi; - ++watchMidi; // make a simple watchdog happy + // Disabled by Tim. p3.3.22 +// extern int watchMidi; +// ++watchMidi; // make a simple watchdog happy //--------------------------------------------------- // read elapsed rtc timer ticks -- cgit v1.2.3