urimime.c revision 711332800108ad6e0e594796e5f8db0da3eff402
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> 23711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 24711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include "SLES/OpenSLES.h" 25711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 26711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#include "SLES/OpenSLES_Android.h" 27711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 28711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 29711332800108ad6e0e594796e5f8db0da3eff402Glenn Kastenint main(int argc, char **argv) 30711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten{ 31711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (argc != 2) { 32711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten fprintf(stderr, "usage: %s URI\n", argv[0]); 33711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten return EXIT_FAILURE; 34711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 35711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 36711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLresult result; 37711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf engineObject; 38711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 39711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create engine 40711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 41711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 42711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLEngineItf engineEngine; 43711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 44711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 45711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 46711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 47711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 48711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create output mix 49711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf outputMixObject; 50711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL); 51711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 52711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 53711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 54711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 55711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // configure audio source 56711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataLocator_URI loc_uri; 57711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_uri.locatorType = SL_DATALOCATOR_URI; 58711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_uri.URI = argv[1]; 59711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataFormat_MIME format_mime; 60711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.formatType = SL_DATAFORMAT_MIME; 61711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.mimeType = NULL; 62711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten format_mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 63711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataSource audioSrc; 64711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSrc.pLocator = &loc_uri; 65711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSrc.pFormat = &format_mime; 66711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 67711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // configure audio sink 68711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataLocator_OutputMix loc_outmix; 69711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 70711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten loc_outmix.outputMix = outputMixObject; 71711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLDataSink audioSnk; 72711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSnk.pLocator = &loc_outmix; 73711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten audioSnk.pFormat = NULL; 74711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 75711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create audio player, requesting a buffer queue interface 76711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLuint32 numInterfaces = 1; 77711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLInterfaceID ids[1]; 78711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLboolean req[1]; 79711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ids[0] = SL_IID_BUFFERQUEUE; 80711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten req[0] = SL_BOOLEAN_TRUE; 81711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLObjectItf playerObject; 82711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 83711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, numInterfaces, ids, req); 84711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 85711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerObject); 86711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 87711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten ids[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; 88711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 89711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, numInterfaces, ids, req); 90711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 91711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerObject); 92711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 93711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 94711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // create audio player, without requesting a buffer queue interface 95711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 96711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &audioSnk, 0, NULL, NULL); 97711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 98711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 99711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // realize the player 100711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 101711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 102711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 103711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the play interface 104711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLPlayItf playerPlay; 105711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 106711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 107711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 108711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the buffer queue interface 109711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLBufferQueueItf playerBufferQueue; 110711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &playerBufferQueue); 111711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 112711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerBufferQueue); 113711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#ifdef ANDROID 114711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLAndroidSimpleBufferQueueItf playerAndroidSimpleBufferQueue; 115711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerObject)->GetInterface(playerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 116711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten &playerAndroidSimpleBufferQueue); 117711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_FEATURE_UNSUPPORTED == result); 118711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(NULL == playerAndroidSimpleBufferQueue); 119711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten#endif 120711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 121711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the player duration 122711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLmillisecond duration; 123711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 124711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 125711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_TIME_UNKNOWN == duration) 126711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: unknown\n"); 127711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten else 128711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: %.1f\n", duration / 1000.0f); 129711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 130711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // set the player's state to playing 131711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 132711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 133711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 134711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // wait for the playback to finish 135711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten for (;;) { 136711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten SLuint32 playState; 137711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetPlayState(playerPlay, &playState); 138711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 139711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_PLAYSTATE_PLAYING != playState) { 140711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten break; 141711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 142711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten usleep(10000); 143711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten } 144711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 145711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // get the player duration 146711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten result = (*playerPlay)->GetDuration(playerPlay, &duration); 147711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten assert(SL_RESULT_SUCCESS == result); 148711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten if (SL_TIME_UNKNOWN == duration) 149711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: unknown\n"); 150711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten else 151711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten printf("Duration: %.1f\n", duration / 1000.0f); 152711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 153711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy audio player 154711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*playerObject)->Destroy(playerObject); 155711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 156711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy output mix 157711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*outputMixObject)->Destroy(outputMixObject); 158711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 159711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten // destroy engine 160711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten (*engineObject)->Destroy(engineObject); 161711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten 162711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten return EXIT_SUCCESS; 163711332800108ad6e0e594796e5f8db0da3eff402Glenn Kasten} 164