130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi/* 230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * 430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * you may not use this file except in compliance with the License. 630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * You may obtain a copy of the License at 730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * 830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * 1030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * See the License for the specific language governing permissions and 1430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * limitations under the License. 1530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi */ 1630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 1730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#include <stdlib.h> 1830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#include <stdio.h> 1930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#include <unistd.h> 2030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//#include <sys/time.h> 2130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 22a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h> 2330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 2430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 2530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 2 2630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#define MAX_NUMBER_PLAYERS 40 2730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 2830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \ 2930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 3030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 3130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi/* the OpenSL ES engine from which we create all other resources */ 3230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLObjectItf slEngine; 3330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLEngineItf engineItf; 3430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLObjectItf outputMix; 3530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 3630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLboolean required[MAX_NUMBER_INTERFACES]; 3730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 3830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 3930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLObjectItf audioPlayer[MAX_NUMBER_PLAYERS]; 4030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivibool validplayer[MAX_NUMBER_PLAYERS]; 4130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Triviint playerNum[MAX_NUMBER_PLAYERS]; 4230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLPlayItf playItfs[MAX_NUMBER_PLAYERS]; 4330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLVolumeItf volItfs[MAX_NUMBER_PLAYERS]; 4430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLPrefetchStatusItf prefetchItfs[MAX_NUMBER_PLAYERS]; 4530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 4630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLDataSource audioSource; 4730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLDataLocator_URI uri; 4830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLDataFormat_MIME mime; 4930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 5030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLDataSink audioSink; 5130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel TriviSLDataLocator_OutputMix locator_outputmix; 5230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 5330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 5430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 5530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//* Exits the application if an error is encountered */ 5630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x, -1, __LINE__) 5730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi#define CheckErrPlyr(x, id) ExitOnErrorFunc(x, id, __LINE__) 5830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 5930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result, int playerId, int line) 6030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi{ 6130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 6230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (playerId == -1) { 6330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stderr, "Error %u code encountered at line %d, exiting\n", result, line); 6430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } else { 6530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stderr, "Error %u code encountered at line %d for player %d, exiting\n", 6630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi result, line, playerId); 6730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 6830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi exit(EXIT_FAILURE); 6930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 7030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 7130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 7230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 7330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi/* PrefetchStatusItf callback for an audio player */ 7430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint32 event) 7530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi{ 7630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLresult res; 7730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLpermille level = 0; 7830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi int* pPlayerId = (int*)pContext; 7930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*caller)->GetFillLevel(caller, &level); CheckErrPlyr(res, *pPlayerId); 8030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLuint32 status; 8130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi //fprintf(stdout, "PrefetchEventCallback: received event %u\n", event); 8230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*caller)->GetPrefetchStatus(caller, &status); CheckErrPlyr(res, *pPlayerId); 8330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) 8430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 8530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Error while prefetching data for player %d, " 8630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi "exiting\n", *pPlayerId); 8730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi exit(EXIT_FAILURE); 8830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 8930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 9030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Buffer fill level is = %d for player %d\n", 9130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi level, *pPlayerId); 9230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 9330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (event & SL_PREFETCHEVENT_STATUSCHANGE) { 9430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Prefetch Status is = %u for player %d\n", 9530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi status, *pPlayerId); 9630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 9730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 9830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 9930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 10030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 10130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi/* PlayItf callback for playback events */ 10230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid PlayEventCallback( 10330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLPlayItf caller, 10430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi void *pContext, 10530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLuint32 event) 10630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi{ 10730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLresult res; 10830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi int* pPlayerId = (int*)pContext; 10930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_PLAYEVENT_HEADATEND & event) { 11030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATEND reached for player %d\n", *pPlayerId); 11130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi //SignalEos(); 11230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 11330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 11430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_PLAYEVENT_HEADATNEWPOS & event) { 11530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLmillisecond pMsec = 0; 11630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*caller)->GetPosition(caller, &pMsec); CheckErrPlyr(res, *pPlayerId); 11730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS current position=%ums for player %d\n", 11830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi pMsec, *pPlayerId); 11930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 12030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 12130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_PLAYEVENT_HEADATMARKER & event) { 12230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLmillisecond pMsec = 0; 12330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*caller)->GetPosition(caller, &pMsec); CheckErrPlyr(res, *pPlayerId); 12430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER current position=%ums for player %d\n", 12530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi pMsec, *pPlayerId); 12630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 12730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 12830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 12930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 13030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 13130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid TestSetup(const char* path) { 13230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLint32 numOutputs = 0; 13330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLuint32 deviceID = 0; 13430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLresult res; 13530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 13630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Create the engine */ 13730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLEngineOption EngineOption[] = { 13830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 13930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 14030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 14130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = slCreateEngine( &slEngine, 1, EngineOption, 0, NULL, NULL); 14230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErr(res); 14330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 14430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*slEngine)->Realize(slEngine, SL_BOOLEAN_FALSE); 14530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErr(res); 14630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 14730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*slEngine)->GetInterface(slEngine, SL_IID_ENGINE, (void*)&engineItf); 14830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErr(res); 14930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 15030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Create Output Mix object to be used by player */ 15130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*engineItf)->CreateOutputMix(engineItf, &outputMix, 0, 15230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi iidArray, required); CheckErr(res); 15330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Realizing the Output Mix object in synchronous mode. */ 15430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 15530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErr(res); 15630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 15730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Setup the data source structure for the URI */ 15830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // the syntax below is more future-proof than the individual field initialization 15930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // with regards to OpenSL ES 1.1 but adds scary compilation warnings 16030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi //uri = { SL_DATALOCATOR_URI /*locatorType*/, (SLchar*) path /*URI*/ }; 16130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi //mime = { /*formatType*/ SL_DATAFORMAT_MIME, /*mimeType*/ (SLchar*)NULL, 16230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // /*containerType*/ SL_CONTAINERTYPE_UNSPECIFIED }; 16330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 16430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi uri.URI = (SLchar*) path; 16530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 16630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 16730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 16830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 16930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi audioSource.pFormat = (void *)&mime; 17030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi audioSource.pLocator = (void *)&uri; 17130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 17230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Setup the data sink structure */ 17330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 17430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi locator_outputmix.outputMix = outputMix; 17530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 17630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi audioSink.pFormat = NULL; 17730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 17830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 17930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 18030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 18130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 18230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 18330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface */ 18430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 18530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 18630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 18730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 18830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 18930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "TestSetup(%s) completed\n", path); 19030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 19130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 19230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 19330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 19430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid TestTeardown() { 19530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Destroy Output Mix object */ 19630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (*outputMix)->Destroy(outputMix); 19730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 19830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Shutdown OpenSL ES */ 19930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (*slEngine)->Destroy(slEngine); 20030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 20130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 20230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 20330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 20430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi/** 20530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * Create a player and, if the creation is successful, 20630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi * configure it, and start playing. 20730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi */ 20830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid CreatePlayer(int playerId) { 20930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLresult res; 21030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi playerNum[playerId] = playerId; 21130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 21230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Create the audio player */ 21330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*engineItf)->CreateAudioPlayer(engineItf, &audioPlayer[playerId], 21430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi &audioSource, &audioSink, MAX_NUMBER_INTERFACES, iidArray, required); 21530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_RESULT_SUCCESS != res) { 21630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // do not abort the test, just flag the player as not a candidate for destruction 21730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "CreateAudioPlayer for player %d failed\n", playerId); 21830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi validplayer[playerId] = false; 21930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi return; 22030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 22130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi validplayer[playerId] = true; 22230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 22330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Realizing the player in synchronous mode. */ 22430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*audioPlayer[playerId])->Realize(audioPlayer[playerId], SL_BOOLEAN_FALSE); 22530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (SL_RESULT_SUCCESS != res) { 22630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // do not abort the test, just stop the player initialization here 22730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Realize for player %d failed\n", playerId); 22830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // this player is still a candidate for destruction 22930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi return; 23030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 23130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi // after this point, any failure is a test failure 23230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 23330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Get interfaces */ 23430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_PLAY, 23530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (void*)&playItfs[playerId]); 23630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 23730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 23830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_VOLUME, 23930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (void*)&volItfs[playerId]); 24030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 24130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 24230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*audioPlayer[playerId])->GetInterface(audioPlayer[playerId], SL_IID_PREFETCHSTATUS, 24330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (void*)&prefetchItfs[playerId]); 24430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 24530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*prefetchItfs[playerId])->RegisterCallback(prefetchItfs[playerId], PrefetchEventCallback, 24630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi &playerNum[playerId]); 24730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 24830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*prefetchItfs[playerId])->SetCallbackEventsMask(prefetchItfs[playerId], 24930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 25030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 25130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 25230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Set the player volume */ 25330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*volItfs[playerId])->SetVolumeLevel( volItfs[playerId], -300); 25430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 25530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 25630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Set up the player callback to get events during the decoding */ 25730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->SetMarkerPosition(playItfs[playerId], 2000); 25830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 25930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->SetPositionUpdatePeriod(playItfs[playerId], 500); 26030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 26130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->SetCallbackEventsMask(playItfs[playerId], 26230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADATEND); 26330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 26430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->RegisterCallback(playItfs[playerId], PlayEventCallback, 26530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi &playerNum[playerId]); 26630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 26730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 26830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Configure fill level updates every 5 percent */ 26930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (*prefetchItfs[playerId])->SetFillUpdatePeriod(prefetchItfs[playerId], 50); 27030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 27130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Play the URI */ 27230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* first cause the player to prefetch the data */ 27330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Setting player %d to PAUSED\n", playerId); 27430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->SetPlayState( playItfs[playerId], SL_PLAYSTATE_PAUSED ); 27530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 27630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* wait until there's data to play */ 27730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 27830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLuint32 timeOutIndex = 10; // 1s, should be enough for a local file 27930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0)) { 28030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi usleep(100 * 1000); 28130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*prefetchItfs[playerId])->GetPrefetchStatus(prefetchItfs[playerId], &prefetchStatus); 28230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 28330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi timeOutIndex--; 28430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 28530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 28630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (timeOutIndex == 0) { 28730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stderr, "Prefetch timed out for player %d\n", playerId); 28830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi return; 28930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 29030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->SetPlayState( playItfs[playerId], SL_PLAYSTATE_PLAYING ); 29130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 29230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 29330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Display duration */ 29430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 29530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi res = (*playItfs[playerId])->GetDuration(playItfs[playerId], &durationInMsec); 29630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CheckErrPlyr(res, playerId); 29730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 29830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Content duration is unknown for player %d\n", playerId); 29930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } else { 30030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Content duration is %u ms for player %d\n", durationInMsec, playerId); 30130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 30230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 30330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 30430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 30530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivivoid DestroyPlayer(int playerId) { 30630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "About to destroy player %d\n", playerId); 30730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Destroy the player */ 30830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi (*audioPlayer[playerId])->Destroy(audioPlayer[playerId]); 30930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 31030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 31130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 31230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi//----------------------------------------------------------------- 31330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Triviint main(int argc, char* const argv[]) 31430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi{ 31530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: creates and destroys as many ", argv[0]); 31630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "AudioPlayer objects as possible (max=%d)\n\n", MAX_NUMBER_PLAYERS); 31730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 31830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (argc == 1) { 31930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Usage: %s path \n\t%s url\n", argv[0], argv[0]); 32030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 32130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi argv[0], argv[0]); 32230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi exit(EXIT_FAILURE); 32330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 32430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 32530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi TestSetup(argv[1]); 32630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 32730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi for (int i=0 ; i<MAX_NUMBER_PLAYERS ; i++) { 32830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi CreatePlayer(i); 32930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 33030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "After creating %d AudioPlayers\n", MAX_NUMBER_PLAYERS); 33130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 33230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi /* Wait for an arbitrary amount of time. if playing a long file, the players will still 33330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi be playing while the destructions start. */ 33430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi usleep(10*1000*1000); // 10s 33530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 33630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi for (int i=0 ; i<MAX_NUMBER_PLAYERS ; i++) { 33730a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi if (validplayer[i]) { 33830a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi DestroyPlayer(i); 33930a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 34030a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi } 34130a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi fprintf(stdout, "After destroying valid players among %d AudioPlayers\n", MAX_NUMBER_PLAYERS); 34230a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 34330a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi TestTeardown(); 34430a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi 34530a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi return EXIT_SUCCESS; 34630a6b6984099be3ce9a8099c97114a43797583b5Jean-Michel Trivi} 347