intbufq.c revision e629abc58c2acadc7487ea71c1e063f8f8989199
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 <assert.h> 24#include <math.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <unistd.h> 28#include "SLES/OpenSLES.h" 29#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE 30#include "SLES/OpenSLES_Android.h" 31#endif 32 33#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE 34#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 35#define IID_BUFFERQUEUE SL_IID_ANDROIDSIMPLEBUFFERQUEUE 36#define BufferQueueItf SLAndroidSimpleBufferQueueItf 37#define BufferQueueState SLAndroidSimpleBufferQueueState 38#define INDEX index 39#else 40#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_BUFFERQUEUE 41#define IID_BUFFERQUEUE SL_IID_BUFFERQUEUE 42#define BufferQueueItf SLBufferQueueItf 43#define BufferQueueState SLBufferQueueState 44#define INDEX playIndex 45#endif 46 47#define checkResult(r) do { if ((r) != SL_RESULT_SUCCESS) fprintf(stderr, "error %d at %s:%d\n", \ 48 (int) r, __FILE__, __LINE__); } while (0) 49 50typedef struct { 51 short left; 52 short right; 53} frame_t; 54 55#define SINE_FRAMES (44100*5) 56frame_t sine[SINE_FRAMES]; 57 58#define SQUARE_FRAMES (44100*5) 59frame_t square[SQUARE_FRAMES]; 60 61#define SAWTOOTH_FRAMES (44100*5) 62frame_t sawtooth[SAWTOOTH_FRAMES]; 63 64#define HALF_FRAMES (44100*5) 65frame_t half[HALF_FRAMES]; 66 67BufferQueueItf expectedCaller = NULL; 68void *expectedContext = NULL; 69 70static void callback(BufferQueueItf caller, void *context) 71{ 72 putchar('.'); 73 if (caller != expectedCaller) 74 printf("caller %p expected %p\r\n", caller, expectedCaller); 75 if (context != expectedContext) 76 printf("context %p expected %p\r\n", context, expectedContext); 77 fflush(stdout); 78} 79 80int main(int argc, char **argv) 81{ 82 SLresult result; 83 84 // create engine 85 SLObjectItf engineObject; 86 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 87 checkResult(result); 88 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 89 checkResult(result); 90 SLEngineItf engineEngine; 91 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 92 checkResult(result); 93 94 // create output mix 95 SLObjectItf outputmixObject; 96 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 97 checkResult(result); 98 result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 99 checkResult(result); 100 101 // create audio player 102 SLDataSource audiosrc; 103 SLDataSink audiosnk; 104 SLDataFormat_PCM pcm; 105 SLDataLocator_OutputMix locator_outputmix; 106 SLDataLocator_BufferQueue locator_bufferqueue; 107 locator_bufferqueue.locatorType = DATALOCATOR_BUFFERQUEUE; 108 locator_bufferqueue.numBuffers = 255; 109 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 110 locator_outputmix.outputMix = outputmixObject; 111 pcm.formatType = SL_DATAFORMAT_PCM; 112 pcm.numChannels = 2; 113 pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; 114 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 115 pcm.containerSize = 16; 116 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 117 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 118 audiosrc.pLocator = &locator_bufferqueue; 119 audiosrc.pFormat = &pcm; 120 audiosnk.pLocator = &locator_outputmix; 121 audiosnk.pFormat = NULL; 122 SLObjectItf playerObject; 123 SLInterfaceID ids[2] = {IID_BUFFERQUEUE, SL_IID_MUTESOLO}; 124 SLboolean flags[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 125 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 126 2, ids, flags); 127 checkResult(result); 128 result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 129 checkResult(result); 130 SLPlayItf playerPlay; 131 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 132 checkResult(result); 133 BufferQueueItf playerBufferqueue; 134 result = (*playerObject)->GetInterface(playerObject, IID_BUFFERQUEUE, &playerBufferqueue); 135 checkResult(result); 136 SLMuteSoloItf playerMuteSolo; 137 result = (*playerObject)->GetInterface(playerObject, SL_IID_MUTESOLO, &playerMuteSolo); 138 checkResult(result); 139 SLuint8 numChannels = 123; 140 result = (*playerMuteSolo)->GetNumChannels(playerMuteSolo, &numChannels); 141 assert(2 == numChannels); 142 SLuint32 state; 143 state = SL_PLAYSTATE_PLAYING; 144 result = (*playerPlay)->SetPlayState(playerPlay, state); 145 checkResult(result); 146 147 unsigned i; 148 float pi2 = 3.14*2; 149 float hz = 441; 150 float sr = 44100; 151 for (i = 0; i < SINE_FRAMES; ++i) { 152 sine[i].left = sin((float) (i / (sr / hz)) * pi2 ) * 32000.0; 153 sine[i].right = sine[i].left; 154 } 155 for (i = 0; i < SQUARE_FRAMES; ++i) { 156 square[i].left = (i % (unsigned) (sr / hz)) < 50 ? 32767 : -32768; 157 square[i].right = square[i].left; 158 } 159 for (i = 0; i < SAWTOOTH_FRAMES; ++i) { 160 sawtooth[i].left = ((((int) (i % (unsigned) (sr / hz))) - 50) / 100.0) * 60000.0 - 30000.0; 161 sawtooth[i].right = sawtooth[i].left; 162 } 163 for (i = 0; i < HALF_FRAMES; ++i) { 164 half[i].left = sine[i].left; 165 half[i].right = sawtooth[i].right / 2; 166 } 167 168 set_conio_terminal_mode(); 169 int in_count = 0; 170 unsigned count = 0; 171 for (;;) { 172 usleep(10000); 173 if (kbhit()) { 174 frame_t *buffer; 175 unsigned size; 176 BufferQueueState bufqstate; 177 int ch = getch(); 178 switch (ch) { 179 case '0' ... '9': 180 if (in_count) { 181 count = count * 10 + (ch - '0'); 182 } else { 183 count = ch - '0'; 184 in_count = 1; 185 } 186 continue; 187 case 'i': 188 buffer = sine; 189 size = sizeof(sine); 190 goto enqueue; 191 case 'q': 192 buffer = square; 193 size = sizeof(square); 194 goto enqueue; 195 case 'h': 196 buffer = half; 197 size = sizeof(half); 198 goto enqueue; 199 case 'r': 200 if (in_count) { 201 expectedCaller = playerBufferqueue; 202 expectedContext = (void *) count; 203 } else { 204 expectedCaller = NULL; 205 expectedContext = (void *) NULL; 206 } 207 result = (*playerBufferqueue)->RegisterCallback(playerBufferqueue, in_count ? 208 callback : NULL, expectedContext); 209 checkResult(result); 210 break; 211 case 'a': 212 buffer = sawtooth; 213 size = sizeof(sawtooth); 214enqueue: 215 for (i = 0; i < (in_count ? count : 1); ++i) { 216 result = (*playerBufferqueue)->Enqueue(playerBufferqueue, buffer, size); 217 checkResult(result); 218 } 219 break; 220 case 'c': 221 result = (*playerBufferqueue)->Clear(playerBufferqueue); 222 checkResult(result); 223 putchar('\r'); 224 result = (*playerBufferqueue)->GetState(playerBufferqueue, &bufqstate); 225 checkResult(result); 226 if (bufqstate.count != 0) 227 printf("\rcount=%u\r\n", (unsigned) bufqstate.count); 228#if 0 229 putchar('\r'); 230 putchar('\n'); 231#endif 232 fflush(stdout); 233 break; 234 case 'g': 235 result = (*playerBufferqueue)->GetState(playerBufferqueue, &bufqstate); 236 checkResult(result); 237 printf("\rplayIndex=%u\r\n", (unsigned) bufqstate.INDEX); 238 printf("count=%u\r\n", (unsigned) bufqstate.count); 239 break; 240 case 'p': 241 state = SL_PLAYSTATE_PAUSED; 242 goto setplaystate; 243 case 's': 244 state = SL_PLAYSTATE_STOPPED; 245 goto setplaystate; 246 case 'P': 247 state = SL_PLAYSTATE_PLAYING; 248setplaystate: 249 result = (*playerPlay)->SetPlayState(playerPlay, state); 250 checkResult(result); 251 SLuint32 newstate; 252 result = (*playerPlay)->GetPlayState(playerPlay, &newstate); 253 checkResult(result); 254 if (newstate != state) 255 printf("\rSetPlayState(%u) -> GetPlayState(%u)\r\n", (unsigned) state, 256 (unsigned) newstate); 257#if 0 258 putchar('\r'); 259 putchar('\n'); 260 fflush(stdout); 261#endif 262 checkResult(result); 263 break; 264 case 'x': 265 exit(EXIT_SUCCESS); 266 break; 267 default: 268 putchar('?'); 269 fflush(stdout); 270 break; 271 } 272 in_count = 0; 273 } 274 } 275 276} 277