Fix scope error with newer GCC.
[spiralsynthmodular.git] / main.cpp
blob4e4db2aad3adb64f2639868dfcccac652c3d539a
1 /* SpiralSynthModular
2 * Copyleft (C) 2002 David Griffiths <dave@pawfal.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <iostream>
24 #include <cstdlib>
25 #include <FL/Fl.H>
26 #include <FL/Fl_Tooltip.H>
27 #include <unistd.h>
28 #include <sys/time.h>
29 #include <sys/resource.h>
31 #include "SpiralSynthModular.h"
32 #include "SpiralSound/SpiralInfo.h"
34 pthread_t loopthread,watchdogthread;
35 SynthModular *synth;
37 char watchdog_check = 1;
38 char gui_watchdog_check = 1;
40 int pthread_create_realtime (pthread_t *new_thread,
41 void *(*start)(void *), void *arg,
42 int priority);
44 bool CallbackOnly = false;
45 bool FIFO = false;
46 bool GUI = true;
48 /////////////////////////////////////////////////////////////
50 void watchdog (void *arg)
52 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
54 watchdog_check = 0;
55 gui_watchdog_check = 0;
57 while (1)
59 usleep (10000000);
60 // gui watchdog goes off with modal dialog boxes
61 if (watchdog_check == 0)// || gui_watchdog_check== 0)
63 cerr<<"ssm watchdog: timeout - killing ssm"<<endl;
64 if (watchdog_check==0) cerr<<"diagnosis: audio hung?"<<endl;
65 if (gui_watchdog_check==0) cerr<<"diagnosis: gui starved by audio"<<endl;
66 exit (1);
68 watchdog_check = 0;
69 gui_watchdog_check = 0;
73 ///////////////////////////////////////////////////////////////////////
75 void audioloop(void* o)
77 while(1)
79 if (!synth->CallbackMode())
81 // do funky stuff
82 synth->Update();
84 // put the brakes on if there is no blocking output running
85 if (!synth->IsBlockingOutputPluginReady()||
86 synth->IsFrozen())
88 usleep(10000);
91 else
93 // the engine is currently in callback mode, so we don't
94 // need to do anything unless we are switched back
95 usleep(1000000);
98 watchdog_check = 1;
102 //////////////////////////////////////////////////////
103 #if __APPLE__
104 #include <CoreFoundation/CFBundle.h>
105 #include <libgen.h>
106 #endif
108 #include "GraphSort.h"
110 int main(int argc, char **argv)
112 #if __APPLE__
113 // --with-plugindir=./Libraries
114 system("pwd");
115 CFBundleRef main = CFBundleGetMainBundle();
116 CFURLRef url = main ? CFBundleCopyExecutableURL(main) : NULL;
117 CFStringRef path = url ? CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) : NULL;
118 char * dst = (char*)CFStringGetCStringPtr(path, 0);
120 printf("main %p url %p path %p dst %p", main, url, path, dst);
121 if (dst) {
122 printf("Have a valid name '%s'\n", dst);
123 chdir(dirname(dst));
124 chdir("..");
125 } else
126 printf("No base pathname\n");
127 #endif
128 srand(time(NULL));
129 SpiralInfo::Get()->LoadPrefs();
131 // get args
132 string cmd_filename="";
133 bool cmd_specd = false;
134 string cmd_pluginPath="";
135 // parse the args
136 if (argc>1)
138 for (int a=1; a<argc; a++)
140 if (!strcmp(argv[a],"--NoGUI")) GUI = false;
141 else if (!strcmp(argv[a],"--Realtime")) FIFO = true;
142 else if (!strcmp(argv[a],"-h"))
144 cout<<"usage: spiralsynthmodular [patch.ssm] [options]"<<endl<<endl
145 <<"options list"<<endl
146 <<"-h : help"<<endl
147 <<"-v : print version"<<endl
148 <<"--NoGUI : run without GUI (only useful when loading patch from command line"<<endl
149 <<"--Realtime : spawn audio thread with FIFO scheduling (run as root)"<<endl
150 <<"--PluginPath <PATH> : look for plugins in the specified directory"<<endl;
151 exit(0);
153 else if (!strcmp(argv[a],"-v"))
155 cout<<VER_STRING<<endl; exit(0);
157 else if (!strcmp(argv[a],"--PluginPath"))
159 a++;
160 cmd_pluginPath=argv[a];
162 else
164 cmd_filename = argv[1];
165 cmd_specd = true;
170 // set some fltk defaults
171 Fl_Tooltip::size(10);
172 Fl::visible_focus(false);
173 Fl::visual(FL_DOUBLE|FL_RGB);
175 synth=new SynthModular;
177 // setup the synth
178 Fl_Window* win = synth->CreateWindow();
180 synth->LoadPlugins(cmd_pluginPath);
181 win->xclass("");
182 if (GUI) win->show(1, argv); // prevents stuff happening before the plugins have loaded
184 // spawn the audio thread
185 if (FIFO)
187 pthread_create_realtime(&watchdogthread,(void*(*)(void*))watchdog,NULL,sched_get_priority_max(SCHED_FIFO));
188 pthread_create_realtime(&loopthread,(void*(*)(void*))audioloop,NULL,sched_get_priority_max(SCHED_FIFO)-1);
190 else
192 pthread_create(&loopthread,NULL,(void*(*)(void*))audioloop,NULL);
193 // reduce the priority of the gui
194 if (setpriority(PRIO_PROCESS,0,20)) cerr<<"Could not set priority for GUI thread"<<endl;
197 // do we need to load a patch on startup?
198 if (cmd_specd) synth->LoadPatch(cmd_filename.c_str());
200 if (!GUI)
202 // if there is no gui needed, there is nothing more to do here
203 Fl::check();
204 for (;;) sleep(1);
207 for (;;)
209 if (!Fl::check()) break;
210 synth->UpdatePluginGUIs(); // deletes any if necc
211 usleep(10000);
212 gui_watchdog_check=1;
215 //pthread_cancel(loopthread);
216 delete synth;
218 return 1;
221 // nicked from Paul Barton-Davis' Ardour code :)
222 int pthread_create_realtime (pthread_t *new_thread,
223 void *(*start)(void *), void *arg,
224 int priority)
227 pthread_attr_t *rt_attributes;
228 struct sched_param *rt_param;
229 int retval;
231 rt_attributes = (pthread_attr_t *) malloc (sizeof (pthread_attr_t));
232 rt_param = (struct sched_param *) malloc (sizeof (struct sched_param));
234 pthread_attr_init (rt_attributes);
236 if (seteuid (0)) {
237 cerr << "Cannot obtain root UID for RT scheduling operations"
238 << endl;
239 return -1;
241 } else {
243 if (pthread_attr_setschedpolicy (rt_attributes, SCHED_FIFO)) {
244 cerr << "Cannot set FIFO scheduling attributes for RT thread" << endl;
248 if (pthread_attr_setscope (rt_attributes, PTHREAD_SCOPE_SYSTEM)) {
249 cerr << "Cannot set scheduling scope for RT thread" << endl;
253 rt_param->sched_priority = priority;
254 if (pthread_attr_setschedparam (rt_attributes, rt_param)) {
255 cerr << "Cannot set scheduling priority for RT thread" << endl;
260 retval = pthread_create (new_thread, rt_attributes, start, arg);
261 seteuid (getuid());
263 return retval;