slesTestPlayStreamType.cpp revision ee21d26b4b66d0f19b826685b3070497523994d5
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_NDEBUG 0 18#define LOG_TAG "slesTest_playStreamType" 19 20#include <utils/Log.h> 21#include <getopt.h> 22#include <stdlib.h> 23#include <stdio.h> 24#include <string.h> 25#include <unistd.h> 26#include <sys/time.h> 27 28#include "SLES/OpenSLES.h" 29#include "SLES/OpenSLES_Android.h" 30 31 32#define MAX_NUMBER_INTERFACES 3 33#define MAX_NUMBER_OUTPUT_DEVICES 6 34 35#define TEST_MUTE 0 36#define TEST_SOLO 1 37 38static int testMode; 39//----------------------------------------------------------------- 40/* Exits the application if an error is encountered */ 41#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__) 42 43void ExitOnErrorFunc( SLresult result , int line) 44{ 45 if (SL_RESULT_SUCCESS != result) { 46 fprintf(stdout, "%lu error code encountered at line %d, exiting\n", result, line); 47 exit(1); 48 } 49} 50 51 52//----------------------------------------------------------------- 53 54/* Play an audio URIs, mute and solo channels */ 55void TestPlayUri( SLObjectItf sl, const char* path, const SLuint32 type) 56{ 57 SLresult result; 58 SLEngineItf EngineItf; 59 60 /* Objects this application uses: one player and an ouput mix */ 61 SLObjectItf player, outputMix; 62 63 /* Source of audio data to play */ 64 SLDataSource audioSource; 65 SLDataLocator_URI uri; 66 SLDataFormat_MIME mime; 67 68 /* Data sinks for the audio player */ 69 SLDataSink audioSink; 70 SLDataLocator_OutputMix locator_outputmix; 71 72 /* Play, Volume and AndroidStreamType interfaces for the audio player */ 73 SLPlayItf playItf; 74 SLPrefetchStatusItf prefetchItf; 75 SLAndroidStreamTypeItf streamTypeItf; 76 77 SLboolean required[MAX_NUMBER_INTERFACES]; 78 SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 79 80 /* Get the SL Engine Interface which is implicit */ 81 result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 82 ExitOnError(result); 83 84 /* Initialize arrays required[] and iidArray[] */ 85 for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 86 required[i] = SL_BOOLEAN_FALSE; 87 iidArray[i] = SL_IID_NULL; 88 } 89 90 /* ------------------------------------------------------ */ 91 /* Configuration of the output mix */ 92 93 /* Create Output Mix object to be used by the player */ 94 result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required); 95 ExitOnError(result); 96 97 /* Realize the Output Mix object in synchronous mode */ 98 result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 99 ExitOnError(result); 100 101 /* Setup the data sink structure */ 102 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 103 locator_outputmix.outputMix = outputMix; 104 audioSink.pLocator = (void*)&locator_outputmix; 105 audioSink.pFormat = NULL; 106 107 /* ------------------------------------------------------ */ 108 /* Configuration of the player */ 109 110 /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */ 111 /* (SLPlayItf is implicit) */ 112 required[0] = SL_BOOLEAN_TRUE; 113 iidArray[0] = SL_IID_PREFETCHSTATUS; 114 115 /* Setup the data source structure for the URI */ 116 uri.locatorType = SL_DATALOCATOR_URI; 117 uri.URI = (SLchar*) path; 118 mime.formatType = SL_DATAFORMAT_MIME; 119 /* this is how ignored mime information is specified, according to OpenSL ES spec 120 * in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */ 121 mime.mimeType = (SLchar*)NULL; 122 mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 123 124 audioSource.pFormat = (void*)&mime; 125 audioSource.pLocator = (void*)&uri; 126 127 /* Create the audio player */ 128 result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 1, 129 iidArray, required); 130 ExitOnError(result); 131 132 /* Realize the player in synchronous mode. */ 133 result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result); 134 fprintf(stdout, "URI example: after Realize\n"); 135 136 /* Get the SLPlayItf, SLPrefetchStatusItf and SLAndroidStreamTypeItf interfaces for the player*/ 137 result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 138 ExitOnError(result); 139 140 result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 141 ExitOnError(result); 142 143 result = (*player)->GetInterface(player, SL_IID_ANDROIDSTREAMTYPE, (void*)&streamTypeItf); 144 ExitOnError(result); 145 146 fprintf(stdout, "Player configured\n"); 147 148 /* ------------------------------------------------------ */ 149 /* Test setting the Android audio stream type on the player */ 150 151 result = (*streamTypeItf)->SetStreamType(streamTypeItf, type); 152 ExitOnError(result); 153 154 /* ------------------------------------------------------ */ 155 /* Playback and test */ 156 157 /* Start the data prefetching by setting the player to the paused state */ 158 result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 159 ExitOnError(result); 160 161 /* Wait until there's data to play */ 162 SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 163 while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) { 164 usleep(100 * 1000); 165 (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus); 166 ExitOnError(result); 167 } 168 169 /* Get duration */ 170 SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 171 result = (*playItf)->GetDuration(playItf, &durationInMsec); 172 ExitOnError(result); 173 if (durationInMsec == SL_TIME_UNKNOWN) { 174 durationInMsec = 5000; 175 } 176 177 /* Start playback */ 178 result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 179 ExitOnError(result); 180 181 usleep((durationInMsec/2) * 1000); 182 183 /* Get the stream type during playback */ 184 SLuint32 currentType = 0; 185 result = (*streamTypeItf)->GetStreamType(streamTypeItf, ¤tType); 186 ExitOnError(result); 187 if (currentType != type) { 188 fprintf(stderr, "ERROR: current stream type is %lu, should be %lu\n", currentType, type); 189 } 190 191 usleep((durationInMsec/2) * 1000); 192 193 /* Make sure player is stopped */ 194 fprintf(stdout, "Stopping playback\n"); 195 result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 196 ExitOnError(result); 197 198 /* Try again to get the stream type, just in case it changed behind our back */ 199 result = (*streamTypeItf)->GetStreamType(streamTypeItf, ¤tType); 200 ExitOnError(result); 201 if (currentType != type) { 202 fprintf(stderr, "ERROR: current stream type is %lu, should be %lu after stop.\n", 203 currentType, type); 204 } 205 206 /* Destroy the player */ 207 (*player)->Destroy(player); 208 209 /* Destroy Output Mix object */ 210 (*outputMix)->Destroy(outputMix); 211} 212 213//----------------------------------------------------------------- 214int main(int argc, char* const argv[]) 215{ 216 LOGV("Starting %s\n", argv[0]); 217 218 SLresult result; 219 SLObjectItf sl; 220 221 fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLAndroidStreamTypeItf\n", 222 argv[0]); 223 fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 224 fprintf(stdout, "Plays a sound on the specified android stream type\n"); 225 226 if (argc < 3) { 227 fprintf(stdout, "Usage: \t%s url stream_type\n", argv[0]); 228 fprintf(stdout, " where stream_type is one of the SL_ANDROID_STREAM_ constants.\n"); 229 fprintf(stdout, "Example: \"%s /sdcard/my.mp3 3\" \n", argv[0]); 230 exit(1); 231 } 232 233 SLEngineOption EngineOption[] = { 234 {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 235 }; 236 237 result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 238 ExitOnError(result); 239 240 /* Realizing the SL Engine in synchronous mode. */ 241 result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 242 ExitOnError(result); 243 244 TestPlayUri(sl, argv[1], (SLuint32)atoi(argv[2])); 245 246 /* Shutdown OpenSL ES */ 247 (*sl)->Destroy(sl); 248 exit(0); 249 250 return 0; 251} 252