made pause an info variable so jack(and other audio plugins) can sanely handle outputing null/0 while paused, fixed jack change buffer and samplerate, Pause/Play and Reset should now work properly.master
@@ -225,6 +225,9 @@ void ChannelHandler::UpdateDataSize(const std::string &ID, int size) | |||||
pthread_mutex_lock(m_Mutex); | pthread_mutex_lock(m_Mutex); | ||||
i->second->size = size; | i->second->size = size; | ||||
free(i->second->data_buf); | |||||
i->second->data_buf = malloc(size); | |||||
memcpy(i->second->data_buf,i->second->data,size); | |||||
pthread_mutex_unlock(m_Mutex); | pthread_mutex_unlock(m_Mutex); | ||||
} | } | ||||
@@ -28,7 +28,7 @@ using namespace std; | |||||
int JackClient::JackProcessInstanceID = -1; | int JackClient::JackProcessInstanceID = -1; | ||||
int JackPlugin::JackInstanceCount = 0; | int JackPlugin::JackInstanceCount = 0; | ||||
const HostInfo *host = NULL; | |||||
///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||
inline void JackClient::JackProcess_i(jack_nframes_t nframes) | inline void JackClient::JackProcess_i(jack_nframes_t nframes) | ||||
{ | { | ||||
@@ -47,7 +47,7 @@ inline void JackClient::JackProcess_i(jack_nframes_t nframes) | |||||
{ | { | ||||
if (jack_port_connected(m_OutputPortMap[n]->Port)) | if (jack_port_connected(m_OutputPortMap[n]->Port)) | ||||
{ | { | ||||
if (m_OutputPortMap[n]->Buf) | |||||
if ((m_OutputPortMap[n]->Buf) && (!host->PAUSED)) | |||||
{ | { | ||||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | ||||
memcpy (out, m_OutputPortMap[n]->Buf, sizeof (sample_t) * GetBufferSize()); | memcpy (out, m_OutputPortMap[n]->Buf, sizeof (sample_t) * GetBufferSize()); | ||||
@@ -55,7 +55,7 @@ inline void JackClient::JackProcess_i(jack_nframes_t nframes) | |||||
else // no output availible, clear | else // no output availible, clear | ||||
{ | { | ||||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | ||||
memset (out, 0, sizeof (sample_t) * GetBufferSize()); | |||||
memset(out, 0, sizeof (sample_t) * GetBufferSize()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -469,7 +469,9 @@ JackPlugin::~JackPlugin() | |||||
PluginInfo &JackPlugin::Initialise(const HostInfo *Host) | PluginInfo &JackPlugin::Initialise(const HostInfo *Host) | ||||
{ | { | ||||
PluginInfo& Info= SpiralPlugin::Initialise(Host); | PluginInfo& Info= SpiralPlugin::Initialise(Host); | ||||
host = Host; | |||||
m_JackClient->SetCallback(cb_Update,m_Parent); | m_JackClient->SetCallback(cb_Update,m_Parent); | ||||
return Info; | return Info; | ||||
@@ -568,18 +570,15 @@ bool JackPlugin::Kill() | |||||
void JackPlugin::Reset() | void JackPlugin::Reset() | ||||
{ | { | ||||
// we want to process this whether we are connected to stuff or not | |||||
JackClient* pJack=m_JackClient; | |||||
// connect the buffers up if we are plugged into something | // connect the buffers up if we are plugged into something | ||||
for (int n=0; n<pJack->GetJackOutputCount(); n++) | |||||
for (int n=0; n<m_JackClient->GetJackOutputCount(); n++) | |||||
{ | { | ||||
pJack->SetOutputBuf(n,NULL); | |||||
m_JackClient->SetOutputBuf(n,NULL); | |||||
} | } | ||||
for (int n=0; n<pJack->GetJackInputCount(); n++) | |||||
for (int n=0; n<m_JackClient->GetJackInputCount(); n++) | |||||
{ | { | ||||
pJack->SetInputBuf(n,NULL); | |||||
m_JackClient->SetInputBuf(n,NULL); | |||||
} | } | ||||
ResetPorts(); | ResetPorts(); | ||||
@@ -598,7 +597,7 @@ void JackPlugin::ProcessAudio() | |||||
// connect the buffers up if we are plugged into something | // connect the buffers up if we are plugged into something | ||||
for (int n=0; n<m_JackClient->GetJackOutputCount(); n++) | for (int n=0; n<m_JackClient->GetJackOutputCount(); n++) | ||||
{ | { | ||||
if (InputExists(n)) | |||||
if (InputExists(n) && !m_HostInfo->PAUSED) | |||||
{ | { | ||||
m_JackClient->SetOutputBuf(n,(float*)GetInput(n)->GetBuffer()); | m_JackClient->SetOutputBuf(n,(float*)GetInput(n)->GetBuffer()); | ||||
} | } | ||||
@@ -610,7 +609,7 @@ void JackPlugin::ProcessAudio() | |||||
for (int n=0; n<m_JackClient->GetJackInputCount(); n++) | for (int n=0; n<m_JackClient->GetJackInputCount(); n++) | ||||
{ | { | ||||
if (OutputExists(n)) | |||||
if (OutputExists(n) && !m_HostInfo->PAUSED) | |||||
{ | { | ||||
m_JackClient->SetInputBuf(n,(float*)GetOutputBuf(n)->GetBuffer()); | m_JackClient->SetInputBuf(n,(float*)GetOutputBuf(n)->GetBuffer()); | ||||
} | } | ||||
@@ -47,6 +47,8 @@ m_VUMode (true) | |||||
m_PluginInfo.PortTips.push_back ("Input"); | m_PluginInfo.PortTips.push_back ("Input"); | ||||
m_PluginInfo.PortTips.push_back ("Output"); | m_PluginInfo.PortTips.push_back ("Output"); | ||||
m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | ||||
m_AudioCH->Register ("DataSizeChanged", &m_DataSizeChanged, ChannelHandler::OUTPUT); | |||||
m_Version = 1; | m_Version = 1; | ||||
} | } | ||||
@@ -71,7 +73,7 @@ void MeterPlugin::Reset() | |||||
m_DataReady = false; | m_DataReady = false; | ||||
delete m_Data; | delete m_Data; | ||||
m_Data = new float[m_HostInfo->BUFSIZE]; | m_Data = new float[m_HostInfo->BUFSIZE]; | ||||
m_AudioCH->UpdateDataSize ("AudioData", m_HostInfo->BUFSIZE * sizeof (float)); | |||||
m_DataSizeChanged = true; | |||||
} | } | ||||
void MeterPlugin::Execute() { | void MeterPlugin::Execute() { | ||||
@@ -87,6 +89,13 @@ void MeterPlugin::Execute() { | |||||
void MeterPlugin::ExecuteCommands () { | void MeterPlugin::ExecuteCommands () { | ||||
if (m_AudioCH->IsCommandWaiting ()) { | if (m_AudioCH->IsCommandWaiting ()) { | ||||
switch (m_AudioCH->GetCommand()) { | switch (m_AudioCH->GetCommand()) { | ||||
case UPDATEDATASIZE : | |||||
{ | |||||
m_AudioCH->UpdateDataSize("AudioData",m_HostInfo->BUFSIZE*sizeof(float)); | |||||
m_DataSizeChanged = false; | |||||
} | |||||
break; | |||||
case (SETVU) : m_VUMode = true; | case (SETVU) : m_VUMode = true; | ||||
break; | break; | ||||
case (SETMM) : m_VUMode = false; | case (SETMM) : m_VUMode = false; | ||||
@@ -33,11 +33,11 @@ class MeterPlugin : public SpiralPlugin { | |||||
virtual void StreamOut (std::ostream &s); | virtual void StreamOut (std::ostream &s); | ||||
virtual void StreamIn (std::istream &s); | virtual void StreamIn (std::istream &s); | ||||
int GetVUMode (void) { return m_VUMode; } | int GetVUMode (void) { return m_VUMode; } | ||||
enum GUICommands {NONE, SETVU, SETMM}; | |||||
enum GUICommands {NONE, SETVU, SETMM, UPDATEDATASIZE}; | |||||
private: | private: | ||||
float *m_Data; | float *m_Data; | ||||
// m_VUMode isn't USED for anything, it's here so we can save/load it | // m_VUMode isn't USED for anything, it's here so we can save/load it | ||||
bool m_DataReady, m_VUMode; | |||||
bool m_DataReady, m_VUMode, m_DataSizeChanged; | |||||
}; | }; | ||||
#endif | #endif |
@@ -94,6 +94,11 @@ void MeterPluginGUI::draw() { | |||||
SpiralGUIType::draw (); | SpiralGUIType::draw (); | ||||
if (! m_Bypass) { | if (! m_Bypass) { | ||||
float datum = 0.0; | float datum = 0.0; | ||||
if (m_GUICH->GetBool ("DataSizeChanged")) | |||||
{ | |||||
m_GUICH->SetCommand (MeterPlugin::UPDATEDATASIZE); | |||||
m_GUICH->Wait(); | |||||
} | |||||
if (m_GUICH->GetBool ("DataReady")) m_GUICH->GetData ("AudioData", m_Data); | if (m_GUICH->GetBool ("DataReady")) m_GUICH->GetData ("AudioData", m_Data); | ||||
else memset (m_Data, 0, m_BufSize * sizeof (float)); | else memset (m_Data, 0, m_BufSize * sizeof (float)); | ||||
// The min and max values are based on the whole buffer | // The min and max values are based on the whole buffer | ||||
@@ -46,6 +46,7 @@ m_DataReady(false) | |||||
m_PluginInfo.PortTips.push_back("Input"); | m_PluginInfo.PortTips.push_back("Input"); | ||||
m_PluginInfo.PortTips.push_back("Output"); | m_PluginInfo.PortTips.push_back("Output"); | ||||
m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | ||||
m_AudioCH->Register ("DataSizeChanged", &m_DataSizeChanged, ChannelHandler::OUTPUT); | |||||
} | } | ||||
ScopePlugin::~ScopePlugin() | ScopePlugin::~ScopePlugin() | ||||
@@ -71,7 +72,7 @@ void ScopePlugin::Reset() | |||||
m_DataReady = false; | m_DataReady = false; | ||||
delete m_Data; | delete m_Data; | ||||
m_Data = new float[m_HostInfo->BUFSIZE]; | m_Data = new float[m_HostInfo->BUFSIZE]; | ||||
m_AudioCH->UpdateDataSize("AudioData",m_HostInfo->BUFSIZE*sizeof(float)); | |||||
m_DataSizeChanged = true; | |||||
} | } | ||||
void ScopePlugin::Execute() { | void ScopePlugin::Execute() { | ||||
@@ -83,3 +84,22 @@ void ScopePlugin::Execute() { | |||||
memcpy (m_Data, GetInput (0)->GetBuffer (), m_HostInfo->BUFSIZE * sizeof (float)); | memcpy (m_Data, GetInput (0)->GetBuffer (), m_HostInfo->BUFSIZE * sizeof (float)); | ||||
} | } | ||||
} | } | ||||
void ScopePlugin::ExecuteCommands() | |||||
{ | |||||
if (m_AudioCH->IsCommandWaiting()) | |||||
{ | |||||
switch (m_AudioCH->GetCommand()) { | |||||
case UPDATEDATASIZE : | |||||
{ | |||||
m_AudioCH->UpdateDataSize("AudioData",m_HostInfo->BUFSIZE*sizeof(float)); | |||||
m_DataSizeChanged = false; | |||||
} | |||||
break; | |||||
default: | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -29,12 +29,16 @@ class ScopePlugin : public SpiralPlugin { | |||||
virtual PluginInfo& Initialise(const HostInfo *Host); | virtual PluginInfo& Initialise(const HostInfo *Host); | ||||
virtual SpiralGUIType* CreateGUI(); | virtual SpiralGUIType* CreateGUI(); | ||||
virtual void Execute(); | virtual void Execute(); | ||||
virtual void ExecuteCommands(); | |||||
virtual void Reset(); | virtual void Reset(); | ||||
virtual void StreamOut(std::ostream &s) {} | virtual void StreamOut(std::ostream &s) {} | ||||
virtual void StreamIn(std::istream &s) {} | virtual void StreamIn(std::istream &s) {} | ||||
enum GUICommands{NONE,UPDATEDATASIZE}; | |||||
private: | private: | ||||
float *m_Data; | float *m_Data; | ||||
bool m_DataReady; | bool m_DataReady; | ||||
bool m_DataSizeChanged; | |||||
}; | }; | ||||
#endif | #endif |
@@ -104,6 +104,11 @@ void ScopePluginGUI::draw() | |||||
SpiralGUIType::draw(); | SpiralGUIType::draw(); | ||||
const float *data; | const float *data; | ||||
//cerr<<"getting and drawing..."<<endl; | //cerr<<"getting and drawing..."<<endl; | ||||
if (m_GUICH->GetBool ("DataSizeChanged")) | |||||
{ | |||||
m_GUICH->SetCommand (ScopePlugin::UPDATEDATASIZE); | |||||
m_GUICH->Wait(); | |||||
} | |||||
if (m_GUICH->GetBool ("DataReady")) m_GUICH->GetData ("AudioData", (void*)m_Scope->m_Data); | if (m_GUICH->GetBool ("DataReady")) m_GUICH->GetData ("AudioData", (void*)m_Scope->m_Data); | ||||
else memset ((void*)m_Scope->m_Data, 0, m_BufSize * sizeof (float)); | else memset ((void*)m_Scope->m_Data, 0, m_BufSize * sizeof (float)); | ||||
if (!m_Bypass) m_Scope->redraw(); | if (!m_Bypass) m_Scope->redraw(); | ||||
@@ -48,7 +48,7 @@ struct HostInfo | |||||
{ | { | ||||
int BUFSIZE; | int BUFSIZE; | ||||
int SAMPLERATE; | int SAMPLERATE; | ||||
/* obsolete - REMOVE SOON */ | /* obsolete - REMOVE SOON */ | ||||
int FRAGSIZE; | int FRAGSIZE; | ||||
int FRAGCOUNT; | int FRAGCOUNT; | ||||
@@ -64,6 +64,8 @@ struct HostInfo | |||||
unsigned SCOPE_MRK_COLOUR; | unsigned SCOPE_MRK_COLOUR; | ||||
unsigned GUICOL_Device; | unsigned GUICOL_Device; | ||||
unsigned GUIDEVICE_Box; | unsigned GUIDEVICE_Box; | ||||
bool PAUSED; | |||||
}; | }; | ||||
///////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////// | ||||
@@ -80,7 +80,8 @@ m_Frozen(false) | |||||
/* Shared Audio State Information */ | /* Shared Audio State Information */ | ||||
m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | ||||
m_Info.SAMPLERATE = SpiralInfo::SAMPLERATE; | m_Info.SAMPLERATE = SpiralInfo::SAMPLERATE; | ||||
m_Info.PAUSED = false; | |||||
/* obsolete - REMOVE SOON */ | /* obsolete - REMOVE SOON */ | ||||
m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | ||||
m_Info.FRAGCOUNT = SpiralInfo::FRAGCOUNT; | m_Info.FRAGCOUNT = SpiralInfo::FRAGCOUNT; | ||||
@@ -179,18 +180,18 @@ void SynthModular::Update() | |||||
#endif | #endif | ||||
// If this is an audio device see if we always need to ProcessAudio here | // If this is an audio device see if we always need to ProcessAudio here | ||||
if (i->second->m_Device->IsAudioDriver()) | |||||
if ((!m_ResetingAudioThread)) | |||||
{ | { | ||||
AudioDriver *driver = ((AudioDriver *)i->second->m_Device); | |||||
if (driver->ProcessType() == AudioDriver::ALWAYS) | |||||
if (i->second->m_Device->IsAudioDriver()) | |||||
{ | { | ||||
driver->ProcessAudio(); | |||||
} | |||||
} | |||||
AudioDriver *driver = ((AudioDriver *)i->second->m_Device); | |||||
if (driver->ProcessType() == AudioDriver::ALWAYS) | |||||
{ | |||||
driver->ProcessAudio(); | |||||
} | |||||
} | |||||
if ((!m_ResetingAudioThread)) | |||||
{ | |||||
// run any commands we've received from the GUI's | // run any commands we've received from the GUI's | ||||
i->second->m_Device->ExecuteCommands(); | i->second->m_Device->ExecuteCommands(); | ||||
} | } | ||||
@@ -204,7 +205,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 && (! di->second->m_Device->IsDead()) && (!m_PauseAudio)) | |||||
if (di!=m_DeviceWinMap.end() && di->second->m_Device && (! di->second->m_Device->IsDead()) && (!m_Info.PAUSED)) | |||||
{ | { | ||||
#ifdef DEBUG_PLUGINS | #ifdef DEBUG_PLUGINS | ||||
cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | ||||
@@ -815,7 +816,7 @@ void SynthModular::cb_ChangeBufferAndSampleRate_i(long int NewBufferSize, long i | |||||
void SynthModular::UpdateHostInfo() | void SynthModular::UpdateHostInfo() | ||||
{ | { | ||||
/* Pause Audio */ | /* Pause Audio */ | ||||
PauseAudio(); | |||||
FreezeAll(); | |||||
/* update the settings */ | /* update the settings */ | ||||
m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | ||||
@@ -1424,7 +1425,7 @@ void SynthModular::cb_NewComment(Fl_Button* o, void* v) | |||||
inline void SynthModular::cb_PlayPause_i(Fl_Button* o, void* v) | inline void SynthModular::cb_PlayPause_i(Fl_Button* o, void* v) | ||||
{ | { | ||||
if (m_PauseAudio) | |||||
if (m_Info.PAUSED) | |||||
{ | { | ||||
m_PlayPause->label("Pause ||"); | m_PlayPause->label("Pause ||"); | ||||
ResumeAudio(); | ResumeAudio(); | ||||
@@ -108,30 +108,23 @@ public: | |||||
void PauseAudio() | void PauseAudio() | ||||
{ | { | ||||
m_PauseAudio = true; | |||||
m_Info.PAUSED = true; | |||||
} | } | ||||
void ResumeAudio() | void ResumeAudio() | ||||
{ | { | ||||
m_PauseAudio = false; | |||||
m_Info.PAUSED = false; | |||||
} | } | ||||
void ResetAudio() | void ResetAudio() | ||||
{ | { | ||||
if (! m_ResetingAudioThread) | if (! m_ResetingAudioThread) | ||||
{ | { | ||||
bool donotresume = false; | |||||
if (m_PauseAudio) | |||||
{ | |||||
PauseAudio(); | |||||
donotresume = true; | |||||
} | |||||
FreezeAll(); | |||||
m_ResetingAudioThread = true; | m_ResetingAudioThread = true; | ||||
if (!donotresume) | |||||
ResumeAudio(); | |||||
ThawAll(); | |||||
} | } | ||||
} | } | ||||
@@ -149,7 +142,6 @@ private: | |||||
HostInfo m_Info; | HostInfo m_Info; | ||||
bool m_ResetingAudioThread; | bool m_ResetingAudioThread; | ||||
bool m_HostNeedsUpdate; | bool m_HostNeedsUpdate; | ||||
bool m_PauseAudio; | |||||
static DeviceGUIInfo BuildDeviceGUIInfo(PluginInfo &PInfo); | static DeviceGUIInfo BuildDeviceGUIInfo(PluginInfo &PInfo); | ||||