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 3514463a8e53e2a5185a395e2045fd33ad4a63050dGlenn Kasten#define SL_PREFETCHSTATUS_ERROR ((SLuint32) -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( 105086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten SLPlayItf caller __unused, 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 SLresult res; 127d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 128d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataSource audioSource; 129d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataLocator_URI uri; 130d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataFormat_MIME mime; 131d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 132d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataSink audioSink; 133d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 134d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 135d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf player; 136d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLPlayItf playItf; 137d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLSeekItf seekItf; 138d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLPrefetchStatusItf prefetchItf; 139d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 140d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf OutputMix; 141d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 142d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 143d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 144d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 145d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 146d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 147d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 148d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 149d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 150d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 151d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 152d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 153d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 154d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 155d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 156d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 157d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi // Create Output Mix object to be used by player 158c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, 159d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray, required); CheckErr(res); 160d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 161d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi // Realizing the Output Mix object in synchronous mode. 162d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE); 163d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 164d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 165d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Setup the data source structure for the URI */ 166d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 167d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi uri.URI = (SLchar*) path; 168d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 169d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 170d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 171d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 172d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSource.pFormat = (void *)&mime; 173d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSource.pLocator = (void *)&uri; 174d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 175d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Setup the data sink structure */ 176d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 177d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi locator_outputmix.outputMix = OutputMix; 178d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 179d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi audioSink.pFormat = NULL; 180d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 181d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Create the audio player */ 182d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 183d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[0] = SL_IID_SEEK; 184d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 185d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 186d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 187d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res); 188d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 189d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Realizing the player in synchronous mode. */ 190d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res); 191d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 192d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 193d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Get interfaces */ 194d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 195d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 196d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 197d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_SEEK, (void*)&seekItf); 198d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 199d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 200d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 201d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 20256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, NULL); 203d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 204d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 205d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 206d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 207d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 208d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Configure fill level updates every 5 percent */ 209d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50); 210d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 21156c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten /* Set up the player callback to get head-at-end events */ 21256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATEND); 21356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(res); 21456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, NULL); 21556c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten CheckErr(res); 21656c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten 217d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Display duration */ 218d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 219d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 220d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 221d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 222d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n"); 223d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } else { 22458432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n", 225d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi durationInMsec); 226d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 227d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 228d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Loop on the whole of the content */ 229d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); 230d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 231d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 232d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Play the URI */ 233d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* first cause the player to prefetch the data */ 234d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 235d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 236d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 23756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten // wait for prefetch status callback to indicate either sufficient data or error 23856c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_mutex_lock(&mutex); 23956c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) { 24056c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_cond_wait(&cond, &mutex); 241d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 24256c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten pthread_mutex_unlock(&mutex); 24356c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten if (prefetch_status == SL_PREFETCHSTATUS_ERROR) { 24456c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten fprintf(stderr, "Error during prefetch, exiting\n"); 245d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi goto destroyRes; 246d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 247d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 248d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Display duration again, */ 249d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 250d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 251d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 252d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (after prefetch completed)\n"); 253d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } else { 25458432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec); 255d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 256d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 25756c5b9b986c00839e841f9660d9847173807a0c1Glenn Kasten /* Start playing */ 258d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "starting to play\n"); 259d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 260d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 261d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 262d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Wait as long as the duration of the content, times the repetitions, 263d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi * before stopping the loop */ 264d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi usleep( (REPETITIONS-1) * durationInMsec * 1100); 265d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); 266d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 267d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "As of now, stopped looping (sound shouldn't repeat from now on)\n"); 268d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* wait some more to make sure it doesn't repeat */ 269d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi usleep(durationInMsec * 1000); 270d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 271d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Stop playback */ 272d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "stopping playback\n"); 273d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 274d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 275d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 276d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel TrividestroyRes: 277d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 278d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Destroy the player */ 279d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*player)->Destroy(player); 280d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 281d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Destroy Output Mix object */ 282d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*OutputMix)->Destroy(OutputMix); 283d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 284d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 285d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//----------------------------------------------------------------- 286d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Triviint main(int argc, char* const argv[]) 287d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi{ 288d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLresult res; 289d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLObjectItf sl; 290d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 291d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLSeekItf ", argv[0]); 292d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 293d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Plays a sound and loops it %d times.\n\n", REPETITIONS); 294d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 295d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi if (argc == 1) { 296d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Usage: \n\t%s path \n\t%s url\n", argv[0], argv[0]); 297d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 298d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi argv[0], argv[0]); 299c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten exit(EXIT_FAILURE); 300d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi } 301d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 302d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi SLEngineOption EngineOption[] = { 303d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 304d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 305d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 306d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 307d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 308d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 309d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 310d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi CheckErr(res); 311d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 312d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi TestLoopUri(sl, argv[1]); 313d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 314d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi /* Shutdown OpenSL ES */ 315d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi (*sl)->Destroy(sl); 316d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi 317c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten return EXIT_SUCCESS; 318d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi} 319