mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-12 17:46:34 +01:00
[Summary] Backend Improvements
[Details] Fixed error handling Fixed switching to None device when something goes wrong with the current device Backend now takes care when device ID changes - Sound Grid does this when the amount of channel changes and it's not going to change in the neared future. Fixed sample rate changes notification from device to DAW - Some devices can respond with such updates, we must correctly process them.
This commit is contained in:
parent
8da1ad9fcf
commit
cb9f19baca
6 changed files with 124 additions and 30 deletions
|
|
@ -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<WCMRCoreAudioDevice*>(m_CurrentDevice);
|
||||
|
||||
if ( current_device &&
|
||||
(current_device->DeviceID() != devInfo.m_DeviceId ) )
|
||||
{
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue