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