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