| @@ -41,7 +41,7 @@ libdir = @libdir@ | |||
| infodir = @infodir@ | |||
| mandir = @mandir@ | |||
| SpiralPlugins = @PLUGINDIR@ | |||
| SpiralPlugins = $(libdir)/SpiralPlugins | |||
| ####### Files | |||
| @@ -57,9 +57,11 @@ HEADERS = SpiralSynthModular.h \ | |||
| SpiralSound/Plugins/SpiralPlugin.h \ | |||
| SpiralSound/Plugins/SpiralPluginGUI.h \ | |||
| SpiralSound/PluginManager.h \ | |||
| SpiralSound/ChannelHandler.h \ | |||
| SettingsWindow.h \ | |||
| SpiralSynthPluginLocation.h | |||
| SOURCES = SpiralSynthModular.C \ | |||
| SOURCES = main.cpp \ | |||
| SpiralSynthModular.C \ | |||
| SpiralSynthModularInfo.C \ | |||
| GraphSort.C \ | |||
| GUI/Widgets/Fl_DeviceGUI.C \ | |||
| @@ -71,8 +73,10 @@ SOURCES = SpiralSynthModular.C \ | |||
| SpiralSound/Plugins/SpiralPlugin.C \ | |||
| SpiralSound/Plugins/SpiralPluginGUI.C \ | |||
| SpiralSound/PluginManager.C \ | |||
| SpiralSound/ChannelHandler.C \ | |||
| SettingsWindow.C | |||
| OBJECTS = SpiralSynthModular.o \ | |||
| OBJECTS = main.o \ | |||
| SpiralSynthModular.o \ | |||
| SpiralSynthModularInfo.o \ | |||
| GraphSort.o \ | |||
| GUI/Widgets/Fl_DeviceGUI.o \ | |||
| @@ -84,6 +88,7 @@ OBJECTS = SpiralSynthModular.o \ | |||
| SpiralSound/Plugins/SpiralPlugin.o \ | |||
| SpiralSound/Plugins/SpiralPluginGUI.o \ | |||
| SpiralSound/PluginManager.o \ | |||
| SpiralSound/ChannelHandler.o \ | |||
| SettingsWindow.o | |||
| INTERFACES = | |||
| UICDECLS = | |||
| @@ -91,7 +96,7 @@ UICIMPLS = | |||
| SRCMOC = | |||
| OBJMOC = | |||
| DIST = | |||
| TARGET = SpiralSynthModular | |||
| TARGET = spiralsynthmodular | |||
| SUBDIRS = @PLUGINLIST@ | |||
| @@ -165,6 +170,9 @@ uninstall: | |||
| ####### Compile | |||
| main.o : main.cpp \ | |||
| SpiralSynthModular.h | |||
| SpiralSynthModular.o: SpiralSynthModular.C \ | |||
| SpiralSynthModular.h \ | |||
| SpiralSynthModularInfo.h \ | |||
| @@ -191,6 +199,9 @@ SpiralSynthModularInfo.o: SpiralSynthModularInfo.C \ | |||
| GraphSort.o: GraphSort.C \ | |||
| GraphSort.h | |||
| SpiralSound/ChannelHandler.o: SpiralSound/ChannelHandler.C \ | |||
| SpiralSound/ChannelHandler.h | |||
| GUI/Widgets/Fl_DeviceGUI.o: GUI/Widgets/Fl_DeviceGUI.C \ | |||
| GUI/Widgets/Fl_DeviceGUI.h \ | |||
| GUI/Widgets/Fl_DragBar.H \ | |||
| @@ -29,6 +29,7 @@ | |||
| #include "SpiralSynthModular.h" | |||
| #include "SpiralSound/PluginManager.h" | |||
| #include "SpiralSound/Plugins/SpiralPluginGUI.h" | |||
| #include "GUI/SSM.xpm" | |||
| #include "GUI/load.xpm" | |||
| @@ -40,7 +41,7 @@ | |||
| //#define DEBUG_PLUGINS | |||
| const static string LABEL = "SpiralSynthModular 0.1.1b1"; | |||
| const static string LABEL = "SpiralSynthModular 0.1.1 MultiThreaded"; | |||
| static string TITLEBAR; | |||
| static const int FILE_VERSION = 3; | |||
| @@ -71,7 +72,8 @@ SynthModular::SynthModular(): | |||
| m_NextID(0), | |||
| m_NextPluginButton(1), | |||
| m_NextPluginButtonXPos(5), | |||
| m_NextPluginButtonYPos(20) | |||
| m_NextPluginButtonYPos(20), | |||
| m_PauseAudio(false) | |||
| { | |||
| m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | |||
| m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | |||
| @@ -83,6 +85,8 @@ m_NextPluginButtonYPos(20) | |||
| //m_Info.GUI_COLOUR = SpiralInfo::GUI_COLOUR; | |||
| for (int n=0; n<512; n++) Numbers[n]=n; | |||
| m_CH.Register("PauseAudio",&m_PauseAudio); | |||
| } | |||
| ////////////////////////////////////////////////////////// | |||
| @@ -97,6 +101,8 @@ SynthModular::~SynthModular() | |||
| void SynthModular::ClearUp() | |||
| { | |||
| PauseAudio(); | |||
| for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | |||
| i!=m_DeviceWinMap.end(); i++) | |||
| { | |||
| @@ -113,13 +119,29 @@ void SynthModular::ClearUp() | |||
| m_Canvas->Clear(); | |||
| m_DeviceWinMap.clear(); | |||
| m_NextID=0; | |||
| ResumeAudio(); | |||
| } | |||
| ////////////////////////////////////////////////////////// | |||
| void SynthModular::Update() | |||
| { | |||
| // run the plugins | |||
| m_CH.UpdateDataNow(); | |||
| if (m_PauseAudio) return; | |||
| // for all the plugins | |||
| for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | |||
| i!=m_DeviceWinMap.end(); i++) | |||
| { | |||
| // updates the data from the gui thread, if it's not blocking | |||
| i->second->m_Device->UpdateChannelHandler(); | |||
| // run any commands we've received from the GUI's | |||
| i->second->m_Device->ExecuteCommands(); | |||
| } | |||
| // run the plugins (only ones connected to anything) | |||
| list<int> ExecutionOrder = m_Canvas->GetGraph()->GetSortedList(); | |||
| for (list<int>::reverse_iterator i=ExecutionOrder.rbegin(); | |||
| i!=ExecutionOrder.rend(); i++) | |||
| @@ -127,7 +149,7 @@ void SynthModular::Update() | |||
| // use the graphsort order to remove internal latency | |||
| map<int,DeviceWin*>::iterator di=m_DeviceWinMap.find(*i); | |||
| if (di!=m_DeviceWinMap.end() && di->second->m_Device) | |||
| { | |||
| { | |||
| #ifdef DEBUG_PLUGINS | |||
| cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | |||
| #endif | |||
| @@ -149,6 +171,11 @@ void SynthModular::UpdatePluginGUIs() | |||
| for (map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | |||
| i!=m_DeviceWinMap.end(); i++) | |||
| { | |||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | |||
| { | |||
| i->second->m_DeviceGUI->GetPluginWindow()->redraw(); | |||
| } | |||
| if (i->second->m_DeviceGUI->Killed()) | |||
| { | |||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | |||
| @@ -160,7 +187,12 @@ void SynthModular::UpdatePluginGUIs() | |||
| 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) delete i->second->m_Device; | |||
| if (i->second->m_Device) | |||
| { | |||
| PauseAudio(); | |||
| delete i->second->m_Device; | |||
| ResumeAudio(); | |||
| } | |||
| m_DeviceWinMap.erase(i); | |||
| break; | |||
| } | |||
| @@ -497,6 +529,7 @@ DeviceWin* SynthModular::NewDeviceWin(int n, int x, int y) | |||
| if (temp) | |||
| { | |||
| temp->hide(); | |||
| temp->position(200,50); | |||
| m_AppGroup->add(temp); | |||
| m_MainWindow->redraw(); | |||
| @@ -578,7 +611,7 @@ void SynthModular::UpdateHostInfo() | |||
| str<<*this; | |||
| ClearUp(); | |||
| // update the settings | |||
| m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | |||
| m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | |||
| @@ -603,6 +636,8 @@ void SynthModular::cb_Update(void* o, bool mode) | |||
| istream &operator>>(istream &s, SynthModular &o) | |||
| { | |||
| o.PauseAudio(); | |||
| string dummy; | |||
| int ver; | |||
| s>>dummy>>dummy>>dummy>>ver; | |||
| @@ -666,8 +701,19 @@ istream &operator>>(istream &s, SynthModular &o) | |||
| temp->m_Device->SetUpdateInfoCallback(ID,o.cb_UpdatePluginInfo); | |||
| o.m_DeviceWinMap[ID]=temp; | |||
| o.m_DeviceWinMap[ID]->m_Device->StreamIn(s); // load the plugin | |||
| if (ver>1 && o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()) | |||
| { | |||
| // set the GUI up with the loaded values | |||
| // looks messy, but if we do it here, the plugin and it's gui can remain | |||
| // totally seperated. | |||
| ((SpiralPluginGUI*)(o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()))-> | |||
| UpdateValues(o.m_DeviceWinMap[ID]->m_Device); | |||
| // updates the data in the channel buffers, so the values don't | |||
| // get overwritten in the next tick. (should maybe be somewhere else) | |||
| o.m_DeviceWinMap[ID]->m_Device->GetChannelHandler()->FlushChannels(); | |||
| // position the plugin window in the main window | |||
| o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()->position(px,py); | |||
| @@ -692,6 +738,8 @@ istream &operator>>(istream &s, SynthModular &o) | |||
| s>>*o.m_Canvas; | |||
| o.ResumeAudio(); | |||
| return s; | |||
| } | |||
| @@ -699,6 +747,8 @@ istream &operator>>(istream &s, SynthModular &o) | |||
| ostream &operator<<(ostream &s, SynthModular &o) | |||
| { | |||
| o.PauseAudio(); | |||
| s<<"SpiralSynthModular File Ver "<<FILE_VERSION<<endl; | |||
| // make external files dir | |||
| @@ -772,6 +822,8 @@ ostream &operator<<(ostream &s, SynthModular &o) | |||
| system(command.c_str()); | |||
| } | |||
| o.ResumeAudio(); | |||
| return s; | |||
| } | |||
| @@ -810,7 +862,7 @@ inline void SynthModular::cb_Load_i(Fl_Button* o, void* v) | |||
| ClearUp(); | |||
| inf>>*this; | |||
| TITLEBAR=LABEL+" "+fn; | |||
| m_TopWindow->label(TITLEBAR.c_str()); | |||
| } | |||
| @@ -842,9 +894,9 @@ inline void SynthModular::cb_Save_i(Fl_Button* o, void* v) | |||
| if (of) | |||
| { | |||
| m_FilePath=fn; | |||
| of<<*this; | |||
| TITLEBAR=LABEL+" "+fn; | |||
| m_TopWindow->label(TITLEBAR.c_str()); | |||
| } | |||
| @@ -1024,7 +1076,7 @@ void SynthModular::LoadPatch(const char *fn) | |||
| { | |||
| m_FilePath=fn; | |||
| ClearUp(); | |||
| ClearUp(); | |||
| inf>>*this; | |||
| TITLEBAR=LABEL+" "+fn; | |||
| @@ -1033,46 +1085,3 @@ void SynthModular::LoadPatch(const char *fn) | |||
| } | |||
| ////////////////////////////////////////////////////////// | |||
| ////////////////////////////////////////////////////////// | |||
| int main(int argc, char **argv) | |||
| { | |||
| srand(time(NULL)); | |||
| SpiralSynthModularInfo::Get()->LoadPrefs(); | |||
| // get args | |||
| string cmd_filename=""; | |||
| bool cmd_specd = false; | |||
| if (argc>1) | |||
| { | |||
| cmd_filename = argv[1]; | |||
| cmd_specd = true; | |||
| } | |||
| Fl::visual(FL_DOUBLE|FL_RGB); | |||
| SynthModular *synth=new SynthModular; | |||
| Fl_Window* win = synth->CreateWindow(); | |||
| synth->LoadPlugins(); | |||
| win->xclass(""); | |||
| win->show(argc, argv); // prevents stuff happening before the plugins have loaded | |||
| Fl_Tooltip::size(10); | |||
| Fl::visible_focus(false); | |||
| // do we need to load a patch on startup? | |||
| if (cmd_specd) synth->LoadPatch(cmd_filename.c_str()); | |||
| for (;;) | |||
| { | |||
| if (!Fl::check()) break; | |||
| if (!synth->CallbackMode()) synth->Update(); | |||
| synth->UpdatePluginGUIs(); // deletes any if necc | |||
| //else Fl::wait(); | |||
| } | |||
| delete synth; | |||
| return 1; | |||
| } | |||
| @@ -36,6 +36,7 @@ | |||
| #include "GUI/Widgets/Fl_CommentGUI.h" | |||
| #include "GUI/Widgets/Fl_Canvas.h" | |||
| #include "SpiralSound/Plugins/SpiralPlugin.h" | |||
| #include "SpiralSound/ChannelHandler.h" | |||
| #include "SettingsWindow.h" | |||
| typedef Fl_Double_Window SpiralWindowType; | |||
| @@ -71,6 +72,17 @@ public: | |||
| void UpdatePluginGUIs(); | |||
| void LoadPatch(const char *fn); | |||
| void PauseAudio() | |||
| { | |||
| m_CH.Set("PauseAudio",true); | |||
| m_CH.Wait(); | |||
| } | |||
| void ResumeAudio() | |||
| { | |||
| m_CH.Set("PauseAudio",false); | |||
| } | |||
| private: | |||
| DeviceWin* NewDeviceWin(int n, int x, int y); | |||
| @@ -121,6 +133,9 @@ private: | |||
| vector<Fl_Button*> m_DeviceVec; | |||
| ChannelHandler m_CH; // used for threadsafe communication | |||
| bool m_PauseAudio; | |||
| inline void cb_NewDevice_i(Fl_Button* o, void* v); | |||
| static void cb_NewDevice(Fl_Button* o, void* v); | |||
| inline void cb_NewDeviceFromMenu_i(Fl_Canvas* o, void* v); | |||
| @@ -86,25 +86,15 @@ SpiralSynthModularInfo::SpiralSynthModularInfo() | |||
| PLUGINVEC.push_back("FilterPlugin.so"); | |||
| PLUGINVEC.push_back("SVFilterPlugin.so"); | |||
| PLUGINVEC.push_back("MoogFilterPlugin.so"); | |||
| PLUGINVEC.push_back("WaveShaperPlugin.so"); | |||
| PLUGINVEC.push_back("EchoPlugin.so"); | |||
| PLUGINVEC.push_back("DelayPlugin.so"); | |||
| PLUGINVEC.push_back("SamplerPlugin.so"); | |||
| PLUGINVEC.push_back("SeqPlugin.so"); | |||
| PLUGINVEC.push_back("MatrixPlugin.so"); | |||
| PLUGINVEC.push_back("SeqSelectorPlugin.so"); | |||
| PLUGINVEC.push_back("EnvFollowerPlugin.so"); | |||
| PLUGINVEC.push_back("SmoothPlugin.so"); | |||
| PLUGINVEC.push_back("LADSPAPlugin.so"); | |||
| PLUGINVEC.push_back("XFadePlugin.so"); | |||
| PLUGINVEC.push_back("StreamPlugin.so"); | |||
| PLUGINVEC.push_back("SpiralLoopPlugin.so"); | |||
| PLUGINVEC.push_back("PoshSamplerPlugin.so"); | |||
| PLUGINVEC.push_back("ComplexEnvelopePlugin.so"); | |||
| PLUGINVEC.push_back("DistributorPlugin.so"); | |||
| PLUGINVEC.push_back("JoystickPlugin.so"); | |||
| PLUGINVEC.push_back("LFOPlugin.so"); | |||
| PLUGINVEC.push_back("MeterPlugin.so"); | |||
| } | |||
| void SpiralSynthModularInfo::StreamInPrefs(istream &s) | |||
| @@ -40,7 +40,7 @@ public: | |||
| protected: | |||
| SpiralSynthModularInfo(); | |||
| virtual string GetResFileName() { return ".SpiralSynthModular"; } | |||
| virtual string GetResFileName() { return ".SpiralSynthModularMT"; } | |||
| static SpiralSynthModularInfo *m_SpiralSynthModularInfo; | |||
| @@ -17,4 +17,4 @@ | |||
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #define PLUGIN_PATH_LOCATION "@PLUGINDIR@/" | |||
| #define PLUGIN_PATH_LOCATION "@prefix@/lib/SpiralPlugins/" | |||
| @@ -41,18 +41,18 @@ if test $ac_arg_jack = "Y" ; then | |||
| PLUGINLIST="AmpPlugin ControllerPlugin DelayPlugin EchoPlugin EnvFollowerPlugin \ | |||
| EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | |||
| NoteSnapPlugin OscillatorPlugin OutputPlugin RingModPlugin SVFilterPlugin \ | |||
| SampleHoldPlugin SamplerPlugin ScopePlugin SeqPlugin SmoothPlugin SplitterPlugin \ | |||
| StereoMixerPlugin WaveTablePlugin SeqSelectorPlugin LADSPAPlugin WaveShaperPlugin \ | |||
| StreamPlugin XFadePlugin SpiralLoopPlugin JackPlugin PoshSamplerPlugin \ | |||
| ComplexEnvelopePlugin DistributorPlugin JoystickPlugin LFOPlugin MeterPlugin" | |||
| SampleHoldPlugin ScopePlugin SmoothPlugin SplitterPlugin \ | |||
| StereoMixerPlugin WaveTablePlugin LADSPAPlugin \ | |||
| XFadePlugin JackPlugin \ | |||
| DistributorPlugin LFOPlugin" | |||
| else | |||
| PLUGINLIST="AmpPlugin ControllerPlugin DelayPlugin EchoPlugin EnvFollowerPlugin \ | |||
| EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | |||
| NoteSnapPlugin OscillatorPlugin OutputPlugin RingModPlugin SVFilterPlugin \ | |||
| SampleHoldPlugin SamplerPlugin ScopePlugin SeqPlugin SmoothPlugin SplitterPlugin \ | |||
| StereoMixerPlugin WaveTablePlugin SeqSelectorPlugin LADSPAPlugin WaveShaperPlugin \ | |||
| StreamPlugin XFadePlugin SpiralLoopPlugin PoshSamplerPlugin ComplexEnvelopePlugin \ | |||
| DistributorPlugin JoystickPlugin LFOPlugin MeterPlugin" | |||
| SampleHoldPlugin ScopePlugin SmoothPlugin SplitterPlugin \ | |||
| StereoMixerPlugin WaveTablePlugin LADSPAPlugin \ | |||
| XFadePlugin PoshSamplerPlugin\ | |||
| DistributorPlugin LFOPlugin" | |||
| fi | |||
| echo "$PLUGINLIST" > SpiralSound/PluginList.txt | |||
| @@ -93,9 +93,10 @@ AC_SUBST(FLTK_CXXFLAGS) | |||
| AC_SUBST(FLTK_CFLAGS) | |||
| AC_SUBST(FLTK_LIBS) | |||
| if test $ac_arg_jack = "Y" ; then | |||
| AM_PATH_GLIB(1.2.0,,AC_MSG_ERROR([*** GLIB >= 1.2.0 not installed])) | |||
| fi | |||
| dnl I can't get this to work ? | |||
| dnl if test $ac_arg_jack = "Y" ; then | |||
| dnl AM_PATH_GLIB(1.2.0,,AC_MSG_ERROR([*** GLIB >= 1.2.0 not installed])) | |||
| dnl fi | |||
| AC_CHECK_HEADERS(dlfcn.h) | |||
| AC_CHECK_LIB(dl, dlopen) | |||
| @@ -0,0 +1,169 @@ | |||
| /* SpiralSynthModular | |||
| * Copyleft (C) 2002 David Griffiths <dave@pawfal.org> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * (at your option) any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU General Public License | |||
| * along with this program; if not, write to the Free Software | |||
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include <iostream.h> | |||
| #include <stdlib.h> | |||
| #include <FL/Fl.H> | |||
| #include <FL/Fl_Tooltip.h> | |||
| #include <unistd.h> | |||
| #include "SpiralSynthModular.h" | |||
| pthread_t loopthread; | |||
| SynthModular *synth; | |||
| int pthread_create_realtime (pthread_t *new_thread, | |||
| void *(*start)(void *), void *arg, | |||
| int priority); | |||
| char flashy[] = {'|','/','-','\\'}; | |||
| void audioloop(void* o) | |||
| { | |||
| int counter=0,flashy_counter=0; | |||
| while(1) | |||
| { | |||
| synth->Update(); | |||
| if (counter==10000) | |||
| { | |||
| cerr<<"\b"<<flashy[flashy_counter%4]; | |||
| counter=0; | |||
| flashy_counter++; | |||
| } | |||
| counter++; | |||
| } | |||
| } | |||
| 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; | |||
| // parse the args | |||
| if (argc>1) | |||
| { | |||
| cmd_filename = argv[1]; | |||
| cmd_specd = true; | |||
| for (int a=2; a<argc; a++) | |||
| { | |||
| if (!strcmp(argv[a],"--NoGUI")) GUI = false; | |||
| if (!strcmp(argv[a],"--SHED_FIFO")) FIFO = true; | |||
| } | |||
| } | |||
| Fl::visual(FL_DOUBLE|FL_RGB); | |||
| synth=new SynthModular; | |||
| // setup the synth | |||
| Fl_Window* win = synth->CreateWindow(); | |||
| synth->LoadPlugins(); | |||
| win->xclass(""); | |||
| if (GUI) win->show(argc, argv); // prevents stuff happening before the plugins have loaded | |||
| // set some fltk defaults | |||
| Fl_Tooltip::size(10); | |||
| Fl::visible_focus(false); | |||
| // spawn the audio thread | |||
| int ret; | |||
| if (FIFO) ret=pthread_create_realtime(&loopthread,(void*(*)(void*))audioloop,NULL,50); | |||
| else ret=pthread_create(&loopthread,NULL,(void*(*)(void*))audioloop,NULL); | |||
| // do we need to load a patch on startup? | |||
| if (cmd_specd) synth->LoadPatch(cmd_filename.c_str()); | |||
| if (!GUI) | |||
| { | |||
| // if there is no gui needed, there is nothing more to do here | |||
| Fl::check(); | |||
| for (;;) sleep(1); | |||
| } | |||
| for (;;) | |||
| { | |||
| if (!Fl::check()) break; | |||
| //if (!synth->CallbackMode()) synth->Update(); | |||
| synth->UpdatePluginGUIs(); // deletes any if necc | |||
| //else Fl::wait(); | |||
| usleep(10000); | |||
| } | |||
| //pthread_cancel(loopthread); | |||
| delete synth; | |||
| return 1; | |||
| } | |||
| // nicked from Paul Barton-Davis' Ardour code :) | |||
| int pthread_create_realtime (pthread_t *new_thread, | |||
| void *(*start)(void *), void *arg, | |||
| int priority) | |||
| { | |||
| pthread_attr_t *rt_attributes; | |||
| struct sched_param *rt_param; | |||
| int retval; | |||
| rt_attributes = (pthread_attr_t *) malloc (sizeof (pthread_attr_t)); | |||
| rt_param = (struct sched_param *) malloc (sizeof (struct sched_param)); | |||
| pthread_attr_init (rt_attributes); | |||
| if (seteuid (0)) { | |||
| cerr << "Cannot obtain root UID for RT scheduling operations" | |||
| << endl; | |||
| return -1; | |||
| } else { | |||
| if (pthread_attr_setschedpolicy (rt_attributes, SCHED_FIFO)) { | |||
| cerr << "Cannot set FIFO scheduling attributes for RT thread" << endl; | |||
| } | |||
| if (pthread_attr_setscope (rt_attributes, PTHREAD_SCOPE_SYSTEM)) { | |||
| cerr << "Cannot set scheduling scope for RT thread" << endl; | |||
| } | |||
| rt_param->sched_priority = priority; | |||
| if (pthread_attr_setschedparam (rt_attributes, rt_param)) { | |||
| cerr << "Cannot set scheduling priority for RT thread" << endl; | |||
| } | |||
| } | |||
| retval = pthread_create (new_thread, rt_attributes, start, arg); | |||
| seteuid (getuid()); | |||
| return retval; | |||
| } | |||