diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 34971438ff..871c76fb91 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -420,19 +420,17 @@ AudioEngine::do_reset_backend() // backup the device name std::string name = _backend->device_name (); - - std::cout << "AudioEngine::RESET::Stoping engine..." << std::endl; - stop(); std::cout << "AudioEngine::RESET::Reseting device..." << std::endl; - if ( 0 == _backend->reset_device () ) { + if ( ( 0 == stop () ) && + ( 0 == _backend->reset_device () ) && + ( 0 == start () ) ) { + + std::cout << "AudioEngine::RESET::Engine started..." << std::endl; - std::cout << "AudioEngine::RESET::Starting engine..." << std::endl; - start (); - // inform about possible changes BufferSizeChanged (_backend->buffer_size() ); - } else { + } else { DeviceError(); } @@ -471,9 +469,11 @@ AudioEngine::do_devicelist_update() _devicelist_update_lock.unlock(); + Glib::Threads::RecMutex::Lock pl (_state_lock); + g_atomic_int_dec_and_test (&_hw_devicelist_update_count); DeviceListChanged (); /* EMIT SIGNAL */ - + _devicelist_update_lock.lock(); } else { diff --git a/libs/ardour/engine_state_controller.cc b/libs/ardour/engine_state_controller.cc index dc67e4b10d..3b4cab4a7a 100644 --- a/libs/ardour/engine_state_controller.cc +++ b/libs/ardour/engine_state_controller.cc @@ -802,8 +802,6 @@ EngineStateController::set_new_sample_rate_in_controller(framecnt_t sample_rate) } - - bool EngineStateController::set_new_buffer_size_in_controller(pframes_t buffer_size) { @@ -1350,11 +1348,10 @@ EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate) framecnt_t sample_rate_to_set = new_sample_rate; if (AudioEngine::instance()->session() ) { // and we have current session we should restore it back to the one tracks uses - sample_rate_to_set = _current_state->sample_rate; + sample_rate_to_set = AudioEngine::instance()->session()->frame_rate (); } if ( set_new_sample_rate_in_controller (sample_rate_to_set) ) { - push_current_state_to_backend(false); SampleRateChanged(); // emit a signal } else { // if sample rate can't be set @@ -1412,7 +1409,7 @@ EngineStateController::_on_device_list_change() _states.push_front(_current_state); } - push_current_state_to_backend(false); + push_current_state_to_backend(true); current_device_disconnected = true; } } else { diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc index be8b4023f3..507a118b8a 100644 --- a/libs/backends/wavesaudio/waves_audiobackend.cc +++ b/libs/backends/wavesaudio/waves_audiobackend.cc @@ -42,6 +42,7 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso case WCMRAudioDeviceManagerClient::BufferSizeChanged: std::cout << "------------------------------- WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(uint32_t*)parameter << std::endl; _buffer_size_change(*(uint32_t*)parameter); + _buffer_size_change(*(int*)parameter); break; case WCMRAudioDeviceManagerClient::RequestReset: std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl; @@ -51,8 +52,8 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl; break; case WCMRAudioDeviceManagerClient::SamplingRateChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl; - set_sample_rate(*(float*)parameter); + std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(int*)parameter << std::endl; + _sample_rate_change(*(float*)parameter); break; case WCMRAudioDeviceManagerClient::Dropout: std::cout << "------------------------------- WCMRAudioDeviceManagerClient::Dropout: " << std::endl; @@ -401,7 +402,11 @@ WavesAudioBackend::set_sample_rate (float sample_rate) return -1; } - _sample_rate_change(sample_rate); + // 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; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp index c1dc758507..e6affd6fc5 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp @@ -359,10 +359,10 @@ WTErr WCMRAudioDevice::ResetDevice () WTErr err = SetStreaming(false); if (err == eNoErr) - SetActive(false); + err = SetActive(false); if (err == eNoErr && wasActive) - SetActive(true); + err = SetActive(true); if (err == eNoErr && wasStreaming) { err = SetStreaming(true); diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp index 822618fd09..203c291b08 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp @@ -247,6 +247,9 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo () WTErr retVal = eNoErr; + // Some devices change the ID during restart + WTErr errId = UpdateDeviceId(); + // Update all devices parts regardless of errors WTErr errName = UpdateDeviceName(); WTErr errIn = UpdateDeviceInputs(); @@ -257,7 +260,7 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo () errSR = UpdateDeviceSampleRates(); errBS = UpdateDeviceBufferSizes(); - if(errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr) + if(errId != eNoErr || errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr) { retVal = eCoreAudioFailed; } @@ -265,6 +268,69 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo () return retVal; } + +WTErr WCMRCoreAudioDevice::UpdateDeviceId() +{ + //Get device count... + UInt32 propSize = 0; + WTErr retVal = eNoErr; + OSStatus osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL); + ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1"); + if (WUIsError(osErr)) + throw osErr; + + size_t numDevices = propSize / sizeof (AudioDeviceID); + AudioDeviceID* deviceIDs = new AudioDeviceID[numDevices]; + + //retrieve the device IDs + propSize = numDevices * sizeof (AudioDeviceID); + osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs); + ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2"); + if (WUIsError(osErr)) + throw osErr; + + //now add the ones that are not there... + for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) + { + DeviceInfo* pDevInfo = 0; + + //Get device name and create new DeviceInfo entry + //Get property name size. + osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL); + if (osErr == kAudioHardwareNoError) + { + //Get property: name. + char* deviceName = new char[propSize]; + osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName); + if (osErr == kAudioHardwareNoError) + { + if ( (m_DeviceName == deviceName) && + (m_DeviceID != deviceIDs[deviceIndex]) ) { + + m_DeviceID = deviceIDs[deviceIndex]; + + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Current device has changed it's id."); + } + } + else + { + retVal = eCoreAudioFailed; + DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID); + } + + delete [] deviceName; + } + else + { + retVal = eCoreAudioFailed; + DEBUG_MSG("Failed to get device name prop Info. Device ID: " << m_DeviceID); + } + } + + delete [] deviceIDs; +} + + //********************************************************************************************** // WCMRCoreAudioDevice::UpdateDeviceName // @@ -875,13 +941,26 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate) OSStatus err = kAudioHardwareNoError; UInt32 propSize = 0; + // Check current sample rate + /* + propSize = sizeof (Float64); + Float64 currentSamplingRate = 0.0; + err = AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, ¤tSamplingRate); + if (err == kAudioHardwareNoError) + { + if (currentSamplingRate == newRate) + { + // nothing to do + return (retVal); + } + }*/ + + // 1. Set new sampling rate Float64 newNominalRate = newRate; propSize = sizeof (Float64); err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyNominalSampleRate, propSize, &newNominalRate); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate."); - if (err != kAudioHardwareNoError) { retVal = eCoreAudioFailed; @@ -925,6 +1004,8 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate) // If sample rate actually changed if (tryAgain != 0) { + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate."); + // Update member with new rate m_CurrentSamplingRate = newRate; @@ -941,6 +1022,9 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate) char debugMsg[128]; snprintf (debugMsg, sizeof(debugMsg), "Unable to change SR, even after waiting for %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg); + + float sample_rate_update = actualSamplingRate; + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::SamplingRateChanged, (void *)&sample_rate_update); } } @@ -1471,8 +1555,8 @@ WTErr WCMRCoreAudioDevice::SetupAUHAL() } //gains access to the services provided by the component - OpenAComponent(comp, &m_AUHALAudioUnit); - + OpenAComponent(comp, &m_AUHALAudioUnit); + retVal = EnableAudioUnitIO(); if (retVal != eNoErr) @@ -1730,7 +1814,6 @@ WTErr WCMRCoreAudioDevice::TearDownAUHAL() } - //********************************************************************************************** // WCMRCoreAudioDevice::SetActive // @@ -1796,9 +1879,8 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState) m_DropsDetected = 0; m_DropsReported = 0; m_IgnoreThisDrop = true; - + UpdateDeviceInfo(); - } m_IsActive = newState; @@ -1926,6 +2008,7 @@ WTErr WCMRCoreAudioDevice::SetStreaming (bool newState) if(err) { DEBUG_MSG( "Failed to start AudioUnit, err " << err ); + m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Failed to start AudioUnit."); retVal = eGenericErr; goto Exit; } @@ -2556,7 +2639,7 @@ WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI return retVal; } - + WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels) { @@ -2878,6 +2961,15 @@ WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl() NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected); return err; } + + WCMRCoreAudioDevice* current_device = dynamic_cast(m_CurrentDevice); + + if ( current_device && + (current_device->DeviceID() != devInfo.m_DeviceId ) ) + { + NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); + return err; + } } NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged); diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h index 74d1d18dfd..8d8958c2e6 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h @@ -138,6 +138,7 @@ protected: #endif //WV_USE_TONE_GEN WTErr UpdateDeviceInfo (); + WTErr UpdateDeviceId (); WTErr UpdateDeviceName(); WTErr UpdateDeviceInputs(); WTErr UpdateDeviceOutputs(); @@ -167,8 +168,7 @@ protected: static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData); void PropertyChangeProc (AudioDevicePropertyID inPropertyID); - - void resetAudioDevice(); + private: };