Browse Source

A bugfix and some fine-tuning for the android openSL audio device.

tags/2021-05-28
jules 13 years ago
parent
commit
dbe71f8c67
1 changed files with 32 additions and 22 deletions
  1. +32
    -22
      modules/juce_audio_devices/native/juce_android_OpenSL.cpp

+ 32
- 22
modules/juce_audio_devices/native/juce_android_OpenSL.cpp View File

@@ -31,8 +31,8 @@ bool isOpenSLAvailable()
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 };
const unsigned short openSLRates[] = { 8000, 16000, 32000, 44100, 48000 };
const unsigned short openSLBufferSizes[] = { 256, 512, 768, 1024, 1280, 1600 }; // must all be multiples of the block size
//==============================================================================
class OpenSLAudioIODevice : public AudioIODevice,
@@ -49,10 +49,15 @@ public:
// 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;
// this is a total guess about how to calculate the latency, but seems to vaguely agree
// with the devices I've tested.. YMMV
inputLatency = ((javaDevice.minBufferSizeIn * 2) / 3);
outputLatency = ((javaDevice.minBufferSizeOut * 2) / 3);
const int longestLatency = jmax (inputLatency, outputLatency);
const int totalLatency = inputLatency + outputLatency;
inputLatency = ((longestLatency * inputLatency) / totalLatency) & ~15;
outputLatency = ((longestLatency * outputLatency) / totalLatency) & ~15;
}
~OpenSLAudioIODevice()
@@ -85,7 +90,7 @@ public:
return (int) openSLRates [index];
}
int getDefaultBufferSize() { return 2048; }
int getDefaultBufferSize() { return 1024; }
int getNumBufferSizesAvailable() { return numElementsInArray (openSLBufferSizes); }
int getBufferSizeSamples (int index)
@@ -124,18 +129,14 @@ public:
startThread (8);
if (recorder != nullptr) recorder->start();
if (player != nullptr) player->start();
deviceOpen = true;
return lastError;
}
void close()
{
stop();
stopThread (2000);
stopThread (6000);
deviceOpen = false;
recorder = nullptr;
player = nullptr;
@@ -175,15 +176,18 @@ public:
void run()
{
if (recorder != nullptr) recorder->start();
if (player != nullptr) player->start();
while (! threadShouldExit())
{
if (player != nullptr && ! threadShouldExit())
player->writeBuffer (outputBuffer, *this);
if (recorder != nullptr)
recorder->readNextBlock (inputBuffer, *this);
invokeCallback();
if (player != nullptr && ! threadShouldExit())
player->writeBuffer (outputBuffer, *this);
}
}
@@ -297,9 +301,8 @@ private:
//==================================================================================================
struct BufferList
{
BufferList (const int numChannels_, const int numSamples_ = 256, const int numBuffers_ = 16)
: numChannels (numChannels_), numSamples (numSamples_), numBuffers (numBuffers_),
bufferSpace (numChannels_ * numSamples_ * numBuffers_), nextBlock (0)
BufferList (const int numChannels_)
: numChannels (numChannels_), bufferSpace (numChannels_ * numSamples * numBuffers), nextBlock (0)
{
}
@@ -307,7 +310,7 @@ private:
{
while (numBlocksOut.get() == numBuffers)
{
Thread::sleep (1);
dataArrived.wait (1);
if (threadToCheck.threadShouldExit())
return nullptr;
@@ -324,17 +327,19 @@ private:
return bufferSpace + nextBlock * numChannels * numSamples;
}
void bufferReturned() { --numBlocksOut; }
void bufferSent() { ++numBlocksOut; }
void bufferReturned() { --numBlocksOut; dataArrived.signal(); }
void bufferSent() { ++numBlocksOut; dataArrived.signal(); }
int getBufferSizeBytes() const { return numChannels * numSamples * sizeof (int16); }
const int numChannels, numSamples, numBuffers;
const int numChannels;
enum { numSamples = 256, numBuffers = 16 };
private:
HeapBlock<int16> bufferSpace;
int nextBlock;
Atomic<int> numBlocksOut;
WaitableEvent dataArrived;
};
//==================================================================================================
@@ -482,6 +487,7 @@ private:
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord));
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
check ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this));
check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED));
for (int i = bufferList.numBuffers; --i >= 0;)
{
@@ -517,6 +523,7 @@ private:
{
jassert (buffer.getNumChannels() == bufferList.numChannels);
jassert (buffer.getNumSamples() < bufferList.numSamples * bufferList.numBuffers);
jassert ((buffer.getNumSamples() % bufferList.numSamples) == 0);
int offset = 0;
int numSamples = buffer.getNumSamples();
@@ -525,6 +532,9 @@ private:
{
int16* const srcBuffer = bufferList.waitForFreeBuffer (thread);
if (srcBuffer == nullptr)
break;
for (int i = 0; i < bufferList.numChannels; ++i)
{
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DstSampleType;


Loading…
Cancel
Save