1d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi/* 2d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 3d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * 4d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * you may not use this file except in compliance with the License. 6d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * You may obtain a copy of the License at 7d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * 8d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * 10d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * See the License for the specific language governing permissions and 14d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * limitations under the License. 15d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi */ 16d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 1756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten#include <assert.h> 1856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten#include <pthread.h> 19d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#include <stdlib.h> 20d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#include <stdio.h> 21d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#include <string.h> 22d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#include <unistd.h> 23d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#include <sys/time.h> 24d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 25c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 26d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 27d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 28d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 2 29d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 30d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#define REPETITIONS 4 31d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 3256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten// These are extensions to OpenSL ES 1.0.1 values 3356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 3456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten#define SL_PREFETCHSTATUS_UNKNOWN 0 3556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten#define SL_PREFETCHSTATUS_ERROR (-1) 3656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 3756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten// Mutex and condition shared with main program to protect prefetch_status 3856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 3956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kastenstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 4056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kastenstatic pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 4156c5b9b986c00839e841f9660d9847173807a0c1Glenn KastenSLuint32 prefetch_status = SL_PREFETCHSTATUS_UNKNOWN; 4256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 4356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten/* used to detect errors likely to have occured when the OpenSL ES framework fails to open 4456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond. 4556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten */ 4656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \ 4756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 4856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 49d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//----------------------------------------------------------------- 50d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//* Exits the application if an error is encountered */ 51d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__) 52d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 53d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line) 54d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi{ 55d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 5658432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line); 57c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten exit(EXIT_FAILURE); 58d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 59d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 60d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 61d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//----------------------------------------------------------------- 62d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi/* PrefetchStatusItf callback for an audio player */ 6356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kastenvoid PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint32 event) 64d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi{ 6556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten SLresult result; 6656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten // pContext is unused here, so we pass NULL 6756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten assert(pContext == NULL); 68d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLpermille level = 0; 6956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten result = (*caller)->GetFillLevel(caller, &level); 7056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(result); 71d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLuint32 status; 7256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten result = (*caller)->GetPrefetchStatus(caller, &status); 7356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(result); 74d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 75d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "\t\tPrefetchEventCallback: Buffer fill level is = %d\n", level); 76d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 77d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (event & SL_PREFETCHEVENT_STATUSCHANGE) { 7858432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "\t\tPrefetchEventCallback: Prefetch Status is = %u\n", status); 79d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 8056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten SLuint32 new_prefetch_status; 8156c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten if ((event & PREFETCHEVENT_ERROR_CANDIDATE) == PREFETCHEVENT_ERROR_CANDIDATE 8256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 8356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten fprintf(stdout, "\t\tPrefetchEventCallback: Error while prefetching data, exiting\n"); 8456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten new_prefetch_status = SL_PREFETCHSTATUS_ERROR; 8556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten } else if (event == SL_PREFETCHEVENT_STATUSCHANGE && 8656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten status == SL_PREFETCHSTATUS_SUFFICIENTDATA) { 8756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten new_prefetch_status = status; 8856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten } else { 8956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten return; 9056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten } 9156c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten int ok; 9256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten ok = pthread_mutex_lock(&mutex); 9356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten assert(ok == 0); 9456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten prefetch_status = new_prefetch_status; 9556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten ok = pthread_cond_signal(&cond); 9656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten assert(ok == 0); 9756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten ok = pthread_mutex_unlock(&mutex); 9856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten assert(ok == 0); 9956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten} 10056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 101d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 10256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten//----------------------------------------------------------------- 10356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten/* PlayItf callback for playback events */ 10456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kastenvoid PlayEventCallback( 10556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten SLPlayItf caller, 10656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten void *pContext, 10756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten SLuint32 event) 10856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten{ 10956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten // pContext is unused here, so we pass NULL 11056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten assert(NULL == pContext); 11156c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten if (SL_PLAYEVENT_HEADATEND == event) { 11256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten printf("SL_PLAYEVENT_HEADATEND reached\n"); 11356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten } else { 11456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten fprintf(stderr, "Unexpected play event 0x%x", event); 11556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten } 116d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 117d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 118d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 119d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//----------------------------------------------------------------- 120d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 121d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi/* Play some music from a URI */ 122d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivivoid TestLoopUri( SLObjectItf sl, const char* path) 123d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi{ 124d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLEngineItf EngineItf; 125d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 126d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLint32 numOutputs = 0; 127d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLuint32 deviceID = 0; 128d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 129d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLresult res; 130d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 131d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataSource audioSource; 132d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataLocator_URI uri; 133d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataFormat_MIME mime; 134d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 135d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataSink audioSink; 136d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 137d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 138d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf player; 139d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLPlayItf playItf; 140d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLSeekItf seekItf; 141d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLPrefetchStatusItf prefetchItf; 142d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 143d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf OutputMix; 144d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 145d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 146d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 147d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 148d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 149d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 150d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 151d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 152d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 153d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 154d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 155d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 156d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 157d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 158d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 159d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 160d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi // Create Output Mix object to be used by player 161c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, 162d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray, required); CheckErr(res); 163d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 164d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi // Realizing the Output Mix object in synchronous mode. 165d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE); 166d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 167d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 168d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Setup the data source structure for the URI */ 169d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 170d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi uri.URI = (SLchar*) path; 171d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 172d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 173d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 174d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 175d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSource.pFormat = (void *)&mime; 176d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSource.pLocator = (void *)&uri; 177d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 178d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Setup the data sink structure */ 179d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 180d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi locator_outputmix.outputMix = OutputMix; 181d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 182d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSink.pFormat = NULL; 183d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 184d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Create the audio player */ 185d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 186d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[0] = SL_IID_SEEK; 187d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 188d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 189d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 190d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res); 191d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 192d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Realizing the player in synchronous mode. */ 193d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res); 194d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 195d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 196d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Get interfaces */ 197d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 198d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 199d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 200d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_SEEK, (void*)&seekItf); 201d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 202d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 203d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 204d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 20556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, NULL); 206d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 207d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 208d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 209d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 210d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 211d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Configure fill level updates every 5 percent */ 212d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50); 213d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 21456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten /* Set up the player callback to get head-at-end events */ 21556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATEND); 21656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(res); 21756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, NULL); 21856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(res); 21956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 220d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Display duration */ 221d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 222d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 223d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 224d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 225d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n"); 226d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } else { 22758432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n", 228d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi durationInMsec); 229d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 230d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 231d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Loop on the whole of the content */ 232d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); 233d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 234d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 235d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Play the URI */ 236d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* first cause the player to prefetch the data */ 237d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 238d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 239d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 24056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten // wait for prefetch status callback to indicate either sufficient data or error 24156c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_mutex_lock(&mutex); 24256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) { 24356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_cond_wait(&cond, &mutex); 244d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 24556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_mutex_unlock(&mutex); 24656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten if (prefetch_status == SL_PREFETCHSTATUS_ERROR) { 24756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten fprintf(stderr, "Error during prefetch, exiting\n"); 248d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi goto destroyRes; 249d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 250d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 251d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Display duration again, */ 252d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 253d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 254d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 255d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (after prefetch completed)\n"); 256d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } else { 25758432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec); 258d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 259d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 26056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten /* Start playing */ 261d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "starting to play\n"); 262d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 263d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 264d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 265d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Wait as long as the duration of the content, times the repetitions, 266d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * before stopping the loop */ 267d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi usleep( (REPETITIONS-1) * durationInMsec * 1100); 268d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); 269d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 270d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "As of now, stopped looping (sound shouldn't repeat from now on)\n"); 271d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* wait some more to make sure it doesn't repeat */ 272d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi usleep(durationInMsec * 1000); 273d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 274d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Stop playback */ 275d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "stopping playback\n"); 276d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 277d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 278d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 279d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel TrividestroyRes: 280d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 281d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Destroy the player */ 282d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*player)->Destroy(player); 283d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 284d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Destroy Output Mix object */ 285d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*OutputMix)->Destroy(OutputMix); 286d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 287d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 288d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//----------------------------------------------------------------- 289d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Triviint main(int argc, char* const argv[]) 290d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi{ 291d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLresult res; 292d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf sl; 293d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 294d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLSeekItf ", argv[0]); 295d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 296d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Plays a sound and loops it %d times.\n\n", REPETITIONS); 297d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 298d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (argc == 1) { 299d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Usage: \n\t%s path \n\t%s url\n", argv[0], argv[0]); 300d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 301d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi argv[0], argv[0]); 302c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten exit(EXIT_FAILURE); 303d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 304d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 305d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLEngineOption EngineOption[] = { 306d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 307d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 308d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 309d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 310d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 311d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 312d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 313d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 314d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 315d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi TestLoopUri(sl, argv[1]); 316d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 317d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Shutdown OpenSL ES */ 318d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*sl)->Destroy(sl); 319d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 320c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten return EXIT_SUCCESS; 321d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 322