1711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten/* 2711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * 4711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * you may not use this file except in compliance with the License. 6711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * You may obtain a copy of the License at 7711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * 8711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * 10711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * See the License for the specific language governing permissions and 14711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten * limitations under the License. 15711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten */ 16711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 17711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten// Test audio player configurations with URI data source and MIME data format 18711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 19711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <assert.h> 20711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <math.h> 21711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <stdio.h> 22711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include <stdlib.h> 23c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#include <unistd.h> 24711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 25c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 26711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 27c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES_Android.h> 28711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 29711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 30711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenint main(int argc, char **argv) 31711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{ 32711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (argc != 2) { 33711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten fprintf(stderr, "usage: %s URI\n", argv[0]); 34711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten return EXIT_FAILURE; 35711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 36711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 37711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLresult result; 38711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf engineObject; 39711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 40711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create engine 41711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 42711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 43711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLEngineItf engineEngine; 44711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 45711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 46711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 47711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 48711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 49711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create output mix 50711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf outputMixObject; 51711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL); 52711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 53711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 54711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 55711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 56711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // configure audio source 57711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataLocator_URI loc_uri; 58711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_uri.locatorType = SL_DATALOCATOR_URI; 59e629abc58c2acadc7487ea71c1e063f8f8989199Glenn Kasten loc_uri.URI = (SLchar *) argv[1]; 60711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataFormat_MIME format_mime; 61711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.formatType = SL_DATAFORMAT_MIME; 62711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.mimeType = NULL; 63711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 64711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataSource audioSrc; 65711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSrc.pLocator = &loc_uri; 66711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSrc.pFormat = &format_mime; 67711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 68711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // configure audio sink 69711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataLocator_OutputMix loc_outmix; 70711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 71711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_outmix.outputMix = outputMixObject; 72711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataSink audioSnk; 73711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSnk.pLocator = &loc_outmix; 74711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSnk.pFormat = NULL; 75711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 76711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create audio player, requesting a buffer queue interface 77711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLuint32 numInterfaces = 1; 78711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLInterfaceID ids[1]; 79711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLboolean req[1]; 80711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ids[0] = SL_IID_BUFFERQUEUE; 81711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten req[0] = SL_BOOLEAN_TRUE; 82711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf playerObject; 83711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 84711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, numInterfaces, ids, req); 85711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 86711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerObject); 87711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 88711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ids[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; 89711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 90711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, numInterfaces, ids, req); 91711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 92711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerObject); 93711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 94711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 95711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create audio player, without requesting a buffer queue interface 96711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 97711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, 0, NULL, NULL); 98711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 99711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 100711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // realize the player 101711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 102711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 103711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 104711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the play interface 105711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLPlayItf playerPlay; 106711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 107711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 108711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 109711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the buffer queue interface 110711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLBufferQueueItf playerBufferQueue; 111711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 112711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 113711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerBufferQueue); 114711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 115711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLAndroidSimpleBufferQueueItf playerAndroidSimpleBufferQueue; 116711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 117711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &playerAndroidSimpleBufferQueue); 118711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 119711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerAndroidSimpleBufferQueue); 120711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 121711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 122711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the player duration 123711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLmillisecond duration; 124711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 125711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 126711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_TIME_UNKNOWN == duration) 127711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: unknown\n"); 128711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten else 129711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: %.1f\n", duration / 1000.0f); 130711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 131711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // set the player's state to playing 132711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 133711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 134711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 135711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // wait for the playback to finish 136711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten for (;;) { 137711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLuint32 playState; 138711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetPlayState(playerPlay, &playState); 139711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 140711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_PLAYSTATE_PLAYING != playState) { 141711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten break; 142711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 143711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten usleep(10000); 144711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 145711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 146711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the player duration 147711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 148711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 149711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_TIME_UNKNOWN == duration) 150711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: unknown\n"); 151711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten else 152711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: %.1f\n", duration / 1000.0f); 153711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 154711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy audio player 155711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*playerObject)->Destroy(playerObject); 156711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 157711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy output mix 158711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*outputMixObject)->Destroy(outputMixObject); 159711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 160711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy engine 161711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*engineObject)->Destroy(engineObject); 162711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 163711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten return EXIT_SUCCESS; 164711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten} 165