1b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi/*
2b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi *
4b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * you may not use this file except in compliance with the License.
6b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * You may obtain a copy of the License at
7b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi *
8b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi *
10b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * See the License for the specific language governing permissions and
14b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi * limitations under the License.
15b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi */
16b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
17b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi#include <stdlib.h>
18b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi#include <stdio.h>
19b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi#include <unistd.h>
20b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
21c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h>
22b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
23b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
24b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3
25b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
26b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
27b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi//-----------------------------------------------------------------
28b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi/* Exits the application if an error is encountered */
29b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivivoid ExitOnError( SLresult result )
30b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi{
31b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
3258432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stdout, "%u error code encountered, exiting\n", result);
33c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
34b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
35b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi}
36b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
37b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi//-----------------------------------------------------------------
38b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi/* PlayItf callback for an audio player */
39086a6f51a7b12880ed114962136972f89ed70da2Glenn Kastenvoid PlayEventCallback( SLPlayItf caller __unused,  void *pContext __unused, SLuint32 event)
40b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi{
41b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "PlayEventCallback event = ");
42b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (event & SL_PLAYEVENT_HEADATEND) {
43b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADATEND ");
44b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
45b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (event & SL_PLAYEVENT_HEADATMARKER) {
46b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER ");
47b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
48b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (event & SL_PLAYEVENT_HEADATNEWPOS) {
49b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS ");
50b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
51b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (event & SL_PLAYEVENT_HEADMOVING) {
52b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADMOVING ");
53b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
54b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (event & SL_PLAYEVENT_HEADSTALLED) {
55b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADSTALLED");
56b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
57b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "\n");
58b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi}
59b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
60b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi//-----------------------------------------------------------------
61b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
62b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi/* Play two audio URIs, pan them left and right  */
63b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path, const char* path2)
64b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi{
65b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLresult  result;
66b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLEngineItf EngineItf;
67b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
68b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Objects this application uses: two players and an ouput mix */
69b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLObjectItf  player, player2, outputMix;
70b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
71b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Source of audio data to play, we'll reuse the same source for two different players */
72b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLDataSource      audioSource;
73b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLDataLocator_URI uri;
74b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLDataFormat_MIME mime;
75b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
76b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Data sinks for the two audio players */
77b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLDataSink               audioSink;
78b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
79b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
80b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Play, Volume and PrefetchStatus interfaces for the audio players */
81b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLPlayItf           playItf, playItf2;
82b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLVolumeItf         volItf, volItf2;
83b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLPrefetchStatusItf prefetchItf, prefetchItf2;
84b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
85b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
86b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
87b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
88b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
89b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
90b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
91b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
92b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
93b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
94b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
95b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
96b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
97b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLVolumeItf and SLPrefetchStatusItf interfaces */
98b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
99b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
100b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    iidArray[0] = SL_IID_VOLUME;
101b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
102b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
103b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
104b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* ------------------------------------------------------ */
105b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Configuration of the output mix  */
106b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
107b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Create Output Mix object to be used each player */
108c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required);
109b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi     ExitOnError(result);
110b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
111b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
112b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
113b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
114b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
115b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Setup the data sink structure */
116b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
117b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
118b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    audioSink.pLocator            = (void *)&locator_outputmix;
119b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    audioSink.pFormat             = NULL;
120b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
121b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* ------------------------------------------------------ */
122b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Configuration of the players  */
123b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
124b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Setup the data source structure for the first URI */
125b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
126b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
127b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    mime.formatType    = SL_DATAFORMAT_MIME;
128b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
129b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
130b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
131b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
132b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
133b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    audioSource.pFormat      = (void *)&mime;
134b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    audioSource.pLocator     = (void *)&uri;
135b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
136b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Create the first audio player */
1374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2,
138b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            iidArray, required);
139b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
140b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
141b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Create the second audio player with a different path for its data source */
142b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    uri.URI =  (SLchar*) path2;
143b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    audioSource.pLocator = (void *)&uri;
1444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player2, &audioSource, &audioSink, 2,
145b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            iidArray, required);
146b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
147b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
148b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Realize the players in synchronous mode. */
149b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
150b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->Realize(player2, SL_BOOLEAN_FALSE); ExitOnError(result);
151b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    //fprintf(stdout, "URI example: after Realize\n");
152b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
153b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Get the SLPlayItf, SLVolumeItf and SLPrefetchStatusItf interfaces for each player */
154b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
155b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
156b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->GetInterface(player2, SL_IID_PLAY, (void*)&playItf2);
157b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
158b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
159b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_VOLUME, (void*)&volItf);
160b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
161b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player2)->GetInterface(player2, SL_IID_VOLUME, (void*)&volItf2);
162b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
163b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
164b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
165b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
166b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*player2)->GetInterface(player2, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf2);
167b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
168b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
169b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /*  Setup to receive playback events */
170b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, &playItf);
171b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
172b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf,
173b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            SL_PLAYEVENT_HEADATEND| SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS
174b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            | SL_PLAYEVENT_HEADMOVING | SL_PLAYEVENT_HEADSTALLED);
175b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
176b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
177b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Set the player volume */
178b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*volItf)->SetVolumeLevel( volItf, -300);
179b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
180b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Pan the first player to the left */
181b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*volItf)->EnableStereoPosition( volItf, SL_BOOLEAN_TRUE); ExitOnError(result);
182b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*volItf)->SetStereoPosition( volItf, -1000); ExitOnError(result);
183b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Pan the second player to the right */
184b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*volItf2)->EnableStereoPosition( volItf2, SL_BOOLEAN_TRUE); ExitOnError(result);
185b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*volItf2)->SetStereoPosition( volItf2, 1000); ExitOnError(result);
186b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
187b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* ------------------------------------------------------ */
188b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Playback */
189b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
190b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Start the data prefetching by setting the players to the paused state */
191b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
192b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
193b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf2)->SetPlayState( playItf2, SL_PLAYSTATE_PAUSED );
194b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
195b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
196b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /*     wait until there's data to play */
197b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
198b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
199b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        usleep(100 * 1000);
200b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
201b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
202b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
203b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
204b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        usleep(100 * 1000);
205b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        (*prefetchItf2)->GetPrefetchStatus(prefetchItf2, &prefetchStatus);
206b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
207b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
208b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
209b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
210b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
211b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Wait 2s before starting the second player */
212b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    usleep(2000 * 1000);
213b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "URI example: starting to play %s\n", path2);
214b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf2)->SetPlayState( playItf2, SL_PLAYSTATE_PLAYING );
215b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
216b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
217b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Display duration */
218b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
219b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->GetDuration(playItf, &durationInMsec);
220b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
221b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
222b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "Content duration of first URI is unknown\n");
223b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    } else {
22458432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stdout, "Content duration of first URI is %u ms\n", durationInMsec);
225b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
226b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
227b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Wait as long as the duration of the first URI + 2s before stopping */
228b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
229b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        durationInMsec = 5000; /* arbitrary time when duration is unknown */
230b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
231b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    usleep((durationInMsec + 2000) * 1000);
232b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
233b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Make sure player is stopped */
234b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "URI example: stopping playback\n");
235b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
236b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
237b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*playItf2)->SetPlayState(playItf2, SL_PLAYSTATE_STOPPED);
238b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
239b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
240b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Destroy the players */
241b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    (*player)->Destroy(player);
242b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    (*player2)->Destroy(player2);
243b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
244b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Destroy Output Mix object */
245b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
246b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi}
247b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
248b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi//-----------------------------------------------------------------
249b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Triviint main(int argc, char* const argv[])
250b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi{
251b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLresult    result;
252b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLObjectItf sl;
253b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
254b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf (incl. stereo position) ",
255b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            argv[0]);
256b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
257b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "Plays two sounds (or twice the same) and pans them left and right.");
258b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    fprintf(stdout, "Stops after the end of the first + 2s\n");
259b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
260b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (argc == 1) {
261b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        fprintf(stdout, "Usage: \n\t%s url1 url2 \n\t%s url\n", argv[0], argv[0]);
2622a00e1105c1e051f13d2b5f3f69f02882de982eaGlenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3 http://blabla/my.wav\" ", argv[0]);
2632a00e1105c1e051f13d2b5f3f69f02882de982eaGlenn Kasten        fprintf(stdout, "or \"%s file:///sdcard/my.mp3\"\n", argv[0]);
264c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
265b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
266b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
267b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    SLEngineOption EngineOption[] = {
268b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
269b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    };
270b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
271b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
272b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
273b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
274b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
275b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
276b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    ExitOnError(result);
277b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
278b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    if (argc == 2) {
279b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        TestPlayUri(sl, argv[1], argv[1]);
280b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    } else if (argc == 3) {
281b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi        TestPlayUri(sl, argv[1], argv[2]);
282b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    }
283b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
284b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    /* Shutdown OpenSL ES */
285b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi    (*sl)->Destroy(sl);
286b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi
287c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten    return EXIT_SUCCESS;
288b0dc406de15e71fb53df0bd070b611317bea1d73Jean-Michel Trivi}
289