[FIXED] Is there any way to sample audio using OpenSL on android with different sampling rates and buffer sizes?

Issue

I have downloaded the audio-echo app from the android NDK portal for opensl. Due to the lack of documentation I’m not able to identify how to change the sampling rate and buffer size of the audio in and out.

If anybody has any idea on how to:

  • Change the buffer size and sampling rate on OpenSL
  • Read the buffers to be fed to a C code to be processed
  • Fed to the output module of OpenSL to be fed to the speakers

Another alternative I feel is read it at the preferred sampling rate and buffer size but downsample and upsample in the code itself and use a circular buffer to get desired data. But how are we reading and feeding the data in openSL?

Solution

In the OpenSL ES API, there are calls to create either a Player or a Recorder:

SLresult (*CreateAudioPlayer) (
    SLEngineItf self,
    SLObjectItf * pPlayer,
    SLDataSource *pAudioSrc,
    SLDataSink *pAudioSnk,
    SLuint32 numInterfaces,
    const SLInterfaceID * pInterfaceIds,
    const SLboolean * pInterfaceRequired
);

SLresult (*CreateAudioRecorder) (
    SLEngineItf self,
    SLObjectItf * pRecorder,
    SLDataSource *pAudioSrc,
    SLDataSink *pAudioSnk,
    SLuint32 numInterfaces,
    const SLInterfaceID * pInterfaceIds,
    const SLboolean * pInterfaceRequired
);

Note that both of these take a SLDataSource *pAudioSrc parameter.

To use a custom playback rate or recording rate, you have to set up this data source properly.

I use an 11Khz playback rate using this code:

// Configure data format.
SLDataFormat_PCM pcm;
pcm.formatType = SL_DATAFORMAT_PCM;
pcm.numChannels = 1;
pcm.samplesPerSec = SL_SAMPLINGRATE_11_025;
pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
pcm.containerSize = 16;
pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;

// Configure Audio Source.
SLDataSource source;
source.pFormat = &pcm;
source.pLocator = &bufferQueue;

To feed data to the speakers, a buffer queue is used that is filled by a callback. To set this callback, use SLAndroidSimpleBufferQueueItf, documented in section 8.12 SLBufferQueueItf of the OpenGL ES specification.

Answered By – Bram

Answer Checked By – Pedro (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published