12b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi/* 22b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 32b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * 42b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 52b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * you may not use this file except in compliance with the License. 62b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * You may obtain a copy of the License at 72b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * 82b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 92b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * 102b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 112b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 122b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * See the License for the specific language governing permissions and 142b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * limitations under the License. 152b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi */ 162b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 172b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#include <stdlib.h> 182b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#include <stdio.h> 192b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#include <unistd.h> 202b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//#include <sys/time.h> 212b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 22c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 232b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 242b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 252b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#define MAX_NUMBER_INTERFACES 2 262b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#define MAX_NUMBER_PLAYERS 40 272b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 282b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \ 292b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 302b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 312b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi/* the OpenSL ES engine from which we create all other resources */ 322b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLObjectItf slEngine; 332b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLEngineItf engineItf; 342b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLObjectItf outputMix; 352b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 362b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLboolean required[MAX_NUMBER_INTERFACES]; 372b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 382b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 392b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLObjectItf audioPlayer[MAX_NUMBER_PLAYERS]; 402b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivibool validplayer[MAX_NUMBER_PLAYERS]; 412b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Triviint playerNum[MAX_NUMBER_PLAYERS]; 422b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLPlayItf playItfs[MAX_NUMBER_PLAYERS]; 432b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLVolumeItf volItfs[MAX_NUMBER_PLAYERS]; 442b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLPrefetchStatusItf prefetchItfs[MAX_NUMBER_PLAYERS]; 452b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 462b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLDataSource audioSource; 472b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLDataLocator_URI uri; 482b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLDataFormat_MIME mime; 492b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 502b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLDataSink audioSink; 512b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel TriviSLDataLocator_OutputMix locator_outputmix; 522b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 532b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 542b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 552b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//* Exits the application if an error is encountered */ 562b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x, -1, __LINE__) 572b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi#define CheckErrPlyr(x, id) ExitOnErrorFunc(x, id, __LINE__) 582b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 592b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid ExitOnErrorFunc( SLresult result, int playerId, int line) 602b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi{ 612b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 622b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (playerId == -1) { 632b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stderr, "Error %u code encountered at line %d, exiting\n", result, line); 642b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } else { 652b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stderr, "Error %u code encountered at line %d for player %d, exiting\n", 662b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi result, line, playerId); 672b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 682b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi exit(EXIT_FAILURE); 692b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 702b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 712b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 722b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 732b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi/* PrefetchStatusItf callback for an audio player */ 742b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint32 event) 752b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi{ 762b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLresult res; 772b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLpermille level = 0; 782b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi int* pPlayerId = (int*)pContext; 792b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*caller)->GetFillLevel(caller, &level); CheckErrPlyr(res, *pPlayerId); 802b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLuint32 status; 812b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi //fprintf(stdout, "PrefetchEventCallback: received event %u\n", event); 822b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*caller)->GetPrefetchStatus(caller, &status); CheckErrPlyr(res, *pPlayerId); 832b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) 842b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 852b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Error while prefetching data for player %d, " 862b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi "exiting\n", *pPlayerId); 872b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi exit(EXIT_FAILURE); 882b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 892b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 902b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Buffer fill level is = %d for player %d\n", 912b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi level, *pPlayerId); 922b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 932b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (event & SL_PREFETCHEVENT_STATUSCHANGE) { 942b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Prefetch Status is = %u for player %d\n", 952b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi status, *pPlayerId); 962b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 972b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 982b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 992b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1002b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 1012b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi/* PlayItf callback for playback events */ 1022b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid PlayEventCallback( 1032b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLPlayItf caller, 1042b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi void *pContext, 1052b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLuint32 event) 1062b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi{ 1072b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLresult res; 1082b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi int* pPlayerId = (int*)pContext; 1092b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_PLAYEVENT_HEADATEND & event) { 1102b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATEND reached for player %d\n", *pPlayerId); 1112b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi //SignalEos(); 1122b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 1132b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1142b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_PLAYEVENT_HEADATNEWPOS & event) { 1152b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLmillisecond pMsec = 0; 1162b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*caller)->GetPosition(caller, &pMsec); CheckErrPlyr(res, *pPlayerId); 1172b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS current position=%ums for player %d\n", 1182b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi pMsec, *pPlayerId); 1192b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 1202b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1212b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_PLAYEVENT_HEADATMARKER & event) { 1222b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLmillisecond pMsec = 0; 1232b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*caller)->GetPosition(caller, &pMsec); CheckErrPlyr(res, *pPlayerId); 1242b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER current position=%ums for player %d\n", 1252b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi pMsec, *pPlayerId); 1262b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 1272b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 1282b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1292b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1302b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 1312b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid TestSetup(const char* path) { 1322b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLresult res; 1332b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1342b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Create the engine */ 1352b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLEngineOption EngineOption[] = { 1362b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 1372b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 1382b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1392b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = slCreateEngine( &slEngine, 1, EngineOption, 0, NULL, NULL); 1402b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErr(res); 1412b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 1422b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*slEngine)->Realize(slEngine, SL_BOOLEAN_FALSE); 1432b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErr(res); 1442b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 1452b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*slEngine)->GetInterface(slEngine, SL_IID_ENGINE, (void*)&engineItf); 1462b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErr(res); 1472b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1482b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Create Output Mix object to be used by player */ 1492b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*engineItf)->CreateOutputMix(engineItf, &outputMix, 0, 1502b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi iidArray, required); CheckErr(res); 1512b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Realizing the Output Mix object in synchronous mode. */ 1522b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 1532b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErr(res); 1542b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1552b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Setup the data source structure for the URI */ 1562b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // the syntax below is more future-proof than the individual field initialization 1572b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // with regards to OpenSL ES 1.1 but adds scary compilation warnings 1582b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi //uri = { SL_DATALOCATOR_URI /*locatorType*/, (SLchar*) path /*URI*/ }; 1592b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi //mime = { /*formatType*/ SL_DATAFORMAT_MIME, /*mimeType*/ (SLchar*)NULL, 1602b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // /*containerType*/ SL_CONTAINERTYPE_UNSPECIFIED }; 1612b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 1622b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi uri.URI = (SLchar*) path; 1632b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 1642b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi mime.mimeType = (SLchar*)NULL; 1652b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 1662b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1672b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi audioSource.pFormat = (void *)&mime; 1682b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi audioSource.pLocator = (void *)&uri; 1692b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1702b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Setup the data sink structure */ 1712b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 1722b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi locator_outputmix.outputMix = outputMix; 1732b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 1742b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi audioSink.pFormat = NULL; 1752b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1762b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 1772b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 1782b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 1792b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi iidArray[i] = SL_IID_NULL; 1802b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 1812b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface */ 1822b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 1832b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 1842b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 1852b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 1862b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1872b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "TestSetup(%s) completed\n", path); 1882b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 1892b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1902b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1912b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 1922b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid TestTeardown() { 1932b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Destroy Output Mix object */ 1942b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (*outputMix)->Destroy(outputMix); 1952b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 1962b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Shutdown OpenSL ES */ 1972b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (*slEngine)->Destroy(slEngine); 1982b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 1992b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2002b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2012b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 2022b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi/** 2032b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * Create a player and, if the creation is successful, 2042b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi * configure it, and start playing. 2052b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi */ 2062b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid CreatePlayer(int playerId) { 2072b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLresult res; 2082b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi playerNum[playerId] = playerId; 2092b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2102b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Create the audio player */ 2112b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*engineItf)->CreateAudioPlayer(engineItf, &audioPlayer[playerId], 2122b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi &audioSource, &audioSink, MAX_NUMBER_INTERFACES, iidArray, required); 2132b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_RESULT_SUCCESS != res) { 2142b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // do not abort the test, just flag the player as not a candidate for destruction 2152b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "CreateAudioPlayer for player %d failed\n", playerId); 2162b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi validplayer[playerId] = false; 2172b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi return; 2182b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 2192b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi validplayer[playerId] = true; 2202b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2212b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Realizing the player in synchronous mode. */ 2222b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*audioPlayer[playerId])->Realize(audioPlayer[playerId], SL_BOOLEAN_FALSE); 2232b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (SL_RESULT_SUCCESS != res) { 2242b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // do not abort the test, just stop the player initialization here 2252b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Realize for player %d failed\n", playerId); 2262b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // this player is still a candidate for destruction 2272b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi return; 2282b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 2292b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi // after this point, any failure is a test failure 2302b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2312b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Get interfaces */ 2322b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_PLAY, 2332b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (void*)&playItfs[playerId]); 2342b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2352b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2362b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_VOLUME, 2372b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (void*)&volItfs[playerId]); 2382b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2392b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2402b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_PREFETCHSTATUS, 2412b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (void*)&prefetchItfs[playerId]); 2422b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2432b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*prefetchItfs[playerId])->RegisterCallback(prefetchItfs[playerId], PrefetchEventCallback, 2442b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi &playerNum[playerId]); 2452b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2462b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*prefetchItfs[playerId])->SetCallbackEventsMask(prefetchItfs[playerId], 2472b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 2482b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2492b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2502b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Set the player volume */ 2512b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*volItfs[playerId])->SetVolumeLevel( volItfs[playerId], -300); 2522b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2532b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2542b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Set up the player callback to get events during the decoding */ 2552b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->SetMarkerPosition(playItfs[playerId], 2000); 2562b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2572b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->SetPositionUpdatePeriod(playItfs[playerId], 500); 2582b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2592b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->SetCallbackEventsMask(playItfs[playerId], 2602b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADATEND); 2612b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2622b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->RegisterCallback(playItfs[playerId], PlayEventCallback, 2632b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi &playerNum[playerId]); 2642b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2652b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2662b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Configure fill level updates every 5 percent */ 2672b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (*prefetchItfs[playerId])->SetFillUpdatePeriod(prefetchItfs[playerId], 50); 2682b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2692b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Play the URI */ 2702b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* first cause the player to prefetch the data */ 2712b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Setting player %d to PAUSED\n", playerId); 2722b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->SetPlayState( playItfs[playerId], SL_PLAYSTATE_PAUSED ); 2732b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2742b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* wait until there's data to play */ 2752b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 2762b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLuint32 timeOutIndex = 10; // 1s, should be enough for a local file 2772b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0)) { 2782b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi usleep(100 * 1000); 2792b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*prefetchItfs[playerId])->GetPrefetchStatus(prefetchItfs[playerId], &prefetchStatus); 2802b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2812b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi timeOutIndex--; 2822b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 2832b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2842b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (timeOutIndex == 0) { 2852b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stderr, "Prefetch timed out for player %d\n", playerId); 2862b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi return; 2872b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 2882b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->SetPlayState( playItfs[playerId], SL_PLAYSTATE_PLAYING ); 2892b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2902b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 2912b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Display duration */ 2922b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 2932b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi res = (*playItfs[playerId])->GetDuration(playItfs[playerId], &durationInMsec); 2942b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CheckErrPlyr(res, playerId); 2952b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 2962b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Content duration is unknown for player %d\n", playerId); 2972b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } else { 2982b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Content duration is %u ms for player %d\n", durationInMsec, playerId); 2992b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 3002b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 3012b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3022b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 3032b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivivoid DestroyPlayer(int playerId) { 3042b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "About to destroy player %d\n", playerId); 3052b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Destroy the player */ 3062b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi (*audioPlayer[playerId])->Destroy(audioPlayer[playerId]); 3072b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 3082b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3092b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3102b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi//----------------------------------------------------------------- 3112b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Triviint main(int argc, char* const argv[]) 3122b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi{ 3132b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: creates and destroys as many ", argv[0]); 3142b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "AudioPlayer objects as possible (max=%d)\n\n", MAX_NUMBER_PLAYERS); 3152b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3162b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (argc == 1) { 3172b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Usage: %s path \n\t%s url\n", argv[0], argv[0]); 3182b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 3192b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi argv[0], argv[0]); 3202b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi exit(EXIT_FAILURE); 3212b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 3222b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3232b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi TestSetup(argv[1]); 3242b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3252b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi for (int i=0 ; i<MAX_NUMBER_PLAYERS ; i++) { 3262b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi CreatePlayer(i); 3272b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 3282b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "After creating %d AudioPlayers\n", MAX_NUMBER_PLAYERS); 3292b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3302b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi /* Wait for an arbitrary amount of time. if playing a long file, the players will still 3312b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi be playing while the destructions start. */ 3322b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi usleep(10*1000*1000); // 10s 3332b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3342b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi for (int i=0 ; i<MAX_NUMBER_PLAYERS ; i++) { 3352b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi if (validplayer[i]) { 3362b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi DestroyPlayer(i); 3372b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 3382b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi } 3392b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi fprintf(stdout, "After destroying valid players among %d AudioPlayers\n", MAX_NUMBER_PLAYERS); 3402b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3412b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi TestTeardown(); 3422b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi 3432b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi return EXIT_SUCCESS; 3442b750ac8e486b75a0f5755d4b595077ec525235eJean-Michel Trivi} 345