| 
							- /*  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>
 - #include <cstdlib>
 - #include <FL/Fl.H>
 - #include <FL/Fl_Tooltip.h>
 - #include <unistd.h>
 - #include <sys/time.h>
 - #include <sys/resource.h>
 - 
 - #include "SpiralSynthModular.h"
 - 
 - 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);
 - 		// gui watchdog goes off with modal dialog boxes
 - 		if (watchdog_check == 0)// || gui_watchdog_check== 0) 
 - 		{
 - 			cerr<<"ssm watchdog: timeout - killing ssm"<<endl;
 - 			if (watchdog_check==0) cerr<<"diagnosis: audio hung?"<<endl;
 - 			if (gui_watchdog_check==0) cerr<<"diagnosis: gui starved by audio"<<endl;
 - 			exit (1);
 - 		}
 - 		watchdog_check = 0;
 - 		gui_watchdog_check = 0;
 - 	}
 - }
 - 
 - ///////////////////////////////////////////////////////////////////////
 - 
 - void audioloop(void* o)
 - {
 - 	while(1)
 - 	{		
 - 		if (!synth->CallbackMode()) 
 - 		{
 - 			// do funky stuff
 - 			synth->Update();
 - 
 - 			// put the brakes on if there is no blocking output running
 - 			if (!synth->IsBlockingOutputPluginReady()||
 - 				 synth->IsPaused()) 
 - 			{
 - 				usleep(10000);
 - 			}
 - 		}
 - 		else
 - 		{
 - 			// the engine is currently in callback mode, so we don't
 - 			// need to do anything unless we are switched back 
 - 			usleep(1000000);
 - 		}
 - 		
 - 		watchdog_check = 1;
 - 	}
 - }
 - 
 - //////////////////////////////////////////////////////
 - #if __APPLE__
 - #include <CoreFoundation/CFBundle.h>
 - #include <libgen.h>
 - #endif
 - 
 - #include "GraphSort.h"
 - 
 - int main(int argc, char **argv)
 - {
 - #if __APPLE__
 - 	// --with-plugindir=./Libraries
 - 	system("pwd");
 - 	CFBundleRef main	= CFBundleGetMainBundle();
 - 	CFURLRef	url		= main ? CFBundleCopyExecutableURL(main) : NULL;
 - 	CFStringRef path	= url ? CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) : NULL;
 - 	char *		dst		= (char*)CFStringGetCStringPtr(path, 0);
 - 	
 - 	printf("main %p url %p path %p dst %p", main, url, path, dst);
 - 	if (dst) {
 - 		printf("Have a valid name '%s'\n", dst);
 - 		chdir(dirname(dst));
 - 		chdir("..");
 - 	} else
 - 		printf("No base pathname\n");
 - #endif
 - 	srand(time(NULL));
 - 	SpiralSynthModularInfo::Get()->LoadPrefs();
 - 	
 - 	// get args
 -     string cmd_filename="";
 -     bool cmd_specd = false;
 - 	string cmd_pluginPath="";
 - 	
 - 	// parse the args
 -     if (argc>1) 
 - 	{
 - 		for (int a=1; a<argc; a++)
 - 		{
 - 			if (!strcmp(argv[a],"--NoGUI")) GUI = false;
 - 			else if (!strcmp(argv[a],"--Realtime")) FIFO = true;
 - 			else if (!strcmp(argv[a],"-h")) 
 - 			{	
 - 				cout<<"usage: spiralsynthmodular [patch.ssm] [options]"<<endl<<endl
 - 				<<"options list"<<endl
 - 				<<"-h : help"<<endl
 - 				<<"-v : print version"<<endl
 - 				<<"--NoGUI : run without GUI (only useful when loading patch from command line"<<endl
 - 				<<"--Realtime : spawn audio thread with FIFO scheduling (run as root)"<<endl
 - 				<<"--PluginPath <PATH> : look for plugins in the specified directory"<<endl;
 - 				exit(0);
 - 			}
 - 			else if (!strcmp(argv[a],"-v")) 
 - 			{
 - 				cout<<VER_STRING<<endl; exit(0);
 - 			} 			
 - 			else if (!strcmp(argv[a],"--PluginPath"))
 - 			{
 - 				a++;
 - 				cmd_pluginPath=argv[a];
 - 			}
 - 			else 
 - 			{
 - 				cmd_filename = argv[1];
 - 				cmd_specd = true;
 - 			}
 - 		}
 -     }	
 - 	
 - 	// set some fltk defaults
 - 	Fl_Tooltip::size(10);	
 - 	Fl::visible_focus(false);
 - 	Fl::visual(FL_DOUBLE|FL_RGB);
 - 	
 - 	synth=new SynthModular;
 - 	
 - 	// setup the synth
 - 	Fl_Window* win = synth->CreateWindow();
 - 	synth->LoadPlugins(cmd_pluginPath);
 - 	win->xclass("");
 - 	if (GUI) win->show(1, argv); // prevents stuff happening before the plugins have loaded
 - 	
 - 	// spawn the audio thread
 - 	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"<<endl;
 - 	}
 - 	
 - 	// 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;    	
 - 		synth->UpdatePluginGUIs(); // deletes any if necc
 - 		usleep(10000);
 - 		gui_watchdog_check=1;
 -   	}
 - 	
 - 	//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;
 - }
 
 
  |