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