Browse Source

Android: Add workaround for devices which falsely report supporting floating point audio

tags/2021-05-28
hogliux 8 years ago
parent
commit
0d601faae5
1 changed files with 37 additions and 30 deletions
  1. +37
    -30
      modules/juce_audio_devices/native/juce_android_OpenSL.cpp

+ 37
- 30
modules/juce_audio_devices/native/juce_android_OpenSL.cpp View File

@@ -155,6 +155,8 @@ template <typename T> struct BufferHelpers {};
template <>
struct BufferHelpers<int16>
{
enum { isFloatingPoint = 0 };
static void initPCMDataFormat (PCMDataFormatEx& dataFormat, int numChannels, double sampleRate)
{
dataFormat.formatType = SL_DATAFORMAT_PCM;
@@ -202,6 +204,8 @@ struct BufferHelpers<int16>
template <>
struct BufferHelpers<float>
{
enum { isFloatingPoint = 1 };
static void initPCMDataFormat (PCMDataFormatEx& dataFormat, int numChannels, double sampleRate)
{
dataFormat.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
@@ -514,6 +518,7 @@ public:
virtual void start() { stop(); jassert (callback.get() != nullptr); running = true; }
virtual void stop() { running = false; }
virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0;
virtual bool supportsFloatingPoint() const noexcept = 0;
void setCallback (AudioIODeviceCallback* callbackToUse)
{
@@ -557,8 +562,7 @@ public:
static OpenSLSession* create (DynamicLibrary& slLibrary,
int numInputChannels, int numOutputChannels,
double samleRateToUse, int bufferSizeToUse,
int numBuffersToUse,
bool floatingPointSupport);
int numBuffersToUse);
//==============================================================================
typedef SLresult (*CreateEngineFunc)(SLObjectItf*,SLuint32,const SLEngineOption*,SLuint32,const SLInterfaceID*,const SLboolean*);
@@ -667,6 +671,8 @@ public:
return true;
}
bool supportsFloatingPoint() const noexcept override { return (BufferHelpers<T>::isFloatingPoint != 0); }
void doSomeWorkOnAudioThread()
{
// only the player or the recorder should enter this section at any time
@@ -738,8 +744,6 @@ public:
inputLatency = (int) ((longestLatency * inputLatency) / totalLatency) & ~15;
outputLatency = (int) ((longestLatency * outputLatency) / totalLatency) & ~15;
supportsFloatingPoint = getSupportsFloatingPoint();
bool success = slLibrary.open ("libOpenSLES.so");
// You can only create this class if you are sure that your hardware supports OpenSL
@@ -824,15 +828,6 @@ public:
const int audioBuffersToEnqueue = hasLowLatencyAudioPath() ? buffersToEnqueueForLowLatency
: buffersToEnqueueSlowAudio;
DBG ("OpenSL: numInputChannels = " << numInputChannels
<< ", numOutputChannels = " << numOutputChannels
<< ", nativeBufferSize = " << getNativeBufferSize()
<< ", nativeSampleRate = " << getNativeSampleRate()
<< ", actualBufferSize = " << actualBufferSize
<< ", audioBuffersToEnqueue = " << audioBuffersToEnqueue
<< ", sampleRate = " << sampleRate
<< ", supportsFloatingPoint = " << (supportsFloatingPoint ? "true" : "false"));
if (numInputChannels > 0 && (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)))
{
// If you hit this assert, you probably forgot to get RuntimePermissions::recordAudio
@@ -842,8 +837,7 @@ public:
}
session = OpenSLSession::create (slLibrary, numInputChannels, numOutputChannels,
sampleRate, actualBufferSize, audioBuffersToEnqueue,
supportsFloatingPoint);
sampleRate, actualBufferSize, audioBuffersToEnqueue);
if (session != nullptr)
session->setAudioPreprocessingEnabled (audioProcessingEnabled);
else
@@ -855,11 +849,19 @@ public:
numInputChannels = 0;
session = OpenSLSession::create(slLibrary, numInputChannels, numOutputChannels,
sampleRate, actualBufferSize, audioBuffersToEnqueue,
supportsFloatingPoint);
sampleRate, actualBufferSize, audioBuffersToEnqueue);
}
}
DBG ("OpenSL: numInputChannels = " << numInputChannels
<< ", numOutputChannels = " << numOutputChannels
<< ", nativeBufferSize = " << getNativeBufferSize()
<< ", nativeSampleRate = " << getNativeSampleRate()
<< ", actualBufferSize = " << actualBufferSize
<< ", audioBuffersToEnqueue = " << audioBuffersToEnqueue
<< ", sampleRate = " << sampleRate
<< ", supportsFloatingPoint = " << (session != nullptr && session->supportsFloatingPoint() ? "true" : "false"));
if (session == nullptr)
lastError = "Unknown error initializing opensl session";
@@ -878,7 +880,7 @@ public:
int getInputLatencyInSamples() override { return inputLatency; }
bool isOpen() override { return deviceOpen; }
int getCurrentBufferSizeSamples() override { return actualBufferSize; }
int getCurrentBitDepth() override { return supportsFloatingPoint ? 32 : 16; }
int getCurrentBitDepth() override { return (session != nullptr && session->supportsFloatingPoint() ? 32 : 16); }
BigInteger getActiveOutputChannels() const override { return activeOutputChans; }
BigInteger getActiveInputChannels() const override { return activeInputChans; }
String getLastError() override { return lastError; }
@@ -960,7 +962,7 @@ private:
DynamicLibrary slLibrary;
int actualBufferSize, sampleRate;
int inputLatency, outputLatency;
bool deviceOpen, supportsFloatingPoint, audioProcessingEnabled;
bool deviceOpen, audioProcessingEnabled;
String lastError;
BigInteger activeOutputChans, activeInputChans;
AudioIODeviceCallback* callback;
@@ -1015,31 +1017,36 @@ private:
return androidHasSystemFeature ("android.hardware.audio.low_latency");
}
static bool getSupportsFloatingPoint()
{
return (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 21);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioIODevice)
};
OpenSLAudioIODevice::OpenSLSession* OpenSLAudioIODevice::OpenSLSession::create (DynamicLibrary& slLibrary,
int numInputChannels, int numOutputChannels,
double samleRateToUse, int bufferSizeToUse,
int numBuffersToUse,
bool floatingPointSupport)
int numBuffersToUse)
{
ScopedPointer<OpenSLSession> retval;
auto sdkVersion = getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT);
if (floatingPointSupport)
// SDK versions 21 and higher should natively support floating point...
if (sdkVersion >= 21)
{
retval = new OpenSLSessionT<float> (slLibrary, numInputChannels, numOutputChannels, samleRateToUse,
bufferSizeToUse, numBuffersToUse);
else
// ...however, some devices lie so re-try without floating point
if (retval != nullptr && (! retval->openedOK()))
retval = nullptr;
}
if (retval == nullptr)
{
retval = new OpenSLSessionT<int16> (slLibrary, numInputChannels, numOutputChannels, samleRateToUse,
bufferSizeToUse, numBuffersToUse);
if (retval != nullptr && (! retval->openedOK()))
retval = nullptr;
if (retval != nullptr && (! retval->openedOK()))
retval = nullptr;
}
return retval.release();
}


Loading…
Cancel
Save