1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-30 02:50:05 +00:00

Improved CoreAudio handling of USB audio devices being unplugged

This commit is contained in:
jules 2016-02-03 09:57:42 +00:00
parent 783d892359
commit 076896d33b

View file

@ -388,65 +388,84 @@ public:
return 0;
}
void updateDetailsFromDevice()
int getFrameSizeFromDevice() const
{
stopTimer();
if (deviceID == 0)
return;
// this collects all the new details from the device without any locking, then
// locks + swaps them afterwards.
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
UInt32 isAlive;
UInt32 size = sizeof (isAlive);
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive)) && isAlive == 0)
return;
const double currentRate = getNominalSampleRate();
if (currentRate > 0)
sampleRate = currentRate;
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
UInt32 framesPerBuf = (UInt32) bufferSize;
size = sizeof (framesPerBuf);
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
UInt32 size = sizeof (framesPerBuf);
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf);
return (int) framesPerBuf;
}
Array<int> newBufferSizes (getBufferSizesFromDevice());
Array<double> newSampleRates (getSampleRatesFromDevice());
bool isDeviceAlive() const
{
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
inputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput);
outputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput);
UInt32 isAlive = 0;
UInt32 size = sizeof (isAlive);
return deviceID != 0
&& OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive))
&& isAlive != 0;
}
bool updateDetailsFromDevice()
{
stopTimer();
if (! isDeviceAlive())
return false;
// this collects all the new details from the device without any locking, then
// locks + swaps them afterwards.
const double newSampleRate = getNominalSampleRate();
const int newBufferSize = getFrameSizeFromDevice();
Array<int> newBufferSizes = getBufferSizesFromDevice();
Array<double> newSampleRates = getSampleRatesFromDevice();
const int newInputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput);
const int newOutputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput);
Array<CallbackDetailsForChannel> newInChans, newOutChans;
StringArray newInNames (getChannelInfo (true, newInChans));
StringArray newOutNames (getChannelInfo (false, newOutChans));
const int inputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeInput);
const int outputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeOutput);
const int newBitDepth = jmax (getBitDepthFromDevice (kAudioDevicePropertyScopeInput),
getBitDepthFromDevice (kAudioDevicePropertyScopeOutput));
bitDepth = jmax (inputBitDepth, outputBitDepth);
if (bitDepth <= 0)
bitDepth = 32;
{
const ScopedLock sl (callbackLock);
// after getting the new values, lock + apply them
const ScopedLock sl (callbackLock);
bitDepth = newBitDepth > 0 ? newBitDepth : 32;
bufferSize = (int) framesPerBuf;
allocateTempBuffers();
if (newSampleRate > 0)
sampleRate = newSampleRate;
sampleRates.swapWith (newSampleRates);
bufferSizes.swapWith (newBufferSizes);
inputLatency = newInputLatency;
outputLatency = newOutputLatency;
bufferSize = newBufferSize;
inChanNames.swapWith (newInNames);
outChanNames.swapWith (newOutNames);
sampleRates.swapWith (newSampleRates);
bufferSizes.swapWith (newBufferSizes);
inputChannelInfo.swapWith (newInChans);
outputChannelInfo.swapWith (newOutChans);
inChanNames.swapWith (newInNames);
outChanNames.swapWith (newOutNames);
inputChannelInfo.swapWith (newInChans);
outputChannelInfo.swapWith (newOutChans);
allocateTempBuffers();
}
return true;
}
//==============================================================================
@ -769,9 +788,10 @@ public:
stopTimer();
const double oldSampleRate = sampleRate;
const int oldBufferSize = bufferSize;
updateDetailsFromDevice();
if (oldBufferSize != bufferSize || oldSampleRate != sampleRate)
if (! updateDetailsFromDevice())
owner.stop();
else if (oldBufferSize != bufferSize || oldSampleRate != sampleRate)
owner.restart();
}