1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-07 04:10:08 +00:00

Added a method AudioIODevice::setGainPreprocessingEnabled() to allow disabling of mic AGC on iOS and Android devices.

This commit is contained in:
jules 2014-05-24 19:04:47 +01:00
parent d8180f7ba5
commit 5fdbdc9e9e
5 changed files with 65 additions and 41 deletions

View file

@ -22,20 +22,16 @@
==============================================================================
*/
AudioIODevice::AudioIODevice (const String& deviceName, const String& typeName_)
: name (deviceName),
typeName (typeName_)
AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName)
: name (deviceName), typeName (deviceTypeName)
{
}
AudioIODevice::~AudioIODevice()
{
}
AudioIODevice::~AudioIODevice() {}
bool AudioIODevice::hasControlPanel() const
{
return false;
}
void AudioIODeviceCallback::audioDeviceError (const String&) {}
bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; }
bool AudioIODevice::hasControlPanel() const { return false; }
bool AudioIODevice::showControlPanel()
{
@ -43,6 +39,3 @@ bool AudioIODevice::showControlPanel()
// their hasControlPanel() method.
return false;
}
//==============================================================================
void AudioIODeviceCallback::audioDeviceError (const String&) {}

View file

@ -289,6 +289,11 @@ public:
*/
virtual bool showControlPanel();
/** On devices which support it, this allows automatic gain control or other
mic processing to be disabled.
If the device doesn't support this operation, it'll return false.
*/
virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled);
//==============================================================================
protected:

View file

@ -125,6 +125,7 @@
#if JUCE_USE_ANDROID_OPENSLES
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <SLES/OpenSLES_AndroidConfiguration.h>
#endif
#endif

View file

@ -165,6 +165,33 @@ public:
oldCallback->audioDeviceStopped();
}
bool setAudioPreprocessingEnabled (bool enable) override
{
return recorder != nullptr && recorder->setAudioPreprocessingEnabled (enable);
}
private:
//==================================================================================================
CriticalSection callbackLock;
AudioIODeviceCallback* callback;
int actualBufferSize, sampleRate;
int inputLatency, outputLatency;
bool deviceOpen;
String lastError;
BigInteger activeOutputChans, activeInputChans;
int numInputChannels, numOutputChannels;
AudioSampleBuffer inputBuffer, outputBuffer;
struct Player;
struct Recorder;
AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback)
{
const ScopedLock sl (callbackLock);
AudioIODeviceCallback* const oldCallback = callback;
callback = newCallback;
return oldCallback;
}
void run() override
{
if (recorder != nullptr) recorder->start();
@ -190,28 +217,6 @@ public:
}
}
private:
//==================================================================================================
CriticalSection callbackLock;
AudioIODeviceCallback* callback;
int actualBufferSize, sampleRate;
int inputLatency, outputLatency;
bool deviceOpen;
String lastError;
BigInteger activeOutputChans, activeInputChans;
int numInputChannels, numOutputChannels;
AudioSampleBuffer inputBuffer, outputBuffer;
struct Player;
struct Recorder;
AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback)
{
const ScopedLock sl (callbackLock);
AudioIODeviceCallback* const oldCallback = callback;
callback = newCallback;
return oldCallback;
}
//==================================================================================================
struct Engine
{
@ -230,6 +235,7 @@ private:
SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY");
SL_IID_RECORD = (SLInterfaceID*) library.getFunction ("SL_IID_RECORD");
SL_IID_ANDROIDCONFIGURATION = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDCONFIGURATION");
check ((*engineObject)->Realize (engineObject, SL_BOOLEAN_FALSE));
check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface));
@ -271,6 +277,7 @@ private:
SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
SLInterfaceID* SL_IID_PLAY;
SLInterfaceID* SL_IID_RECORD;
SLInterfaceID* SL_IID_ANDROIDCONFIGURATION;
private:
DynamicLibrary library;
@ -434,7 +441,8 @@ private:
struct Recorder
{
Recorder (int numChannels, int sampleRate, Engine& engine)
: recorderObject (nullptr), recorderRecord (nullptr), recorderBufferQueue (nullptr),
: recorderObject (nullptr), recorderRecord (nullptr),
recorderBufferQueue (nullptr), configObject (nullptr),
bufferList (numChannels)
{
jassert (numChannels == 1); // STEREO doesn't always work!!
@ -466,6 +474,7 @@ private:
{
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord));
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDCONFIGURATION, &configObject));
check ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this));
check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED));
@ -532,10 +541,20 @@ private:
}
}
bool setAudioPreprocessingEnabled (bool enable)
{
SLuint32 mode = enable ? SL_ANDROID_RECORDING_PRESET_GENERIC
: SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
return configObject != nullptr
&& check ((*configObject)->SetConfiguration (configObject, SL_ANDROID_KEY_RECORDING_PRESET, &mode, sizeof (mode)));
}
private:
SLObjectItf recorderObject;
SLRecordItf recorderRecord;
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
SLAndroidConfigurationItf configObject;
BufferList bufferList;

View file

@ -208,6 +208,12 @@ public:
bool isPlaying() override { return isRunning && callback != nullptr; }
String getLastError() override { return lastError; }
bool setAudioPreprocessingEnabled (bool enable) override
{
return setSessionUInt32Property (kAudioSessionProperty_Mode, enable ? kAudioSessionMode_Default
: kAudioSessionMode_Measurement);
}
private:
//==================================================================================================
CriticalSection callbackLock;
@ -433,12 +439,12 @@ private:
static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time,
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data)
{
return static_cast <iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
return static_cast<iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
}
static void routingChangedStatic (void* client, AudioSessionPropertyID, UInt32 /*inDataSize*/, const void* propertyValue)
{
static_cast <iOSAudioIODevice*> (client)->routingChanged (propertyValue);
static_cast<iOSAudioIODevice*> (client)->routingChanged (propertyValue);
}
//==================================================================================================
@ -530,9 +536,9 @@ private:
return AudioSessionGetProperty (propID, &valueSize, &result);
}
static void setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
static void setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
static void setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
static bool setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
static bool setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
static bool setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
};