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