intbufq.c revision 01e9f5fa4698856f92bcfd88188ee4c8397b22db
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* interactive buffer queue test program */ 18 19#ifdef ANDROID 20#define USE_ANDROID_SIMPLE_BUFFER_QUEUE // change to #undef for compatibility testing 21#endif 22 23#include <math.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include "SLES/OpenSLES.h" 27#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE 28#include "SLES/OpenSLES_Android.h" 29#endif 30 31#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE 32#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 33#define IID_BUFFERQUEUE SL_IID_ANDROIDSIMPLEBUFFERQUEUE 34#define BufferQueueItf SLAndroidSimpleBufferQueueItf 35#define BufferQueueState SLAndroidSimpleBufferQueueState 36#define INDEX index 37#else 38#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_BUFFERQUEUE 39#define IID_BUFFERQUEUE SL_IID_BUFFERQUEUE 40#define BufferQueueItf SLBufferQueueItf 41#define BufferQueueState SLBufferQueueState 42#define INDEX playIndex 43#endif 44 45#define checkResult(r) do { if ((r) != SL_RESULT_SUCCESS) fprintf(stderr, "error %d at %s:%d\n", \ 46 (int) r, __FILE__, __LINE__); } while (0) 47 48typedef struct { 49 short left; 50 short right; 51} frame_t; 52 53#define SINE_FRAMES (44100*5) 54frame_t sine[SINE_FRAMES]; 55 56#define SQUARE_FRAMES (44100*5) 57frame_t square[SQUARE_FRAMES]; 58 59#define SAWTOOTH_FRAMES (44100*5) 60frame_t sawtooth[SAWTOOTH_FRAMES]; 61 62BufferQueueItf expectedCaller = NULL; 63void *expectedContext = NULL; 64 65static void callback(BufferQueueItf caller, void *context) 66{ 67 putchar('.'); 68 if (caller != expectedCaller) 69 printf("caller %p expected %p\r\n", caller, expectedCaller); 70 if (context != expectedContext) 71 printf("context %p expected %p\r\n", context, expectedContext); 72 fflush(stdout); 73} 74 75int main(int argc, char **argv) 76{ 77 SLresult result; 78 79 // create engine 80 SLObjectItf engineObject; 81 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 82 checkResult(result); 83 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 84 checkResult(result); 85 SLEngineItf engineEngine; 86 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 87 checkResult(result); 88 89 // create output mix 90 SLObjectItf outputmixObject; 91 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 92 checkResult(result); 93 result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 94 checkResult(result); 95 96 // create audio player 97 SLDataSource audiosrc; 98 SLDataSink audiosnk; 99 SLDataFormat_PCM pcm; 100 SLDataLocator_OutputMix locator_outputmix; 101 SLDataLocator_BufferQueue locator_bufferqueue; 102 locator_bufferqueue.locatorType = DATALOCATOR_BUFFERQUEUE; 103 locator_bufferqueue.numBuffers = 255; 104 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 105 locator_outputmix.outputMix = outputmixObject; 106 pcm.formatType = SL_DATAFORMAT_PCM; 107 pcm.numChannels = 2; 108 pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; 109 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 110 pcm.containerSize = 16; 111 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 112 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 113 audiosrc.pLocator = &locator_bufferqueue; 114 audiosrc.pFormat = &pcm; 115 audiosnk.pLocator = &locator_outputmix; 116 audiosnk.pFormat = NULL; 117 SLObjectItf playerObject; 118 SLInterfaceID ids[1] = {IID_BUFFERQUEUE}; 119 SLboolean flags[1] = {SL_BOOLEAN_TRUE}; 120 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 121 1, ids, flags); 122 checkResult(result); 123 result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 124 checkResult(result); 125 SLPlayItf playerPlay; 126 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 127 checkResult(result); 128 BufferQueueItf playerBufferqueue; 129 result = (*playerObject)->GetInterface(playerObject, IID_BUFFERQUEUE, &playerBufferqueue); 130 checkResult(result); 131 SLuint32 state; 132 state = SL_PLAYSTATE_PLAYING; 133 result = (*playerPlay)->SetPlayState(playerPlay, state); 134 checkResult(result); 135 136 unsigned i; 137 float pi2 = 3.14*2; 138 float hz = 441; 139 float sr = 44100; 140 for (i = 0; i < SINE_FRAMES; ++i) { 141 sine[i].left = sin((float) (i / (sr / hz)) * pi2 ) * 32000.0; 142 sine[i].right = sine[i].left; 143 } 144 for (i = 0; i < SQUARE_FRAMES; ++i) { 145 square[i].left = (i % (unsigned) (sr / hz)) < 50 ? 32767 : -32768; 146 square[i].right = square[i].left; 147 } 148 for (i = 0; i < SAWTOOTH_FRAMES; ++i) { 149 sawtooth[i].left = ((((int) (i % (unsigned) (sr / hz))) - 50) / 100.0) * 60000.0 - 30000.0; 150 sawtooth[i].right = sawtooth[i].left; 151 } 152 153 set_conio_terminal_mode(); 154 int in_count = 0; 155 unsigned count = 0; 156 for (;;) { 157 usleep(10000); 158 if (kbhit()) { 159 frame_t *buffer; 160 unsigned size; 161 BufferQueueState bufqstate; 162 int ch = getch(); 163 switch (ch) { 164 case '0' ... '9': 165 if (in_count) { 166 count = count * 10 + (ch - '0'); 167 } else { 168 count = ch - '0'; 169 in_count = 1; 170 } 171 continue; 172 case 'i': 173 buffer = sine; 174 size = sizeof(sine); 175 goto enqueue; 176 case 'q': 177 buffer = square; 178 size = sizeof(square); 179 goto enqueue; 180 case 'r': 181 if (in_count) { 182 expectedCaller = playerBufferqueue; 183 expectedContext = (void *) count; 184 } else { 185 expectedCaller = NULL; 186 expectedContext = (void *) NULL; 187 } 188 result = (*playerBufferqueue)->RegisterCallback(playerBufferqueue, in_count ? 189 callback : NULL, expectedContext); 190 checkResult(result); 191 break; 192 case 'a': 193 buffer = sawtooth; 194 size = sizeof(sawtooth); 195enqueue: 196 for (i = 0; i < (in_count ? count : 1); ++i) { 197 result = (*playerBufferqueue)->Enqueue(playerBufferqueue, buffer, size); 198 checkResult(result); 199 } 200 break; 201 case 'c': 202 result = (*playerBufferqueue)->Clear(playerBufferqueue); 203 checkResult(result); 204 putchar('\r'); 205 result = (*playerBufferqueue)->GetState(playerBufferqueue, &bufqstate); 206 checkResult(result); 207 if (bufqstate.count != 0) 208 printf("\rcount=%u\r\n", (unsigned) bufqstate.count); 209#if 0 210 putchar('\r'); 211 putchar('\n'); 212#endif 213 fflush(stdout); 214 break; 215 case 'g': 216 result = (*playerBufferqueue)->GetState(playerBufferqueue, &bufqstate); 217 checkResult(result); 218 printf("\rplayIndex=%u\r\n", (unsigned) bufqstate.INDEX); 219 printf("count=%u\r\n", (unsigned) bufqstate.count); 220 break; 221 case 'p': 222 state = SL_PLAYSTATE_PAUSED; 223 goto setplaystate; 224 case 's': 225 state = SL_PLAYSTATE_STOPPED; 226 goto setplaystate; 227 case 'P': 228 state = SL_PLAYSTATE_PLAYING; 229setplaystate: 230 result = (*playerPlay)->SetPlayState(playerPlay, state); 231 checkResult(result); 232 SLuint32 newstate; 233 result = (*playerPlay)->GetPlayState(playerPlay, &newstate); 234 checkResult(result); 235 if (newstate != state) 236 printf("\rSetPlayState(%u) -> GetPlayState(%u)\r\n", (unsigned) state, 237 (unsigned) newstate); 238#if 0 239 putchar('\r'); 240 putchar('\n'); 241 fflush(stdout); 242#endif 243 checkResult(result); 244 break; 245 case 'x': 246 exit(EXIT_SUCCESS); 247 break; 248 default: 249 putchar('?'); 250 fflush(stdout); 251 break; 252 } 253 in_count = 0; 254 } 255 } 256 257} 258