slesTestFeedback.cpp revision f460ec604707d0bdaf8124d84c5f8595cba9c804
1f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten/* 2f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * 4f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * you may not use this file except in compliance with the License. 6f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * You may obtain a copy of the License at 7f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * 8f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * 10f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * See the License for the specific language governing permissions and 14f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten * limitations under the License. 15f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten */ 16f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 17f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten// Test program to record from default audio input and playback to default audio output 18f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 19f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#include "SLES/OpenSLES.h" 20f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#include <assert.h> 21f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#include <stdio.h> 22f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#include <stdlib.h> 23f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#include <unistd.h> 24f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 25f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#define ASSERT_EQ(x, y) assert((x) == (y)) 26f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 27f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastentypedef struct { 28f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten short left; 29f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten short right; 30f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten} stereo; 31f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 32f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten// These ping-pong buffers hold 1 second of audio at 44.1 kHz 33f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#define SR 8000 //44100 34f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten#define N 3 35f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastenstatic stereo buffers[SR*N]; 36f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 37f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten// Index of which buffer to enqueue next 38f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastenstatic SLuint32 whichRecord; 39f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastenstatic SLuint32 whichPlay; 40f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 41f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn KastenSLBufferQueueItf recorderBufferQueue; 42f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn KastenSLBufferQueueItf playerBufferQueue; 43f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 44f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten// Called after audio recorder fills a buffer with data 45f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastenstatic void recorderCallback(SLBufferQueueItf caller, void *context) 46f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten{ 47f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLresult result; 48f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten putchar('*'); 49f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten fflush(stdout); 50f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 51f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Enqueue the next empty buffer for the recorder to fill 52f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten assert(whichRecord < N); 53f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten void *buffer = &buffers[SR*whichRecord]; 54f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLuint32 size = SR*sizeof(stereo); 55f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, buffer, size); 56f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 57f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten if (++whichRecord >= N) 58f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten whichRecord = 0; 59f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 60f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Enqueue the just-filled buffer for the player to empty 61f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten assert(whichPlay < N); 62f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten buffer = &buffers[SR*whichPlay]; 63f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, size); 64f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 65f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten if (++whichPlay >= N) 66f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten whichPlay = 0; 67f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 68f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten} 69f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 70f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kastenint main(int argc, char **argv) 71f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten{ 72f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLresult result; 73f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 74f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // create engine 75f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLObjectItf engineObject; 76f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 77f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 78f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 79f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 80f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLEngineItf engineEngine; 81f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 82f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 83f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 84f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // create output mix 85f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLObjectItf outputmixObject; 86f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 87f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 88f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 89f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 90f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 91f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // create an audio player with buffer queue source and output mix sink 92f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataSource audiosrc; 93f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataSink audiosnk; 94f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataFormat_PCM pcm; 95f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataLocator_OutputMix locator_outputmix; 96f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataLocator_BufferQueue locator_bufferqueue; 97f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_bufferqueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE; 98f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_bufferqueue.numBuffers = 2; 99f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 100f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_outputmix.outputMix = outputmixObject; 101f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.formatType = SL_DATAFORMAT_PCM; 102f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.numChannels = 1; //2; 103f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.samplesPerSec = SL_SAMPLINGRATE_8; //44_1; 104f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 105f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.containerSize = 16; 106f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.channelMask = SL_SPEAKER_FRONT_CENTER; //SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 107f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 108f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosrc.pLocator = &locator_bufferqueue; 109f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosrc.pFormat = &pcm; 110f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosnk.pLocator = &locator_outputmix; 111f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosnk.pFormat = NULL; 112f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLObjectItf playerObject; 113f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE}; 114f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLboolean flags[1] = {SL_BOOLEAN_TRUE}; 115f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 1, ids, flags); 116f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 117f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 118f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 119f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLPlayItf playerPlay; 120f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 121f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 122f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 123f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 124f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 125f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 126f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 127f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Create an audio recorder with microphone device source and buffer queue sink. 128f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // The buffer queue as sink is an Android-specific extension. 129f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 130f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLDataLocator_IODevice locator_iodevice; 131f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_iodevice.locatorType = SL_DATALOCATOR_IODEVICE; 132f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_iodevice.deviceType = SL_IODEVICE_AUDIOINPUT; 133f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_iodevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT; 134f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten locator_iodevice.device = NULL; 135f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosrc.pLocator = &locator_iodevice; 136f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosrc.pFormat = &pcm; 137f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosnk.pLocator = &locator_bufferqueue; 138f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten audiosnk.pFormat = &pcm; 139f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLObjectItf recorderObject; 140f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audiosrc, &audiosnk, 1, ids, flags); 141f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 142f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE); 143f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 144f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLRecordItf recorderRecord; 145f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord); 146f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 147f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderObject)->GetInterface(recorderObject, SL_IID_BUFFERQUEUE, &recorderBufferQueue); 148f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 149f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, recorderCallback, NULL); 150f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 151f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 152f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Enqueue some empty buffers for the recorder 153f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten for (whichRecord = 0; whichRecord < N-1; ++whichRecord) { 154f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, &buffers[SR*whichRecord], SR*sizeof(stereo)); 155f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 156f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten } 157f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 158f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Kick off the recorder 159f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten whichPlay = 0; 160f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING); 161f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 162f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 163f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten // Wait patiently 164f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten for (;;) { 165f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten usleep(1000000); 166f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten putchar('.'); 167f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLBufferQueueState playerBQState; 168f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*playerBufferQueue)->GetState(playerBufferQueue, &playerBQState); 169f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 170f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten SLBufferQueueState recorderBQState; 171f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten result = (*recorderBufferQueue)->GetState(recorderBufferQueue, &recorderBQState); 172f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten ASSERT_EQ(SL_RESULT_SUCCESS, result); 173f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten printf("pC%u pI%u rC%u rI%u\n", (unsigned) playerBQState.count, (unsigned) playerBQState.playIndex, (unsigned) recorderBQState.count, (unsigned) recorderBQState.playIndex); 174f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten fflush(stdout); 175f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten } 176f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten 177f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten //return EXIT_SUCCESS; 178f460ec604707d0bdaf8124d84c5f8595cba9c804Glenn Kasten} 179