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 #define LOG_NDEBUG 0 20 #define LOG_TAG "BufferQueue_test" 21 22 #ifdef ANDROID 23 #include <utils/Log.h> 24 #else 25 #define ALOGV printf 26 #endif 27 28 #include <assert.h> 29 #include <math.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <SLES/OpenSLES.h> 34 #include "OpenSLESUT.h" 35 #include <gtest/gtest.h> 36 37 typedef struct { 38 short left; 39 short right; 40 } stereo; 41 42 // volume of sine wave in range 0.0 to 1.0 43 static float gVolume = 1.0f; 44 45 // 1 second of stereo audio at 44.1 kHz 46 static stereo stereoBuffer1[44100 * 1]; 47 static const SLuint32 invalidNumBuffers[] = { 0, 0xFFFFFFFF, 0x80000000, 0x10002, 0x102, 48 0x101, 0x100 }; 49 static const SLuint32 validNumBuffers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 255 }; 50 51 //----------------------------------------------------------------- 52 /* Checks for error. If any errors exit the application! */ 53 void CheckErr(SLresult res) { 54 if (SL_RESULT_SUCCESS != res) { 55 const char *str = slesutResultToString(res); 56 if (NULL == str) 57 str = "unknown"; 58 fprintf(stderr, "CheckErr failure: %s (0x%x), exiting\n", str, res); 59 //Fail the test case 60 FAIL(); 61 } 62 } 63 64 static const SLInterfaceID ids[1] = { SL_IID_BUFFERQUEUE }; 65 static const SLboolean flags[1] = { SL_BOOLEAN_TRUE }; 66 static const SLInterfaceID ids_mutesolo[2] = { SL_IID_BUFFERQUEUE, SL_IID_MUTESOLO }; 67 static const SLboolean flags_mutesolo[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 68 static const SLInterfaceID ids_seek[2] = { SL_IID_BUFFERQUEUE, SL_IID_SEEK }; 69 static const SLboolean flags_seek[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 70 71 // The fixture for testing class BufferQueue 72 class TestBufferQueue: public ::testing::Test { 73 public: 74 SLresult res; 75 SLObjectItf outputmixObject; 76 SLObjectItf engineObject; 77 78 SLDataSource audiosrc; 79 SLDataSink audiosnk; 80 SLDataFormat_PCM pcm; 81 SLDataLocator_OutputMix locator_outputmix; 82 SLDataLocator_BufferQueue locator_bufferqueue; 83 SLBufferQueueItf playerBufferQueue; 84 SLBufferQueueState bufferqueueState; 85 SLPlayItf playerPlay; 86 SLObjectItf playerObject; 87 SLEngineItf engineEngine; 88 SLuint32 playerState; 89 90 protected: 91 TestBufferQueue() { 92 } 93 94 virtual ~TestBufferQueue() { 95 96 } 97 98 /*Test setup*/ 99 virtual void SetUp() { 100 101 // create engine 102 res = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 103 CheckErr(res); 104 res = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 105 CheckErr(res); 106 res = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 107 CheckErr(res); 108 109 // create output mix 110 res = (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); 111 CheckErr(res); 112 res = (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); 113 CheckErr(res); 114 115 locator_bufferqueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE; 116 locator_bufferqueue.numBuffers = 0; 117 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 118 locator_outputmix.outputMix = outputmixObject; 119 120 pcm.formatType = SL_DATAFORMAT_PCM; 121 pcm.numChannels = 2; 122 pcm.samplesPerSec = SL_SAMPLINGRATE_44_1; 123 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 124 pcm.containerSize = 16; 125 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 126 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 127 128 audiosrc.pLocator = &locator_bufferqueue; 129 audiosrc.pFormat = &pcm; 130 audiosnk.pLocator = &locator_outputmix; 131 audiosnk.pFormat = NULL; 132 133 // initialize the test tone to be a sine sweep from 441 Hz to 882 Hz 134 unsigned nframes = sizeof(stereoBuffer1) / sizeof(stereoBuffer1[0]); 135 float nframes_ = (float) nframes; 136 SLuint32 i; 137 for (i = 0; i < nframes; ++i) { 138 float i_ = (float) i; 139 float pcm_ = sin((i_ * (1.0f + 0.5f * (i_ / nframes_)) * 0.01 * M_PI * 2.0)); 140 int pcm = (int) (pcm_ * 32766.0 * gVolume); 141 ASSERT_TRUE(-32768 <= pcm && pcm <= 32767) << "pcm out of bound " << pcm; 142 stereoBuffer1[i].left = pcm; 143 stereoBuffer1[nframes - 1 - i].right = pcm; 144 } 145 } 146 147 virtual void TearDown() { 148 // Clean up the mixer and the engine 149 // (must be done in that order, and after player destroyed) 150 if (outputmixObject){ 151 (*outputmixObject)->Destroy(outputmixObject); 152 outputmixObject = NULL; 153 } 154 if (engineObject){ 155 (*engineObject)->Destroy(engineObject); 156 engineObject = NULL; 157 } 158 } 159 160 void DestroyPlayer() { 161 if (playerObject){ 162 //printf("destroy player\n"); 163 (*playerObject)->Destroy(playerObject); 164 playerObject = NULL; 165 } 166 } 167 168 /* Test case for creating audio player with various invalid values for numBuffers*/ 169 void InvalidBuffer() { 170 171 for (unsigned i = 0; i < sizeof(invalidNumBuffers) / sizeof(invalidNumBuffers[0]); ++i) { 172 SLuint32 numBuffers = invalidNumBuffers[i]; 173 174 locator_bufferqueue.numBuffers = numBuffers; 175 //printf("create audio player - invalid\n"); 176 SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, 177 &audiosrc, &audiosnk, 1, ids, flags); 178 ASSERT_EQ(SL_RESULT_PARAMETER_INVALID, result); 179 ASSERT_EQ(NULL, playerObject); 180 181 } 182 } 183 184 /*Prepare the buffer*/ 185 void PrepareValidBuffer(SLuint32 numBuffers) { 186 187 locator_bufferqueue.numBuffers = numBuffers; 188 //printf("create audio player - valid\n"); 189 res = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 190 1, ids, flags); 191 CheckErr(res); 192 res = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 193 CheckErr(res); 194 // get the play interface 195 res = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 196 CheckErr(res); 197 // verify that player is initially stopped 198 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 199 CheckErr(res); 200 ASSERT_EQ(SL_PLAYSTATE_STOPPED, playerState); 201 202 // get the buffer queue interface 203 res = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 204 CheckErr(res); 205 206 // verify that buffer queue is initially empty 207 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 208 CheckErr(res); 209 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 210 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 211 } 212 213 void EnqueueMaxBuffer(SLuint32 numBuffers) { 214 SLuint32 j; 215 216 for (j = 0; j < numBuffers; ++j) { 217 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 218 CheckErr(res); 219 // verify that each buffer is enqueued properly and increments the buffer count 220 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 221 CheckErr(res); 222 ASSERT_EQ(j + 1, bufferqueueState.count); 223 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 224 } 225 } 226 227 void EnqueueExtraBuffer(SLuint32 numBuffers) { 228 // enqueue one more buffer and make sure it fails 229 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, "test", 4); 230 ASSERT_EQ(SL_RESULT_BUFFER_INSUFFICIENT, res); 231 // verify that the failed enqueue did not affect the buffer count 232 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 233 CheckErr(res); 234 ASSERT_EQ(numBuffers, bufferqueueState.count); 235 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 236 } 237 238 void SetPlayerState(SLuint32 state) { 239 res = (*playerPlay)->SetPlayState(playerPlay, state); 240 CheckErr(res); 241 //verify the state can set correctly 242 GetPlayerState(state); 243 } 244 245 void GetPlayerState(SLuint32 state) { 246 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 247 CheckErr(res); 248 ASSERT_EQ(state, playerState); 249 } 250 251 void ClearQueue() { 252 // now clear the buffer queue 253 res = (*playerBufferQueue)->Clear(playerBufferQueue); 254 CheckErr(res); 255 // make sure the clear works 256 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 257 CheckErr(res); 258 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 259 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 260 } 261 262 void CheckBufferCount(SLuint32 ExpectedCount, SLuint32 ExpectedPlayIndex) { 263 // changing the play state should not affect the buffer count 264 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 265 CheckErr(res); 266 ASSERT_EQ(ExpectedCount, bufferqueueState.count); 267 ASSERT_EQ(ExpectedPlayIndex, bufferqueueState.playIndex); 268 } 269 270 void PlayBufferQueue() { 271 // enqueue a buffer 272 res = (*playerBufferQueue)->Enqueue(playerBufferQueue, stereoBuffer1, 273 sizeof(stereoBuffer1)); 274 CheckErr(res); 275 // set play state to playing 276 res = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 277 CheckErr(res); 278 // state should be playing immediately after enqueue 279 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 280 CheckErr(res); 281 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 282 // buffer should still be on the queue 283 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 284 CheckErr(res); 285 ASSERT_EQ((SLuint32) 1, bufferqueueState.count); 286 ASSERT_EQ((SLuint32) 0, bufferqueueState.playIndex); 287 //ALOGV("Before 1.5 sec"); 288 // wait 1.5 seconds 289 usleep(1500000); 290 //ALOGV("After 1.5 sec"); 291 // state should still be playing 292 res = (*playerPlay)->GetPlayState(playerPlay, &playerState); 293 //ALOGV("GetPlayState"); 294 CheckErr(res); 295 ASSERT_EQ(SL_PLAYSTATE_PLAYING, playerState); 296 // buffer should be removed from the queue 297 res = (*playerBufferQueue)->GetState(playerBufferQueue, &bufferqueueState); 298 CheckErr(res); 299 ASSERT_EQ((SLuint32) 0, bufferqueueState.count); 300 ASSERT_EQ((SLuint32) 1, bufferqueueState.playIndex); 301 //ALOGV("TestEnd"); 302 } 303 }; 304 305 TEST_F(TestBufferQueue, testInvalidBuffer){ 306 //ALOGV("Test Fixture: InvalidBuffer"); 307 InvalidBuffer(); 308 } 309 310 TEST_F(TestBufferQueue, testMuteSolo) { 311 // create audio player with buffer queue data source in stereo PCM format and ask for mute solo 312 locator_bufferqueue.numBuffers = 1; 313 SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, 314 &audiosnk, 2, ids_mutesolo, flags_mutesolo); 315 ASSERT_EQ(SL_RESULT_SUCCESS, result); 316 ASSERT_TRUE(NULL != playerObject); 317 DestroyPlayer(); 318 // create audio player with buffer queue data source in mono PCM format and ask for mute solo 319 pcm.numChannels = 1; 320 pcm.channelMask = SL_SPEAKER_FRONT_CENTER; 321 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk, 322 2, ids_mutesolo, flags_mutesolo); 323 ASSERT_EQ(SL_RESULT_FEATURE_UNSUPPORTED, result); 324 ASSERT_EQ(NULL, playerObject); 325 DestroyPlayer(); 326 } 327 328 TEST_F(TestBufferQueue, testSeek) { 329 // can create audio player with buffer queue data source and ask for seek 330 locator_bufferqueue.numBuffers = 1; 331 SLresult result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, 332 &audiosrc, &audiosnk, 2, ids_seek, flags_seek); 333 ASSERT_EQ(SL_RESULT_FEATURE_UNSUPPORTED, result); 334 ASSERT_EQ(NULL, playerObject); 335 DestroyPlayer(); 336 } 337 338 TEST_F(TestBufferQueue, testValidBuffer) { 339 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 340 SLuint32 numBuffers = validNumBuffers[i]; 341 PrepareValidBuffer(numBuffers); 342 DestroyPlayer(); 343 } 344 } 345 346 TEST_F(TestBufferQueue, testEnqueueMaxBuffer) { 347 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 348 SLuint32 numBuffers = validNumBuffers[i]; 349 PrepareValidBuffer(numBuffers); 350 EnqueueMaxBuffer(numBuffers); 351 DestroyPlayer(); 352 } 353 } 354 355 TEST_F(TestBufferQueue, testEnqueueExtraBuffer) { 356 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 357 SLuint32 numBuffers = validNumBuffers[i]; 358 PrepareValidBuffer(numBuffers); 359 EnqueueMaxBuffer(numBuffers); 360 EnqueueExtraBuffer(numBuffers); 361 GetPlayerState(SL_PLAYSTATE_STOPPED); 362 DestroyPlayer(); 363 } 364 } 365 366 TEST_F(TestBufferQueue, testEnqueueAtStopped) { 367 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 368 SLuint32 numBuffers = validNumBuffers[i]; 369 PrepareValidBuffer(numBuffers); 370 SetPlayerState(SL_PLAYSTATE_STOPPED); 371 EnqueueMaxBuffer(numBuffers); 372 CheckBufferCount(numBuffers, (SLuint32) 0); 373 DestroyPlayer(); 374 } 375 } 376 377 TEST_F(TestBufferQueue, testEnqueueAtPaused) { 378 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 379 SLuint32 numBuffers = validNumBuffers[i]; 380 PrepareValidBuffer(numBuffers); 381 SetPlayerState(SL_PLAYSTATE_PAUSED); 382 EnqueueMaxBuffer(numBuffers); 383 CheckBufferCount(numBuffers, (SLuint32) 0); 384 DestroyPlayer(); 385 } 386 } 387 388 TEST_F(TestBufferQueue, testClearQueue) { 389 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 390 SLuint32 numBuffers = validNumBuffers[i]; 391 PrepareValidBuffer(numBuffers); 392 EnqueueMaxBuffer(numBuffers); 393 ClearQueue(); 394 DestroyPlayer(); 395 } 396 } 397 398 TEST_F(TestBufferQueue, testStateTransitionEmptyQueue) { 399 static const SLuint32 newStates[] = { 400 SL_PLAYSTATE_PAUSED, // paused -> paused 401 SL_PLAYSTATE_STOPPED, // paused -> stopped 402 SL_PLAYSTATE_PAUSED, // stopped -> paused 403 SL_PLAYSTATE_PLAYING, // paused -> playing 404 SL_PLAYSTATE_PLAYING, // playing -> playing 405 SL_PLAYSTATE_STOPPED, // playing -> stopped 406 SL_PLAYSTATE_STOPPED, // stopped -> stopped 407 SL_PLAYSTATE_PLAYING, // stopped -> playing 408 SL_PLAYSTATE_PAUSED // playing -> paused 409 }; 410 411 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 412 SLuint32 numBuffers = validNumBuffers[i]; 413 SLuint32 j; 414 415 PrepareValidBuffer(numBuffers); 416 /* Set initial state to paused*/ 417 SetPlayerState(SL_PLAYSTATE_PAUSED); 418 419 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 420 SetPlayerState(newStates[j]); 421 CheckBufferCount((SLuint32) 0, (SLuint32) 0); 422 } 423 DestroyPlayer(); 424 } 425 } 426 427 TEST_F(TestBufferQueue, testStateTransitionNonEmptyQueue) { 428 static const SLuint32 newStates[] = { 429 SL_PLAYSTATE_PAUSED, // paused -> paused 430 SL_PLAYSTATE_STOPPED, // paused -> stopped 431 SL_PLAYSTATE_STOPPED, // stopped -> stopped 432 SL_PLAYSTATE_PAUSED // stopped -> paused 433 }; 434 435 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 436 SLuint32 numBuffers = validNumBuffers[i]; 437 SLuint32 j; 438 439 /* Prepare the player */ 440 PrepareValidBuffer(numBuffers); 441 EnqueueMaxBuffer(numBuffers); 442 SetPlayerState(SL_PLAYSTATE_PAUSED); 443 444 for (j = 0; j < sizeof(newStates) / sizeof(newStates[0]); ++j) { 445 SetPlayerState(newStates[j]); 446 CheckBufferCount(numBuffers, (SLuint32) 0); 447 } 448 DestroyPlayer(); 449 } 450 } 451 452 TEST_F(TestBufferQueue, testStatePlayBuffer){ 453 for (unsigned i = 0; i < sizeof(validNumBuffers) / sizeof(validNumBuffers[0]); ++i) { 454 SLuint32 numBuffers = validNumBuffers[i]; 455 PrepareValidBuffer(numBuffers); 456 PlayBufferQueue(); 457 DestroyPlayer(); 458 } 459 } 460 461 int main(int argc, char **argv) { 462 testing::InitGoogleTest(&argc, argv); 463 #if 1 // temporary workaround if hardware volume control is not working 464 const char *VOLUME = getenv("BufferQueue_test_VOLUME"); 465 if (NULL != VOLUME) { 466 float volume = atof(VOLUME); 467 if (volume >= 0.0f && volume <= 1.0f) { 468 gVolume = volume; 469 } 470 } 471 #endif 472 return RUN_ALL_TESTS(); 473 } 474