diff options
Diffstat (limited to 'libs/backends/wavesaudio/waves_audiobackend.cc')
-rw-r--r-- | libs/backends/wavesaudio/waves_audiobackend.cc | 1355 |
1 files changed, 0 insertions, 1355 deletions
diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc deleted file mode 100644 index 2c6824e4b2..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.cc +++ /dev/null @@ -1,1355 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_audiobackend.h" -#include "waves_audioport.h" -#include "waves_midiport.h" - -#include "ardour/runtime_functions.h" - -#ifdef COMPILER_MSVC -#include <windows.h> -#define sleep(X) Sleep((X) * 1000) -// JE - Perhaps we should be using Glib::usleep() here, rather than sleep()?? But -// that would make the Waves backend dependent on Glib (which is isn't, currently). -#endif - -using namespace ARDOUR; - -#if defined __MINGW64__ || defined __MINGW32__ - extern "C" __declspec(dllexport) ARDOUR::AudioBackendInfo* descriptor () -#else - extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor () -#endif -{ - // COMMENTED DBG LOGS */ std::cout << "waves_backend.dll : ARDOUR::AudioBackendInfo* descriptor (): " << std::endl; - return &WavesAudioBackend::backend_info (); -} - -void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reason, void* parameter) -{ - switch (reason) { - case WCMRAudioDeviceManagerClient::DeviceDebugInfo: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDebugInfo -- " << (char*)parameter << std::endl; - break; - case WCMRAudioDeviceManagerClient::BufferSizeChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(int*)parameter << std::endl; - _buffer_size_change(*(int*)parameter); - break; - case WCMRAudioDeviceManagerClient::RequestReset: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl; - engine.request_backend_reset(); - break; - case WCMRAudioDeviceManagerClient::RequestResync: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl; - break; - case WCMRAudioDeviceManagerClient::SamplingRateChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl; - _sample_rate_change(*(float*)parameter); - break; - case WCMRAudioDeviceManagerClient::Dropout: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::Dropout: " << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceDroppedSamples: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDroppedSamples" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceStoppedStreaming: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceStoppedStreaming" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceStartsStreaming: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceStartsStreaming" << std::endl; - _call_thread_init_callback = true; // streaming will be started from device side, just set thread init flag - break; - case WCMRAudioDeviceManagerClient::DeviceConnectionLost: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceConnectionLost" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceListChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceListChanged" << std::endl; - engine.request_device_list_update(); - break; - case WCMRAudioDeviceManagerClient::IODeviceDisconnected: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::IODeviceDisconnected" << std::endl; - engine.request_device_list_update(); - break; - case WCMRAudioDeviceManagerClient::AudioCallback: - if (parameter) { - const AudioCallbackData* audio_callback_data = (AudioCallbackData*)parameter; - _audio_device_callback ( - audio_callback_data->acdInputBuffer, - audio_callback_data->acdOutputBuffer, - audio_callback_data->acdFrames, - audio_callback_data->acdSampleTime, - audio_callback_data->acdCycleStartTimeNanos - ); - } - break; - - default: - break; - }; -} - - -WavesAudioBackend::WavesAudioBackend (AudioEngine& e) - : AudioBackend (e, __backend_info) - , _audio_device_manager (this) - , _midi_device_manager (*this) - , _device (NULL) - , _sample_format (FormatFloat) - , _interleaved (true) - , _input_channels (0) - , _max_input_channels (0) - , _output_channels (0) - , _max_output_channels (0) - , _sample_rate (0) - , _buffer_size (0) - , _systemic_input_latency (0) - , _systemic_output_latency (0) - , _call_thread_init_callback (false) - , _use_midi (true) - , _sample_time_at_cycle_start (0) - , _freewheeling (false) - , _freewheel_thread_active (false) - , _dsp_load_accumulator (0) - , _audio_cycle_period_nanos (0) - , _dsp_load_history_length(0) -{ -} - - -WavesAudioBackend::~WavesAudioBackend () -{ - -} - -std::string -WavesAudioBackend::name () const -{ -#ifdef __APPLE__ - return std::string ("CoreAudio"); -#elif PLATFORM_WINDOWS - return std::string ("ASIO"); -#endif -} - - -bool -WavesAudioBackend::is_realtime () const -{ - return true; -} - - -bool -WavesAudioBackend::requires_driver_selection () const -{ - return false; -} - - -std::vector<std::string> -WavesAudioBackend::enumerate_drivers () const -{ - // this backend does not suppose driver selection - assert (false); - - return std::vector<std::string> (); -} - - -int -WavesAudioBackend::set_driver (const std::string& /*drivername*/) -{ - //Waves audio backend does not suppose driver selection - assert (false); - - return -1; -} - - -std::vector<AudioBackend::DeviceStatus> -WavesAudioBackend::enumerate_devices () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_devices (): " << std::endl; - - std::vector<DeviceStatus> devicesStatus; - const DeviceInfoVec& deviceInfoList = _audio_device_manager.DeviceInfoList(); - - for (DeviceInfoVecConstIter deviceInfoIter = deviceInfoList.begin (); deviceInfoIter != deviceInfoList.end (); ++deviceInfoIter) { - // COMMENTED DBG LOGS */ std::cout << "\t Device found: " << (*deviceInfoIter)->m_DeviceName << std::endl; - devicesStatus.push_back (DeviceStatus ((*deviceInfoIter)->m_DeviceName, true)); - } - - return devicesStatus; -} - - -std::vector<float> -WavesAudioBackend::available_sample_rates (const std::string& device_name) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_sample_rates (): [" << device_name << "]" << std::endl; - - std::vector<int> sr; - - WTErr retVal = _audio_device_manager.GetDeviceSampleRates(device_name, sr); - - if (eNoErr != retVal) { - std::cerr << "WavesAudioBackend::available_sample_rates (): Failed to find device [" << device_name << "]" << std::endl; - return std::vector<float> (); - } - - // COMMENTED DBG LOGS */ std::cout << "\tFound " << devInfo.m_AvailableSampleRates.size () << " sample rates for " << device_name << ":"; - - std::vector<float> sample_rates (sr.begin (), sr.end ()); - - // COMMENTED DBG LOGS */ for (std::vector<float>::iterator i = sample_rates.begin (); i != sample_rates.end (); ++i) std::cout << " " << *i; std::cout << std::endl; - - return sample_rates; -} - - -float WavesAudioBackend::default_sample_rate () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::default_sample_rate (): " << AudioBackend::default_sample_rate () << std::endl; - return AudioBackend::default_sample_rate (); -} - - -std::vector<uint32_t> -WavesAudioBackend::available_buffer_sizes (const std::string& device_name) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_buffer_sizes (): [" << device_name << "]" << std::endl; - - std::vector<int> bs; - - WTErr retVal = _audio_device_manager.GetDeviceBufferSizes(device_name, bs); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::available_buffer_sizes (): Failed to get buffer size for device [" << device_name << "]" << std::endl; - return std::vector<uint32_t> (); - } - - std::vector<uint32_t> buffer_sizes (bs.begin (), bs.end ()); - - // COMMENTED DBG LOGS */ std::cout << "\tFound " << buffer_sizes.size () << " buffer sizes for " << device_name << ":"; - // COMMENTED DBG LOGS */ for (std::vector<uint32_t>::const_iterator i = buffer_sizes.begin (); i != buffer_sizes.end (); ++i) std::cout << " " << *i; std::cout << std::endl; - - return buffer_sizes; -} - - -uint32_t -WavesAudioBackend::available_input_channel_count (const std::string& device_name) const -{ - DeviceInfo devInfo; - WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::available_input_channel_count (): Failed to find device [" << device_name << "]" << std::endl; - return 0; - } - - uint32_t num_of_input_channels = devInfo.m_MaxInputChannels; - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_input_channel_count (): " << num_of_input_channels << std::endl; - return num_of_input_channels; -} - - -uint32_t -WavesAudioBackend::available_output_channel_count (const std::string& device_name) const -{ - DeviceInfo devInfo; - WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::available_output_channel_count (): Failed to find device [" << device_name << "]" << std::endl; - return 0; - } - - uint32_t num_of_output_channels = devInfo.m_MaxOutputChannels; - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_output_channel_count (): " << num_of_output_channels << std::endl; - - return num_of_output_channels; -} - - -bool -WavesAudioBackend::can_change_sample_rate_when_running () const -{ - // VERIFY IT CAREFULLY - return true; -} - - -bool -WavesAudioBackend::can_change_buffer_size_when_running () const -{ - // VERIFY IT CAREFULLY - return true; -} - - -int -WavesAudioBackend::set_device_name (const std::string& device_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_device_name (): " << device_name << std::endl; - - if (_ports.size ()) { - std::cerr << "WavesAudioBackend::set_device_name (): There are unregistered ports left after [" << (_device ? _device->DeviceName () : std::string ("<NULL>")) << "]!" << std::endl; - for (size_t i = 0; i < _ports.size (); ++i) { - std::cerr << "\t[" << _ports[i]->name () << "]!" << std::endl; - } - return -1; - } - - if (_device && _device->Streaming () ) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "] is streaming! Current device must be stopped before setting another device as current" << std::endl; - } - - // we must have only one device initialized at a time - // stop current device first - WTErr retVal; - if (_device) { - retVal = _device->SetActive (false); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "]->SetActive (false) failed!" << std::endl; - return -1; - } - } - - // deinitialize it - _audio_device_manager.DestroyCurrentDevice(); - _device = 0; - - WCMRAudioDevice * device = _audio_device_manager.InitNewCurrentDevice(device_name); - - if (!device) { - std::cerr << "WavesAudioBackend::set_device_name (): Failed to initialize device [" << device_name << "]!" << std::endl; - return -1; - } - - - retVal = device->SetActive (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << device->DeviceName () << "]->SetActive () failed!" << std::endl; - return -1; - } - - _device = device; - return 0; -} - - -int -WavesAudioBackend::drop_device() -{ - WTErr wtErr = 0; - - if (_device) - { - wtErr = _device->SetActive (false); - if (wtErr != eNoErr) { - std::cerr << "WavesAudioBackend::drop_device (): [" << _device->DeviceName () << "]->SetActive () failed!" << std::endl; - return -1; - } - } - - _audio_device_manager.DestroyCurrentDevice(); - _device = 0; - - return 0; -} - - -int -WavesAudioBackend::set_sample_rate (float sample_rate) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_rate (): " << sample_rate << std::endl; - - WTErr retVal = eNoErr; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_sample_rate (): No device is set!" << std::endl; - return -1; - } - - - bool device_needs_restart = _device->Streaming (); - - if (device_needs_restart) { - retVal = _device->SetStreaming (false); - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->_device->SetStreaming (false);"<< std::endl; - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - retVal = _device->SetCurrentSamplingRate ((int)sample_rate); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName() << "]->SetCurrentSamplingRate ((int)" << sample_rate << ") failed (" << retVal << ") !" << std::endl; - return -1; - } - - // if call to set sample rate is successful - // but device sample rate differs from the value we tried to set - // this means we are driven by device for buffer size - sample_rate = _device->CurrentSamplingRate (); - _sample_rate_change(sample_rate); - - if (device_needs_restart) { - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - return 0; -} - - -int -WavesAudioBackend::set_buffer_size (uint32_t buffer_size) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_buffer_size (" << buffer_size << "):"<< std::endl; - - WTErr retVal = eNoErr; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; - return -1; - } - - bool device_needs_restart = _device->Streaming (); - - if (device_needs_restart) { - retVal = _device->SetStreaming (false); - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (false);"<< std::endl; - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - retVal = _device->SetCurrentBufferSize (buffer_size); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName() << "]->SetCurrentBufferSize (" << buffer_size << ") failed (" << retVal << ") !" << std::endl; - return -1; - } - - // if call to set buffer is successful but device buffer size differs from the value we tried to set - // this means we are driven by device for buffer size - buffer_size = _device->CurrentBufferSize (); - - _buffer_size_change(buffer_size); - - if (device_needs_restart) { - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - return 0; -} - - -int -WavesAudioBackend::set_sample_format (SampleFormat sample_format) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_format (): " << sample_format << std::endl; - - _sample_format = sample_format; - return 0; -} - -int -WavesAudioBackend::reset_device () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; - return -1; - } - - return _device->ResetDevice(); -} - - -int -WavesAudioBackend::_buffer_size_change (uint32_t new_buffer_size) -{ - _buffer_size = new_buffer_size; - _init_dsp_load_history(); - return engine.buffer_size_change (new_buffer_size); -} - - -int -WavesAudioBackend::_sample_rate_change (float new_sample_rate) -{ - _sample_rate = new_sample_rate; - _init_dsp_load_history(); - return engine.sample_rate_change (new_sample_rate); -} - - -int -WavesAudioBackend::set_interleaved (bool yn) -{ - /*you can ignore them totally*/ - _interleaved = yn; - return 0; -} - - -int -WavesAudioBackend::set_input_channels (uint32_t input_channels) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_input_channels (): " << input_channels << std::endl; - - _input_channels = input_channels; - return 0; -} - - -int -WavesAudioBackend::set_output_channels (uint32_t output_channels) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_output_channels (): " << output_channels << std::endl; - - _output_channels = output_channels; - return 0; -} - - -std::string -WavesAudioBackend::device_name () const -{ - if (!_device) { - return ""; - } - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::device_name (): " << _device->DeviceName () << std::endl; - - return _device->DeviceName (); -} - - -float -WavesAudioBackend::sample_rate () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_rate (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::sample_rate (): No device is set!" << std::endl; - return -1; - } - - int sample_rate = _device->CurrentSamplingRate (); - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentSamplingRate () returned " << sample_rate << std::endl; - - return (float)sample_rate; -} - - -uint32_t -WavesAudioBackend::buffer_size () const -{ - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::buffer_size (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::buffer_size (): No device is set!" << std::endl; - return 0; - } - - int size = _device->CurrentBufferSize (); - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentBufferSize () returned " << size << std::endl; - - return (uint32_t)size; -} - - -SampleFormat -WavesAudioBackend::sample_format () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_format ()" << std::endl; - return _sample_format; -} - - -bool -WavesAudioBackend::interleaved () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::interleaved ()" << std::endl; - - return _interleaved; -} - - -uint32_t -WavesAudioBackend::input_channels () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::input_channels ()" << std::endl; - - return _input_channels; -} - - -uint32_t -WavesAudioBackend::output_channels () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::output_channels ()" << std::endl; - - return _output_channels; -} - - -std::string -WavesAudioBackend::control_app_name () const -{ - std::string app_name = ""; - - if (_device && !dynamic_cast<WCMRNativeAudioNoneDevice*> (_device)) { - app_name = "PortAudioMayKnowIt"; - } - - return app_name; -} - - -void -WavesAudioBackend::launch_control_app () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::launch_control_app ()" << std::endl; - if (!_device) { - std::cerr << "WavesAudioBackend::launch_control_app (): No device is set!" << std::endl; - return; - } - - WTErr err = _device->ShowConfigPanel (NULL); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel () failed (" << err << ")!" << std::endl; - } - - // COMMENTED DBG LOGS */ else std::cout << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel () successfully launched!" << std::endl; -} - - -int -WavesAudioBackend::_start (bool for_latency_measurement) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_start ()" << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::_start (): No device is set!" << std::endl; - stop(); - return -1; - } - - if (_register_system_audio_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): _register_system_audio_ports () failed!" << std::endl; - stop(); - return -1; - } - - if (_use_midi) { - if (_midi_device_manager.start () != 0) { - std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.start () failed!" << std::endl; - stop(); - return -1; - } - if (_register_system_midi_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): _register_system_midi_ports () failed!" << std::endl; - stop(); - return -1; - } - } - - if (engine.reestablish_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): engine.reestablish_ports () failed!" << std::endl; - } - - manager.registration_callback (); - - WTErr retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::_start (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - stop(); - return -1; - } - - if (_use_midi) { - if (_midi_device_manager.stream (true)) { - std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.stream (true) failed!" << std::endl; - stop(); - return -1; - } - } - - return 0; -} - - -void -WavesAudioBackend::_audio_device_callback (const float* input_buffer, - float* output_buffer, - unsigned long nframes, - framepos_t sample_time, - uint64_t cycle_start_time_nanos) -{ - uint64_t dsp_start_time_nanos = __get_time_nanos(); - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_audio_device_callback ():" << _device->DeviceName () << std::endl; - _sample_time_at_cycle_start = sample_time; - _cycle_start_time_nanos = cycle_start_time_nanos; - - if (_buffer_size != nframes) { - // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() buffer size and nframes are not equal: " << _buffer_size << "!=" << nframes << std::endl; - return; - } - - _read_audio_data_from_device (input_buffer, nframes); - _read_midi_data_from_devices (); - - 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; - - /* There is the possibility that the thread this runs in may change from - * callback to callback, so do it every time. - */ - _main_thread = pthread_self (); - - AudioEngine::thread_init_callback (this); - } - - if ( !engine.thread_initialised_for_audio_processing () ) { - std::cerr << "\tWavesAudioBackend::_audio_device_callback (): It's an attempt to call process callback from the thread which didn't initialize it " << std::endl; - - AudioEngine::thread_init_callback (this); - } - - if (pthread_equal (_main_thread, pthread_self()) == 0) { -#ifdef PTW32_VERSION - std::cerr << "Process thread ID has changed. Expected thread: " << _main_thread.p << " current thread: " << pthread_self().p << std::dec << " !" << std::endl; -#else - std::cerr << "Process thread ID has changed. Expected thread: " << _main_thread << " current thread: " << pthread_self() << std::dec << " !" << std::endl; -#endif - _main_thread = pthread_self(); - } - - engine.process_callback (nframes); - - _write_audio_data_to_device (output_buffer, nframes); - _write_midi_data_to_devices (nframes); - - uint64_t dsp_end_time_nanos = __get_time_nanos(); - - _dsp_load_accumulator -= *_dsp_load_history.begin(); - _dsp_load_history.pop_front(); - uint64_t dsp_load_nanos = dsp_end_time_nanos - dsp_start_time_nanos; - _dsp_load_accumulator += dsp_load_nanos; - _dsp_load_history.push_back(dsp_load_nanos); - - return; -} - - -int -WavesAudioBackend::stop () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::stop ()" << std::endl; - - WTErr wtErr = eNoErr; - int retVal = 0; - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]" << std::endl; - - if (_device) { - wtErr = _device->SetStreaming (false); - if (wtErr != eNoErr) { - std::cerr << "WavesAudioBackend::stop (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - retVal = -1; - } - } - - _midi_device_manager.stop (); - _unregister_system_audio_ports (); - _unregister_system_midi_ports (); - - return retVal; -} - - -int -WavesAudioBackend::freewheel (bool start_stop) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::freewheel (" << start_stop << "):" << std::endl; - - if (start_stop != _freewheeling) { - if (start_stop == true) { - WTErr retval = _device->SetStreaming (false); - if (retval != eNoErr) { - std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - return -1; - } - _call_thread_init_callback = true; - _freewheel_thread (); - - while (!engine.freewheeling()) { - sleep(0); - } - - // freewheel thread was not activated successfully - if (_freewheel_thread_active == false) { - engine.freewheel_callback(false); - } - } - else { - _freewheel_thread_active = false; // stop _freewheel_thread () - - while (engine.freewheeling()) { - sleep(0); - } - - _call_thread_init_callback = true; - WTErr retval = _device->SetStreaming (true); - if (retval != eNoErr) { - std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - return -1; - } - } - _freewheeling = start_stop; - } - // already doing what has been asked for - return 0; -} - - -void -WavesAudioBackend::_freewheel_thread () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread ():" << std::endl; - if (!_freewheel_thread_active) { // Lets create it - - // COMMENTED DBG LOGS */ std::cout << "\tCreating the thread _freewheel_thread () . . ." << std::endl; - pthread_attr_t attributes; - pthread_t thread_id; - - ThreadData* thread_data = new ThreadData (this, boost::bind (&WavesAudioBackend::_freewheel_thread, this), __thread_stack_size ()); - - if (pthread_attr_init (&attributes)) { - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_init () failed!" << std::endl; - return; - } - - if (pthread_attr_setstacksize (&attributes, __thread_stack_size ())) { - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_setstacksize () failed!" << std::endl; - return; - } - - _freewheel_thread_active = true; - if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) { - _freewheel_thread_active = false; - - // release invoking thread - engine.freewheel_callback(true); - - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl; - return; - } - - // COMMENTED DBG LOGS */ std::cout << "\t. . . _freewheel_thread () complete." << std::endl; - return; - } - - // notify angine that freewheeling is started - engine.freewheel_callback(true); - - if (_call_thread_init_callback) { - _call_thread_init_callback = false; - AudioEngine::thread_init_callback (this); - } - - while (_freewheel_thread_active) { - engine.process_callback (_buffer_size); - } - - // notify angine that freewheeling is stopped - engine.freewheel_callback(false); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread (): FINISHED" << std::endl; - return; -} - - -float -WavesAudioBackend::dsp_load () const -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::dsp_load (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::cpu_load (): No device is set!" << std::endl; - return 0; - } - - float average_dsp_load = (float)_dsp_load_accumulator/_dsp_load_history_length; - - return ( average_dsp_load / _audio_cycle_period_nanos)*100.0; -} - - -void -WavesAudioBackend::_init_dsp_load_history() -{ - if((_sample_rate <= 0.0) || (_buffer_size <= 0.0)) { - return; - } - - _audio_cycle_period_nanos = ((uint64_t)1000000000L * _buffer_size) / _sample_rate; - - _dsp_load_accumulator = 0; - - _dsp_load_history_length = (_sample_rate + _buffer_size - 1) / _buffer_size; - // COMMENTED DBG LOGS */ std::cout << "\t\t_dsp_load_history_length = " << _dsp_load_history_length << std::endl; - _dsp_load_history = std::list<uint64_t>(_dsp_load_history_length, 0); -} - - -void -WavesAudioBackend::transport_start () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_start (): " << std::endl; -} - - -void -WavesAudioBackend::transport_stop () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_stop (): " << std::endl; -} - - -TransportState -WavesAudioBackend::transport_state () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_state (): " << std::endl; - return TransportStopped; -} - - -void -WavesAudioBackend::transport_locate (framepos_t pos) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_locate (" << pos << "): " << std::endl; -} - - -framepos_t -WavesAudioBackend::transport_frame () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_frame (): " << std::endl; - return 0; -} - - -int -WavesAudioBackend::set_time_master (bool yn) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_time_master (): " << yn << std::endl; - return 0; -} - - -int -WavesAudioBackend::usecs_per_cycle () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::usecs_per_cycle (): " << std::endl; - return (1000000 * _sample_rate) / _buffer_size; -} - - -size_t -WavesAudioBackend::raw_buffer_size (DataType data_type) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::raw_buffer_size (" << data_type.to_string () << "): " << std::endl; - switch (data_type) { - case DataType::AUDIO: - return WavesAudioPort::MAX_BUFFER_SIZE_BYTES; - break; - - case DataType::MIDI: - return WavesMidiPort::MAX_BUFFER_SIZE_BYTES; - break; - - default: - std::cerr << "WavesAudioBackend::raw_buffer_size (): unexpected data type (" << (uint32_t)data_type <<")!" << std::endl; - break; - } - return 0; -} - - -framepos_t -WavesAudioBackend::sample_time () -{ - // WARNING: This is approximate calculation. Implementation of accurate calculation is pending. - // http://kokkinizita.linuxaudio.org/papers/usingdll.pdf - - return _sample_time_at_cycle_start + ((__get_time_nanos () - _cycle_start_time_nanos)*_sample_rate)/1000000000L; -} - - -uint64_t -WavesAudioBackend::__get_time_nanos () -{ -#ifdef __APPLE__ - // here we exploit the time counting API which is used by the WCMRCoreAudioDeviceManager. However, - // the API should be a part of WCMRCoreAudioDeviceManager to give a chance of being tied to the - // audio device transport timeß. - return AudioConvertHostTimeToNanos (AudioGetCurrentHostTime ()); - -#elif PLATFORM_WINDOWS - LARGE_INTEGER Count; - QueryPerformanceCounter (&Count); - return uint64_t ((Count.QuadPart * 1000000000L / __performance_counter_frequency)); -#endif -} - - -framepos_t -WavesAudioBackend::sample_time_at_cycle_start () -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::sample_time_at_cycle_start (): " << _sample_time_at_cycle_start << std::endl; - return _sample_time_at_cycle_start; -} - - -pframes_t -WavesAudioBackend::samples_since_cycle_start () -{ - pframes_t diff_sample_time; - diff_sample_time = sample_time () - _sample_time_at_cycle_start; - // COMMENTED DBG LOGS */ std::cout << "samples_since_cycle_start: " << diff_sample_time << std::endl; - - return diff_sample_time; -} - - -bool -WavesAudioBackend::get_sync_offset (pframes_t& /*offset*/) const -{ - // COMMENTED DBG LOGS */ std::cout << "get_sync_offset: false" << std::endl; - - return false; -} - - -int -WavesAudioBackend::create_process_thread (boost::function<void ()> func) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::create_process_thread ():" << std::endl; - int retVal; - pthread_attr_t attributes; - size_t stacksize_aligned; - pthread_t thread_id; - - // Align stacksize to PTHREAD_STACK_MIN. - stacksize_aligned = __thread_stack_size (); - - ThreadData* td = new ThreadData (this, func, stacksize_aligned); - - if ((retVal = pthread_attr_init (&attributes))) { - std::cerr << "Cannot set thread attr init res = " << retVal << endmsg; - return -1; - } - - if ((retVal = pthread_attr_setstacksize (&attributes, stacksize_aligned))) { - std::cerr << "Cannot set thread stack size (" << stacksize_aligned << ") res = " << retVal << endmsg; - return -1; - } - - if ((retVal = pthread_create (&thread_id, &attributes, __start_process_thread, td))) { - std::cerr << "Cannot create thread res = " << retVal << endmsg; - return -1; - } - - _backend_threads.push_back (thread_id); - // COMMENTED DBG LOGS */ std::cout << "\t\t\t. . . thread " << std::hex << thread_id << std::dec << " has been created" << std::endl; - - return 0; -} - - -void* -WavesAudioBackend::__start_process_thread (void* arg) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__start_process_thread ():" << std::endl; - ThreadData* td = reinterpret_cast<ThreadData*> (arg); - boost::function<void ()> f = td->f; - delete td; - f (); - return 0; -} - - -int -WavesAudioBackend::join_process_threads () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::join_process_thread ()" << std::endl; - int ret = 0; - - for (std::vector<pthread_t>::const_iterator i = _backend_threads.begin (); - i != _backend_threads.end (); - ++i) { - // COMMENTED DBG LOGS */ std::cout << "\t\t\tstopping thread " << std::hex << *i << std::dec << "...\n"; - - void* status; - if (pthread_join (*i, &status) != 0) { - std::cerr << "AudioEngine: cannot stop process thread !" << std::endl; - ret += -1; - } - // COMMENTED DBG LOGS */ std::cout << "\t\t\t\t...done" << std::endl; - } - // COMMENTED DBG LOGS */ std::cout << "\t\t\tall threads finished..." << std::endl; - _backend_threads.clear (); - // COMMENTED DBG LOGS */ std::cout << "\t\t\tthread list cleared..." << std::endl; - - return ret; -} - - -bool -WavesAudioBackend::in_process_thread () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::in_process_thread ()" << std::endl; - if (pthread_equal (_main_thread, pthread_self()) != 0) { - return true; - } - for (std::vector<pthread_t>::const_iterator i = _backend_threads.begin (); - i != _backend_threads.end (); i++) { - if (pthread_equal (*i, pthread_self ()) != 0) { - return true; - } - } - return false; -} - - -size_t -WavesAudioBackend::__thread_stack_size () -{ - // Align stacksize to PTHREAD_STACK_MIN. -#if defined (__APPLE__) - return (((thread_stack_size () - 1) / PTHREAD_STACK_MIN) + 1) * PTHREAD_STACK_MIN; -#elif defined (PLATFORM_WINDOWS) - return thread_stack_size (); -#endif -} - - -uint32_t -WavesAudioBackend::process_thread_count () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::process_thread_count (): returns " << _backend_threads.size () << std::endl; - return _backend_threads.size (); -} - - -void -WavesAudioBackend::_read_audio_data_from_device (const float* input_buffer, pframes_t nframes) -{ -#if defined(PLATFORM_WINDOWS) - const float **buffer = (const float**)input_buffer; - - for(std::vector<WavesAudioPort*>::iterator it = _physical_audio_inputs.begin (); - it != _physical_audio_inputs.end(); - ++it) - { - ARDOUR::copy_vector ((*it)->buffer(), *buffer, nframes); - ++buffer; - } -#else - std::vector<WavesAudioPort*>::iterator it = _physical_audio_inputs.begin (); - - // Well, let's de-interleave here: - const Sample* source = input_buffer; - - for (uint32_t chann_cnt = 0; (chann_cnt < _max_input_channels) && (it != _physical_audio_inputs.end ()); ++chann_cnt, ++source, ++it) { - const Sample* src = source; - Sample* tgt = (*it)->buffer (); - - for (uint32_t frame = 0; frame < nframes; ++frame, src += _max_input_channels, ++tgt) { - *tgt = *src; - } - } -#endif -} - -void -WavesAudioBackend::_write_audio_data_to_device (float* output_buffer, pframes_t nframes) -{ -#if defined(_WnonononoINDOWS) - float **buffer = (float**)output_buffer; - size_t copied_bytes = nframes*sizeof(float); - int i = 0; - for(std::vector<WavesAudioPort*>::iterator it = _physical_audio_outputs.begin (); - it != _physical_audio_outputs.end(); - ++it) - { - memcpy(*buffer, (*it)->buffer(), copied_bytes); - //*buffer = (*it)->buffer(); - buffer++; - } -#else - // Well, let's interleave here: - std::vector<WavesAudioPort*>::iterator it = _physical_audio_outputs.begin (); - Sample* target = output_buffer; - - for (uint32_t chann_cnt = 0; - (chann_cnt < _max_output_channels) && (it != _physical_audio_outputs.end ()); - ++chann_cnt, ++target, ++it) { - const Sample* src = (Sample*) ((*it)->get_buffer (nframes)); - Sample* tgt = target; - for (uint32_t frame = 0; frame < nframes; ++frame, tgt += _max_output_channels, ++src) { - *tgt = *src; - } - } -#endif -} - - -static boost::shared_ptr<WavesAudioBackend> __instance; - - -boost::shared_ptr<AudioBackend> -WavesAudioBackend::__waves_backend_factory (AudioEngine& e) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl; - if (!__instance) { - __instance.reset (new WavesAudioBackend (e)); - } - return __instance; -} - - -#if defined(PLATFORM_WINDOWS) - -uint64_t WavesAudioBackend::__performance_counter_frequency; - -#endif - -int -WavesAudioBackend::__instantiate (const std::string& arg1, const std::string& arg2) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__instantiate ():" << "[" << arg1 << "], [" << arg2 << "]" << std::endl; - __instantiated_name = arg1; -#if defined(PLATFORM_WINDOWS) - - LARGE_INTEGER Frequency; - QueryPerformanceFrequency(&Frequency); - __performance_counter_frequency = Frequency.QuadPart; - -#endif - return 0; -} - - -int -WavesAudioBackend::__deinstantiate () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__deinstantiate ():" << std::endl; - __instance.reset (); - return 0; -} - - -bool -WavesAudioBackend::__already_configured () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__already_configured ():" << std::endl; - return false; -} - -bool -WavesAudioBackend::__available () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__available ():" << std::endl; - return true; -} - - -void* -WavesAudioBackend::private_handle () const -{ - // COMMENTED DBG LOGS */ std::cout << "WHY DO CALL IT: WavesAudioBackend::private_handle: " << std::endl; - return NULL; -} - - -bool -WavesAudioBackend::available () const -{ - // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::available: " << std::endl; - return true; -} - - -const std::string& -WavesAudioBackend::my_name () const -{ - // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::my_name: " << _port_prefix_name << std::endl; - return __instantiated_name; -} - - -bool -WavesAudioBackend::can_monitor_input () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::can_monitor_input: " << std::endl; - return false; -} - -std::string WavesAudioBackend::__instantiated_name; - -AudioBackendInfo WavesAudioBackend::__backend_info = { -#ifdef __APPLE__ - "CoreAudio", -#elif PLATFORM_WINDOWS - "ASIO", -#endif - __instantiate, - WavesAudioBackend::__deinstantiate, - WavesAudioBackend::__waves_backend_factory, - WavesAudioBackend::__already_configured, - WavesAudioBackend::__available, -}; - - |