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); | |||
| 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); | |||
| } | |||
| @@ -28,7 +28,7 @@ using namespace std; | |||
| int JackClient::JackProcessInstanceID = -1; | |||
| int JackPlugin::JackInstanceCount = 0; | |||
| const HostInfo *host = NULL; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| 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 (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); | |||
| 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 | |||
| { | |||
| 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& Info= SpiralPlugin::Initialise(Host); | |||
| host = Host; | |||
| m_JackClient->SetCallback(cb_Update,m_Parent); | |||
| return Info; | |||
| @@ -568,18 +570,15 @@ bool JackPlugin::Kill() | |||
| 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 | |||
| 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(); | |||
| @@ -598,7 +597,7 @@ void JackPlugin::ProcessAudio() | |||
| // connect the buffers up if we are plugged into something | |||
| 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()); | |||
| } | |||
| @@ -610,7 +609,7 @@ void JackPlugin::ProcessAudio() | |||
| 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()); | |||
| } | |||
| @@ -47,6 +47,8 @@ m_VUMode (true) | |||
| m_PluginInfo.PortTips.push_back ("Input"); | |||
| m_PluginInfo.PortTips.push_back ("Output"); | |||
| m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | |||
| m_AudioCH->Register ("DataSizeChanged", &m_DataSizeChanged, ChannelHandler::OUTPUT); | |||
| m_Version = 1; | |||
| } | |||
| @@ -71,7 +73,7 @@ void MeterPlugin::Reset() | |||
| m_DataReady = false; | |||
| delete m_Data; | |||
| m_Data = new float[m_HostInfo->BUFSIZE]; | |||
| m_AudioCH->UpdateDataSize ("AudioData", m_HostInfo->BUFSIZE * sizeof (float)); | |||
| m_DataSizeChanged = true; | |||
| } | |||
| void MeterPlugin::Execute() { | |||
| @@ -87,6 +89,13 @@ void MeterPlugin::Execute() { | |||
| void MeterPlugin::ExecuteCommands () { | |||
| if (m_AudioCH->IsCommandWaiting ()) { | |||
| switch (m_AudioCH->GetCommand()) { | |||
| case UPDATEDATASIZE : | |||
| { | |||
| m_AudioCH->UpdateDataSize("AudioData",m_HostInfo->BUFSIZE*sizeof(float)); | |||
| m_DataSizeChanged = false; | |||
| } | |||
| break; | |||
| case (SETVU) : m_VUMode = true; | |||
| break; | |||
| case (SETMM) : m_VUMode = false; | |||
| @@ -33,11 +33,11 @@ class MeterPlugin : public SpiralPlugin { | |||
| virtual void StreamOut (std::ostream &s); | |||
| virtual void StreamIn (std::istream &s); | |||
| int GetVUMode (void) { return m_VUMode; } | |||
| enum GUICommands {NONE, SETVU, SETMM}; | |||
| enum GUICommands {NONE, SETVU, SETMM, UPDATEDATASIZE}; | |||
| private: | |||
| float *m_Data; | |||
| // 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 | |||
| @@ -94,6 +94,11 @@ void MeterPluginGUI::draw() { | |||
| SpiralGUIType::draw (); | |||
| if (! m_Bypass) { | |||
| 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); | |||
| else memset (m_Data, 0, m_BufSize * sizeof (float)); | |||
| // 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("Output"); | |||
| m_AudioCH->Register ("DataReady", &m_DataReady, ChannelHandler::OUTPUT); | |||
| m_AudioCH->Register ("DataSizeChanged", &m_DataSizeChanged, ChannelHandler::OUTPUT); | |||
| } | |||
| ScopePlugin::~ScopePlugin() | |||
| @@ -71,7 +72,7 @@ void ScopePlugin::Reset() | |||
| m_DataReady = false; | |||
| delete m_Data; | |||
| m_Data = new float[m_HostInfo->BUFSIZE]; | |||
| m_AudioCH->UpdateDataSize("AudioData",m_HostInfo->BUFSIZE*sizeof(float)); | |||
| m_DataSizeChanged = true; | |||
| } | |||
| void ScopePlugin::Execute() { | |||
| @@ -83,3 +84,22 @@ void ScopePlugin::Execute() { | |||
| 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 SpiralGUIType* CreateGUI(); | |||
| virtual void Execute(); | |||
| virtual void ExecuteCommands(); | |||
| virtual void Reset(); | |||
| virtual void StreamOut(std::ostream &s) {} | |||
| virtual void StreamIn(std::istream &s) {} | |||
| enum GUICommands{NONE,UPDATEDATASIZE}; | |||
| private: | |||
| float *m_Data; | |||
| bool m_DataReady; | |||
| bool m_DataSizeChanged; | |||
| }; | |||
| #endif | |||
| @@ -104,6 +104,11 @@ void ScopePluginGUI::draw() | |||
| SpiralGUIType::draw(); | |||
| const float *data; | |||
| //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); | |||
| else memset ((void*)m_Scope->m_Data, 0, m_BufSize * sizeof (float)); | |||
| if (!m_Bypass) m_Scope->redraw(); | |||
| @@ -48,7 +48,7 @@ struct HostInfo | |||
| { | |||
| int BUFSIZE; | |||
| int SAMPLERATE; | |||
| /* obsolete - REMOVE SOON */ | |||
| int FRAGSIZE; | |||
| int FRAGCOUNT; | |||
| @@ -64,6 +64,8 @@ struct HostInfo | |||
| unsigned SCOPE_MRK_COLOUR; | |||
| unsigned GUICOL_Device; | |||
| unsigned GUIDEVICE_Box; | |||
| bool PAUSED; | |||
| }; | |||
| ///////////////////////////////////////////////////////////////////// | |||
| @@ -80,7 +80,8 @@ m_Frozen(false) | |||
| /* Shared Audio State Information */ | |||
| m_Info.BUFSIZE = SpiralInfo::BUFSIZE; | |||
| m_Info.SAMPLERATE = SpiralInfo::SAMPLERATE; | |||
| m_Info.PAUSED = false; | |||
| /* obsolete - REMOVE SOON */ | |||
| m_Info.FRAGSIZE = SpiralInfo::FRAGSIZE; | |||
| m_Info.FRAGCOUNT = SpiralInfo::FRAGCOUNT; | |||
| @@ -179,18 +180,18 @@ void SynthModular::Update() | |||
| #endif | |||
| // 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 | |||
| i->second->m_Device->ExecuteCommands(); | |||
| } | |||
| @@ -204,7 +205,7 @@ void SynthModular::Update() | |||
| { | |||
| // use the graphsort order to remove internal latency | |||
| 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 | |||
| 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() | |||
| { | |||
| /* Pause Audio */ | |||
| PauseAudio(); | |||
| FreezeAll(); | |||
| /* update the settings */ | |||
| 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) | |||
| { | |||
| if (m_PauseAudio) | |||
| if (m_Info.PAUSED) | |||
| { | |||
| m_PlayPause->label("Pause ||"); | |||
| ResumeAudio(); | |||
| @@ -108,30 +108,23 @@ public: | |||
| void PauseAudio() | |||
| { | |||
| m_PauseAudio = true; | |||
| m_Info.PAUSED = true; | |||
| } | |||
| void ResumeAudio() | |||
| { | |||
| m_PauseAudio = false; | |||
| m_Info.PAUSED = false; | |||
| } | |||
| void ResetAudio() | |||
| { | |||
| if (! m_ResetingAudioThread) | |||
| { | |||
| bool donotresume = false; | |||
| if (m_PauseAudio) | |||
| { | |||
| PauseAudio(); | |||
| donotresume = true; | |||
| } | |||
| FreezeAll(); | |||
| m_ResetingAudioThread = true; | |||
| if (!donotresume) | |||
| ResumeAudio(); | |||
| ThawAll(); | |||
| } | |||
| } | |||
| @@ -149,7 +142,6 @@ private: | |||
| HostInfo m_Info; | |||
| bool m_ResetingAudioThread; | |||
| bool m_HostNeedsUpdate; | |||
| bool m_PauseAudio; | |||
| static DeviceGUIInfo BuildDeviceGUIInfo(PluginInfo &PInfo); | |||