mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Android Oboe: Reopen streams correctly after device disconnection
Even if the output stream is the only one receiving callbacks, it's possible that the input device got disconnected, in which case we'll still need to recreate both streams.
This commit is contained in:
parent
6473deb155
commit
9be03bc99e
1 changed files with 60 additions and 59 deletions
|
|
@ -666,44 +666,9 @@ private:
|
|||
sampleRate (sampleRateToUse),
|
||||
bufferSize (bufferSizeToUse),
|
||||
streamFormat (streamFormatToUse),
|
||||
bitDepth (bitDepthToUse),
|
||||
outputStream (new OboeStream (outputDeviceId,
|
||||
oboe::Direction::Output,
|
||||
oboe::SharingMode::Exclusive,
|
||||
numOutputChannels,
|
||||
streamFormatToUse,
|
||||
sampleRateToUse,
|
||||
bufferSizeToUse,
|
||||
this))
|
||||
bitDepth (bitDepthToUse)
|
||||
{
|
||||
if (numInputChannels > 0)
|
||||
{
|
||||
inputStream.reset (new OboeStream (inputDeviceId,
|
||||
oboe::Direction::Input,
|
||||
oboe::SharingMode::Exclusive,
|
||||
numInputChannels,
|
||||
streamFormatToUse,
|
||||
sampleRateToUse,
|
||||
bufferSizeToUse,
|
||||
nullptr));
|
||||
|
||||
if (inputStream->openedOk() && outputStream->openedOk())
|
||||
{
|
||||
const auto getSampleRate = [] (auto nativeStream)
|
||||
{
|
||||
return nativeStream != nullptr ? nativeStream->getSampleRate() : 0;
|
||||
};
|
||||
// Input & output sample rates should match!
|
||||
jassert (getSampleRate (inputStream->getNativeStream())
|
||||
== getSampleRate (outputStream->getNativeStream()));
|
||||
}
|
||||
|
||||
checkStreamSetup (inputStream.get(), inputDeviceId, numInputChannels,
|
||||
sampleRate, bufferSize, streamFormat);
|
||||
}
|
||||
|
||||
checkStreamSetup (outputStream.get(), outputDeviceId, numOutputChannels,
|
||||
sampleRate, bufferSize, streamFormat);
|
||||
openStreams();
|
||||
}
|
||||
|
||||
// Not strictly required as these should not change, but recommended by Google anyway
|
||||
|
|
@ -735,6 +700,47 @@ private:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void openStreams()
|
||||
{
|
||||
outputStream = std::make_unique<OboeStream> (outputDeviceId,
|
||||
oboe::Direction::Output,
|
||||
oboe::SharingMode::Exclusive,
|
||||
numOutputChannels,
|
||||
streamFormat,
|
||||
sampleRate,
|
||||
bufferSize,
|
||||
static_cast<AudioStreamCallback*> (this));
|
||||
|
||||
checkStreamSetup (outputStream.get(), outputDeviceId, numOutputChannels,
|
||||
sampleRate, bufferSize, streamFormat);
|
||||
|
||||
if (numInputChannels <= 0)
|
||||
return;
|
||||
|
||||
inputStream = std::make_unique<OboeStream> (inputDeviceId,
|
||||
oboe::Direction::Input,
|
||||
oboe::SharingMode::Exclusive,
|
||||
numInputChannels,
|
||||
streamFormat,
|
||||
sampleRate,
|
||||
bufferSize,
|
||||
nullptr);
|
||||
|
||||
checkStreamSetup (inputStream.get(), inputDeviceId, numInputChannels,
|
||||
sampleRate, bufferSize, streamFormat);
|
||||
|
||||
if (! inputStream->openedOk() || ! outputStream->openedOk())
|
||||
return;
|
||||
|
||||
const auto getSampleRate = [] (auto nativeStream)
|
||||
{
|
||||
return nativeStream != nullptr ? nativeStream->getSampleRate() : 0;
|
||||
};
|
||||
// Input & output sample rates should match!
|
||||
jassert (getSampleRate (inputStream->getNativeStream())
|
||||
== getSampleRate (outputStream->getNativeStream()));
|
||||
}
|
||||
|
||||
OboeAudioIODevice& owner;
|
||||
int inputDeviceId, outputDeviceId;
|
||||
int numInputChannels, numOutputChannels;
|
||||
|
|
@ -782,8 +788,7 @@ private:
|
|||
{
|
||||
const SpinLock::ScopedLockType lock { audioCallbackMutex };
|
||||
|
||||
inputStream = nullptr;
|
||||
outputStream = nullptr;
|
||||
destroyStreams();
|
||||
}
|
||||
|
||||
int getOutputLatencyInSamples() override { return outputLatency; }
|
||||
|
|
@ -958,30 +963,26 @@ private:
|
|||
|
||||
JUCE_OBOE_LOG ("Oboe stream onErrorAfterClose(): " + getOboeString (error));
|
||||
|
||||
if (error == oboe::Result::ErrorDisconnected)
|
||||
{
|
||||
const SpinLock::ScopedTryLockType streamRestartLock { streamRestartMutex };
|
||||
const SpinLock::ScopedTryLockType streamRestartLock { streamRestartMutex };
|
||||
|
||||
if (streamRestartLock.isLocked())
|
||||
{
|
||||
// Close, recreate, and start the stream, not much use in current one.
|
||||
// Use default device id, to let the OS pick the best ID (since our was disconnected).
|
||||
if (! streamRestartLock.isLocked())
|
||||
return;
|
||||
|
||||
const SpinLock::ScopedLockType audioCallbackLock { audioCallbackMutex };
|
||||
const SpinLock::ScopedLockType audioCallbackLock { audioCallbackMutex };
|
||||
|
||||
outputStream = nullptr;
|
||||
outputStream.reset (new OboeStream (oboe::kUnspecified,
|
||||
oboe::Direction::Output,
|
||||
oboe::SharingMode::Exclusive,
|
||||
numOutputChannels,
|
||||
streamFormat,
|
||||
sampleRate,
|
||||
bufferSize,
|
||||
this));
|
||||
destroyStreams();
|
||||
|
||||
outputStream->start();
|
||||
}
|
||||
}
|
||||
if (error != oboe::Result::ErrorDisconnected)
|
||||
return;
|
||||
|
||||
openStreams();
|
||||
start();
|
||||
}
|
||||
|
||||
void destroyStreams()
|
||||
{
|
||||
inputStream = nullptr;
|
||||
outputStream = nullptr;
|
||||
}
|
||||
|
||||
std::vector<SampleType> inputStreamNativeBuffer;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue