BufferQueue_test.cpp revision a15af1c45c3ad1d96e3012f1613a79a86c0b2547
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/** \file BufferQueue_test.cpp */ 18 19#include <assert.h> 20#include <math.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <unistd.h> 24#include "SLES/OpenSLES.h" 25 26#ifdef ANDROID 27#include "gtest/gtest.h" 28#else 29#define ASSERT_EQ(x, y) assert((x) == (y)) 30#endif 31 32typedef struct { 33 short left; 34 short right; 35} stereo; 36 37// 1 second of stereo audio at 44.1 kHz 38static stereo stereoBuffer1[44100 * 1]; 39 40static void do_my_testing() 41{ 42 SLresult result; 43 44 // initialize the test tone to be a sine sweep from 441 Hz to 882 Hz 45 unsigned nframes = sizeof(stereoBuffer1) / sizeof(stereoBuffer1[0]); 46 float nframes_ = (float) nframes; 47 SLuint32 i; 48 for (i = 0; i < nframes; ++i) { 49 float i_ = (float) i; 50 float pcm_ = sin((i_*(1.0f+0.5f*(i_/nframes_))*0.01 * M_PI * 2.0)); 51 int pcm = (int) (pcm_ * 32766.0); 52 assert(-32768 <= pcm && pcm <= 32767); 53 stereoBuffer1[i].left = pcm; 54 stereoBuffer1[nframes - 1 - i].right = pcm; 55 } 56 57 // create engine 58 SLObjectItf engineObject; 59 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 60 ASSERT_EQ(SL_RESULT_SUCCESS, result); 61 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 62 ASSERT_EQ(SL_RESULT_SUCCESS, result); 63 SLEngineItf engineEngine; 64 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 65 ASSERT_EQ(SL_RESULT_SUCCESS, result); 66 67 // create output mix 68 SLObjectItf outputmixObject; 69 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 70 ASSERT_EQ(SL_RESULT_SUCCESS, result); 71 result = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 72 ASSERT_EQ(SL_RESULT_SUCCESS, result); 73 74 // set up data structures to create an audio player with buffer queue source and output mix sink 75 SLDataSource audiosrc; 76 SLDataSink audiosnk; 77 SLDataFormat_PCM pcm; 78 SLDataLocator_OutputMix locator_outputmix; 79 SLDataLocator_BufferQueue locator_bufferqueue; 80 locator_bufferqueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE; 81 locator_bufferqueue.numBuffers = 0; 82 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 83 locator_outputmix.outputMix = outputmixObject; 84 pcm.formatType = SL_DATAFORMAT_PCM; 85 pcm.numChannels = 2; 86 pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; 87 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 88 pcm.containerSize = 16; 89 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 90 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 91 audiosrc.pLocator = &locator_bufferqueue; 92 audiosrc.pFormat = &pcm; 93 audiosnk.pLocator = &locator_outputmix; 94 audiosnk.pFormat = NULL; 95 SLObjectItf playerObject; 96 SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE}; 97 SLboolean flags[1] = {SL_BOOLEAN_TRUE}; 98 99 // try creating audio player with various invalid values for numBuffers 100 static const SLuint32 invalidNumBuffers[] = {0, 0xFFFFFFFF, 0x80000000, 0x10002, 0x102, 0x101, 0x100}; 101 for (i = 0; i < sizeof(invalidNumBuffers) / sizeof(invalidNumBuffers[0]); ++i) { 102 locator_bufferqueue.numBuffers = invalidNumBuffers[i]; 103 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 1, ids, flags); 104 ASSERT_EQ(SL_RESULT_PARAMETER_INVALID, result); 105 } 106 107 // now try some valid values for numBuffers */ 108 static const SLuint32 validNumBuffers[] = {1, 2, 3, 4, 5, 6, 7, 8, 255}; 109 for (i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 110 locator_bufferqueue.numBuffers = validNumBuffers[i]; 111 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 1, ids, flags); 112 ASSERT_EQ(SL_RESULT_SUCCESS, result); 113 result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 114 ASSERT_EQ(SL_RESULT_SUCCESS, result); 115 // get the play interface 116 SLPlayItf playerPlay; 117 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 118 ASSERT_EQ(SL_RESULT_SUCCESS, result); 119 SLuint32 playerState; 120 // verify that player is initially stopped 121 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 122 ASSERT_EQ(SL_RESULT_SUCCESS, result); 123 ASSERT_EQ(SL_PLAYSTATE_STOPPED, playerState); 124 // get the buffer queue interface 125 SLBufferQueueItf playerBufferQueue; 126 result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 127 ASSERT_EQ(SL_RESULT_SUCCESS, result); 128 // verify that buffer queue is initially empty 129 SLBufferQueueState bufferqueueState; 130 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 131 ASSERT_EQ(SL_RESULT_SUCCESS, result); 132 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 133 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 134 // try enqueuing the maximum number of buffers while stopped 135 SLuint32 j; 136 for (j = 0; j < validNumBuffers[i]; ++j) { 137 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 138 ASSERT_EQ(SL_RESULT_SUCCESS, result); 139 // verify that each buffer is enqueued properly and increments the buffer count 140 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 141 ASSERT_EQ(SL_RESULT_SUCCESS, result); 142 ASSERT_EQ(j + 1, bufferqueueState.count); 143 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 144 // verify that player is still stopped; enqueue should not affect play state 145 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 146 ASSERT_EQ(SL_RESULT_SUCCESS, result); 147 ASSERT_EQ(SL_PLAYSTATE_STOPPED, playerState); 148 } 149 // enqueue one more buffer and make sure it fails 150 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 151 ASSERT_EQ(SL_RESULT_BUFFER_INSUFFICIENT, result); 152 // verify that the failed enqueue did not affect the buffer count 153 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 154 ASSERT_EQ(SL_RESULT_SUCCESS, result); 155 ASSERT_EQ(validNumBuffers[i], bufferqueueState.count); 156 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 157 // now clear the buffer queue 158 result = (*playerBufferQueue)->Clear(playerBufferQueue); 159 ASSERT_EQ(SL_RESULT_SUCCESS, result); 160 // make sure the clear works 161 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 162 ASSERT_EQ(SL_RESULT_SUCCESS, result); 163 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 164 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 165 // change play state from paused to stopped 166 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED); 167 ASSERT_EQ(SL_RESULT_SUCCESS, result); 168 // verify that player is really paused 169 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 170 ASSERT_EQ(SL_RESULT_SUCCESS, result); 171 ASSERT_EQ(SL_PLAYSTATE_PAUSED, playerState); 172 // try enqueuing the maximum number of buffers while paused 173 for (j = 0; j < validNumBuffers[i]; ++j) { 174 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 175 ASSERT_EQ(SL_RESULT_SUCCESS, result); 176 // verify that each buffer is enqueued properly and increments the buffer count 177 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 178 ASSERT_EQ(SL_RESULT_SUCCESS, result); 179 ASSERT_EQ(j + 1, bufferqueueState.count); 180 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 181 // verify that player is still paused; enqueue should not affect play state 182 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 183 ASSERT_EQ(SL_RESULT_SUCCESS, result); 184 ASSERT_EQ(SL_PLAYSTATE_PAUSED, playerState); 185 } 186 // enqueue one more buffer and make sure it fails 187 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 188 ASSERT_EQ(SL_RESULT_BUFFER_INSUFFICIENT, result); 189 // verify that the failed enqueue did not affect the buffer count 190 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 191 ASSERT_EQ(SL_RESULT_SUCCESS, result); 192 ASSERT_EQ(validNumBuffers[i], bufferqueueState.count); 193 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 194 // now clear the buffer queue 195 result = (*playerBufferQueue)->Clear(playerBufferQueue); 196 ASSERT_EQ(SL_RESULT_SUCCESS, result); 197 // make sure the clear works 198 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 199 ASSERT_EQ(SL_RESULT_SUCCESS, result); 200 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 201 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 202 // try every possible play state transition while buffer queue is empty 203 static const SLuint32 newStates1[] = { 204 SL_PLAYSTATE_PAUSED, // paused -> paused 205 SL_PLAYSTATE_STOPPED, // paused -> stopped 206 SL_PLAYSTATE_PAUSED, // stopped -> paused, also done earlier 207 SL_PLAYSTATE_PLAYING, // paused -> playing 208 SL_PLAYSTATE_PLAYING, // playing -> playing 209 SL_PLAYSTATE_STOPPED, // playing -> stopped 210 SL_PLAYSTATE_STOPPED, // stopped -> stopped 211 SL_PLAYSTATE_PLAYING, // stopped -> playing 212 SL_PLAYSTATE_PAUSED // playing -> paused 213 }; 214 // initially the play state is (still) paused 215 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 216 ASSERT_EQ(SL_RESULT_SUCCESS, result); 217 ASSERT_EQ(SL_PLAYSTATE_PAUSED, playerState); 218 for (j = 0; j < sizeof(newStates1) / sizeof(newStates1[0]); ++j) { 219 // change play state 220 result = (*playerPlay)->SetPlayState(playerPlay, newStates1[j]); 221 ASSERT_EQ(SL_RESULT_SUCCESS, result); 222 // make sure the new play state is taken 223 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 224 ASSERT_EQ(SL_RESULT_SUCCESS, result); 225 ASSERT_EQ(newStates1[j], playerState); 226 // changing the play state should not affect the buffer count 227 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 228 ASSERT_EQ(SL_RESULT_SUCCESS, result); 229 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 230 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 231 } 232 // finally the play state is (again) paused 233 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 234 ASSERT_EQ(SL_RESULT_SUCCESS, result); 235 ASSERT_EQ(SL_PLAYSTATE_PAUSED, playerState); 236 // enqueue a buffer 237 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 238 ASSERT_EQ(SL_RESULT_SUCCESS, result); 239 // try several inaudible play state transitions while buffer queue is non-empty 240 static const SLuint32 newStates2[] = { 241 SL_PLAYSTATE_PAUSED, // paused -> paused 242 SL_PLAYSTATE_STOPPED, // paused -> stopped 243 SL_PLAYSTATE_STOPPED, // stopped -> stopped 244 SL_PLAYSTATE_PAUSED // stopped -> paused 245 }; 246 for (j = 0; j < sizeof(newStates2) / sizeof(newStates2[0]); ++j) { 247 // change play state 248 result = (*playerPlay)->SetPlayState(playerPlay, newStates2[j]); 249 ASSERT_EQ(SL_RESULT_SUCCESS, result); 250 // make sure the new play state is taken 251 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 252 ASSERT_EQ(SL_RESULT_SUCCESS, result); 253 ASSERT_EQ(newStates2[j], playerState); 254 // changing the play state should not affect the buffer count 255 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 256 ASSERT_EQ(SL_RESULT_SUCCESS, result); 257 ASSERT_EQ((SLuint32) 1, bufferqueueState.count); 258 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 259 } 260 // clear the buffer queue 261 result = (*playerBufferQueue)->Clear(playerBufferQueue); 262 ASSERT_EQ(SL_RESULT_SUCCESS, result); 263 264 // now we're finally ready to make some noise 265 266 // enqueue a buffer 267 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, stereoBuffer1, sizeof(stereoBuffer1)); 268 ASSERT_EQ(SL_RESULT_SUCCESS, result); 269 // set play state to playing 270 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 271 ASSERT_EQ(SL_RESULT_SUCCESS, result); 272 // state should be playing immediately after enqueue 273 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 274 ASSERT_EQ(SL_RESULT_SUCCESS, result); 275 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 276 // buffer should still be on the queue 277 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 278 ASSERT_EQ(SL_RESULT_SUCCESS, result); 279 ASSERT_EQ((SLuint32) 1, bufferqueueState.count); 280 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 281 // wait 1.5 seconds 282 usleep(1500000); 283 // state should still be playing 284 result = (*playerPlay)->GetPlayState(playerPlay, &playerState); 285 ASSERT_EQ(SL_RESULT_SUCCESS, result); 286 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 287 // buffer should be removed from the queue 288 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 289 ASSERT_EQ(SL_RESULT_SUCCESS, result); 290 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 291 ASSERT_EQ((SLuint32) 1, bufferqueueState.playIndex); 292 // destroy the player 293 (*playerObject)->Destroy(playerObject); 294 } 295 296 // destroy the output mix 297 (*outputmixObject)->Destroy(outputmixObject); 298 // destroy the engine 299 (*engineObject)->Destroy(engineObject); 300 301} 302 303int main(int argc, char **argv) 304{ 305 do_my_testing(); 306 return EXIT_SUCCESS; 307} 308