1ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/*
2ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
3ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi *
4ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * you may not use this file except in compliance with the License.
6ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * You may obtain a copy of the License at
7ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi *
8ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi *
10ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * See the License for the specific language governing permissions and
14ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * limitations under the License.
15ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi */
16ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
17ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Audio Decode Test
18ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
19ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel TriviFirst run the program from shell:
20ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  # slesTest_decodeToBuffQueue /sdcard/myFile.mp3 4
21ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
22ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel TriviThese use adb on host to retrieve the decoded file:
23ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  % adb pull /sdcard/myFile.mp3.raw myFile.raw
24ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
25ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel TriviHow to examine the output with Audacity:
26ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi Project / Import raw data
27ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi Select myFile.raw file, then click Open button
28ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi Choose these options:
29ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  Signed 16-bit PCM
30ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  Little-endian
31ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  1 Channel (Mono) / 2 Channels (Stereo) based on the selected file
32ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi  Sample rate same as the selected file
33ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi Click Import button
34ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
35ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi*/
36ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
37ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
38ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <stdlib.h>
39ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <stdio.h>
40ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <string.h>
41ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <unistd.h>
42ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <sys/time.h>
43ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <fcntl.h>
44ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <utils/threads.h>
45ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
46ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <SLES/OpenSLES.h>
47ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#include <SLES/OpenSLES_Android.h>
4854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
49ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Explicitly requesting SL_IID_ANDROIDSIMPLEBUFFERQUEUE and SL_IID_PREFETCHSTATUS
507f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi * on the AudioPlayer object for decoding, SL_IID_METADATAEXTRACTION for retrieving the
517f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi * format of the decoded audio */
527f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi#define NUM_EXPLICIT_INTERFACES_FOR_PLAYER 3
53ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
54ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Size of the decode buffer queue */
55ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#define NB_BUFFERS_IN_QUEUE 4
56ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Size of each buffer in the queue */
57ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#define BUFFER_SIZE_IN_SAMPLES 1152 // number of samples per MP3 frame
58ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#define BUFFER_SIZE_IN_BYTES   (2*BUFFER_SIZE_IN_SAMPLES)
59ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
60ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Local storage for decoded audio data */
61ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Triviint8_t pcmData[NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES];
62ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
63ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* destination for decoded data */
64ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivistatic FILE* gFp;
65ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
66ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* to display the number of decode iterations */
67ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivistatic int counter=0;
68ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
6954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi/* metadata key index for the PCM format information we want to retrieve */
7054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivistatic int channelCountKeyIndex = -1;
7154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivistatic int sampleRateKeyIndex = -1;
7254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi/* size of the struct to retrieve the PCM format metadata values: the values we're interested in
7354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi * are SLuint32, but it is saved in the data field of a SLMetadataInfo, hence the larger size.
7454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi * Nate that this size is queried and displayed at l.452 for demonstration/test purposes.
7554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi *  */
7654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi#define PCM_METADATA_VALUE_SIZE 32
7754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi/* used to query metadata values */
7854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivistatic SLMetadataInfo *pcmMetaData = NULL;
7954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi/* we only want to query / display the PCM format once */
8054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivistatic bool formatQueried = false;
8154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
82ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* to signal to the test app the end of the stream to decode has been reached */
83ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivibool eos = false;
84ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Triviandroid::Mutex eosLock;
85ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Triviandroid::Condition eosCondition;
86ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
87ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* used to detect errors likely to have occured when the OpenSL ES framework fails to open
88ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond.
89ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi */
90ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \
91ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
92ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
93ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
94ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Exits the application if an error is encountered */
95ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
96ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
97ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
98ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
99ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
100d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        fprintf(stderr, "Error code %u encountered at line %d, exiting\n", result, line);
101ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        exit(EXIT_FAILURE);
102ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
103ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
104ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
1057f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi/* Used to signal prefetching failures */
1067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivibool prefetchError = false;
1077f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
108ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
109ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Structure for passing information to callback function */
110ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivitypedef struct CallbackCntxt_ {
111ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLPlayItf playItf;
11254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    SLMetadataExtractionItf metaItf;
113ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLuint32  size;
114ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLint8*   pDataBase;    // Base address of local audio data storage
115ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLint8*   pData;        // Current address of local audio data storage
116ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi} CallbackCntxt;
117ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
118ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
119ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivivoid SignalEos() {
120ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    android::Mutex::Autolock autoLock(eosLock);
121ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    eos = true;
122ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    eosCondition.signal();
123ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
124ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
125ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
126ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Callback for "prefetch" events, here used to detect audio resource opening errors */
127ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivivoid PrefetchEventCallback( SLPrefetchStatusItf caller,  void *pContext, SLuint32 event)
128ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
129ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLpermille level = 0;
130d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    SLresult result;
131d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    result = (*caller)->GetFillLevel(caller, &level);
132d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    ExitOnError(result);
133ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLuint32 status;
13458432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten    //fprintf(stdout, "PrefetchEventCallback: received event %u\n", event);
135d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    result = (*caller)->GetPrefetchStatus(caller, &status);
136d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    ExitOnError(result);
137ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE))
138ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
139ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        fprintf(stdout, "PrefetchEventCallback: Error while prefetching data, exiting\n");
1407f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        prefetchError = true;
141ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SignalEos();
142ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
143ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
144ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
145ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Callback for "playback" events, i.e. event happening during decoding */
1465050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivivoid DecProgressCallback(
147ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SLPlayItf caller,
148ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        void *pContext,
149ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SLuint32 event)
150ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
151d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    SLresult result;
152d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    SLmillisecond msec;
153d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    result = (*caller)->GetPosition(caller, &msec);
154d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    ExitOnError(result);
155d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten
156ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATEND & event) {
157d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        fprintf(stdout, "SL_PLAYEVENT_HEADATEND current position=%u ms\n", msec);
158ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SignalEos();
159ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
160ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
161ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATNEWPOS & event) {
162d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS current position=%u ms\n", msec);
163ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
164ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
165ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATMARKER & event) {
166d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER current position=%u ms\n", msec);
167ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
168ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
169ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
170ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
171ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Callback for decoding buffer queue events */
1725050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivivoid DecPlayCallback(
173ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SLAndroidSimpleBufferQueueItf queueItf,
174ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        void *pContext)
175ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
176ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    counter++;
177ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
178ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    CallbackCntxt *pCntxt = (CallbackCntxt*)pContext;
179ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
180d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    if (counter % 1000 == 0) {
181d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        SLmillisecond msec;
182d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        SLresult result = (*pCntxt->playItf)->GetPosition(pCntxt->playItf, &msec);
183d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        ExitOnError(result);
184d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        printf("DecPlayCallback called (iteration %d): current position=%u ms\n", counter, msec);
185d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten    }
186d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten
187ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Save the decoded data  */
1881fd0cd18598d76e9a0f9e6675e4d988be41644f7Jean-Michel Trivi    if (fwrite(pCntxt->pDataBase, 1, BUFFER_SIZE_IN_BYTES, gFp) < BUFFER_SIZE_IN_BYTES) {
189ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        fprintf(stdout, "Error writing to output file, signaling EOS\n");
190ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        SignalEos();
191ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        return;
192ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
193ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
194ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Increase data pointer by buffer size */
195ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pCntxt->pData += BUFFER_SIZE_IN_BYTES;
196ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
197ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (pCntxt->pData >= pCntxt->pDataBase + (NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES)) {
198ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        pCntxt->pData = pCntxt->pDataBase;
199ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
200ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
201ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError( (*queueItf)->Enqueue(queueItf, pCntxt->pDataBase, BUFFER_SIZE_IN_BYTES) );
202ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    // Note: adding a sleep here or any sync point is a way to slow down the decoding, or
203ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    //  synchronize it with some other event, as the OpenSL ES framework will block until the
204ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    //  buffer queue callback return to proceed with the decoding.
205ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
2067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi#if 0
20754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    /* Example: buffer queue state display */
208ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLAndroidSimpleBufferQueueState decQueueState;
209ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError( (*queueItf)->GetState(queueItf, &decQueueState) );
210ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
211ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stderr, "\DecBufferQueueCallback now has pCntxt->pData=%p queue: "
21258432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten            "count=%u playIndex=%u\n",
213ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            pCntxt->pData, decQueueState.count, decQueueState.index);
2147f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi#endif
2157f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
2167f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi#if 0
21754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    /* Example: display duration in callback where we use the callback context for the SLPlayItf*/
2187f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
2197f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult result = (*pCntxt->playItf)->GetDuration(pCntxt->playItf, &durationInMsec);
2207f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    ExitOnError(result);
2217f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
2227f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        fprintf(stdout, "Content duration is unknown (in dec callback)\n");
2237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    } else {
2247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        fprintf(stdout, "Content duration is %ums (in dec callback)\n",
2257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                durationInMsec);
2267f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
2277f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi#endif
22854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
2295050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi#if 0
2305050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    /* Example: display position in callback where we use the callback context for the SLPlayItf*/
2315050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    SLmillisecond posMsec = SL_TIME_UNKNOWN;
2325050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    SLresult result = (*pCntxt->playItf)->GetPosition(pCntxt->playItf, &posMsec);
2335050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    ExitOnError(result);
2345050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    if (posMsec == SL_TIME_UNKNOWN) {
2355050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi        fprintf(stdout, "Content position is unknown (in dec callback)\n");
2365050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    } else {
2375050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi        fprintf(stdout, "Content position is %ums (in dec callback)\n",
2385050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi                posMsec);
2395050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    }
2405050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi#endif
2415050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi
24254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    /* Example: query of the decoded PCM format */
24354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    if (formatQueried) {
24454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        return;
24554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
24654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    SLresult res = (*pCntxt->metaItf)->GetValue(pCntxt->metaItf, sampleRateKeyIndex,
24754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi            PCM_METADATA_VALUE_SIZE, pcmMetaData);  ExitOnError(res);
24854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    // Note: here we could verify the following:
24954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    //         pcmMetaData->encoding == SL_CHARACTERENCODING_BINARY
25054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    //         pcmMetaData->size == sizeof(SLuint32)
25154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    //       but the call was successful for the PCM format keys, so those conditions are implied
25254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    fprintf(stdout, "sample rate = %dHz, ", *((SLuint32*)pcmMetaData->data));
25354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    res = (*pCntxt->metaItf)->GetValue(pCntxt->metaItf, channelCountKeyIndex,
25454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi            PCM_METADATA_VALUE_SIZE, pcmMetaData);  ExitOnError(res);
25554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    fprintf(stdout, " channel count = %d\n", *((SLuint32*)pcmMetaData->data));
25654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    formatQueried = true;
257ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
258ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
259ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
260ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
261ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi/* Decode an audio path by opening a file descriptor on that path  */
262ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivivoid TestDecToBuffQueue( SLObjectItf sl, const char* path)
263ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
264ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    size_t len = strlen((const char *) path);
265ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    char* outputPath = (char*) malloc(len + 4 + 1); // save room to concatenate ".raw"
266ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (NULL == outputPath) {
267ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        ExitOnError(SL_RESULT_RESOURCE_ERROR);
268ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
269ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    memcpy(outputPath, path, len + 1);
270ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    strcat(outputPath, ".raw");
271ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    gFp = fopen(outputPath, "w");
272ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (NULL == gFp) {
273ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        ExitOnError(SL_RESULT_RESOURCE_ERROR);
274ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
275ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
276ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLresult  result;
277ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLEngineItf EngineItf;
278ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
279ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Objects this application uses: one audio player */
280ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLObjectItf  player;
281ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
282ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Interfaces for the audio player */
283ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLAndroidSimpleBufferQueueItf decBuffQueueItf;
284ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLPrefetchStatusItf           prefetchItf;
285ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLPlayItf                     playItf;
2867f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLMetadataExtractionItf       mdExtrItf;
287ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
288ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Source of audio data for the decoding */
289ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataSource      decSource;
290ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataLocator_URI decUri;
291ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataFormat_MIME decMime;
292ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
293ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Data sink for decoded audio */
294ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataSink                decDest;
295ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataLocator_AndroidSimpleBufferQueue decBuffQueue;
296ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLDataFormat_PCM          pcm;
297ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
298ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLboolean required[NUM_EXPLICIT_INTERFACES_FOR_PLAYER];
299ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLInterfaceID iidArray[NUM_EXPLICIT_INTERFACES_FOR_PLAYER];
300ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
301ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
302ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
303ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
304ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
305ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
306ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    for (int i=0 ; i < NUM_EXPLICIT_INTERFACES_FOR_PLAYER ; i++) {
307ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
308ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
309ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
310ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
31154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    /* allocate memory to receive the PCM format metadata */
31254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    if (!pcmMetaData) {
31354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        pcmMetaData = (SLMetadataInfo*) malloc(PCM_METADATA_VALUE_SIZE);
31454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
31554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
31654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    formatQueried = false;
317ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
318ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* ------------------------------------------------------ */
319ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Configuration of the player  */
320ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
321ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Request the AndroidSimpleBufferQueue interface */
322ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
323ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    iidArray[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
324ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Request the PrefetchStatus interface */
325ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
326ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
3277f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* Request the PrefetchStatus interface */
3287f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    required[2] = SL_BOOLEAN_TRUE;
3297f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    iidArray[2] = SL_IID_METADATAEXTRACTION;
330ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
331ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Setup the data source */
332ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decUri.locatorType = SL_DATALOCATOR_URI;
333ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decUri.URI = (SLchar*)path;
334ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decMime.formatType = SL_DATAFORMAT_MIME;
335ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
336ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
337ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decMime.mimeType      = (SLchar*)NULL;
338ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decMime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
339ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decSource.pLocator = (void *) &decUri;
340ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decSource.pFormat  = (void *) &decMime;
341ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
342ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Setup the data sink */
343ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
344ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE;
345ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /*    set up the format of the data in the buffer queue */
346ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.formatType = SL_DATAFORMAT_PCM;
347ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    // FIXME valid value required but currently ignored
348ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.numChannels = 1;
3497f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    pcm.samplesPerSec = SL_SAMPLINGRATE_8;
350ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
351ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.containerSize = 16;
352ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
353ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
354ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
355ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decDest.pLocator = (void *) &decBuffQueue;
356ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    decDest.pFormat = (void * ) &pcm;
357ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
358ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Create the audio player */
359ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &decSource, &decDest,
360ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            NUM_EXPLICIT_INTERFACES_FOR_PLAYER, iidArray, required);
361ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
362ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "Player created\n");
363ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
364ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Realize the player in synchronous mode. */
365ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE);
366ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
367ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "Player realized\n");
368ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
369ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Get the play interface which is implicit */
370ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
371ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
372ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
373ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Set up the player callback to get events during the decoding */
374ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    // FIXME currently ignored
375ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*playItf)->SetMarkerPosition(playItf, 2000);
376ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
377ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*playItf)->SetPositionUpdatePeriod(playItf, 500);
378ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
379ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf,
380ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADATEND);
381ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
3825050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    result = (*playItf)->RegisterCallback(playItf, DecProgressCallback, NULL);
383ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
384ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "Play callback registered\n");
385ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
386ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Get the buffer queue interface which was explicitly requested */
387ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
388ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            (void*)&decBuffQueueItf);
389ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
390ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
391ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Get the prefetch status interface which was explicitly requested */
392ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
393ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
394ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
39554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    /* Get the metadata extraction interface which was explicitly requested */
39654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_METADATAEXTRACTION, (void*)&mdExtrItf);
39754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    ExitOnError(result);
39854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
399ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* ------------------------------------------------------ */
400ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Initialize the callback and its context for the decoding buffer queue */
401ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    CallbackCntxt cntxt;
402ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    cntxt.playItf = playItf;
40354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    cntxt.metaItf = mdExtrItf;
404ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    cntxt.pDataBase = (int8_t*)&pcmData;
405ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    cntxt.pData = cntxt.pDataBase;
406ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    cntxt.size = sizeof(pcmData);
4075050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    result = (*decBuffQueueItf)->RegisterCallback(decBuffQueueItf, DecPlayCallback, &cntxt);
408ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
409ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
410ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Enqueue buffers to map the region of memory allocated to store the decoded data */
411ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout,"Enqueueing buffer ");
412ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    for(int i = 0 ; i < NB_BUFFERS_IN_QUEUE ; i++) {
413d6cdd7f7efdce16fc321f11bf5a3f88b3f28e244Glenn Kasten        fprintf(stdout,"%d ", i);
414ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        result = (*decBuffQueueItf)->Enqueue(decBuffQueueItf, cntxt.pData, BUFFER_SIZE_IN_BYTES);
415ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        ExitOnError(result);
416ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        cntxt.pData += BUFFER_SIZE_IN_BYTES;
417ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
418ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout,"\n");
419ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    cntxt.pData = cntxt.pDataBase;
420ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
421ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* ------------------------------------------------------ */
422ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Initialize the callback for prefetch errors, if we can't open the resource to decode */
423ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, &prefetchItf);
424ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
425ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, PREFETCHEVENT_ERROR_CANDIDATE);
426ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
427ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
428ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* ------------------------------------------------------ */
4297f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* Prefetch the data so we can get information about the format before starting to decode */
4307f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /*     1/ cause the player to prefetch the data */
4317f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
4327f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    ExitOnError(result);
4337f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /*     2/ block until data has been prefetched */
4347f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
4357f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLuint32 timeOutIndex = 50; // time out prefetching after 5s
4367f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0) &&
4377f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            !prefetchError) {
4387f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        usleep(10 * 1000);
4397f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
4407f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        timeOutIndex--;
4417f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
4427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (timeOutIndex == 0 || prefetchError) {
4437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        fprintf(stderr, "Failure to prefetch data in time, exiting\n");
4447f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        ExitOnError(SL_RESULT_CONTENT_NOT_FOUND);
4457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
4467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
4477f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* ------------------------------------------------------ */
4487f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* Display duration */
4497f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
4507f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    result = (*playItf)->GetDuration(playItf, &durationInMsec);
4517f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    ExitOnError(result);
4527f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
4537f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        fprintf(stdout, "Content duration is unknown\n");
4547f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    } else {
4557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        fprintf(stdout, "Content duration is %ums\n", durationInMsec);
4567f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
4577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
4587f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* ------------------------------------------------------ */
4597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* Display the metadata obtained from the decoder */
4607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    //   This is for test / demonstration purposes only where we discover the key and value sizes
4617f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    //   of a PCM decoder. An application that would want to directly get access to those values
4627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    //   can make assumptions about the size of the keys and their matching values (all SLuint32)
4637f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLuint32 itemCount;
4647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    result = (*mdExtrItf)->GetItemCount(mdExtrItf, &itemCount);
4657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLuint32 i, keySize, valueSize;
4667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLMetadataInfo *keyInfo, *value;
4677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    for(i=0 ; i<itemCount ; i++) {
4687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        keyInfo = NULL; keySize = 0;
4697f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        value = NULL;   valueSize = 0;
4707f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        result = (*mdExtrItf)->GetKeySize(mdExtrItf, i, &keySize);
4717f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        ExitOnError(result);
4727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        result = (*mdExtrItf)->GetValueSize(mdExtrItf, i, &valueSize);
4737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        ExitOnError(result);
4747f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        keyInfo = (SLMetadataInfo*) malloc(keySize);
47554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        if (NULL != keyInfo) {
4767f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            result = (*mdExtrItf)->GetKey(mdExtrItf, i, keySize, keyInfo);
4777f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            ExitOnError(result);
47854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi            fprintf(stdout, "key[%d] size=%d, name=%s \tvalue size=%d \n",
47954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi                    i, keyInfo->size, keyInfo->data, valueSize);
48054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi            /* find out the key index of the metadata we're interested in */
48154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi            if (!strcmp((char*)keyInfo->data, ANDROID_KEY_PCMFORMAT_NUMCHANNELS)) {
48254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi                channelCountKeyIndex = i;
4830f92f48017588949daf7d24a339423e149bb2555Glenn Kasten            } else if (!strcmp((char*)keyInfo->data, ANDROID_KEY_PCMFORMAT_SAMPLERATE)) {
48454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi                sampleRateKeyIndex = i;
4857f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
4867f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            free(keyInfo);
4877f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
4887f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
48954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    if (channelCountKeyIndex != -1) {
49054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        fprintf(stdout, "Key %s is at index %d\n",
49154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi                ANDROID_KEY_PCMFORMAT_NUMCHANNELS, channelCountKeyIndex);
49254cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    } else {
49354cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        fprintf(stderr, "Unable to find key %s\n", ANDROID_KEY_PCMFORMAT_NUMCHANNELS);
49454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
49554cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    if (sampleRateKeyIndex != -1) {
49654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi        fprintf(stdout, "Key %s is at index %d\n",
4970f92f48017588949daf7d24a339423e149bb2555Glenn Kasten                ANDROID_KEY_PCMFORMAT_SAMPLERATE, sampleRateKeyIndex);
49854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    } else {
4990f92f48017588949daf7d24a339423e149bb2555Glenn Kasten        fprintf(stderr, "Unable to find key %s\n", ANDROID_KEY_PCMFORMAT_SAMPLERATE);
50054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
5017f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
5027f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    /* ------------------------------------------------------ */
503ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Start decoding */
504ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
505ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
506ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "Starting to decode\n");
507ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
508ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Decode until the end of the stream is reached */
509ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    {
510ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        android::Mutex::Autolock autoLock(eosLock);
511ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        while (!eos) {
512ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            eosCondition.wait(eosLock);
513ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        }
514ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
515ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "EOS signaled\n");
516ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
517ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* ------------------------------------------------------ */
518ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* End of decoding */
519ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
520ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Stop decoding */
521ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
522ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
523ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "Stopped decoding\n");
524ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
525ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Destroy the AudioPlayer object */
526ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    (*player)->Destroy(player);
527ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
528ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fclose(gFp);
52954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
53054cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    free(pcmMetaData);
53154cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    pcmMetaData = NULL;
532ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
533ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
534ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi//-----------------------------------------------------------------
535ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Triviint main(int argc, char* const argv[])
536ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi{
537ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLresult    result;
538ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLObjectItf sl;
539ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
540ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf and SLAndroidSimpleBufferQueueItf ",
541ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            argv[0]);
542ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    fprintf(stdout, "on an AudioPlayer object to decode a URI to PCM\n");
543ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
544ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    if (argc != 2) {
545ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s source_file\n", argv[0]);
546ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        fprintf(stdout, "Example: \"%s /sdcard/myFile.mp3\n", argv[0]);
547ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi        exit(EXIT_FAILURE);
548ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    }
549ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
550ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    SLEngineOption EngineOption[] = {
551ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
552ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    };
553ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
554ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
555ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
556ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
557ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
558ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
559ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    ExitOnError(result);
560ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
561ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    TestDecToBuffQueue(sl, argv[1]);
562ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
563ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    /* Shutdown OpenSL ES */
564ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    (*sl)->Destroy(sl);
565ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi
566ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi    return EXIT_SUCCESS;
567ebd4303bd8fb9f1c6a61ff66332248a43b781df5Jean-Michel Trivi}
568