slesTestPlayStream.cpp revision ad887a253969ac2017a1dbe062d0b76d505594c0
1fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi/*
2fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
4fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * you may not use this file except in compliance with the License.
6fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * You may obtain a copy of the License at
7fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
8fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
10fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * See the License for the specific language governing permissions and
14fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * limitations under the License.
15fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi */
16fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
17fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
18fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <stdlib.h>
19fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <stdio.h>
20fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//#include <string.h>
21fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <unistd.h>
22fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//#include <sys/time.h>
23fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
24fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include "SLES/OpenSLES.h"
25fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include "SLES/OpenSLES_Android.h"
26fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
27fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
28fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 2
29fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
30fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \
31fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
32fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
33fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//-----------------------------------------------------------------
34fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//* Exits the application if an error is encountered */
35fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__)
36fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
37fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
38fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
39fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
40fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stderr, "%lu error code encountered at line %d, exiting\n", result, line);
41fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        exit(EXIT_FAILURE);
42fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
43fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
44fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
45fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivibool prefetchError = false;
46fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
47ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi
48fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//-----------------------------------------------------------------
49ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi/* AndroidStreamSourceItf callback for an audio player */
50ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel TriviSLresult AndroidStreamSourceCallback(
51ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        SLAndroidStreamSourceItf caller,/* input */
52ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        void *pContext,                 /* input */
53ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        SLAint64 offset,                /* input */
54ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        SLAint64* pLength,              /* input, output */
55ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        SLAstreamEvent* pEvent,         /* output */
56ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        void *pData)                    /* output */
57fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
58ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    *pLength = 0; // not returning any data
59ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    *pEvent = SL_ANDROID_STREAMEVENT_NO_ERROR;
60ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    //leaving pData untouched
61ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    return SL_RESULT_SUCCESS;
62fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
63fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
64fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
65fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//-----------------------------------------------------------------
66fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
67fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi/* Play some music from a URI  */
68fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivivoid TestPlayStream( SLObjectItf sl, const char* path)
69fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
70fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLEngineItf                EngineItf;
71fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
72fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLint32                    numOutputs = 0;
73fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLuint32                   deviceID = 0;
74fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
75fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLresult                   res;
76fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
77fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLDataSource               audioSource;
78ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    SLDataLocator_AndroidStreamer streamLocator;
79fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLDataFormat_MIME          mime;
80fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
81fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLDataSink                 audioSink;
82fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLDataLocator_OutputMix    locator_outputmix;
83fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
84fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLObjectItf                player;
85fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLPlayItf                  playItf;
86fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLVolumeItf                volItf;
87ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    SLAndroidStreamSourceItf   streamSrcItf;
88fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
89fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLObjectItf                OutputMix;
90fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
91fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
92fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
93fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
94fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
95fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
96fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
97fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
98fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
99fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
100fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
101fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
102fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
103fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
104fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    // Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface
105fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
106fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    iidArray[0] = SL_IID_VOLUME;
107fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
108ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    iidArray[1] = SL_IID_ANDROIDSTREAMSOURCE;
109fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    // Create Output Mix object to be used by player
110fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0,
111fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            iidArray, required); CheckErr(res);
112fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
113fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    // Realizing the Output Mix object in synchronous mode.
114fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
115fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
116fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
117fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Setup the data source structure for the URI */
118ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    streamLocator.locatorType  = SL_DATALOCATOR_ANDROIDSTREAMER;
119ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    streamLocator.URI          =  (SLchar*) path;
120ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    streamLocator.streamOrigin = SL_ANDROID_STREAMORIGIN_FILE;
121fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    mime.formatType    = SL_DATAFORMAT_MIME;
122fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
123fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
124fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
125fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    audioSource.pFormat      = (void *)&mime;
126ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    audioSource.pLocator     = (void *)&streamLocator;
127fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
128fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Setup the data sink structure */
129fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    locator_outputmix.locatorType   = SL_DATALOCATOR_OUTPUTMIX;
130fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    locator_outputmix.outputMix    = OutputMix;
131fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    audioSink.pLocator           = (void *)&locator_outputmix;
132fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    audioSink.pFormat            = NULL;
133fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
134fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Create the audio player */
135fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
136fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res);
137fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
138fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Realizing the player in synchronous mode. */
139fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res);
140fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
141fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
142fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Get interfaces */
143ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); CheckErr(res);
144fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
145ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_VOLUME,  (void*)&volItf); CheckErr(res);
146fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
147ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_ANDROIDSTREAMSOURCE, (void*)&streamSrcItf);
148fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
149ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi    res = (*streamSrcItf)->RegisterCallback(streamSrcItf, AndroidStreamSourceCallback,
150ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi            &streamSrcItf); CheckErr(res);
151fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
152fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Display duration */
153fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
154fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*playItf)->GetDuration(playItf, &durationInMsec);
155fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
156fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
157fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n");
158fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    } else {
159fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Content duration is %lu ms (before starting to prefetch)\n",
160fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi                durationInMsec);
161fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
162fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
163fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Set the player volume */
164fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*volItf)->SetVolumeLevel( volItf, -300);
165fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
166fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
167fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Play the URI */
168fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /*     first cause the player to prefetch the data */
169fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "Before set to PAUSED\n");
170fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
171fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "After set to PAUSED\n");
172fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
173fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
174fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /*     wait until there's data to play */
175fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //SLpermille fillLevel = 0;
176fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
177fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLuint32 timeOutIndex = 2;
178fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0) &&
179fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            !prefetchError) {
180fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        usleep(1 * 1000 * 1000); // 1s
181ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi        //(*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
182fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        timeOutIndex--;
183fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
184fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
185fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    if (timeOutIndex == 0 || prefetchError) {
186fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stderr, "We\'re done waiting, failed to prefetch data in time, exiting\n");
187fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        goto destroyRes;
188fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
189fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
190fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Display duration again, */
191fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*playItf)->GetDuration(playItf, &durationInMsec);
192fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
193fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
194fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Content duration is unknown (after prefetch completed)\n");
195fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    } else {
196fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Content duration is %lu ms (after prefetch completed)\n", durationInMsec);
197fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
198fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
199fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "URI example: starting to play\n");
200fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
201fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
202fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
203fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Wait as long as the duration of the content before stopping */
204fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    usleep(durationInMsec * 1000);
205fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
206fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Make sure player is stopped */
207fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "URI example: stopping playback\n");
208fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
209fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
210fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
211fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel TrividestroyRes:
212fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
213fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Destroy the player */
214fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    (*player)->Destroy(player);
215fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
216fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Destroy Output Mix object */
217fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    (*OutputMix)->Destroy(OutputMix);
218fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
219fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
220fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//-----------------------------------------------------------------
221fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Triviint main(int argc, char* const argv[])
222fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
223fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLresult    res;
224fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLObjectItf sl;
225fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
226fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLAndroidStreamSource ",
227fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            argv[0]);
228fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SL_DATALOCATOR_ANDROIDSTREAMER source / OutputMix sink\n");
229fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    fprintf(stdout, "Plays a sound and stops after its reported duration\n\n");
230fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
231fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    if (argc == 1) {
232fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Usage: %s path \n\t%s url\n", argv[0], argv[0]);
233fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"  or \"%s file:///sdcard/my.mp3\"\n",
234fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi                argv[0], argv[0]);
235fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        exit(EXIT_FAILURE);
236fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    }
237fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
238fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    SLEngineOption EngineOption[] = {
239fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE,
240fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi            (SLuint32) SL_BOOLEAN_TRUE}};
241fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
242fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
243fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
244fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
245fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
246fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    CheckErr(res);
247fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
248fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    TestPlayStream(sl, argv[1]);
249fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
250fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    /* Shutdown OpenSL ES */
251fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    (*sl)->Destroy(sl);
252fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
253fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    return EXIT_SUCCESS;
254fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
255