|
|
@@ -165,29 +165,9 @@ public: |
|
|
oldCallback->audioDeviceStopped();
|
|
|
oldCallback->audioDeviceStopped();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void run() override
|
|
|
|
|
|
|
|
|
bool setAudioPreprocessingEnabled (bool enable) override
|
|
|
{
|
|
|
{
|
|
|
if (recorder != nullptr) recorder->start();
|
|
|
|
|
|
if (player != nullptr) player->start();
|
|
|
|
|
|
|
|
|
|
|
|
while (! threadShouldExit())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (player != nullptr) player->writeBuffer (outputBuffer, *this);
|
|
|
|
|
|
if (recorder != nullptr) recorder->readNextBlock (inputBuffer, *this);
|
|
|
|
|
|
|
|
|
|
|
|
const ScopedLock sl (callbackLock);
|
|
|
|
|
|
|
|
|
|
|
|
if (callback != nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
callback->audioDeviceIOCallback (numInputChannels > 0 ? inputBuffer.getArrayOfReadPointers() : nullptr, numInputChannels,
|
|
|
|
|
|
numOutputChannels > 0 ? outputBuffer.getArrayOfWritePointers() : nullptr, numOutputChannels,
|
|
|
|
|
|
actualBufferSize);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputBuffer.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
return recorder != nullptr && recorder->setAudioPreprocessingEnabled (enable);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private:
|
|
|
private:
|
|
|
@@ -212,6 +192,31 @@ private: |
|
|
return oldCallback;
|
|
|
return oldCallback;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void run() override
|
|
|
|
|
|
{
|
|
|
|
|
|
if (recorder != nullptr) recorder->start();
|
|
|
|
|
|
if (player != nullptr) player->start();
|
|
|
|
|
|
|
|
|
|
|
|
while (! threadShouldExit())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (player != nullptr) player->writeBuffer (outputBuffer, *this);
|
|
|
|
|
|
if (recorder != nullptr) recorder->readNextBlock (inputBuffer, *this);
|
|
|
|
|
|
|
|
|
|
|
|
const ScopedLock sl (callbackLock);
|
|
|
|
|
|
|
|
|
|
|
|
if (callback != nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
callback->audioDeviceIOCallback (numInputChannels > 0 ? inputBuffer.getArrayOfReadPointers() : nullptr, numInputChannels,
|
|
|
|
|
|
numOutputChannels > 0 ? outputBuffer.getArrayOfWritePointers() : nullptr, numOutputChannels,
|
|
|
|
|
|
actualBufferSize);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputBuffer.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
//==================================================================================================
|
|
|
//==================================================================================================
|
|
|
struct Engine
|
|
|
struct Engine
|
|
|
{
|
|
|
{
|
|
|
@@ -230,6 +235,7 @@ private: |
|
|
SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
|
|
|
SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
|
|
|
SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY");
|
|
|
SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY");
|
|
|
SL_IID_RECORD = (SLInterfaceID*) library.getFunction ("SL_IID_RECORD");
|
|
|
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)->Realize (engineObject, SL_BOOLEAN_FALSE));
|
|
|
check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface));
|
|
|
check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface));
|
|
|
@@ -271,6 +277,7 @@ private: |
|
|
SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
|
|
SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
|
|
SLInterfaceID* SL_IID_PLAY;
|
|
|
SLInterfaceID* SL_IID_PLAY;
|
|
|
SLInterfaceID* SL_IID_RECORD;
|
|
|
SLInterfaceID* SL_IID_RECORD;
|
|
|
|
|
|
SLInterfaceID* SL_IID_ANDROIDCONFIGURATION;
|
|
|
|
|
|
|
|
|
private:
|
|
|
private:
|
|
|
DynamicLibrary library;
|
|
|
DynamicLibrary library;
|
|
|
@@ -434,7 +441,8 @@ private: |
|
|
struct Recorder
|
|
|
struct Recorder
|
|
|
{
|
|
|
{
|
|
|
Recorder (int numChannels, int sampleRate, Engine& engine)
|
|
|
Recorder (int numChannels, int sampleRate, Engine& engine)
|
|
|
: recorderObject (nullptr), recorderRecord (nullptr), recorderBufferQueue (nullptr),
|
|
|
|
|
|
|
|
|
: recorderObject (nullptr), recorderRecord (nullptr),
|
|
|
|
|
|
recorderBufferQueue (nullptr), configObject (nullptr),
|
|
|
bufferList (numChannels)
|
|
|
bufferList (numChannels)
|
|
|
{
|
|
|
{
|
|
|
jassert (numChannels == 1); // STEREO doesn't always work!!
|
|
|
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_RECORD, &recorderRecord));
|
|
|
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
|
|
|
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 ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this));
|
|
|
check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED));
|
|
|
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:
|
|
|
private:
|
|
|
SLObjectItf recorderObject;
|
|
|
SLObjectItf recorderObject;
|
|
|
SLRecordItf recorderRecord;
|
|
|
SLRecordItf recorderRecord;
|
|
|
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
|
|
|
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
|
|
|
|
|
|
SLAndroidConfigurationItf configObject;
|
|
|
|
|
|
|
|
|
BufferList bufferList;
|
|
|
BufferList bufferList;
|
|
|
|
|
|
|
|
|
|