diff --git a/modules/juce_audio_devices/native/juce_android_Audio.cpp b/modules/juce_audio_devices/native/juce_android_Audio.cpp index f894150150..c4c6ab5946 100644 --- a/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_android_Audio.cpp @@ -74,11 +74,10 @@ public: AndroidAudioIODevice (const String& deviceName) : AudioIODevice (deviceName, javaAudioTypeName), Thread ("audio"), - callback (0), sampleRate (0), + minBufferSizeOut (0), minBufferSizeIn (0), callback (0), sampleRate (0), numClientInputChannels (0), numDeviceInputChannels (0), numDeviceInputChannelsAvailable (2), numClientOutputChannels (0), numDeviceOutputChannels (0), - minBufferSizeOut (0), minBufferSizeIn (0), actualBufferSize (0), - isRunning (false), + actualBufferSize (0), isRunning (false), outputChannelBuffer (1, 1), inputChannelBuffer (1, 1) { @@ -239,8 +238,8 @@ public: } } - int getOutputLatencyInSamples() { return minBufferSizeOut; } - int getInputLatencyInSamples() { return minBufferSizeIn; } + int getOutputLatencyInSamples() { return (minBufferSizeOut * 3) / 4; } + int getInputLatencyInSamples() { return (minBufferSizeIn * 3) / 4; } bool isOpen() { return isRunning; } int getCurrentBufferSizeSamples() { return actualBufferSize; } int getCurrentBitDepth() { return 16; } @@ -360,6 +359,8 @@ public: } } + int minBufferSizeOut, minBufferSizeIn; + private: //================================================================================================== CriticalSection callbackLock; @@ -367,7 +368,7 @@ private: jint sampleRate; int numClientInputChannels, numDeviceInputChannels, numDeviceInputChannelsAvailable; int numClientOutputChannels, numDeviceOutputChannels; - int minBufferSizeOut, minBufferSizeIn, actualBufferSize; + int actualBufferSize; bool isRunning; String lastError; BigInteger activeOutputChans, activeInputChans; @@ -430,7 +431,14 @@ private: //============================================================================== +extern bool isOpenSLAvailable(); + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() { + #if JUCE_USE_ANDROID_OPENSLES + if (isOpenSLAvailable()) + return nullptr; + #endif + return new AndroidAudioIODeviceType(); } diff --git a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index 980ea46955..d4e44be71f 100644 --- a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -25,6 +25,15 @@ const char* const openSLTypeName = "Android OpenSL"; +bool isOpenSLAvailable() +{ + DynamicLibrary library; + return library.open ("libOpenSLES.so"); +} + +const unsigned short openSLRates[] = { 8000, 16000, 32000, 44100, 48000 }; +const unsigned short openSLBufferSizes[] = { 256, 512, 768, 1024, 1280, 1600, 2048, 3072 }; + //============================================================================== class OpenSLAudioIODevice : public AudioIODevice, public Thread @@ -36,6 +45,14 @@ public: callback (nullptr), sampleRate (0), deviceOpen (false), inputBuffer (2, 2), outputBuffer (2, 2) { + // OpenSL has piss-poor support for determining latency, so the only way I can find to + // get a number for this is by asking the AudioTrack/AudioRecord classes.. + AndroidAudioIODevice javaDevice (String::empty); + + // this is a total guess about how to calculate this: assuming that internally the + // hardware probably uses 3 buffers, so the latency is about 2/3 of it.. YMMV + inputLatency = (javaDevice.minBufferSizeIn * 2) / 3; + outputLatency = (javaDevice.minBufferSizeOut * 2) / 3; } ~OpenSLAudioIODevice() @@ -60,30 +77,23 @@ public: return s; } - int getNumSampleRates() { return 5;} + int getNumSampleRates() { return numElementsInArray (openSLRates); } + double getSampleRate (int index) { - int rates[] = { 8000, 16000, 32000, 44100, 48000 }; - jassert (index >= 0 && index < numElementsInArray (rates)); - return rates [index]; + jassert (index >= 0 && index < getNumSampleRates()); + return (int) openSLRates [index]; } - int getDefaultBufferSize() { return 2048; } - int getNumBufferSizesAvailable() { return 50; } + int getDefaultBufferSize() { return 2048; } + int getNumBufferSizesAvailable() { return numElementsInArray (openSLBufferSizes); } int getBufferSizeSamples (int index) { - int n = 16; - for (int i = 0; i < index; ++i) - n += n < 64 ? 16 - : (n < 512 ? 32 - : (n < 1024 ? 64 - : (n < 2048 ? 128 : 256))); - - return n; + jassert (index >= 0 && index < getNumBufferSizesAvailable()); + return (int) openSLBufferSizes [index]; } - String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double requestedSampleRate, @@ -131,8 +141,8 @@ public: player = nullptr; } - int getOutputLatencyInSamples() { return 0; } - int getInputLatencyInSamples() { return 0; } + int getOutputLatencyInSamples() { return outputLatency; } + int getInputLatencyInSamples() { return inputLatency; } bool isOpen() { return deviceOpen; } int getCurrentBufferSizeSamples() { return actualBufferSize; } int getCurrentBitDepth() { return 16; } @@ -200,6 +210,7 @@ private: CriticalSection callbackLock; AudioIODeviceCallback* callback; int actualBufferSize, sampleRate; + int inputLatency, outputLatency; bool deviceOpen; String lastError; BigInteger activeOutputChans, activeInputChans; @@ -608,6 +619,5 @@ private: //============================================================================== AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { - DynamicLibrary library; - return library.open ("libOpenSLES.so") ? new OpenSLAudioDeviceType() : nullptr; + return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; }