mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
A bugfix and some fine-tuning for the android openSL audio device.
This commit is contained in:
parent
63bc3f29de
commit
dbe71f8c67
1 changed files with 32 additions and 22 deletions
|
|
@ -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…
Add table
Add a link
Reference in a new issue