Browse Source

Realtime SCHED_FIFO mode working, matrix fixes, PawfalYesNo fixes

master
nebogeo 23 years ago
parent
commit
5531587854
12 changed files with 276 additions and 116 deletions
  1. +1
    -0
      GUI/Widgets/PawfalYesNo.C
  2. +44
    -15
      SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C
  3. +2
    -0
      SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.h
  4. +8
    -24
      SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.C
  5. +1
    -0
      SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h
  6. +89
    -25
      SpiralSound/Plugins/OutputPlugin/OutputPlugin.C
  7. +9
    -5
      SpiralSound/Plugins/OutputPlugin/OutputPlugin.h
  8. +23
    -14
      SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C
  9. +9
    -2
      SpiralSound/Plugins/SpiralPlugin.h
  10. +20
    -8
      SpiralSynthModular.C
  11. +7
    -0
      SpiralSynthModular.h
  12. +63
    -23
      main.cpp

+ 1
- 0
GUI/Widgets/PawfalYesNo.C View File

@@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

bool Pawfal_YesNo(const char *a,...)
{


+ 44
- 15
SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.C View File

@@ -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<NUM_PATTERNS; n++)
{
m_Matrix[n].Length=32;
m_Matrix[n].Length=64;
m_Matrix[n].Speed=1.0f;
m_Matrix[n].Octave=0;
@@ -149,7 +153,7 @@ void MatrixPlugin::Execute()
if (m_Step+1 >= 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; i<MATY; i++)
{
@@ -271,7 +300,7 @@ void MatrixPlugin::ExecuteCommands()
break;
case MAT_SPEED :
m_Matrix[m_Current].Speed=m_GUIArgs.Speed;
m_Matrix[m_Current].Speed=m_GUIArgs.Speed/8.0f;
break;
case MAT_ACTIVATE :


+ 2
- 0
SpiralSound/Plugins/MatrixPlugin/MatrixPlugin.h View File

@@ -95,6 +95,8 @@ private:
bool m_Triggered;
bool m_ClockHigh;
int m_CopyPattern;
bool m_PatAdvance;
bool m_PatReset;
};

#endif

+ 8
- 24
SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.C View File

@@ -87,7 +87,8 @@ int Fl_MatrixButton::handle(int event)
////////////////////////////////////////////

MatrixPluginGUI::MatrixPluginGUI(int w, int h,MatrixPlugin *o,ChannelHandler *ch,const HostInfo *Info) :
SpiralPluginGUI(w,h,o,ch)
SpiralPluginGUI(w,h,o,ch),
m_LastLight(0)
{
//size_range(10,10);
m_NoteCut = new Fl_Button (5, h-30, 85, 20,"NoteCut");
@@ -207,14 +208,13 @@ SpiralPluginGUI(w,h,o,ch)

void MatrixPluginGUI::Update()
{
for(int x=0; x<MATX; x++)
int Light=m_GUICH->GetInt("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; i<MATX; i++)
{
m_Flash[i]->value(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()<<endl;
m_GUICH->Set("Length",(int)o->value());
m_GUICH->SetCommand(MatrixPlugin::MAT_LENGTH);



+ 1
- 0
SpiralSound/Plugins/MatrixPlugin/MatrixPluginGUI.h View File

@@ -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;


+ 89
- 25
SpiralSound/Plugins/OutputPlugin/OutputPlugin.C View File

@@ -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"<<endl;
close(m_Dspfd);
return true;
}

//////////////////////////////////////////////////////////////////////

void OSSOutput::OpenWrite()
bool OSSOutput::OpenWrite()
{
int result,val;
cerr<<"Opening dsp output"<<endl;
@@ -334,7 +389,7 @@ void OSSOutput::OpenWrite()
{
fprintf(stderr,"Can't open audio driver for writing.\n");
m_OutputOk=false;
return;
return false;
}
result = ioctl(m_Dspfd,SNDCTL_DSP_RESET,NULL);
@@ -381,11 +436,14 @@ void OSSOutput::OpenWrite()
val = host->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)"<<endl;
@@ -427,7 +488,7 @@ void OSSOutput::OpenReadWrite()
{
fprintf(stderr,"Can't open audio driver for writing.\n");
m_OutputOk=false;
return;
return false;
}
result = ioctl(m_Dspfd,SNDCTL_DSP_RESET,NULL);
@@ -474,4 +535,7 @@ void OSSOutput::OpenReadWrite()
val = host->SAMPLERATE;
result = ioctl(m_Dspfd,SNDCTL_DSP_SPEED,&val);
CHECK_AND_REPORT_ERROR;
m_OutputOk=true;
return true;
}

+ 9
- 5
SpiralSound/Plugins/OutputPlugin/OutputPlugin.h View File

@@ -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:


+ 23
- 14
SpiralSound/Plugins/OutputPlugin/OutputPluginGUI.C View File

@@ -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)


+ 9
- 2
SpiralSound/Plugins/SpiralPlugin.h View File

@@ -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:



+ 20
- 8
SpiralSynthModular.C View File

@@ -59,6 +59,7 @@ using namespace std;

map<int,DeviceWin*> 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 "<<i->second->m_PluginID<<endl;
cerr<<"Updating channelhandler of plugin "<<i->second->m_PluginID<<endl;
#endif
// updates the data from the gui thread, if it's not blocking
@@ -191,21 +192,24 @@ void SynthModular::UpdatePluginGUIs()
if (i->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;
}



+ 7
- 0
SpiralSynthModular.h View File

@@ -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);
};


+ 63
- 23
main.cpp View File

@@ -25,30 +25,66 @@
#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;
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"<<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();
// 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<argc; a++)
{
if (!strcmp(argv[a],"--NoGUI")) GUI = false;
else if (!strcmp(argv[a],"--SHED_FIFO")) FIFO = true;
else if (!strcmp(argv[a],"--CallbackOnly")) CallbackOnly = true;
else if (!strcmp(argv[a],"--Realtime")) FIFO = true;
else if (!strcmp(argv[a],"-h"))
{
cout<<"usage: spiralsynthmodular [options] [patch.ssm]"<<endl<<endl
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
<<"--SHED_FIFO : spawn audio thread with FIFO sheduling (run as root)"<<endl
<<"--CallbackOnly : prevents 100% cpu usage when idle, but makes OSS output unsable"<<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++;
@@ -108,12 +143,10 @@ int main(int argc, char **argv)
}
}
}
// set some fltk defaults
Fl_Tooltip::size(10);
Fl::visible_focus(false);
//Fl::set_font(FL_HELVETICA,FL_SCREEN);
Fl::visual(FL_DOUBLE|FL_RGB);
synth=new SynthModular;
@@ -125,11 +158,17 @@ int main(int argc, char **argv)
if (GUI) win->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"<<endl;
}
// do we need to load a patch on startup?
if (cmd_specd) synth->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);


Loading…
Cancel
Save