1f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* 2f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 3f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * 4f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * you may not use this file except in compliance with the License. 6f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * You may obtain a copy of the License at 7f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * 8f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * 10f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * See the License for the specific language governing permissions and 14f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * limitations under the License. 15f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi */ 16f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 17342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten#include <assert.h> 18342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten#include <pthread.h> 19f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <stdlib.h> 20f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <stdio.h> 21f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <string.h> 22f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <unistd.h> 23f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <sys/time.h> 24f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 25a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h> 26f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 27f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 28f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3 29f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 30f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define TEST_MUTE 0 31f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define TEST_SOLO 1 32f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 3366f75c45c9aea410b1f913d76995661e72571b67Glenn Kastentypedef struct { 3466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten int testMode; 3566f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten SLPlayItf playItf; 3666f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten SLMuteSoloItf muteSoloItf; 3766f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten} Context; 3866f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten 39f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//----------------------------------------------------------------- 40f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* Exits the application if an error is encountered */ 41f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__) 42f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 43f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line) 44f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{ 45f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 46d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten fprintf(stdout, "%u error code encountered at line %d, exiting\n", result, line); 474d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten exit(EXIT_FAILURE); 48f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 49f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi} 50f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 51342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten// These are extensions to OpenSL ES 1.0.1 values 52342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 53342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten#define SL_PREFETCHSTATUS_UNKNOWN 0 54342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten#define SL_PREFETCHSTATUS_ERROR (-1) 55342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 56342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten// Mutex and condition shared with main program to protect prefetch_status 57342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 58342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kastenstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 59342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kastenstatic pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 60342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn KastenSLuint32 prefetch_status = SL_PREFETCHSTATUS_UNKNOWN; 61342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 62342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten/* used to detect errors likely to have occured when the OpenSL ES framework fails to open 63342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond. 64342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten */ 65342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \ 66342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 67342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 68342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten// Prefetch status callback 69342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 70342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kastenvoid prefetch_callback(SLPrefetchStatusItf caller, void *context, SLuint32 event) 71342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten{ 72342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SLresult result; 73342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(context == NULL); 74342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SLpermille level; 75342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*caller)->GetFillLevel(caller, &level); 76342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(SL_RESULT_SUCCESS == result); 77342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SLuint32 status; 78342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*caller)->GetPrefetchStatus(caller, &status); 79342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(SL_RESULT_SUCCESS == result); 80342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SLuint32 new_prefetch_status; 81342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten if ((event & PREFETCHEVENT_ERROR_CANDIDATE) == PREFETCHEVENT_ERROR_CANDIDATE 82342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten && level == 0 && status == SL_PREFETCHSTATUS_UNDERFLOW) { 83342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten new_prefetch_status = SL_PREFETCHSTATUS_ERROR; 84342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten } else if (event == SL_PREFETCHEVENT_STATUSCHANGE && 85342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten status == SL_PREFETCHSTATUS_SUFFICIENTDATA) { 86342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten new_prefetch_status = status; 87342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten } else { 88342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten return; 89342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten } 90342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten int ok; 91342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ok = pthread_mutex_lock(&mutex); 92342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(ok == 0); 93342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten prefetch_status = new_prefetch_status; 94342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ok = pthread_cond_signal(&cond); 95342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(ok == 0); 96342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ok = pthread_mutex_unlock(&mutex); 97342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(ok == 0); 98342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten} 99342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 100f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//----------------------------------------------------------------- 101f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* PlayItf callback for an audio player, will be called for every SL_PLAYEVENT_HEADATNEWPOS event */ 102f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid PlayEventCallback( SLPlayItf caller, void *pContext, SLuint32 event) 103f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{ 10466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten Context *context = (Context *) pContext; 10566f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten SLPlayItf playItf = context->playItf; 10666f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten SLMuteSoloItf muteSolo = context->muteSoloItf; 107f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLuint8 numChannels = 0; 108f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLresult res = (*muteSolo)->GetNumChannels(muteSolo, &numChannels); ExitOnError(res); 109f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi //fprintf(stdout, "Content has %d channel(s)\n", numChannels); 11066f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten SLmillisecond position; 11166f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten res = (*playItf)->GetPosition(playItf, &position); ExitOnError(res); 11266f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten printf("position=%u\n", (unsigned) position); 113f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 11466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten switch (context->testMode) { 115f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi case TEST_MUTE: { 116f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi //--------------------------------------------------- 117f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel 118f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLboolean leftMuted = SL_BOOLEAN_TRUE; 119f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->GetChannelMute(muteSolo, 0, &leftMuted); ExitOnError(res); 120f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi // swap channel mute 121f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->SetChannelMute(muteSolo, 0, 122f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE); 123f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(res); 124f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->SetChannelMute(muteSolo, 1, 125f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE); 126f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(res); 127f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (leftMuted == SL_BOOLEAN_TRUE) { // we've swapped the channel mute above 128f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "channel 0: playing, channel 1: muted\n"); 129f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } else { 130f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "channel 0: muted, channel 1: playing\n"); 131f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 132f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 133f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } break; 134f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 135f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi case TEST_SOLO: { 136f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi //--------------------------------------------------- 137f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel 138f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLboolean leftSoloed = SL_BOOLEAN_TRUE; 139f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->GetChannelSolo(muteSolo, 0, &leftSoloed); ExitOnError(res); 140f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi // swap channel solo 141f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->SetChannelSolo(muteSolo, 0, 142f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE); 143f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(res); 144f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi res = (*muteSolo)->SetChannelSolo(muteSolo, 1, 145f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE); 146f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(res); 147f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (leftSoloed == SL_BOOLEAN_TRUE) { // we've swapped the channel solo above 148f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "channel 0: normal, channel 1: soloed\n"); 149f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } else { 150f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "channel 0: soloed, channel 1: normal\n"); 151f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 152f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 153f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } break; 154f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 155f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi default: 156f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi break; 157f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 158f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi} 159f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 160f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//----------------------------------------------------------------- 161f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 162f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* Play an audio URIs, mute and solo channels */ 163f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path) 164f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{ 165f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLresult result; 166f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLEngineItf EngineItf; 167f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 168342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten /* Objects this application uses: one player and an output mix */ 169f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLObjectItf player, outputMix; 170f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 171f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Source of audio data to play */ 172f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLDataSource audioSource; 173f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLDataLocator_URI uri; 174f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLDataFormat_MIME mime; 175f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 176f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Data sinks for the audio player */ 177f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLDataSink audioSink; 178f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 179f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 180f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Play, Volume and PrefetchStatus interfaces for the audio player */ 181f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLPlayItf playItf; 182f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLMuteSoloItf muteSoloItf; 183f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLPrefetchStatusItf prefetchItf; 184f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 185f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 186f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 187f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 188f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 189f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 190f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 191f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 192f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 193f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 194f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 195f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 196f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 197f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 198f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* ------------------------------------------------------ */ 199f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Configuration of the output mix */ 200f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 201f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Create Output Mix object to be used by the player */ 2024d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required); 203f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 204f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 205f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Realize the Output Mix object in synchronous mode */ 206f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 207f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 208f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 209f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Setup the data sink structure */ 210f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 211f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi locator_outputmix.outputMix = outputMix; 212f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi audioSink.pLocator = (void*)&locator_outputmix; 213f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi audioSink.pFormat = NULL; 214f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 215f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* ------------------------------------------------------ */ 216f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Configuration of the player */ 217f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 218f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */ 219f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* (SLPlayItf is implicit) */ 220f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 221f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi iidArray[0] = SL_IID_MUTESOLO; 222f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 223f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 224f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 225f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Setup the data source structure for the URI */ 226f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 227f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi uri.URI = (SLchar*) path; 228f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 229f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* this is how ignored mime information is specified, according to OpenSL ES spec 230f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */ 231f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 232f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 233f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 234f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi audioSource.pFormat = (void*)&mime; 235f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi audioSource.pLocator = (void*)&uri; 236f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 237f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Create the audio player */ 23823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2, 239f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi iidArray, required); 240f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 241f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 242f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Realize the player in synchronous mode. */ 243f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result); 244f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 245f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 246f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */ 247f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 248f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 249f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 250342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // get the prefetch status interface 251f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 252f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 253f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 254342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // enable prefetch status callbacks 255342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*prefetchItf)->RegisterCallback(prefetchItf, prefetch_callback, NULL); 256342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(SL_RESULT_SUCCESS == result); 257342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 258342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE); 259342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten assert(SL_RESULT_SUCCESS == result); 260342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 261342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // get the mute solo interface 262f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf); 263f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 264f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 265342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // Attempt to get the duration before it is necessarily known. 266342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // This should always return successfully. 267342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // The reported duration may be either 268342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // a particular duration or SL_TIME_UNKNOWN, depending on the platform. 269342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten SLmillisecond duration; 270342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*playItf)->GetDuration(playItf, &duration); 271342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ExitOnError(result); 272342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten printf("GetDuration after Realize but before pre-fetch: result=%u, duration=%u\n", 273342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result, duration); 274342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 275ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten // Attempt to get the channel count before it is necessarily known. 276342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // This should either return successfully with a specific value (e.g. 1 or 2), 277342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // or fail with SL_RESULT_PRECONDITIONS_VIOLATED, depending on the platform. 278ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten SLuint8 numChannels = 123; 279ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels); 280d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten printf("GetNumChannels after Realize but before pre-fetch: result=%u, numChannels=%u\n", 281ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten result, numChannels); 282342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten if (result != SL_RESULT_PRECONDITIONS_VIOLATED) { 283342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ExitOnError(result); 284342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten } 285ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten 286342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten /* Initialize a context for use by the play event callback */ 28766f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten Context context; 28866f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten context.playItf = playItf; 28966f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten context.muteSoloItf = muteSoloItf; 29066f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten context.testMode = TEST_MUTE; 29166f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten 292f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Setup to receive playback events on position updates */ 29366f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void *) &context); 294f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 295f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATNEWPOS); 296f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 297f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*playItf)->SetPositionUpdatePeriod(playItf, 1000); 298f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 299f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 300f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Player configured\n"); 301f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 302f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* ------------------------------------------------------ */ 303f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Playback and test */ 304f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 305f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Start the data prefetching by setting the player to the paused state */ 306f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 307f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 308f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 309342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten // wait for prefetch status callback to indicate either sufficient data or error 310342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten pthread_mutex_lock(&mutex); 311342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) { 312342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten pthread_cond_wait(&cond, &mutex); 313342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten } 314342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten pthread_mutex_unlock(&mutex); 315342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten if (prefetch_status == SL_PREFETCHSTATUS_ERROR) { 316342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten fprintf(stderr, "Error during prefetch, exiting\n"); 317342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten goto destroyKillKill; 318f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 319f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 320342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten /* Query the duration */ 321342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result = (*playItf)->GetDuration(playItf, &duration); 322342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten printf("GetDuration after Realize and after pre-fetch: result=%u, duration=%u\n", 323342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result, duration); 324342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten ExitOnError(result); 325342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten 326f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Query the number of channels */ 327ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten numChannels = 123; 328f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels); 329342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten printf("GetNumChannels after Realize and after pre-fetch: result=%u, numChannels=%u\n", 330342a97ea313edccccda34dc5e5ec0aacfbc1ff62Glenn Kasten result, numChannels); 331f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 332f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Content has %d channel(s)\n", numChannels); 333f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 334f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (numChannels == 1) { 335f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "SLMuteSolotItf only works one content with more than one channel. Bye\n"); 336f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi goto destroyKillKill; 337f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } else { 338f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Mute left channel */ 3391a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_TRUE); 3401a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten ExitOnError(result); 3411a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); 3421a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten ExitOnError(result); 343f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 344f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 345f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Run the test for 10s */ 346f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* see PlayEventCallback() for more of the test of the SLMuteSoloItf interface */ 347f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "\nTesting mute functionality:\n"); 34866f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten context.testMode = TEST_MUTE; 349f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); ExitOnError(result); 350f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi usleep( 5 * 1000 * 1000); 351f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_FALSE); ExitOnError(result); 352f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result); 353f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "\nTesting solo functionality:\n"); 35466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten context.testMode = TEST_SOLO; 355f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi usleep( 5 * 1000 * 1000); 356f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 357f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Make sure player is stopped */ 358f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Stopping playback\n"); 359f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 360f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 361f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 362f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel TrividestroyKillKill: 363f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 364f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Destroy the players */ 365f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi (*player)->Destroy(player); 366f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 367f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Destroy Output Mix object */ 368f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi (*outputMix)->Destroy(outputMix); 369f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi} 370f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 371f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//----------------------------------------------------------------- 372f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Triviint main(int argc, char* const argv[]) 373f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{ 374f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLresult result; 375f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLObjectItf sl; 376f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 377f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n", 378f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi argv[0]); 379f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 380f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n"); 381f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n"); 382f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Stops after 10s\n"); 383f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 384f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (argc == 1) { 385f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi fprintf(stdout, "Usage: \t%s url\n", argv[0]); 38615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]); 3874d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten exit(EXIT_FAILURE); 388f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 389f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 390f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi SLEngineOption EngineOption[] = { 391f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 392f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi }; 393f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 394f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 395f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 396f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 397f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 398f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 399f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi ExitOnError(result); 400f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 401f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi if (argc > 1) { 402f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi TestPlayUri(sl, argv[1]); 403f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi } 404f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 405f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi /* Shutdown OpenSL ES */ 406f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi (*sl)->Destroy(sl); 407f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi 4084d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten return EXIT_SUCCESS; 409f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi} 410