19ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi/*
29ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
39ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
49ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
59ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * you may not use this file except in compliance with the License.
69ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * You may obtain a copy of the License at
79ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
89ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
99ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
109ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
119ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
129ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * See the License for the specific language governing permissions and
149ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * limitations under the License.
159ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi */
169ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
179ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi/*
189ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Copyright (c) 2009 The Khronos Group Inc.
199ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
209ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Permission is hereby granted, free of charge, to any person obtaining a copy of this
219ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * software and /or associated documentation files (the "Materials "), to deal in the
229ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * Materials without restriction, including without limitation the rights to use, copy,
239ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * modify, merge, publish, distribute, sublicense, and/or sell copies of the Materials,
249ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * and to permit persons to whom the Materials are furnished to do so, subject to
259ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * the following conditions:
269ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
279ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * The above copyright notice and this permission notice shall be included
289ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * in all copies or substantial portions of the Materials.
299ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi *
309ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
319ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
329ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
339ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
349ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
359ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
369ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE
379ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi * MATERIALS.
389ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi */
399ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
409ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi#include <stdlib.h>
419ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi#include <stdio.h>
424d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten//#include <string.h>
439ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi#include <unistd.h>
444d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten//#include <sys/time.h>
459ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
46a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h>
479ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
488ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi//#define TEST_VOLUME_ITF
498ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi//#define TEST_COLD_START
509ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
512b10d238deaa6df9789c8230fff2453df4a62277Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 2
529ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
531d55992cb3ea102899cb7799d428960358ad7214Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \
541d55992cb3ea102899cb7799d428960358ad7214Jean-Michel Trivi        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
551d55992cb3ea102899cb7799d428960358ad7214Jean-Michel Trivi
569ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi//-----------------------------------------------------------------
576da4dc84721fc3ee7fdf42cd87dc5953b69d9acdJean-Michel Trivi//* Exits the application if an error is encountered */
586da4dc84721fc3ee7fdf42cd87dc5953b69d9acdJean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__)
596da4dc84721fc3ee7fdf42cd87dc5953b69d9acdJean-Michel Trivi
606da4dc84721fc3ee7fdf42cd87dc5953b69d9acdJean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
619ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi{
626da4dc84721fc3ee7fdf42cd87dc5953b69d9acdJean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
63d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line);
644d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        exit(EXIT_FAILURE);
659ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    }
669ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi}
679ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
6867829bfddb97775be06af15dd8181611b4af581eGlenn Kastenbool prefetchError = false;
6967829bfddb97775be06af15dd8181611b4af581eGlenn Kasten
70060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi//-----------------------------------------------------------------
71060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi/* PrefetchStatusItf callback for an audio player */
72060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivivoid PrefetchEventCallback( SLPrefetchStatusItf caller,  void *pContext, SLuint32 event)
73060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi{
74060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    SLpermille level = 0;
7529938d3faad1af483dc040ad1a776ec03bc41f0dGlenn Kasten    SLresult result;
7629938d3faad1af483dc040ad1a776ec03bc41f0dGlenn Kasten    result = (*caller)->GetFillLevel(caller, &level);
7729938d3faad1af483dc040ad1a776ec03bc41f0dGlenn Kasten    CheckErr(result);
78060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    SLuint32 status;
79d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten    //fprintf(stdout, "PrefetchEventCallback: received event %u\n", event);
8029938d3faad1af483dc040ad1a776ec03bc41f0dGlenn Kasten    result = (*caller)->GetPrefetchStatus(caller, &status);
8129938d3faad1af483dc040ad1a776ec03bc41f0dGlenn Kasten    CheckErr(result);
821d55992cb3ea102899cb7799d428960358ad7214Jean-Michel Trivi    if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE))
83060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi            && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
844d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        fprintf(stdout, "PrefetchEventCallback: Error while prefetching data, exiting\n");
8567829bfddb97775be06af15dd8181611b4af581eGlenn Kasten        prefetchError = true;
86060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    }
87060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
884d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        fprintf(stdout, "PrefetchEventCallback: Buffer fill level is = %d\n", level);
895d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    }
905d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    if (event & SL_PREFETCHEVENT_STATUSCHANGE) {
91d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stdout, "PrefetchEventCallback: Prefetch Status is = %u\n", status);
92060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    }
938ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi}
948ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
958ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
968ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi//-----------------------------------------------------------------
978ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi/* PlayItf callback for playback events */
988ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivivoid PlayEventCallback(
998ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SLPlayItf caller,
1008ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        void *pContext,
1018ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SLuint32 event)
1028ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi{
1038ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATEND & event) {
1048ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        fprintf(stdout, "SL_PLAYEVENT_HEADATEND reached\n");
1058ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        //SignalEos();
1068ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
1078ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
1088ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATNEWPOS & event) {
1098ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SLmillisecond pMsec = 0;
1108ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        (*caller)->GetPosition(caller, &pMsec);
111d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS current position=%ums\n", pMsec);
1128ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
113060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
1148ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (SL_PLAYEVENT_HEADATMARKER & event) {
1158ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SLmillisecond pMsec = 0;
1168ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        (*caller)->GetPosition(caller, &pMsec);
117d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER current position=%ums\n", pMsec);
1188ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
119060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi}
120060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
1219ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1229ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi//-----------------------------------------------------------------
1239ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
124226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi/* Play some music from a URI  */
1259ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path)
1269ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi{
1279ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLEngineItf                EngineItf;
1289ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1299ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLint32                    numOutputs = 0;
1309ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLuint32                   deviceID = 0;
1319ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1329ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLresult                   res;
1339ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1349ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLDataSource               audioSource;
1359ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLDataLocator_URI          uri;
1369ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLDataFormat_MIME          mime;
1379ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1389ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLDataSink                 audioSink;
1399ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLDataLocator_OutputMix    locator_outputmix;
1409ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1419ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLObjectItf                player;
1429ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLPlayItf                  playItf;
1439ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLVolumeItf                volItf;
144060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    SLPrefetchStatusItf        prefetchItf;
1459ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1469ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLObjectItf                OutputMix;
1479ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1489ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
1499ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
1509ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1519ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
1529ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
1539ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
1549ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1559ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
156226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
157226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
158226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
159226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi    }
1609ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
161060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    // Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface
1629ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
1639ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    iidArray[0] = SL_IID_VOLUME;
164060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
165060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
1669ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    // Create Output Mix object to be used by player
1674d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten    res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0,
1689ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi            iidArray, required); CheckErr(res);
1699ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1709ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    // Realizing the Output Mix object in synchronous mode.
1719ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
1729ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
1739ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1749ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Setup the data source structure for the URI */
1759ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
1769ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    uri.URI         =  (SLchar*) path;
1779ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    mime.formatType    = SL_DATAFORMAT_MIME;
178f6f90fc5202248e2ae0abde6e655d7186cebc6afGlenn Kasten    mime.mimeType      = (SLchar*)NULL;
179f6f90fc5202248e2ae0abde6e655d7186cebc6afGlenn Kasten    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
1809ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1819ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    audioSource.pFormat      = (void *)&mime;
1829ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    audioSource.pLocator     = (void *)&uri;
1839ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1849ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Setup the data sink structure */
1859ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    locator_outputmix.locatorType   = SL_DATALOCATOR_OUTPUTMIX;
1869ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    locator_outputmix.outputMix    = OutputMix;
1879ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    audioSink.pLocator           = (void *)&locator_outputmix;
1889ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    audioSink.pFormat            = NULL;
1899ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1909ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Create the audio player */
1912b10d238deaa6df9789c8230fff2453df4a62277Jean-Michel Trivi    res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
1922b10d238deaa6df9789c8230fff2453df4a62277Jean-Michel Trivi            MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res);
1939ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
1949ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Realizing the player in synchronous mode. */
1959ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res);
1962b10d238deaa6df9789c8230fff2453df4a62277Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
1979ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
198060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    /* Get interfaces */
1999ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
2009ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
2019ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
202060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_VOLUME,  (void*)&volItf);
203060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    CheckErr(res);
204060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
205060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
206060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    CheckErr(res);
207060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, &prefetchItf);
2089ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
2095d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf,
2105d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi            SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
2112b10d238deaa6df9789c8230fff2453df4a62277Jean-Michel Trivi    CheckErr(res);
2125d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi
21390417a10fd988e37bc4e51b61c2fb8e70301345cJean-Michel Trivi    /* Configure fill level updates every 5 percent */
21490417a10fd988e37bc4e51b61c2fb8e70301345cJean-Michel Trivi    (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50);
2159ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
2168ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    /* Set up the player callback to get events during the decoding */
2178ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    res = (*playItf)->SetMarkerPosition(playItf, 2000);
2188ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CheckErr(res);
2198ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    res = (*playItf)->SetPositionUpdatePeriod(playItf, 500);
2208ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CheckErr(res);
2218ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    res = (*playItf)->SetCallbackEventsMask(playItf,
2228ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADATEND);
2238ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CheckErr(res);
2248ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, NULL);
2258ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CheckErr(res);
2268ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
2274953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    /* Display duration */
2284953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
2294953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    res = (*playItf)->GetDuration(playItf, &durationInMsec);
2304953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    CheckErr(res);
2314953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
232060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi        fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n");
2334953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    } else {
234d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n",
235060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi                durationInMsec);
2364953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    }
2374953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi
2389ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Set the player volume */
2399ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*volItf)->SetVolumeLevel( volItf, -300);
2409ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
2419ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
2429ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Play the URI */
243060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    /*     first cause the player to prefetch the data */
2444d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten    fprintf(stdout, "Before set to PAUSED\n");
245060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
2464d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten    fprintf(stdout, "After set to PAUSED\n");
247060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    CheckErr(res);
248060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
2498ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(100 * 1000);
250060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    /*     wait until there's data to play */
251060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    //SLpermille fillLevel = 0;
252060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
2535d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    SLuint32 timeOutIndex = 100; // 10s
25467829bfddb97775be06af15dd8181611b4af581eGlenn Kasten    while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0) &&
25567829bfddb97775be06af15dd8181611b4af581eGlenn Kasten            !prefetchError) {
256060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi        usleep(100 * 1000);
257060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
2585d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi        timeOutIndex--;
2595d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    }
2605d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi
26167829bfddb97775be06af15dd8181611b4af581eGlenn Kasten    if (timeOutIndex == 0 || prefetchError) {
2624d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        fprintf(stderr, "We\'re done waiting, failed to prefetch data in time, exiting\n");
2635d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi        goto destroyRes;
264060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    }
265060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
266060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    /* Display duration again, */
267060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    res = (*playItf)->GetDuration(playItf, &durationInMsec);
268060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    CheckErr(res);
269060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
270060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi        fprintf(stdout, "Content duration is unknown (after prefetch completed)\n");
271060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    } else {
272d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec);
273060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi    }
274060adae7c9af5b1470ca12f44d8f36a27987efcbJean-Michel Trivi
2759ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    fprintf(stdout, "URI example: starting to play\n");
2769ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
2779ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
2789ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
2798ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#ifdef TEST_VOLUME_ITF
2808ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(5*1000 * 1000);
2818ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    fprintf(stdout, "setting vol to 0\n");
2828ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    (*volItf)->SetVolumeLevel( volItf, 0);
2838ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(3*1000 * 1000);
2848ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    fprintf(stdout, "setting vol to -20dB\n");
2858ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    (*volItf)->SetVolumeLevel( volItf, -2000);
2868ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(3*1000 * 1000);
2878ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    fprintf(stdout, "mute\n");
2888ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    (*volItf)->SetMute( volItf, SL_BOOLEAN_TRUE);
2898ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(3*1000 * 1000);
2908ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    fprintf(stdout, "setting vol to 0dB while muted\n");
2918ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    (*volItf)->SetVolumeLevel( volItf, 0);
2928ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(3*1000 * 1000);
2938ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    fprintf(stdout, "unmuting\n");
2948ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    (*volItf)->SetMute( volItf, SL_BOOLEAN_FALSE);
2958ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep(3*1000 * 1000);
2968ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#endif
2978ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
2988ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#ifndef TEST_COLD_START
2994953c969d04ebe01add892ea63199375434994d0Jean-Michel Trivi    usleep(durationInMsec * 1000);
3008ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#else
3018ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    /* Wait as long as the duration of the content before stopping */
3028ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    /* Experiment: wait for the duration + 200ms: with a cold start of the audio hardware, we */
3038ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    /*    won't see the SL_PLAYEVENT_HEADATEND event, due to hw wake up induced latency, but  */
3048ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    /*    with a warm start it will be received.                                              */
3058ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    usleep((durationInMsec + 200) * 1000);
3068ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#endif
3079ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3089ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Make sure player is stopped */
3099ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    fprintf(stdout, "URI example: stopping playback\n");
3109ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
3119ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
3129ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3135d9e8432d0217fe139987703b8e1f129296171ffJean-Michel TrividestroyRes:
3145d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi
3159ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Destroy the player */
3169ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    (*player)->Destroy(player);
3179ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3189ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Destroy Output Mix object */
3199ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    (*OutputMix)->Destroy(OutputMix);
3209ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi}
3219ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3229ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi//-----------------------------------------------------------------
3239ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Triviint main(int argc, char* const argv[])
3249ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi{
3259ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLresult    res;
3269ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLObjectItf sl;
3279ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
328226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf ", argv[0]);
329226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
3305d9e8432d0217fe139987703b8e1f129296171ffJean-Michel Trivi    fprintf(stdout, "Plays a sound and stops after its reported duration\n\n");
331226ce6a635c4a333a66b8e0ea28316a6d405ee33Jean-Michel Trivi
3329ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    if (argc == 1) {
3334d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        fprintf(stdout, "Usage: %s path \n\t%s url\n", argv[0], argv[0]);
3341a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"  or \"%s file:///sdcard/my.mp3\"\n",
3351a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten                argv[0], argv[0]);
3364d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten        exit(EXIT_FAILURE);
3379ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    }
3389ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3399ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    SLEngineOption EngineOption[] = {
3409ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE,
3419ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi            (SLuint32) SL_BOOLEAN_TRUE}};
3429ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3439ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
3449ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
3459ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
3469ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
3479ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    CheckErr(res);
3489ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3499ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    TestPlayUri(sl, argv[1]);
3509ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3519ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    /* Shutdown OpenSL ES */
3529ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi    (*sl)->Destroy(sl);
3539ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi
3544d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten    return EXIT_SUCCESS;
3559ecb3dfd2397fa1970409f4af1eb5ca1c685ef3bJean-Michel Trivi}
356