@@ -41,7 +41,7 @@ libdir = @libdir@ | |||||
infodir = @infodir@ | infodir = @infodir@ | ||||
mandir = @mandir@ | mandir = @mandir@ | ||||
SpiralPlugins = @PLUGINDIR@ | |||||
SpiralPlugins = $(libdir)/SpiralPlugins | |||||
####### Files | ####### Files | ||||
@@ -57,9 +57,11 @@ HEADERS = SpiralSynthModular.h \ | |||||
SpiralSound/Plugins/SpiralPlugin.h \ | SpiralSound/Plugins/SpiralPlugin.h \ | ||||
SpiralSound/Plugins/SpiralPluginGUI.h \ | SpiralSound/Plugins/SpiralPluginGUI.h \ | ||||
SpiralSound/PluginManager.h \ | SpiralSound/PluginManager.h \ | ||||
SpiralSound/ChannelHandler.h \ | |||||
SettingsWindow.h \ | SettingsWindow.h \ | ||||
SpiralSynthPluginLocation.h | SpiralSynthPluginLocation.h | ||||
SOURCES = SpiralSynthModular.C \ | |||||
SOURCES = main.cpp \ | |||||
SpiralSynthModular.C \ | |||||
SpiralSynthModularInfo.C \ | SpiralSynthModularInfo.C \ | ||||
GraphSort.C \ | GraphSort.C \ | ||||
GUI/Widgets/Fl_DeviceGUI.C \ | GUI/Widgets/Fl_DeviceGUI.C \ | ||||
@@ -71,8 +73,10 @@ SOURCES = SpiralSynthModular.C \ | |||||
SpiralSound/Plugins/SpiralPlugin.C \ | SpiralSound/Plugins/SpiralPlugin.C \ | ||||
SpiralSound/Plugins/SpiralPluginGUI.C \ | SpiralSound/Plugins/SpiralPluginGUI.C \ | ||||
SpiralSound/PluginManager.C \ | SpiralSound/PluginManager.C \ | ||||
SpiralSound/ChannelHandler.C \ | |||||
SettingsWindow.C | SettingsWindow.C | ||||
OBJECTS = SpiralSynthModular.o \ | |||||
OBJECTS = main.o \ | |||||
SpiralSynthModular.o \ | |||||
SpiralSynthModularInfo.o \ | SpiralSynthModularInfo.o \ | ||||
GraphSort.o \ | GraphSort.o \ | ||||
GUI/Widgets/Fl_DeviceGUI.o \ | GUI/Widgets/Fl_DeviceGUI.o \ | ||||
@@ -84,6 +88,7 @@ OBJECTS = SpiralSynthModular.o \ | |||||
SpiralSound/Plugins/SpiralPlugin.o \ | SpiralSound/Plugins/SpiralPlugin.o \ | ||||
SpiralSound/Plugins/SpiralPluginGUI.o \ | SpiralSound/Plugins/SpiralPluginGUI.o \ | ||||
SpiralSound/PluginManager.o \ | SpiralSound/PluginManager.o \ | ||||
SpiralSound/ChannelHandler.o \ | |||||
SettingsWindow.o | SettingsWindow.o | ||||
INTERFACES = | INTERFACES = | ||||
UICDECLS = | UICDECLS = | ||||
@@ -91,7 +96,7 @@ UICIMPLS = | |||||
SRCMOC = | SRCMOC = | ||||
OBJMOC = | OBJMOC = | ||||
DIST = | DIST = | ||||
TARGET = SpiralSynthModular | |||||
TARGET = spiralsynthmodular | |||||
SUBDIRS = @PLUGINLIST@ | SUBDIRS = @PLUGINLIST@ | ||||
@@ -165,6 +170,9 @@ uninstall: | |||||
####### Compile | ####### Compile | ||||
main.o : main.cpp \ | |||||
SpiralSynthModular.h | |||||
SpiralSynthModular.o: SpiralSynthModular.C \ | SpiralSynthModular.o: SpiralSynthModular.C \ | ||||
SpiralSynthModular.h \ | SpiralSynthModular.h \ | ||||
SpiralSynthModularInfo.h \ | SpiralSynthModularInfo.h \ | ||||
@@ -191,6 +199,9 @@ SpiralSynthModularInfo.o: SpiralSynthModularInfo.C \ | |||||
GraphSort.o: GraphSort.C \ | GraphSort.o: GraphSort.C \ | ||||
GraphSort.h | 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.o: GUI/Widgets/Fl_DeviceGUI.C \ | ||||
GUI/Widgets/Fl_DeviceGUI.h \ | GUI/Widgets/Fl_DeviceGUI.h \ | ||||
GUI/Widgets/Fl_DragBar.H \ | GUI/Widgets/Fl_DragBar.H \ | ||||
@@ -29,6 +29,7 @@ | |||||
#include "SpiralSynthModular.h" | #include "SpiralSynthModular.h" | ||||
#include "SpiralSound/PluginManager.h" | #include "SpiralSound/PluginManager.h" | ||||
#include "SpiralSound/Plugins/SpiralPluginGUI.h" | |||||
#include "GUI/SSM.xpm" | #include "GUI/SSM.xpm" | ||||
#include "GUI/load.xpm" | #include "GUI/load.xpm" | ||||
@@ -40,7 +41,7 @@ | |||||
//#define DEBUG_PLUGINS | //#define DEBUG_PLUGINS | ||||
const static string LABEL = "SpiralSynthModular 0.1.1b1"; | |||||
const static string LABEL = "SpiralSynthModular 0.1.1 MultiThreaded"; | |||||
static string TITLEBAR; | static string TITLEBAR; | ||||
static const int FILE_VERSION = 3; | static const int FILE_VERSION = 3; | ||||
@@ -71,7 +72,8 @@ SynthModular::SynthModular(): | |||||
m_NextID(0), | m_NextID(0), | ||||
m_NextPluginButton(1), | m_NextPluginButton(1), | ||||
m_NextPluginButtonXPos(5), | m_NextPluginButtonXPos(5), | ||||
m_NextPluginButtonYPos(20) | |||||
m_NextPluginButtonYPos(20), | |||||
m_PauseAudio(false) | |||||
{ | { | ||||
m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | ||||
m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | ||||
@@ -83,6 +85,8 @@ m_NextPluginButtonYPos(20) | |||||
//m_Info.GUI_COLOUR = SpiralInfo::GUI_COLOUR; | //m_Info.GUI_COLOUR = SpiralInfo::GUI_COLOUR; | ||||
for (int n=0; n<512; n++) Numbers[n]=n; | 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() | void SynthModular::ClearUp() | ||||
{ | { | ||||
PauseAudio(); | |||||
for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | ||||
i!=m_DeviceWinMap.end(); i++) | i!=m_DeviceWinMap.end(); i++) | ||||
{ | { | ||||
@@ -113,13 +119,29 @@ void SynthModular::ClearUp() | |||||
m_Canvas->Clear(); | m_Canvas->Clear(); | ||||
m_DeviceWinMap.clear(); | m_DeviceWinMap.clear(); | ||||
m_NextID=0; | m_NextID=0; | ||||
ResumeAudio(); | |||||
} | } | ||||
////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////// | ||||
void SynthModular::Update() | 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(); | list<int> ExecutionOrder = m_Canvas->GetGraph()->GetSortedList(); | ||||
for (list<int>::reverse_iterator i=ExecutionOrder.rbegin(); | for (list<int>::reverse_iterator i=ExecutionOrder.rbegin(); | ||||
i!=ExecutionOrder.rend(); i++) | i!=ExecutionOrder.rend(); i++) | ||||
@@ -127,7 +149,7 @@ void SynthModular::Update() | |||||
// use the graphsort order to remove internal latency | // use the graphsort order to remove internal latency | ||||
map<int,DeviceWin*>::iterator di=m_DeviceWinMap.find(*i); | map<int,DeviceWin*>::iterator di=m_DeviceWinMap.find(*i); | ||||
if (di!=m_DeviceWinMap.end() && di->second->m_Device) | if (di!=m_DeviceWinMap.end() && di->second->m_Device) | ||||
{ | |||||
{ | |||||
#ifdef DEBUG_PLUGINS | #ifdef DEBUG_PLUGINS | ||||
cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | ||||
#endif | #endif | ||||
@@ -149,6 +171,11 @@ void SynthModular::UpdatePluginGUIs() | |||||
for (map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | for (map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | ||||
i!=m_DeviceWinMap.end(); i++) | 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->Killed()) | ||||
{ | { | ||||
if (i->second->m_DeviceGUI->GetPluginWindow()) | if (i->second->m_DeviceGUI->GetPluginWindow()) | ||||
@@ -160,7 +187,12 @@ void SynthModular::UpdatePluginGUIs() | |||||
m_Canvas->RemoveDevice(i->second->m_DeviceGUI); | m_Canvas->RemoveDevice(i->second->m_DeviceGUI); | ||||
// deleted by Canvas::Remove()? seems to cause random crashes | // deleted by Canvas::Remove()? seems to cause random crashes | ||||
//delete i->second->m_DeviceGUI; | //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); | m_DeviceWinMap.erase(i); | ||||
break; | break; | ||||
} | } | ||||
@@ -497,6 +529,7 @@ DeviceWin* SynthModular::NewDeviceWin(int n, int x, int y) | |||||
if (temp) | if (temp) | ||||
{ | { | ||||
temp->hide(); | |||||
temp->position(200,50); | temp->position(200,50); | ||||
m_AppGroup->add(temp); | m_AppGroup->add(temp); | ||||
m_MainWindow->redraw(); | m_MainWindow->redraw(); | ||||
@@ -578,7 +611,7 @@ void SynthModular::UpdateHostInfo() | |||||
str<<*this; | str<<*this; | ||||
ClearUp(); | ClearUp(); | ||||
// update the settings | // update the settings | ||||
m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | ||||
m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | ||||
@@ -603,6 +636,8 @@ void SynthModular::cb_Update(void* o, bool mode) | |||||
istream &operator>>(istream &s, SynthModular &o) | istream &operator>>(istream &s, SynthModular &o) | ||||
{ | { | ||||
o.PauseAudio(); | |||||
string dummy; | string dummy; | ||||
int ver; | int ver; | ||||
s>>dummy>>dummy>>dummy>>ver; | s>>dummy>>dummy>>dummy>>ver; | ||||
@@ -666,8 +701,19 @@ istream &operator>>(istream &s, SynthModular &o) | |||||
temp->m_Device->SetUpdateInfoCallback(ID,o.cb_UpdatePluginInfo); | temp->m_Device->SetUpdateInfoCallback(ID,o.cb_UpdatePluginInfo); | ||||
o.m_DeviceWinMap[ID]=temp; | o.m_DeviceWinMap[ID]=temp; | ||||
o.m_DeviceWinMap[ID]->m_Device->StreamIn(s); // load the plugin | o.m_DeviceWinMap[ID]->m_Device->StreamIn(s); // load the plugin | ||||
if (ver>1 && o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()) | 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 | // position the plugin window in the main window | ||||
o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()->position(px,py); | o.m_DeviceWinMap[ID]->m_DeviceGUI->GetPluginWindow()->position(px,py); | ||||
@@ -692,6 +738,8 @@ istream &operator>>(istream &s, SynthModular &o) | |||||
s>>*o.m_Canvas; | s>>*o.m_Canvas; | ||||
o.ResumeAudio(); | |||||
return s; | return s; | ||||
} | } | ||||
@@ -699,6 +747,8 @@ istream &operator>>(istream &s, SynthModular &o) | |||||
ostream &operator<<(ostream &s, SynthModular &o) | ostream &operator<<(ostream &s, SynthModular &o) | ||||
{ | { | ||||
o.PauseAudio(); | |||||
s<<"SpiralSynthModular File Ver "<<FILE_VERSION<<endl; | s<<"SpiralSynthModular File Ver "<<FILE_VERSION<<endl; | ||||
// make external files dir | // make external files dir | ||||
@@ -772,6 +822,8 @@ ostream &operator<<(ostream &s, SynthModular &o) | |||||
system(command.c_str()); | system(command.c_str()); | ||||
} | } | ||||
o.ResumeAudio(); | |||||
return s; | return s; | ||||
} | } | ||||
@@ -810,7 +862,7 @@ inline void SynthModular::cb_Load_i(Fl_Button* o, void* v) | |||||
ClearUp(); | ClearUp(); | ||||
inf>>*this; | inf>>*this; | ||||
TITLEBAR=LABEL+" "+fn; | TITLEBAR=LABEL+" "+fn; | ||||
m_TopWindow->label(TITLEBAR.c_str()); | m_TopWindow->label(TITLEBAR.c_str()); | ||||
} | } | ||||
@@ -842,9 +894,9 @@ inline void SynthModular::cb_Save_i(Fl_Button* o, void* v) | |||||
if (of) | if (of) | ||||
{ | { | ||||
m_FilePath=fn; | m_FilePath=fn; | ||||
of<<*this; | of<<*this; | ||||
TITLEBAR=LABEL+" "+fn; | TITLEBAR=LABEL+" "+fn; | ||||
m_TopWindow->label(TITLEBAR.c_str()); | m_TopWindow->label(TITLEBAR.c_str()); | ||||
} | } | ||||
@@ -1024,7 +1076,7 @@ void SynthModular::LoadPatch(const char *fn) | |||||
{ | { | ||||
m_FilePath=fn; | m_FilePath=fn; | ||||
ClearUp(); | |||||
ClearUp(); | |||||
inf>>*this; | inf>>*this; | ||||
TITLEBAR=LABEL+" "+fn; | 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_CommentGUI.h" | ||||
#include "GUI/Widgets/Fl_Canvas.h" | #include "GUI/Widgets/Fl_Canvas.h" | ||||
#include "SpiralSound/Plugins/SpiralPlugin.h" | #include "SpiralSound/Plugins/SpiralPlugin.h" | ||||
#include "SpiralSound/ChannelHandler.h" | |||||
#include "SettingsWindow.h" | #include "SettingsWindow.h" | ||||
typedef Fl_Double_Window SpiralWindowType; | typedef Fl_Double_Window SpiralWindowType; | ||||
@@ -71,6 +72,17 @@ public: | |||||
void UpdatePluginGUIs(); | void UpdatePluginGUIs(); | ||||
void LoadPatch(const char *fn); | void LoadPatch(const char *fn); | ||||
void PauseAudio() | |||||
{ | |||||
m_CH.Set("PauseAudio",true); | |||||
m_CH.Wait(); | |||||
} | |||||
void ResumeAudio() | |||||
{ | |||||
m_CH.Set("PauseAudio",false); | |||||
} | |||||
private: | private: | ||||
DeviceWin* NewDeviceWin(int n, int x, int y); | DeviceWin* NewDeviceWin(int n, int x, int y); | ||||
@@ -121,6 +133,9 @@ private: | |||||
vector<Fl_Button*> m_DeviceVec; | 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); | inline void cb_NewDevice_i(Fl_Button* o, void* v); | ||||
static void cb_NewDevice(Fl_Button* o, void* v); | static void cb_NewDevice(Fl_Button* o, void* v); | ||||
inline void cb_NewDeviceFromMenu_i(Fl_Canvas* 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("FilterPlugin.so"); | ||||
PLUGINVEC.push_back("SVFilterPlugin.so"); | PLUGINVEC.push_back("SVFilterPlugin.so"); | ||||
PLUGINVEC.push_back("MoogFilterPlugin.so"); | PLUGINVEC.push_back("MoogFilterPlugin.so"); | ||||
PLUGINVEC.push_back("WaveShaperPlugin.so"); | |||||
PLUGINVEC.push_back("EchoPlugin.so"); | PLUGINVEC.push_back("EchoPlugin.so"); | ||||
PLUGINVEC.push_back("DelayPlugin.so"); | PLUGINVEC.push_back("DelayPlugin.so"); | ||||
PLUGINVEC.push_back("SamplerPlugin.so"); | |||||
PLUGINVEC.push_back("SeqPlugin.so"); | |||||
PLUGINVEC.push_back("MatrixPlugin.so"); | PLUGINVEC.push_back("MatrixPlugin.so"); | ||||
PLUGINVEC.push_back("SeqSelectorPlugin.so"); | |||||
PLUGINVEC.push_back("EnvFollowerPlugin.so"); | PLUGINVEC.push_back("EnvFollowerPlugin.so"); | ||||
PLUGINVEC.push_back("SmoothPlugin.so"); | PLUGINVEC.push_back("SmoothPlugin.so"); | ||||
PLUGINVEC.push_back("LADSPAPlugin.so"); | PLUGINVEC.push_back("LADSPAPlugin.so"); | ||||
PLUGINVEC.push_back("XFadePlugin.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("DistributorPlugin.so"); | ||||
PLUGINVEC.push_back("JoystickPlugin.so"); | |||||
PLUGINVEC.push_back("LFOPlugin.so"); | PLUGINVEC.push_back("LFOPlugin.so"); | ||||
PLUGINVEC.push_back("MeterPlugin.so"); | |||||
} | } | ||||
void SpiralSynthModularInfo::StreamInPrefs(istream &s) | void SpiralSynthModularInfo::StreamInPrefs(istream &s) | ||||
@@ -40,7 +40,7 @@ public: | |||||
protected: | protected: | ||||
SpiralSynthModularInfo(); | SpiralSynthModularInfo(); | ||||
virtual string GetResFileName() { return ".SpiralSynthModular"; } | |||||
virtual string GetResFileName() { return ".SpiralSynthModularMT"; } | |||||
static SpiralSynthModularInfo *m_SpiralSynthModularInfo; | static SpiralSynthModularInfo *m_SpiralSynthModularInfo; | ||||
@@ -17,4 +17,4 @@ | |||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | * 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 \ | PLUGINLIST="AmpPlugin ControllerPlugin DelayPlugin EchoPlugin EnvFollowerPlugin \ | ||||
EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | ||||
NoteSnapPlugin OscillatorPlugin OutputPlugin RingModPlugin SVFilterPlugin \ | 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 | else | ||||
PLUGINLIST="AmpPlugin ControllerPlugin DelayPlugin EchoPlugin EnvFollowerPlugin \ | PLUGINLIST="AmpPlugin ControllerPlugin DelayPlugin EchoPlugin EnvFollowerPlugin \ | ||||
EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | EnvelopePlugin FilterPlugin MatrixPlugin MidiPlugin MixerPlugin MoogFilterPlugin \ | ||||
NoteSnapPlugin OscillatorPlugin OutputPlugin RingModPlugin SVFilterPlugin \ | 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 | fi | ||||
echo "$PLUGINLIST" > SpiralSound/PluginList.txt | echo "$PLUGINLIST" > SpiralSound/PluginList.txt | ||||
@@ -93,9 +93,10 @@ AC_SUBST(FLTK_CXXFLAGS) | |||||
AC_SUBST(FLTK_CFLAGS) | AC_SUBST(FLTK_CFLAGS) | ||||
AC_SUBST(FLTK_LIBS) | 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_HEADERS(dlfcn.h) | ||||
AC_CHECK_LIB(dl, dlopen) | 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; | |||||
} |