From 8da1ad9fcf518dab594a9506bc3d0ad6cd085e33 Mon Sep 17 00:00:00 2001 From: GZharun Date: Wed, 11 Feb 2015 19:45:10 +0200 Subject: [PATCH] [Summary] Fixed issue when Audio Callback thread is changed [Reviewed by] PDavis, VKamyshniy --- libs/backends/wavesaudio/waves_audiobackend.cc | 18 ++++++++++++------ .../devicemanager/WCMRAudioDeviceManager.cpp | 7 +++++-- .../WCMRCoreAudioDeviceManager.cpp | 3 +++ .../WCMRPortAudioDeviceManager.cpp | 7 ++++--- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc index fbb1a378a1..be8b4023f3 100644 --- a/libs/backends/wavesaudio/waves_audiobackend.cc +++ b/libs/backends/wavesaudio/waves_audiobackend.cc @@ -405,7 +405,6 @@ WavesAudioBackend::set_sample_rate (float sample_rate) if (device_needs_restart) { // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - _call_thread_init_callback = true; retVal = _device->SetStreaming (true); if (retVal != eNoErr) { std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; @@ -454,7 +453,6 @@ WavesAudioBackend::set_buffer_size (uint32_t buffer_size) if (device_needs_restart) { // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - _call_thread_init_callback = true; retVal = _device->SetStreaming (true); if (retVal != eNoErr) { std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; @@ -480,8 +478,6 @@ WavesAudioBackend::reset_device () { // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl; - WTErr retVal = eNoErr; - if (!_device) { std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; return -1; @@ -690,7 +686,6 @@ WavesAudioBackend::_start (bool for_latency_measurement) manager.registration_callback (); - _call_thread_init_callback = true; WTErr retVal = _device->SetStreaming (true); if (retVal != eNoErr) { std::cerr << "WavesAudioBackend::_start (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; @@ -730,12 +725,23 @@ WavesAudioBackend::_audio_device_callback (const float* input_buffer, _read_audio_data_from_device (input_buffer, nframes); _read_midi_data_from_devices (); + static pthread_t process_id; if (_call_thread_init_callback) { _call_thread_init_callback = false; // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() invoked for " << std::hex << pthread_self() << std::dec << " !" << std::endl; - AudioEngine::thread_init_callback (this); + + process_id = pthread_self(); + AudioEngine::thread_init_callback (this); } + if (process_id != pthread_self() ) { + std::cerr << "\tWavesAudioBackend::_audio_device_callback (): It's an attempt to call process callback from the thread which didn't initialize it " << std::endl; + std::cerr << "Expected thread: " << process_id << " current thread: " << pthread_self() << std::dec << " !" << std::endl; + + process_id = pthread_self(); + AudioEngine::thread_init_callback (this); + } + engine.process_callback (nframes); _write_audio_data_to_device (output_buffer, nframes); diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp index 2c293f8b9a..c1dc758507 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp @@ -339,6 +339,10 @@ bool WCMRAudioDevice::Streaming () //********************************************************************************************** WTErr WCMRAudioDevice::SetStreaming (bool newState) { + // We must notify angine about our intention to start streming + // so Engine will provide all the initializations in the first audio callback + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); + //This will most likely be overridden, the base class simply //changes the member. m_IsStreaming = newState; @@ -361,8 +365,7 @@ WTErr WCMRAudioDevice::ResetDevice () SetActive(true); if (err == eNoErr && wasStreaming) { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); - SetStreaming(true); + err = SetStreaming(true); } return err; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp index 5c1ceac63e..822618fd09 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp @@ -1908,6 +1908,9 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState) m_IOProcThreadPort = 0; m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Starting AUHAL."); + // Prepare for streaming - tell Engine to do the initialization for process callback + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); + if (m_UseMultithreading) { //set thread constraints... diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp index e6088cf140..d9b477ae86 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp @@ -944,6 +944,9 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/) unsigned int inChannelCount = pDeviceInfo->maxInputChannels; unsigned int outChannelCount = pDeviceInfo->maxOutputChannels; + // Prepare for streaming - tell Engine to do the initialization for process callback + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); + paErr = Pa_StartStream( m_PortAudioStream ); if(paErr == paNoError) @@ -1088,8 +1091,7 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ ) // Resume streaming if the device was streaming before if(wasStreaming && m_lastErr == eNoErr && m_ConnectionStatus == DeviceAvailable) { - // Notify the Application to prepare for the stream start - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); + // start streaming startStreaming(); } } else { @@ -1342,7 +1344,6 @@ WTErr WCMRPortAudioDevice::ShowConfigPanel (void *pParam) // restore previous state for the device SetActive(true); if (wasStreaming) { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); SetStreaming(true); } }