diff --git a/GUI/Widgets/PawfalYesNo.C b/GUI/Widgets/PawfalYesNo.C index a371fca..5174762 100644 --- a/GUI/Widgets/PawfalYesNo.C +++ b/GUI/Widgets/PawfalYesNo.C @@ -20,6 +20,7 @@ #include #include #include +#include bool Pawfal_YesNo(const char *a,...) { diff --git a/SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C b/SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C index d58ba5f..b5e3bd2 100644 --- a/SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C +++ b/SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C @@ -53,7 +53,9 @@ m_CurrentNoteCV(0), m_CurrentTriggerCV(0), m_Triggered(false), m_ClockHigh(false), -m_CopyPattern(0) +m_CopyPattern(0), +m_PatAdvance(false), +m_PatReset(false) { m_Version=3; @@ -67,6 +69,8 @@ m_CopyPattern(0) m_PluginInfo.PortTips.push_back("Input Pitch CV"); m_PluginInfo.PortTips.push_back("Input Trigger CV"); m_PluginInfo.PortTips.push_back("External Clock"); + //m_PluginInfo.PortTips.push_back("Pattern Advance"); + //m_PluginInfo.PortTips.push_back("Pattern Reset"); m_PluginInfo.PortTips.push_back("Output Pitch"); m_PluginInfo.PortTips.push_back("Output Trigger"); m_PluginInfo.PortTips.push_back("Trigger 1"); @@ -89,7 +93,7 @@ m_CopyPattern(0) for (int n=0; n= m_Matrix[m_Current].Length) SetOutput(18, n, 1); else SetOutput(18, n, 0); - + if (GetInputPitch(0,n)>0) { if (!m_Triggered) @@ -167,10 +171,7 @@ void MatrixPlugin::Execute() } // make it so the next note to trigger - // will be the first one - - //if (m_GUI) ((MatrixPluginGUI*)m_GUI)->UpdateValues(); - + // will be the first one m_Time=m_StepTime*(1/m_Matrix[m_Current].Speed); m_Step=-1; @@ -216,9 +217,40 @@ void MatrixPlugin::Execute() ExternalClockTriggered=true; } } - - - +/* not yet... + // external pattern advance + if (GetInput(5,n)>0) + { + if (!m_PatAdvance) + { + m_Current++; + if (m_Current==16) m_Current=0; + m_PatAdvance=true; + m_Step=-1; + ExternalClockTriggered=true; + } + } + else + { + m_PatAdvance=false; + } + + // external pattern reset + if (GetInput(6,n)>0) + { + if (!m_PatReset) + { + m_Current=0; + m_PatReset=true; + m_Step=-1; + ExternalClockTriggered=true; + } + } + else + { + m_PatReset=false; + } +*/ // An external clock pulse overrides the internal timing if ((!ExternalClock && m_Time>=m_StepTime*(1/m_Matrix[m_Current].Speed)) || (ExternalClock && ExternalClockTriggered)) @@ -227,9 +259,7 @@ void MatrixPlugin::Execute() m_Step++; if (m_Step >= m_Matrix[m_Current].Length) m_Step=0; - - //if (m_GUI) ((MatrixPluginGUI*)m_GUI)->SetLED(m_Step); - + // Reset the values m_CurrentTriggerCV=0; if (m_NoteCut) m_CurrentNoteCV=0; @@ -239,7 +269,6 @@ void MatrixPlugin::Execute() m_TriggerLevel[t]=0; } - // Scan the matrix at current time for (int i=0; iGetInt("Step"); + if (Light!=m_LastLight) { - m_Flash[x]->value(0); + m_Flash[Light]->value(1); + m_Flash[m_LastLight]->value(0); + m_LastLight=Light; } - - m_Flash[m_GUICH->GetInt("Step")]->value(1); - - redraw(); } void MatrixPluginGUI::UpdateValues(SpiralPlugin *o) @@ -233,21 +233,8 @@ void MatrixPluginGUI::UpdateValues(SpiralPlugin *o) m_Matrix[x][y]->value(Plugin->GetPattern()->Matrix[x][y]); m_Matrix[x][y]->SetVolume(Plugin->GetPattern()->Volume[x][y]); } - - //if (Plugin->CanTransposeUp()) m_TransUpBtn->activate(); else m_TransUpBtn->deactivate(); - //if (Plugin->CanTransposeDown()) m_TransDnBtn->activate(); else m_TransDnBtn->deactivate(); } -/*void MatrixPluginGUI::SetLED(int n) -{ - for (int i=0; ivalue(false); - } - - m_Flash[n]->value(true); -}*/ - void MatrixPluginGUI::UpdateMatrix() { m_GUICH->Wait(); @@ -307,10 +294,7 @@ inline void MatrixPluginGUI::cb_Length_i(Fl_Counter* o, void* v) { if (o->value()<1) o->value(1); if (o->value()>64) o->value(64); - //m_GUICH->GetPattern()->Length=(int)o->value(); - - cerr<<(int)o->value()<Set("Length",(int)o->value()); m_GUICH->SetCommand(MatrixPlugin::MAT_LENGTH); diff --git a/SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h b/SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h index 998b784..c1fd196 100644 --- a/SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h +++ b/SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h @@ -74,6 +74,7 @@ private: int Numbers[MATX*MATY]; Pattern m_GUIMatrix[NUM_PATTERNS]; + int m_LastLight; Fl_Button* m_NoteCut; Fl_Counter* m_Pattern; diff --git a/SpiralSound/Plugins/OutputPlugin/OutputPlugin.C b/SpiralSound/Plugins/OutputPlugin/OutputPlugin.C index 38bd95a..b7e3f6c 100644 --- a/SpiralSound/Plugins/OutputPlugin/OutputPlugin.C +++ b/SpiralSound/Plugins/OutputPlugin/OutputPlugin.C @@ -60,7 +60,7 @@ int OutputPlugin::m_NoExecuted=0; { \ perror("Sound device did not accept settings"); \ m_OutputOk=false; \ - return; \ + return false; \ } extern "C" @@ -83,10 +83,11 @@ int GetID() /////////////////////////////////////////////////////// -OutputPlugin::OutputPlugin() +OutputPlugin::OutputPlugin() : +m_Volume(1.0f) { m_RefCount++; - + m_PluginInfo.Name="OSS"; m_PluginInfo.Width=100; m_PluginInfo.Height=130; @@ -98,16 +99,17 @@ OutputPlugin::OutputPlugin() m_PluginInfo.PortTips.push_back("Left In"); m_PluginInfo.PortTips.push_back("Right In"); - m_AudioCH->Register("Mode",(char*)&m_Mode,ChannelHandler::INPUT); + m_AudioCH->Register("Volume",(char*)&m_Volume); - m_Mode=OUTPUT; + m_Mode=NO_MODE; } OutputPlugin::~OutputPlugin() -{ +{ m_RefCount--; if (m_RefCount==0) - { + { + cb_Blocking(m_Parent,false); OSSOutput::PackUpAndGoHome(); } } @@ -117,6 +119,7 @@ PluginInfo &OutputPlugin::Initialise(const HostInfo *Host) PluginInfo& Info= SpiralPlugin::Initialise(Host); host=Host; OSSOutput::Get()->AllocateBuffer(); + return Info; } @@ -131,15 +134,18 @@ SpiralGUIType *OutputPlugin::CreateGUI() void OutputPlugin::Execute() { - // Only Play() once per set of plugins - m_NoExecuted++; - if (m_NoExecuted==m_RefCount) - { - if (m_Mode==INPUT || m_Mode==DUPLEX) OSSOutput::Get()->Read(); - if (m_Mode==OUTPUT || m_Mode==DUPLEX) OSSOutput::Get()->Play(); - m_NoExecuted=0; + if (m_Mode==NO_MODE) + { + if (OSSOutput::Get()->OpenWrite()) + { + cb_Blocking(m_Parent,true); + m_Mode=OUTPUT; + } } + //if (m_Mode==NO_MODE || m_Mode==CLOSED) cb_Blocking(m_Parent,false); + //else cb_Blocking(m_Parent,true); + if (m_Mode==OUTPUT || m_Mode==DUPLEX) { OSSOutput::Get()->SendStereo(GetInput(0),GetInput(1)); @@ -177,6 +183,54 @@ void OutputPlugin::Execute() if (m_Mode==INPUT || m_Mode==DUPLEX) OSSOutput::Get()->GetStereo(GetOutputBuf(0),GetOutputBuf(1)); } +void OutputPlugin::ExecuteCommands() +{ + // Only Play() once per set of plugins + m_NoExecuted++; + if (m_NoExecuted==m_RefCount) + { + if (m_Mode==INPUT || m_Mode==DUPLEX) OSSOutput::Get()->Read(); + if (m_Mode==OUTPUT || m_Mode==DUPLEX) OSSOutput::Get()->Play(); + m_NoExecuted=0; + } + + + if (m_AudioCH->IsCommandWaiting()) + { + switch(m_AudioCH->GetCommand()) + { + case OPENREAD : + if (OSSOutput::Get()->OpenRead()) + { + m_Mode=INPUT; + //cb_Blocking(m_Parent,true); + } + break; + case OPENWRITE : + if (OSSOutput::Get()->OpenWrite()) + { + m_Mode=OUTPUT; + cb_Blocking(m_Parent,true); + } + break; + case OPENDUPLEX : + if (OSSOutput::Get()->OpenReadWrite()) + { + m_Mode=DUPLEX; + cb_Blocking(m_Parent,true); + } + break; + case CLOSE : + m_Mode=CLOSED; + cb_Blocking(m_Parent,false); + OSSOutput::Get()->Close(); + break; + case SET_VOLUME : OSSOutput::Get()->SetVolume(m_Volume); break; + default : break; + } + } +} + ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// @@ -185,14 +239,12 @@ m_Amp(0.5), m_Channels(2), m_ReadBufferNum(0), m_WriteBufferNum(0), -m_OutputOk(true) +m_OutputOk(false) { m_Buffer[0]=NULL; m_Buffer[1]=NULL; m_InBuffer[0]=NULL; m_InBuffer[1]=NULL; - - OpenWrite(); } ////////////////////////////////////////////////////////////////////// @@ -264,9 +316,10 @@ void OSSOutput::Play() ((m_Buffer[BufferToSend][n]>>8)&0xff); } #endif - if (m_OutputOk) + { write(m_Dspfd,m_Buffer[BufferToSend],m_BufSizeBytes); + } if(m_Wav.Recording()) { @@ -316,15 +369,17 @@ void OSSOutput::Read() ////////////////////////////////////////////////////////////////////// -void OSSOutput::Close() +bool OSSOutput::Close() { cerr<<"Closing dsp output"<SAMPLERATE; result = ioctl(m_Dspfd,SNDCTL_DSP_SPEED,&val); CHECK_AND_REPORT_ERROR; + + m_OutputOk=true; + return true; } ////////////////////////////////////////////////////////////////////// -void OSSOutput::OpenRead() +bool OSSOutput::OpenRead() { int result,val; @@ -396,7 +454,7 @@ void OSSOutput::OpenRead() { fprintf(stderr,"Can't open audio driver for reading.\n"); m_OutputOk=false; - return; + return false; } result = ioctl(m_Dspfd,SNDCTL_DSP_RESET,NULL); @@ -413,11 +471,14 @@ void OSSOutput::OpenRead() val = host->SAMPLERATE; result = ioctl(m_Dspfd,SNDCTL_DSP_SPEED,&val); CHECK_AND_REPORT_ERROR; + m_OutputOk=true; + + return true; } ////////////////////////////////////////////////////////////////////// -void OSSOutput::OpenReadWrite() +bool OSSOutput::OpenReadWrite() { int result,val; cerr<<"Opening dsp output (duplex)"<SAMPLERATE; result = ioctl(m_Dspfd,SNDCTL_DSP_SPEED,&val); CHECK_AND_REPORT_ERROR; + m_OutputOk=true; + + return true; } diff --git a/SpiralSound/Plugins/OutputPlugin/OutputPlugin.h b/SpiralSound/Plugins/OutputPlugin/OutputPlugin.h index 976b3b1..155e7ec 100644 --- a/SpiralSound/Plugins/OutputPlugin/OutputPlugin.h +++ b/SpiralSound/Plugins/OutputPlugin/OutputPlugin.h @@ -42,10 +42,10 @@ public: void WavClose() {m_Wav.Close();} short *GetBuffer() {return m_Buffer[m_WriteBufferNum];} - void OpenReadWrite(); - void OpenWrite(); - void OpenRead(); - void Close(); + bool OpenReadWrite(); + bool OpenWrite(); + bool OpenRead(); + bool Close(); private: static OSSOutput* m_Singleton; @@ -68,7 +68,7 @@ private: class OutputPlugin : public SpiralPlugin { public: - enum Mode{INPUT,OUTPUT,DUPLEX}; + enum Mode{NO_MODE,INPUT,OUTPUT,DUPLEX,CLOSED}; OutputPlugin(); virtual ~OutputPlugin(); @@ -76,9 +76,13 @@ public: virtual PluginInfo& Initialise(const HostInfo *Host); virtual SpiralGUIType* CreateGUI(); virtual void Execute(); + virtual void ExecuteCommands(); virtual void StreamOut(ostream &s) {} virtual void StreamIn(istream &s) {} + enum GUICommands {NONE,OPENREAD,OPENWRITE,OPENDUPLEX,CLOSE,SET_VOLUME}; + float m_Volume; + Mode GetMode() { return m_Mode; } private: diff --git a/SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C b/SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C index 6df63ff..1d5a236 100644 --- a/SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C +++ b/SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C @@ -71,7 +71,10 @@ void OutputPluginGUI::UpdateValues(SpiralPlugin *o) //// Callbacks //// inline void OutputPluginGUI::cb_Volume_i(Fl_Knob* o, void* v) -{ OSSOutput::Get()->SetVolume(o->value()); } +{ + m_GUICH->Set("Volume",(float)o->value()); + m_GUICH->SetCommand(OutputPlugin::SET_VOLUME); +} void OutputPluginGUI::cb_Volume(Fl_Knob* o, void* v) { ((OutputPluginGUI*)(o->parent()))->cb_Volume_i(o,v); } @@ -104,14 +107,16 @@ inline void OutputPluginGUI::cb_OpenRead_i(Fl_Button* o, void* v) if (o->value()) { OpenWrite->value(0); - OSSOutput::Get()->Close(); - OSSOutput::Get()->OpenRead(); - m_GUICH->Set("Mode",(char)OutputPlugin::INPUT); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); + m_GUICH->SetCommand(OutputPlugin::OPENREAD); + m_GUICH->Wait(); } else { - OpenWrite->value(0); - OSSOutput::Get()->Close(); + OpenWrite->value(0); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); } } void OutputPluginGUI::cb_OpenRead(Fl_Button* o, void* v) @@ -122,14 +127,16 @@ inline void OutputPluginGUI::cb_OpenDuplex_i(Fl_Button* o, void* v) if (o->value()) { OpenRead->value(0); - OSSOutput::Get()->Close(); - OSSOutput::Get()->OpenReadWrite(); - m_GUICH->Set("Mode",(char)OutputPlugin::DUPLEX); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); + m_GUICH->SetCommand(OutputPlugin::OPENDUPLEX); + m_GUICH->Wait(); } else { OpenRead->value(0); - OSSOutput::Get()->Close(); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); } } void OutputPluginGUI::cb_OpenDuplex(Fl_Button* o, void* v) @@ -140,14 +147,16 @@ inline void OutputPluginGUI::cb_OpenWrite_i(Fl_Button* o, void* v) if (o->value()) { OpenRead->value(0); - OSSOutput::Get()->Close(); - OSSOutput::Get()->OpenWrite(); - m_GUICH->Set("Mode",(char)OutputPlugin::OUTPUT); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); + m_GUICH->SetCommand(OutputPlugin::OPENWRITE); + m_GUICH->Wait(); } else { OpenRead->value(0); - OSSOutput::Get()->Close(); + m_GUICH->SetCommand(OutputPlugin::CLOSE); + m_GUICH->Wait(); } } void OutputPluginGUI::cb_OpenWrite(Fl_Button* o, void* v) diff --git a/SpiralSound/Plugins/SpiralPlugin.h b/SpiralSound/Plugins/SpiralPlugin.h index fc11720..06f6d84 100644 --- a/SpiralSound/Plugins/SpiralPlugin.h +++ b/SpiralSound/Plugins/SpiralPlugin.h @@ -94,11 +94,14 @@ public: string GetName() { return m_PluginInfo.Name; } void UpdatePluginInfoWithHost(); + void SetInPortType(PluginInfo &pinfo, int port, Sample::SampleType type); + void SetOutPortType(PluginInfo &pinfo, int port, Sample::SampleType type); + + // Callbacks to main engine. Should only called by plugin hosts. void SetUpdateInfoCallback(int ID, void(*s)(int, void *)); void SetUpdateCallback(void (*s)(void*,bool m)) { cb_Update=s; } + void SetBlockingCallback(void (*s)(void*,bool m)) { cb_Blocking=s; } void SetParent(void *s) { m_Parent=s; } - void SetInPortType(PluginInfo &pinfo, int port, Sample::SampleType type); - void SetOutPortType(PluginInfo &pinfo, int port, Sample::SampleType type); void UpdateChannelHandler(); @@ -146,6 +149,10 @@ protected: // needed for jack void (*cb_Update)(void*o ,bool m); void *m_Parent; + + // tell the engine that we are taking control of the + // timing for output. + void (*cb_Blocking)(void*o ,bool m); private: diff --git a/SpiralSynthModular.C b/SpiralSynthModular.C index bca78ad..d4118b0 100644 --- a/SpiralSynthModular.C +++ b/SpiralSynthModular.C @@ -59,6 +59,7 @@ using namespace std; map SynthModular::m_DeviceWinMap; bool SynthModular::m_CallbackUpdateMode = false; +bool SynthModular::m_BlockingOutputPluginIsReady = false; ////////////////////////////////////////////////////////// @@ -138,7 +139,7 @@ void SynthModular::Update() if (i->second->m_Device) // if it's not a comment { #ifdef DEBUG_PLUGINS - cerr<<"Updating channelhandler of pluin "<second->m_PluginID<second->m_PluginID<second->m_DeviceGUI->Killed()) { + if (i->second->m_Device) + { + PauseAudio(); + delete i->second->m_Device; + ResumeAudio(); + } + if (i->second->m_DeviceGUI->GetPluginWindow()) { i->second->m_DeviceGUI->GetPluginWindow()->hide(); m_MainWindow->remove(i->second->m_DeviceGUI->GetPluginWindow()); } + i->second->m_DeviceGUI->Clear(); m_Canvas->RemoveDevice(i->second->m_DeviceGUI); // deleted by Canvas::Remove()? seems to cause random crashes //delete i->second->m_DeviceGUI; - if (i->second->m_Device) - { - PauseAudio(); - delete i->second->m_Device; - ResumeAudio(); - } + m_DeviceWinMap.erase(i); break; } @@ -542,6 +546,7 @@ DeviceWin* SynthModular::NewDeviceWin(int n, int x, int y) { return NULL; } + nlw->m_Device->SetBlockingCallback(cb_Blocking); nlw->m_Device->SetUpdateCallback(cb_Update); nlw->m_Device->SetParent((void*)this); @@ -662,12 +667,20 @@ void SynthModular::UpdateHostInfo() ////////////////////////////////////////////////////////// +// called when a callback output plugin wants to run the audio thread void SynthModular::cb_Update(void* o, bool mode) { m_CallbackUpdateMode=mode; ((SynthModular*)o)->Update(); } +// called by a blocking output plugin to notify the engine its ready to +// take control of the update timing (so take the brakes off) +void SynthModular::cb_Blocking(void* o, bool mode) +{ + m_BlockingOutputPluginIsReady=mode; +} + ////////////////////////////////////////////////////////// istream &operator>>(istream &s, SynthModular &o) @@ -775,7 +788,6 @@ istream &operator>>(istream &s, SynthModular &o) s>>*o.m_Canvas; o.ResumeAudio(); - return s; } diff --git a/SpiralSynthModular.h b/SpiralSynthModular.h index dec1a3d..36ab769 100644 --- a/SpiralSynthModular.h +++ b/SpiralSynthModular.h @@ -71,6 +71,7 @@ public: void ClearUp(); void UpdateHostInfo(); bool CallbackMode() { return m_CallbackUpdateMode; } + bool IsBlockingOutputPluginReady() { return m_BlockingOutputPluginIsReady; } void UpdatePluginGUIs(); void LoadPatch(const char *fn); @@ -85,6 +86,9 @@ public: m_CH.Set("PauseAudio",false); } + // only for audio thread + bool IsPaused() { return m_PauseAudio; } + private: DeviceWin* NewDeviceWin(int n, int x, int y); @@ -104,6 +108,7 @@ private: int m_NextPluginButtonYPos; static bool m_CallbackUpdateMode; + static bool m_BlockingOutputPluginIsReady; string m_FilePath; // Main GUI stuff @@ -164,8 +169,10 @@ private: static void cb_Rload(Fl_Button* o, void* v); static void cb_Update(void* o, bool Mode); + static void cb_Blocking(void* o, bool Mode); static void cb_UpdatePluginInfo(int ID, void *PluginInfo); + friend istream &operator>>(istream &s, SynthModular &o); friend ostream &operator<<(ostream &s, SynthModular &o); }; diff --git a/main.cpp b/main.cpp index 215cab6..6a85718 100644 --- a/main.cpp +++ b/main.cpp @@ -25,30 +25,66 @@ #include #include #include +#include +#include #include "SpiralSynthModular.h" -pthread_t loopthread; +pthread_t loopthread,watchdogthread; SynthModular *synth; +char watchdog_check = 1; +char gui_watchdog_check = 1; + int pthread_create_realtime (pthread_t *new_thread, void *(*start)(void *), void *arg, int priority); bool CallbackOnly = false; +bool FIFO = false; +bool GUI = true; + +///////////////////////////////////////////////////////////// + +void watchdog (void *arg) +{ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + watchdog_check = 0; + gui_watchdog_check = 0; + + while (1) + { + usleep (10000000); + if (watchdog_check == 0 || gui_watchdog_check== 0) + { + cerr<<"ssm watchdog: timeout - killing ssm"<CallbackMode()) { // do funky stuff synth->Update(); - - // slow down this thread if we are not going to be using the - // oss plugin. prevents maxing the CPU out for no reason. - if (CallbackOnly) usleep(100); + + // put the brakes on if there is no blocking output running + if (!synth->IsBlockingOutputPluginReady()|| + synth->IsPaused()) + { + usleep(10000); + } } else { @@ -56,17 +92,18 @@ void audioloop(void* o) // need to do anything unless we are switched back usleep(1000000); } + + watchdog_check = 1; } } +////////////////////////////////////////////////////// + int main(int argc, char **argv) { srand(time(NULL)); SpiralSynthModularInfo::Get()->LoadPrefs(); - bool GUI = true; - bool FIFO = false; - // get args string cmd_filename=""; bool cmd_specd = false; @@ -78,24 +115,22 @@ int main(int argc, char **argv) for (int a=1; a : look for plugins in the specified directory"<show(1, argv); // prevents stuff happening before the plugins have loaded // spawn the audio thread - int ret; - if (FIFO) ret=pthread_create_realtime(&loopthread,(void*(*)(void*))audioloop,NULL,10); - else ret=pthread_create(&loopthread,NULL,(void*(*)(void*))audioloop,NULL); - - pthread_t GUIThread = pthread_self(); + if (FIFO) + { + pthread_create_realtime(&watchdogthread,(void*(*)(void*))watchdog,NULL,sched_get_priority_max(SCHED_FIFO)); + pthread_create_realtime(&loopthread,(void*(*)(void*))audioloop,NULL,sched_get_priority_max(SCHED_FIFO)-1); + } + else + { + pthread_create(&loopthread,NULL,(void*(*)(void*))audioloop,NULL); + // reduce the priority of the gui + if (setpriority(PRIO_PROCESS,0,20)) cerr<<"Could not set priority for GUI thread"<LoadPatch(cmd_filename.c_str()); @@ -146,6 +185,7 @@ int main(int argc, char **argv) if (!Fl::check()) break; synth->UpdatePluginGUIs(); // deletes any if necc usleep(10000); + gui_watchdog_check=1; } //pthread_cancel(loopthread);