@@ -1,10 +1,10 @@ | |||
Release 0.2.0 | |||
App now multithreaded, and plugins use a new api to support this | |||
Jack support fully functional | |||
Jack support fully functional and stable | |||
-Realtime commandline option (as root) runs ssm audio in SCHED_FIFO | |||
LADSPA plugin much improved with built in GUI generator | |||
App help added with Helptext for most of the plugins | |||
App help added with Helptext for all of the plugins | |||
Numerous fixes, additions and GUI improvements | |||
Release 0.1.1 | |||
@@ -1,12 +1,13 @@ | |||
** SpiralSynthModular ** | |||
Last changed Saturday March 23 2002. | |||
Last changed Saturday December 11 2002. | |||
SpiralSynthModular is open source software, distributed under the General | |||
Public License (GPL). See the file COPYING. | |||
Dependancies: | |||
FLTK (www.fltk.org) | |||
FLTK (www.fltk.org) If you build FLTK from source use | |||
"./configure --enable-shared" | |||
Sound output can be provided by either OSS or JACK (and therefore alsa). | |||
@@ -26,7 +27,10 @@ For more examples be sure to check out the noize farm | |||
(http://groups.yahoo.com/group/noize_farm) an open source repository of | |||
ssm patches. | |||
options list | |||
usage: | |||
spiralsynthmodular options [patch.ssm] | |||
options list: | |||
-h : help | |||
-v : print version | |||
--NoGUI : run without GUI (only useful when loading patch from command line | |||
@@ -54,7 +58,7 @@ the realtime output doesn't. | |||
BufferSize = 512 - Size of sample buffer to be calculated each cycle. | |||
FragmentSize = 256 - Subbuffer size sent to the soundcard | |||
FragmentCount = -1 - Subbuffer count, -1 computes a suitable size, | |||
FragmentCount = 8 - Subbuffer count, -1 computes a suitable size, | |||
setting to 4 or 8 gets better latencies. | |||
Samplerate = 44100 - Sets the samplerate | |||
@@ -49,6 +49,7 @@ m_Step(0), | |||
m_Loop(true), | |||
m_NoteCut(false), | |||
m_Current(0), | |||
m_GUICurrent(0), | |||
m_CurrentNoteCV(0), | |||
m_CurrentTriggerCV(0), | |||
m_Triggered(false), | |||
@@ -109,7 +110,7 @@ m_PatReset(false) | |||
m_AudioCH->Register("NoteCut",&m_NoteCut,ChannelHandler::INPUT); | |||
m_AudioCH->Register("Volume",&m_GUIArgs.Volume,ChannelHandler::INPUT); | |||
m_AudioCH->Register("Current",&m_Current,ChannelHandler::INPUT); | |||
m_AudioCH->Register("Current",&m_GUICurrent,ChannelHandler::INPUT); | |||
m_AudioCH->Register("StepTime",&m_StepTime,ChannelHandler::INPUT); | |||
m_AudioCH->Register("Num",&m_GUIArgs.Num,ChannelHandler::INPUT); | |||
m_AudioCH->Register("Length",&m_GUIArgs.Length,ChannelHandler::INPUT); | |||
@@ -153,6 +154,9 @@ void MatrixPlugin::Execute() | |||
// clear the pattern sync | |||
SetOutput(18, n, 0); | |||
bool ExternalClock = InputExists(4); | |||
bool ExternalClockTriggered=false; | |||
if (GetInputPitch(0,n)>0) | |||
{ | |||
@@ -174,7 +178,7 @@ void MatrixPlugin::Execute() | |||
// will be the first one | |||
m_Time=m_StepTime*(1/m_Matrix[m_Current].Speed); | |||
m_Step=-1; | |||
ExternalClockTriggered=true; | |||
m_Triggered=true; | |||
} | |||
} | |||
@@ -186,10 +190,6 @@ void MatrixPlugin::Execute() | |||
// set the individual triggers | |||
for (int t=0; t<NUM_PATTERNS; t++) SetOutput(t+2,n,m_TriggerLevel[t]); | |||
bool ExternalClock = InputExists(4); | |||
bool ExternalClockTriggered=false; | |||
if (ExternalClock) | |||
{ | |||
@@ -258,6 +258,7 @@ void MatrixPlugin::Execute() | |||
m_Time=0; | |||
m_Step++; | |||
if (m_Step >= m_Matrix[m_Current].Length) | |||
{ | |||
SetOutput(18, n, 1); | |||
@@ -300,22 +301,22 @@ void MatrixPlugin::ExecuteCommands() | |||
switch (m_AudioCH->GetCommand()) | |||
{ | |||
case MAT_LENGTH : | |||
m_Matrix[m_Current].Length=m_GUIArgs.Length; | |||
m_Matrix[m_GUICurrent].Length=m_GUIArgs.Length; | |||
break; | |||
case MAT_SPEED : | |||
m_Matrix[m_Current].Speed=m_GUIArgs.Speed/8.0f; | |||
m_Matrix[m_GUICurrent].Speed=m_GUIArgs.Speed; | |||
break; | |||
case MAT_ACTIVATE : | |||
m_Matrix[m_Current].Matrix[m_GUIArgs.X][m_GUIArgs.Y]=true; | |||
m_Matrix[m_GUICurrent].Matrix[m_GUIArgs.X][m_GUIArgs.Y]=true; | |||
break; | |||
case MAT_DEACTIVATE : | |||
m_Matrix[m_Current].Matrix[m_GUIArgs.X][m_GUIArgs.Y]=false; | |||
m_Matrix[m_GUICurrent].Matrix[m_GUIArgs.X][m_GUIArgs.Y]=false; | |||
break; | |||
case MAT_OCTAVE : | |||
m_Matrix[m_Current].Octave=m_GUIArgs.Octave; | |||
m_Matrix[m_GUICurrent].Octave=m_GUIArgs.Octave; | |||
break; | |||
case COPY : | |||
CopyPattern(); | |||
@@ -333,16 +334,19 @@ void MatrixPlugin::ExecuteCommands() | |||
if (CanTransposeDown()) TransposeDown(); | |||
break; | |||
case MAT_VOLUME : | |||
m_Matrix[m_Current].Volume[m_GUIArgs.X][m_GUIArgs.Y]=m_GUIArgs.Volume; | |||
m_Matrix[m_GUICurrent].Volume[m_GUIArgs.X][m_GUIArgs.Y]=m_GUIArgs.Volume; | |||
break; | |||
case SET_CURRENT : | |||
m_Current=m_GUIArgs.Num; | |||
break; | |||
} | |||
} | |||
} | |||
void MatrixPlugin::PastePattern() { | |||
m_Matrix[m_Current].Length = m_Matrix[m_CopyPattern].Length; | |||
m_Matrix[m_Current].Speed = m_Matrix[m_CopyPattern].Speed; | |||
m_Matrix[m_Current].Octave = m_Matrix[m_CopyPattern].Octave; | |||
m_Matrix[m_GUICurrent].Length = m_Matrix[m_CopyPattern].Length; | |||
m_Matrix[m_GUICurrent].Speed = m_Matrix[m_CopyPattern].Speed; | |||
m_Matrix[m_GUICurrent].Octave = m_Matrix[m_CopyPattern].Octave; | |||
for (int y=0; y<MATY; y++) { | |||
for (int x=0; x<MATX; x++) { | |||
m_Matrix[m_Current].Matrix[x][y] = m_Matrix[m_CopyPattern].Matrix[x][y]; | |||
@@ -353,7 +357,7 @@ void MatrixPlugin::PastePattern() { | |||
void MatrixPlugin::ClearPattern() { | |||
for (int y=0; y<MATY; y++) { | |||
for (int x=0; x<MATX; x++) { | |||
m_Matrix[m_Current].Matrix[x][y] = 0; | |||
m_Matrix[m_GUICurrent].Matrix[x][y] = 0; | |||
} | |||
} | |||
} | |||
@@ -362,11 +366,11 @@ void MatrixPlugin::TransposeUp() { | |||
int x, y; | |||
for (y=MATY-1; y>=0; y--) { | |||
for (x=0; x<MATX; x++) { | |||
m_Matrix[m_Current].Matrix[x][y] = m_Matrix[m_Current].Matrix[x][y-1]; | |||
m_Matrix[m_GUICurrent].Matrix[x][y] = m_Matrix[m_GUICurrent].Matrix[x][y-1]; | |||
} | |||
} | |||
for (x=0; x<MATX; x++) { | |||
m_Matrix[m_Current].Matrix[x][0] = 0; | |||
m_Matrix[m_GUICurrent].Matrix[x][0] = 0; | |||
} | |||
} | |||
@@ -377,18 +381,18 @@ void MatrixPlugin::TransposeDown() | |||
{ | |||
for (x=0; x<MATX; x++) | |||
{ | |||
m_Matrix[m_Current].Matrix[x][y] = m_Matrix[m_Current].Matrix[x][y+1]; | |||
m_Matrix[m_GUICurrent].Matrix[x][y] = m_Matrix[m_GUICurrent].Matrix[x][y+1]; | |||
} | |||
} | |||
for (x=0; x<MATX; x++) | |||
{ | |||
m_Matrix[m_Current].Matrix[x][MATY-1] = 0; | |||
m_Matrix[m_GUICurrent].Matrix[x][MATY-1] = 0; | |||
} | |||
} | |||
bool MatrixPlugin::CanTransposeDown() | |||
{ | |||
for (int x=0; x<MATX; x++) if (m_Matrix[m_Current].Matrix[x][0]) return False; | |||
for (int x=0; x<MATX; x++) if (m_Matrix[m_GUICurrent].Matrix[x][0]) return False; | |||
return True; | |||
} | |||
@@ -54,7 +54,7 @@ public: | |||
Pattern* GetPattern() { return &m_Matrix[m_Current]; } | |||
enum GUICommands{NONE,MAT_LENGTH,MAT_SPEED,MAT_ACTIVATE,MAT_DEACTIVATE, | |||
MAT_OCTAVE,COPY,PASTE,CLEAR,TUP,TDOWN,MAT_VOLUME}; | |||
MAT_OCTAVE,COPY,PASTE,CLEAR,TUP,TDOWN,MAT_VOLUME,SET_CURRENT}; | |||
struct GUIArgs | |||
{ | |||
@@ -86,6 +86,7 @@ private: | |||
bool m_NoteCut; | |||
int m_Current; | |||
int m_GUICurrent; | |||
Pattern m_Matrix[NUM_PATTERNS]; | |||
float m_TriggerLevel[MATY]; | |||
@@ -111,7 +111,7 @@ m_LastLight(0) | |||
m_NoteCut->callback((Fl_Callback*)cb_NoteCut); | |||
add(m_NoteCut); | |||
m_Pattern = new Fl_Counter(5, 20, 40, 20, "Pattern"); | |||
m_Pattern = new Fl_Counter(5, 20, 40, 20, "View"); | |||
m_Pattern->labelsize(10); | |||
m_Pattern->type(FL_SIMPLE_COUNTER); | |||
m_Pattern->step(1); | |||
@@ -119,6 +119,14 @@ m_LastLight(0) | |||
m_Pattern->callback((Fl_Callback*)cb_Pattern); | |||
add(m_Pattern); | |||
m_PlayPattern = new Fl_Counter(50, 20, 40, 20, "Play"); | |||
m_PlayPattern->labelsize(10); | |||
m_PlayPattern->type(FL_SIMPLE_COUNTER); | |||
m_PlayPattern->step(1); | |||
m_PlayPattern->value(0); | |||
m_PlayPattern->callback((Fl_Callback*)cb_PlayPattern); | |||
add(m_PlayPattern); | |||
m_Length = new Fl_Counter(5, 55, 40, 20, "Length"); | |||
m_Length->labelsize(10); | |||
m_Length->type(FL_SIMPLE_COUNTER); | |||
@@ -248,7 +256,7 @@ void MatrixPluginGUI::UpdateValues(SpiralPlugin *o) | |||
m_Pattern->value(Plugin->GetCurrent()); | |||
m_Length->value(Plugin->GetPattern()->Length); | |||
m_Speed->value(Plugin->GetPattern()->Speed); | |||
m_Speed->value(Plugin->GetPattern()->Speed*8); | |||
m_SpeedVal->value((int)m_Speed->value()); | |||
m_Octave->value(Plugin->GetPattern()->Octave); | |||
@@ -266,11 +274,18 @@ void MatrixPluginGUI::UpdateMatrix() | |||
m_GUICH->RequestChannelAndWait("Matrix"); | |||
m_GUICH->GetData("Matrix",(void*)m_GUIMatrix); | |||
Pattern *p=&m_GUIMatrix[(int)m_Pattern->value()]; | |||
m_Length->value(p->Length); | |||
m_Speed->value(p->Speed*8); | |||
m_SpeedVal->value((int)m_Speed->value()); | |||
m_Octave->value(p->Octave); | |||
for(int x=0; x<MATX; x++) | |||
for(int y=0; y<MATY; y++) | |||
{ | |||
m_Matrix[x][y]->value(m_GUIMatrix[(int)m_Pattern->value()].Matrix[x][y]); | |||
m_Matrix[x][y]->SetVolume(m_GUIMatrix[(int)m_Pattern->value()].Volume[x][y]); | |||
m_Matrix[x][y]->value(p->Matrix[x][y]); | |||
m_Matrix[x][y]->SetVolume(p->Volume[x][y]); | |||
} | |||
} | |||
@@ -315,6 +330,16 @@ inline void MatrixPluginGUI::cb_Pattern_i(Fl_Counter* o, void* v) | |||
void MatrixPluginGUI::cb_Pattern(Fl_Counter* o, void* v) | |||
{ ((MatrixPluginGUI*)(o->parent()))->cb_Pattern_i(o,v);} | |||
inline void MatrixPluginGUI::cb_PlayPattern_i(Fl_Counter* o, void* v) | |||
{ | |||
if (o->value()<0) o->value(0); | |||
if (o->value()>NUM_PATTERNS-1) o->value(NUM_PATTERNS-1); | |||
m_GUICH->Set("Num",(int)o->value()); | |||
m_GUICH->SetCommand(MatrixPlugin::SET_CURRENT); | |||
} | |||
void MatrixPluginGUI::cb_PlayPattern(Fl_Counter* o, void* v) | |||
{ ((MatrixPluginGUI*)(o->parent()))->cb_PlayPattern_i(o,v);} | |||
inline void MatrixPluginGUI::cb_Length_i(Fl_Counter* o, void* v) | |||
{ | |||
if (o->value()<1) o->value(1); | |||
@@ -333,7 +358,7 @@ inline void MatrixPluginGUI::cb_Speed_i(Fl_Knob* o, void* v) | |||
float value=o->value()+((int)o->value()-o->value()); | |||
m_SpeedVal->value(value); | |||
m_GUICH->Set("Speed",(float)value); | |||
m_GUICH->Set("Speed",(float)value/8.0f); | |||
m_GUICH->SetCommand(MatrixPlugin::MAT_SPEED); | |||
} | |||
void MatrixPluginGUI::cb_Speed(Fl_Knob* o, void* v) | |||
@@ -84,6 +84,7 @@ private: | |||
Fl_Button* m_NoteCut; | |||
Fl_Counter* m_Pattern; | |||
Fl_Counter* m_PlayPattern; | |||
Fl_Counter* m_Length; | |||
Fl_Knob* m_Speed; | |||
Fl_MatrixButton* m_Matrix[MATX][MATY]; | |||
@@ -104,6 +105,8 @@ private: | |||
static void cb_MatVol(Fl_Button* o, void* v); | |||
inline void cb_Pattern_i(Fl_Counter* o, void* v); | |||
static void cb_Pattern(Fl_Counter* o, void* v); | |||
inline void cb_PlayPattern_i(Fl_Counter* o, void* v); | |||
static void cb_PlayPattern(Fl_Counter* o, void* v); | |||
inline void cb_Length_i(Fl_Counter* o, void* v); | |||
static void cb_Length(Fl_Counter* o, void* v); | |||
inline void cb_Speed_i(Fl_Knob* o, void* v); | |||
@@ -54,6 +54,7 @@ static const HostInfo* host; | |||
OSSOutput* OSSOutput::m_Singleton = NULL; | |||
int OutputPlugin::m_RefCount=0; | |||
int OutputPlugin::m_NoExecuted=0; | |||
OutputPlugin::Mode OutputPlugin::m_Mode=NO_MODE; | |||
#define CHECK_AND_REPORT_ERROR if (result<0) \ | |||
@@ -103,8 +104,6 @@ m_Volume(1.0f) | |||
m_PluginInfo.PortTips.push_back("Right In"); | |||
m_AudioCH->Register("Volume",&m_Volume); | |||
m_Mode=NO_MODE; | |||
} | |||
OutputPlugin::~OutputPlugin() | |||
@@ -137,7 +136,7 @@ SpiralGUIType *OutputPlugin::CreateGUI() | |||
void OutputPlugin::Execute() | |||
{ | |||
if (m_Mode==NO_MODE) | |||
if (m_Mode==NO_MODE && m_RefCount==1) | |||
{ | |||
if (OSSOutput::Get()->OpenWrite()) | |||
{ | |||
@@ -192,12 +191,15 @@ void OutputPlugin::Execute() | |||
void OutputPlugin::ExecuteCommands() | |||
{ | |||
// Only Play() once per set of plugins | |||
m_NoExecuted++; | |||
if (m_NoExecuted==m_RefCount) | |||
cerr<<m_RefCount<<" "<<m_NoExecuted<<endl; | |||
m_NoExecuted--; | |||
if (m_NoExecuted<=0) | |||
{ | |||
if (m_Mode==INPUT || m_Mode==DUPLEX) OSSOutput::Get()->Read(); | |||
if (m_Mode==OUTPUT || m_Mode==DUPLEX) OSSOutput::Get()->Play(); | |||
m_NoExecuted=0; | |||
m_NoExecuted=m_RefCount; | |||
} | |||
@@ -88,7 +88,7 @@ public: | |||
private: | |||
static int m_RefCount; | |||
static int m_NoExecuted; | |||
Mode m_Mode; | |||
static Mode m_Mode; | |||
bool m_CheckedAlready; | |||
bool m_Recmode; | |||
}; | |||
@@ -143,7 +143,6 @@ SpiralSound/Plugins/SVFilterPlugin/Makefile | |||
SpiralSound/Plugins/SampleHoldPlugin/Makefile | |||
SpiralSound/Plugins/SeqSelectorPlugin/Makefile | |||
SpiralSound/Plugins/SmoothPlugin/Makefile | |||
SpiralSound/Plugins/SpiralLoopPlugin/Makefile | |||
SpiralSound/Plugins/SplitterPlugin/Makefile | |||
SpiralSound/Plugins/StereoMixerPlugin/Makefile | |||
SpiralSound/Plugins/StreamPlugin/Makefile | |||