16cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi/* 26cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 36cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * 46cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 56cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * you may not use this file except in compliance with the License. 66cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * You may obtain a copy of the License at 76cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * 86cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 96cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * 106cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 116cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 126cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * See the License for the specific language governing permissions and 146cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * limitations under the License. 156cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi */ 166cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 17dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten#include <assert.h> 18dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten#include <pthread.h> 196cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#include <stdlib.h> 206cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#include <stdio.h> 216cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#include <string.h> 226cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#include <unistd.h> 236cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#include <sys/time.h> 246cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 25a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h> 266cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 276cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 286cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#define MAX_NUMBER_INTERFACES 2 296cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 306cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#define REPETITIONS 4 316cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 32dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten// These are extensions to OpenSL ES 1.0.1 values 33dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 34dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten#define SL_PREFETCHSTATUS_UNKNOWN 0 35dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten#define SL_PREFETCHSTATUS_ERROR (-1) 36dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 37dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten// Mutex and condition shared with main program to protect prefetch_status 38dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 39dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kastenstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 40dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kastenstatic pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 41dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn KastenSLuint32 prefetch_status = SL_PREFETCHSTATUS_UNKNOWN; 42dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 43dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten/* used to detect errors likely to have occured when the OpenSL ES framework fails to open 44dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond. 45dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten */ 46dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \ 47dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 48dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 496cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi//----------------------------------------------------------------- 506cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi//* Exits the application if an error is encountered */ 516cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__) 526cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 536cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line) 546cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi{ 556cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 56d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line); 574d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten exit(EXIT_FAILURE); 586cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 596cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi} 606cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 616cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi//----------------------------------------------------------------- 626cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi/* PrefetchStatusItf callback for an audio player */ 63dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kastenvoid PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint32 event) 646cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi{ 65dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten SLresult result; 66dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten // pContext is unused here, so we pass NULL 67dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten assert(pContext == NULL); 686cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLpermille level = 0; 69dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten result = (*caller)->GetFillLevel(caller, &level); 70dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten CheckErr(result); 716cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLuint32 status; 72dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten result = (*caller)->GetPrefetchStatus(caller, &status); 73dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten CheckErr(result); 746cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 756cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "\t\tPrefetchEventCallback: Buffer fill level is = %d\n", level); 766cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 776cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (event & SL_PREFETCHEVENT_STATUSCHANGE) { 78d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten fprintf(stdout, "\t\tPrefetchEventCallback: Prefetch Status is = %u\n", status); 796cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 80dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten SLuint32 new_prefetch_status; 81dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten if ((event & PREFETCHEVENT_ERROR_CANDIDATE) == PREFETCHEVENT_ERROR_CANDIDATE 82dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 83dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten fprintf(stdout, "\t\tPrefetchEventCallback: Error while prefetching data, exiting\n"); 84dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten new_prefetch_status = SL_PREFETCHSTATUS_ERROR; 85dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten } else if (event == SL_PREFETCHEVENT_STATUSCHANGE && 86dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten status == SL_PREFETCHSTATUS_SUFFICIENTDATA) { 87dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten new_prefetch_status = status; 88dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten } else { 89dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten return; 90dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten } 91dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten int ok; 92dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten ok = pthread_mutex_lock(&mutex); 93dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten assert(ok == 0); 94dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten prefetch_status = new_prefetch_status; 95dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten ok = pthread_cond_signal(&cond); 96dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten assert(ok == 0); 97dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten ok = pthread_mutex_unlock(&mutex); 98dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten assert(ok == 0); 99dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten} 100dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 1016cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 102dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten//----------------------------------------------------------------- 103dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten/* PlayItf callback for playback events */ 104dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kastenvoid PlayEventCallback( 105dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten SLPlayItf caller, 106dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten void *pContext, 107dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten SLuint32 event) 108dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten{ 109dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten // pContext is unused here, so we pass NULL 110dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten assert(NULL == pContext); 111dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten if (SL_PLAYEVENT_HEADATEND == event) { 112dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten printf("SL_PLAYEVENT_HEADATEND reached\n"); 113dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten } else { 114dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten fprintf(stderr, "Unexpected play event 0x%x", event); 115dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten } 1166cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi} 1176cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1186cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1196cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi//----------------------------------------------------------------- 1206cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1216cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi/* Play some music from a URI */ 1226cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivivoid TestLoopUri( SLObjectItf sl, const char* path) 1236cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi{ 1246cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLEngineItf EngineItf; 1256cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1266cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLint32 numOutputs = 0; 1276cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLuint32 deviceID = 0; 1286cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1296cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLresult res; 1306cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1316cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLDataSource audioSource; 1326cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLDataLocator_URI uri; 1336cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLDataFormat_MIME mime; 1346cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1356cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLDataSink audioSink; 1366cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 1376cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1386cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLObjectItf player; 1396cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLPlayItf playItf; 1406cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLSeekItf seekItf; 1416cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLPrefetchStatusItf prefetchItf; 1426cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1436cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLObjectItf OutputMix; 1446cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1456cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 1466cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 1476cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1486cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 1496cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 1506cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 1516cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1526cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 1536cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 1546cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 1556cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi iidArray[i] = SL_IID_NULL; 1566cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 1576cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1586cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 1596cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 1606cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi // Create Output Mix object to be used by player 1614d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, 1626cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi iidArray, required); CheckErr(res); 1636cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1646cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi // Realizing the Output Mix object in synchronous mode. 1656cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE); 1666cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 1676cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1686cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Setup the data source structure for the URI */ 1696cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 1706cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi uri.URI = (SLchar*) path; 1716cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 1726cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi mime.mimeType = (SLchar*)NULL; 1736cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 1746cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1756cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi audioSource.pFormat = (void *)&mime; 1766cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi audioSource.pLocator = (void *)&uri; 1776cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1786cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Setup the data sink structure */ 1796cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 1806cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi locator_outputmix.outputMix = OutputMix; 1816cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 1826cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi audioSink.pFormat = NULL; 1836cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1846cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Create the audio player */ 1856cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 1866cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi iidArray[0] = SL_IID_SEEK; 1876cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 1886cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 1896cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 1906cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res); 1916cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1926cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Realizing the player in synchronous mode. */ 1936cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res); 1946cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 1956cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 1966cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Get interfaces */ 1976cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 1986cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 1996cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2006cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_SEEK, (void*)&seekItf); 2016cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2026cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2036cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 2046cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 205dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, NULL); 2066cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2076cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 2086cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 2096cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2106cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2116cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Configure fill level updates every 5 percent */ 2126cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50); 2136cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 214dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten /* Set up the player callback to get head-at-end events */ 215dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten res = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATEND); 216dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten CheckErr(res); 217dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, NULL); 218dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten CheckErr(res); 219dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten 2206cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Display duration */ 2216cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 2226cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 2236cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2246cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 2256cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n"); 2266cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } else { 227d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n", 2286cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi durationInMsec); 2296cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 2306cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2316cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Loop on the whole of the content */ 2326cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); 2336cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2346cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2356cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Play the URI */ 2366cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* first cause the player to prefetch the data */ 2376cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 2386cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2396cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 240dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten // wait for prefetch status callback to indicate either sufficient data or error 241dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten pthread_mutex_lock(&mutex); 242dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) { 243dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten pthread_cond_wait(&cond, &mutex); 2446cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 245dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten pthread_mutex_unlock(&mutex); 246dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten if (prefetch_status == SL_PREFETCHSTATUS_ERROR) { 247dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten fprintf(stderr, "Error during prefetch, exiting\n"); 2486cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi goto destroyRes; 2496cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 2506cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2516cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Display duration again, */ 2526cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 2536cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2546cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 2556cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "Content duration is unknown (after prefetch completed)\n"); 2566cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } else { 257d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec); 2586cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 2596cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 260dfc3110139e5aa8205e5736c93c3d2bcc077f71bGlenn Kasten /* Start playing */ 2616cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "starting to play\n"); 2626cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 2636cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2646cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2656cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Wait as long as the duration of the content, times the repetitions, 2666cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi * before stopping the loop */ 2676cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi usleep( (REPETITIONS-1) * durationInMsec * 1100); 2686cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); 2696cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2706cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "As of now, stopped looping (sound shouldn't repeat from now on)\n"); 2716cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* wait some more to make sure it doesn't repeat */ 2726cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi usleep(durationInMsec * 1000); 2736cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2746cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Stop playback */ 2756cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "stopping playback\n"); 2766cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 2776cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 2786cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2796cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel TrividestroyRes: 2806cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2816cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Destroy the player */ 2826cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi (*player)->Destroy(player); 2836cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2846cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Destroy Output Mix object */ 2856cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi (*OutputMix)->Destroy(OutputMix); 2866cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi} 2876cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2886cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi//----------------------------------------------------------------- 2896cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Triviint main(int argc, char* const argv[]) 2906cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi{ 2916cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLresult res; 2926cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLObjectItf sl; 2936cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2946cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLSeekItf ", argv[0]); 2956cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 2966cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "Plays a sound and loops it %d times.\n\n", REPETITIONS); 2976cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 2986cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi if (argc == 1) { 2996cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "Usage: \n\t%s path \n\t%s url\n", argv[0], argv[0]); 3006cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 3016cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi argv[0], argv[0]); 3024d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten exit(EXIT_FAILURE); 3036cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi } 3046cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 3056cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi SLEngineOption EngineOption[] = { 3066cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 3076cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 3086cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 3096cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 3106cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 3116cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 3126cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 3136cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi CheckErr(res); 3146cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 3156cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi TestLoopUri(sl, argv[1]); 3166cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 3176cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi /* Shutdown OpenSL ES */ 3186cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi (*sl)->Destroy(sl); 3196cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi 3204d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten return EXIT_SUCCESS; 3216cb166eb8284fb9c9cf2d26daf7eb802168d710dJean-Michel Trivi} 322