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