mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-08 22:55:44 +01:00
meld-driven unification of current ardour-ish WavesAudio backend and current tracks WavesAudio backend.
May be incomplete, and may not compile (testing to follow)
This commit is contained in:
parent
0fca07fa9d
commit
237f255fb5
14 changed files with 490 additions and 253 deletions
|
|
@ -361,13 +361,14 @@ 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)
|
||||
SetStreaming(true);
|
||||
if (err == eNoErr && wasStreaming) {
|
||||
err = SetStreaming(true);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,6 +248,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();
|
||||
|
|
@ -258,7 +261,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;
|
||||
}
|
||||
|
|
@ -266,6 +269,70 @@ 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;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDevice::UpdateDeviceName
|
||||
//
|
||||
|
|
@ -881,8 +948,6 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int 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;
|
||||
|
|
@ -926,6 +991,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;
|
||||
|
||||
|
|
@ -936,12 +1003,28 @@ WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate)
|
|||
// If sample rate did not change after time out
|
||||
else
|
||||
{
|
||||
// Update member with last read value
|
||||
m_CurrentSamplingRate = static_cast<int>(actualSamplingRate);
|
||||
// Check if current device sample rate is supported
|
||||
bool found = false;
|
||||
for(int i = 0; gAllSampleRates[i] > 0; i++)
|
||||
{
|
||||
if (fabs(gAllSampleRates[i] - actualSamplingRate) < 0.01) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (found) {
|
||||
// Update member with last read value
|
||||
m_CurrentSamplingRate = static_cast<int>(actualSamplingRate);
|
||||
|
||||
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);
|
||||
} else {
|
||||
retVal = eGenericErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1731,7 +1814,6 @@ WTErr WCMRCoreAudioDevice::TearDownAUHAL()
|
|||
}
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDevice::SetActive
|
||||
//
|
||||
|
|
@ -1799,7 +1881,6 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState)
|
|||
m_IgnoreThisDrop = true;
|
||||
|
||||
UpdateDeviceInfo();
|
||||
|
||||
}
|
||||
|
||||
m_IsActive = newState;
|
||||
|
|
@ -1909,6 +1990,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...
|
||||
|
|
@ -1924,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;
|
||||
}
|
||||
|
|
@ -2554,7 +2639,7 @@ WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
|
|||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels)
|
||||
{
|
||||
|
|
@ -2876,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);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ protected:
|
|||
#endif //WV_USE_TONE_GEN
|
||||
|
||||
WTErr UpdateDeviceInfo ();
|
||||
WTErr UpdateDeviceId ();
|
||||
WTErr UpdateDeviceName();
|
||||
WTErr UpdateDeviceInputs();
|
||||
WTErr UpdateDeviceOutputs();
|
||||
|
|
|
|||
|
|
@ -901,6 +901,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)
|
||||
|
|
@ -1082,13 +1085,19 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
|
|||
case kAsioLatenciesChanged:
|
||||
m_BufferSizeChangeRequested++;
|
||||
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl;
|
||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
|
||||
if (m_ResetRequested == 0) {
|
||||
m_ResetRequested++;
|
||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAsioBufferSizeChange:
|
||||
m_BufferSizeChangeRequested++;
|
||||
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl;
|
||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
|
||||
if (m_ResetRequested == 0) {
|
||||
m_ResetRequested++;
|
||||
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAsioResetRequest:
|
||||
|
|
@ -1540,6 +1549,32 @@ WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
|
|||
}
|
||||
|
||||
|
||||
WTErr WCMRPortAudioDeviceManager::getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers)
|
||||
{
|
||||
WTErr retVal = eNoErr;
|
||||
|
||||
buffers.clear();
|
||||
|
||||
//make PA request to get actual device buffer sizes
|
||||
long minSize, maxSize, preferredSize, granularity;
|
||||
|
||||
PaError paErr = PaAsio_GetAvailableBufferSizes(deviceId, &minSize, &maxSize, &preferredSize, &granularity);
|
||||
|
||||
//for Windows ASIO devices we always use prefferes buffer size ONLY
|
||||
if (paNoError == paErr )
|
||||
{
|
||||
buffers.push_back(preferredSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eAsioFailed;
|
||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceId << std::endl;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
|
||||
{
|
||||
std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl;
|
||||
|
|
@ -1586,6 +1621,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
|
|||
DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name);
|
||||
if (pDevInfo)
|
||||
{
|
||||
//Get available sample rates
|
||||
std::vector<int> availableSampleRates;
|
||||
WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates);
|
||||
|
||||
|
|
@ -1600,6 +1636,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
|
|||
pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels;
|
||||
pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels;
|
||||
|
||||
//Get available buffer sizes
|
||||
std::vector<int> availableBuffers;
|
||||
wErr = getDeviceAvailableBufferSizes(thisDeviceID, availableBuffers);
|
||||
|
||||
if (wErr != eNoErr)
|
||||
{
|
||||
DEBUG_MSG ("Failed to get device available buffer sizes. Device ID: " << m_DeviceID);
|
||||
delete pDevInfo;
|
||||
continue; //proceed to the next device
|
||||
}
|
||||
|
||||
pDevInfo->m_AvailableBufferSizes = availableBuffers;
|
||||
|
||||
//Now check if this device is acceptable according to current input/output settings
|
||||
bool bRejectDevice = false;
|
||||
switch(m_eAudioDeviceFilter)
|
||||
|
|
@ -1681,7 +1730,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
|
|||
|
||||
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
|
||||
{
|
||||
sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() );
|
||||
sampleRates=m_CurrentDevice->SamplingRates();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
@ -1690,7 +1739,7 @@ WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & d
|
|||
|
||||
if (eNoErr == retVal)
|
||||
{
|
||||
sampleRates.assign(devInfo.m_AvailableSampleRates.begin(), devInfo.m_AvailableSampleRates.end() );
|
||||
sampleRates=devInfo.m_AvailableSampleRates;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1710,44 +1759,28 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
|
|||
//first check if the request has been made for None device
|
||||
if (deviceName == m_NoneDevice->DeviceName() )
|
||||
{
|
||||
buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() );
|
||||
buffers=m_NoneDevice->BufferSizes();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
|
||||
{
|
||||
buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() );
|
||||
buffers=m_CurrentDevice->BufferSizes();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Pa_Initialize();
|
||||
|
||||
DeviceInfo devInfo;
|
||||
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
||||
|
||||
if (eNoErr == retVal)
|
||||
{
|
||||
//make PA request to get actual device buffer sizes
|
||||
long minSize, maxSize, preferredSize, granularity;
|
||||
PaError paErr = PaAsio_GetAvailableBufferSizes(devInfo.m_DeviceId, &minSize, &maxSize, &preferredSize, &granularity);
|
||||
|
||||
//for Windows ASIO devices we always use prefferes buffer size ONLY
|
||||
if (paNoError == paErr )
|
||||
{
|
||||
buffers.push_back(preferredSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eAsioFailed;
|
||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceName << std::endl;
|
||||
}
|
||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl;
|
||||
buffers = devInfo.m_AvailableBufferSizes;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
|
||||
}
|
||||
|
||||
Pa_Terminate();
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ protected:
|
|||
private:
|
||||
// helper functions for this class only
|
||||
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
|
||||
WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers);
|
||||
|
||||
WCMRAudioDevice* m_NoneDevice;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue