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