105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi/*
205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi *
405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * you may not use this file except in compliance with the License.
605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * You may obtain a copy of the License at
705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi *
805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi *
1005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * See the License for the specific language governing permissions and
1405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi * limitations under the License.
1505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi */
1605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
1705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#include <stdlib.h>
1805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#include <stdio.h>
1905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#include <string.h>
2005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#include <unistd.h>
2105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#include <sys/time.h>
2205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
23c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h>
2491bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#ifdef ANDROID
25c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES_Android.h>
2691bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif
2705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
2805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
29453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi#define MAX_NUMBER_INTERFACES 2
3005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
3105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
3205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------
3305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi/* Exits the application if an error is encountered */
3405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
3505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
3605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
3705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi{
3805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
3958432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stdout, "%u error code encountered at line %d, exiting\n", result, line);
40c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
4105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
4205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
4305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
4405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
4505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------
4605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
47453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi/* Play an audio URIs on the given stream type  */
48453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivivoid TestStreamTypeConfiguration( SLObjectItf sl, const char* path, const SLint32 type)
4905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi{
5005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLresult  result;
5105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLEngineItf EngineItf;
5205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
5305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
5405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLObjectItf  player, outputMix;
5505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
5605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Source of audio data to play */
5705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLDataSource      audioSource;
5805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLDataLocator_URI uri;
5905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLDataFormat_MIME mime;
6005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
6105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Data sinks for the audio player */
6205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLDataSink               audioSink;
6305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
6405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
6505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Play, Volume and AndroidStreamType interfaces for the audio player */
6605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLPlayItf              playItf;
6705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLPrefetchStatusItf    prefetchItf;
6891bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#ifdef ANDROID
69453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    SLAndroidConfigurationItf configItf;
7091bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif
7105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
7205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
7305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
7405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
7505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
7605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
7705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
7805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
7905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
8005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
8105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
8205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
8305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
8405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
8505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* ------------------------------------------------------ */
8605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Configuration of the output mix  */
8705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
8805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
89c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required);
9005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi     ExitOnError(result);
9105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
9205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
9305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
9405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
9505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
9605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Setup the data sink structure */
9705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
9805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
9905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
10005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    audioSink.pFormat             = NULL;
10105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
10205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* ------------------------------------------------------ */
10305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Configuration of the player  */
10405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
105453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLAndroidConfigurationItf interfaces */
10605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
10705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
10805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    iidArray[0] = SL_IID_PREFETCHSTATUS;
1097126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#ifdef ANDROID
110453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
111453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    iidArray[1] = SL_IID_ANDROIDCONFIGURATION;
1127126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#endif
113453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi
11405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
11505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Setup the data source structure for the URI */
11605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
11705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
11805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
11905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
12005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
12105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
12205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
12305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
12405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
12505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    audioSource.pLocator = (void*)&uri;
12605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
12705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Create the audio player */
128453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
129453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi            MAX_NUMBER_INTERFACES, iidArray, required);
130453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    ExitOnError(result);
131453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi
132453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    /* Retrieve the configuration interface before the player is realized so its resources
133453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi     * can be configured.
134453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi     */
135453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi#ifdef ANDROID
136453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf);
137453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    ExitOnError(result);
138453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi
139453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    /* Set the Android audio stream type on the player */
140453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*configItf)->SetConfiguration(configItf,
141453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi            SL_ANDROID_KEY_STREAM_TYPE, &type, sizeof(SLint32));
142363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten    if (SL_RESULT_PARAMETER_INVALID == result) {
14358432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stderr, "invalid stream type %d\n", type);
144363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten    } else {
145363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten        ExitOnError(result);
146363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten    }
147453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi#endif
14805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
14905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Realize the player in synchronous mode. */
15005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
15105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
15205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
15301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    /* Get the SLPlayItf, SLPrefetchStatusItf and SLAndroidConfigurationItf interfaces for player */
15405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
15505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
15605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
15705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
15805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
15905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
16005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
16105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
16205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* ------------------------------------------------------ */
16305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Playback and test */
16405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
16505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Start the data prefetching by setting the player to the paused state */
16605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
16705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
16805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
16905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Wait until there's data to play */
17005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
17105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
17205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        usleep(100 * 1000);
17305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
17405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        ExitOnError(result);
17505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
17605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
17705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Get duration */
17805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
17905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*playItf)->GetDuration(playItf, &durationInMsec);
18005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
18105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
18205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        durationInMsec = 5000;
18305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
18405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
18505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Start playback */
18605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
18705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
18805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
189b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    usleep((durationInMsec/2) * 1000);
190b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi
19191bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#ifdef ANDROID
192b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    /* Get the stream type during playback  */
193453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    SLint32 currentType = -1;
194453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    SLuint32 valueSize = sizeof(SLint32) * 2; // trying too big on purpose
195453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*configItf)->GetConfiguration(configItf,
196453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi            SL_ANDROID_KEY_STREAM_TYPE, &valueSize, NULL);
197453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    ExitOnError(result);
198453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    if (valueSize != sizeof(SLint32)) {
19901f8573bc2a850536b02855d483dfe130c050a2fAshok Bhat        fprintf(stderr, "ERROR: size for stream type is %u, should be %zu\n",
200453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi                valueSize, sizeof(SLint32));
201453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    }
202453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*configItf)->GetConfiguration(configItf,
203453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi                SL_ANDROID_KEY_STREAM_TYPE, &valueSize, &currentType);
204b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    ExitOnError(result);
205b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    if (currentType != type) {
20658432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stderr, "ERROR: stream type is %u, should be %u\n", currentType, type);
207b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    }
20891bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif
209b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi
210b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    usleep((durationInMsec/2) * 1000);
21105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
21205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Make sure player is stopped */
21305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
21405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
21505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
21605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
21791bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#ifdef ANDROID
218b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    /* Try again to get the stream type, just in case it changed behind our back */
219453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    result = (*configItf)->GetConfiguration(configItf,
220453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi            SL_ANDROID_KEY_STREAM_TYPE, &valueSize, &currentType);
221b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    ExitOnError(result);
222b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    if (currentType != type) {
22358432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stderr, "ERROR: stream type is %u, should be %u\n", currentType, type);
224b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi    }
22591bfd060b992810ca092f640f77f795bc3d008beGlenn Kasten#endif
226b98e6b7b1cc2a130a29904e52ae7a71e15332a49Jean-Michel Trivi
22705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Destroy the player */
22805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    (*player)->Destroy(player);
22905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
23005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Destroy Output Mix object */
23105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
23205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
23305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
23405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------
23505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Triviint main(int argc, char* const argv[])
23605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi{
23705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLresult    result;
23805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLObjectItf sl;
23905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
240453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLAndroidConfigurationItf\n",
24105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi            argv[0]);
24205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
24305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    fprintf(stdout, "Plays a sound on the specified android stream type\n");
24405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
24505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    if (argc < 3) {
24605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s url stream_type\n", argv[0]);
24705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi        fprintf(stdout, " where stream_type is one of the SL_ANDROID_STREAM_ constants.\n");
248363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3 5\" \n", argv[0]);
24958432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stdout, "Stream type %d is the default (media or music), %d is notifications\n",
250363ce43ae920463fd93896cfe16190253e770ee2Glenn Kasten            SL_ANDROID_STREAM_MEDIA, SL_ANDROID_STREAM_NOTIFICATION);
251c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        return EXIT_FAILURE;
25205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    }
25305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
25405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    SLEngineOption EngineOption[] = {
25505ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
25605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    };
25705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
25805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
25905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
26005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
26105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
26205ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
26305ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    ExitOnError(result);
26405ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
265453dd564a81fe98b7a947ae4a9844a53fa957c2bJean-Michel Trivi    TestStreamTypeConfiguration(sl, argv[1], (SLint32)atoi(argv[2]));
26605ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
26705ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    /* Shutdown OpenSL ES */
26805ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi    (*sl)->Destroy(sl);
26905ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi
270c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten    return EXIT_SUCCESS;
27105ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi}
272