slesTest_playMuteSolo.cpp revision 4b65ef9efdf5aba01bea89d8cdd64f500560a28d
185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/*
285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi *
485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * you may not use this file except in compliance with the License.
685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * You may obtain a copy of the License at
785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi *
885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi *
1085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * See the License for the specific language governing permissions and
1485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi * limitations under the License.
1585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi */
1685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
1785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define LOG_NDEBUG 0
1885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define LOG_TAG "slesTest_playMuteSolo"
1985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
208eabaa529bf4796543a54bccc6f87def95e0b326Glenn Kasten#ifdef ANDROID
2185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <utils/Log.h>
228eabaa529bf4796543a54bccc6f87def95e0b326Glenn Kasten#else
238eabaa529bf4796543a54bccc6f87def95e0b326Glenn Kasten#define LOGV printf
248eabaa529bf4796543a54bccc6f87def95e0b326Glenn Kasten#endif
258eabaa529bf4796543a54bccc6f87def95e0b326Glenn Kasten
2685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <getopt.h>
2785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <stdlib.h>
2885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <stdio.h>
2985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <string.h>
3085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <unistd.h>
3185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <sys/time.h>
3285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include "OpenSLES.h"
3485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3
3785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define MAX_NUMBER_OUTPUT_DEVICES 6
3885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_MUTE 0
4085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_SOLO 1
4185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
4285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivistatic int testMode;
4385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
4485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Exits the application if an error is encountered */
4585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
4685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
4785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
4885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
4985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
5085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "%lu error code encountered at line %d, exiting\n", result, line);
5185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        exit(1);
5285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
5385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
5485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
5585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
5685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* PlayItf callback for an audio player, will be called for every SL_PLAYEVENT_HEADATNEWPOS event */
5785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid PlayEventCallback( SLPlayItf caller,  void *pContext, SLuint32 event)
5885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
5985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLMuteSoloItf muteSolo = (SLMuteSoloItf)pContext;
6085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint8 numChannels = 0;
6185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult res = (*muteSolo)->GetNumChannels(muteSolo, &numChannels); ExitOnError(res);
6285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    //fprintf(stdout, "Content has %d channel(s)\n", numChannels);
6385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
6485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    switch (testMode) {
6585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_MUTE: {
6685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
6785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
6885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftMuted = SL_BOOLEAN_TRUE;
6985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelMute(muteSolo, 0, &leftMuted); ExitOnError(res);
7085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel mute
7185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 0,
7285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
7385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
7485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 1,
7585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
7685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
7785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftMuted == SL_BOOLEAN_TRUE) { // we've swapped the channel mute above
7885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: playing, channel 1: muted\n");
7985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
8085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: muted, channel 1: playing\n");
8185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
8285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
8385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
8485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
8585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_SOLO: {
8685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
8785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
8885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftSoloed = SL_BOOLEAN_TRUE;
8985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelSolo(muteSolo, 0, &leftSoloed); ExitOnError(res);
9085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel solo
9185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 0,
9285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
9385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
9485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 1,
9585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
9685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
9785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftSoloed == SL_BOOLEAN_TRUE) { // we've swapped the channel solo above
9885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: normal, channel 1: soloed\n");
9985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
10085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: soloed, channel 1: normal\n");
10185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
10285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
10385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
10485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
10585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        default:
10685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            break;
10785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
10885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
10985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
11185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Play an audio URIs, mute and solo channels  */
11385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path)
11485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
11585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult  result;
11685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineItf EngineItf;
11785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
11985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf  player, outputMix;
12085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Source of audio data to play */
12285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSource      audioSource;
12385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_URI uri;
12485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataFormat_MIME mime;
12585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Data sinks for the audio player */
12785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSink               audioSink;
12885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
12985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Play, Volume and PrefetchStatus interfaces for the audio player */
13185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPlayItf           playItf;
13285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLMuteSoloItf       muteSoloItf;
13385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPrefetchStatusItf prefetchItf;
13485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
13685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
13785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
13985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
14085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
14185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
14385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
14485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
14585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
14685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
14785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
14985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the output mix  */
15085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
15285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required);
15385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     ExitOnError(result);
15485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
15685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
15785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
15885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data sink structure */
16085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
16185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
16285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
16385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pFormat             = NULL;
16485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
16685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the player  */
16785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
16985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
17085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
17185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[0] = SL_IID_MUTESOLO;
17285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
17385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
17485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
17585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data source structure for the URI */
17685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
17785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
17885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
17985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
18085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
18185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
18285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
18385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
18485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
18585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pLocator = (void*)&uri;
18685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
18785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create the audio player */
1884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2,
18985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            iidArray, required);
19085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
19185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the player in synchronous mode. */
19385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
19485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
19585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
19785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
19885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
19985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
20185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
20485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  Setup to receive playback events on position updates */
20785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void*)muteSoloItf);
20885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATNEWPOS);
21085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
21185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPositionUpdatePeriod(playItf, 1000);
21285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
21385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
21485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
21585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
21685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
21785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Playback and test */
21885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
21985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Start the data prefetching by setting the player to the paused state */
22085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
22185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
22385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Wait until there's data to play */
22485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
22585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
22685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        usleep(100 * 1000);
22785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
22885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
22985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Query the number of channels */
23185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint8 numChannels = 0;
23285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
23385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
23485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Content has %d channel(s)\n", numChannels);
23585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (numChannels == 1) {
23785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "SLMuteSolotItf only works one content with more than one channel. Bye\n");
23885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        goto destroyKillKill;
23985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    } else {
24085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        /* Mute left channel */
24185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_TRUE); ExitOnError(result);
24285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
24385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
24485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
24585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Run the test for 10s */
24685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* see PlayEventCallback() for more of the test of the SLMuteSoloItf interface */
24785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting mute functionality:\n");
24885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    testMode = TEST_MUTE;
24985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); ExitOnError(result);
25085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
25185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_FALSE); ExitOnError(result);
25285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
25385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting solo functionality:\n");
25485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    testMode = TEST_SOLO;
25585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
25685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
25785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Make sure player is stopped */
25885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
25985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
26085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
26185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
26285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel TrividestroyKillKill:
26385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
26485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy the players */
26585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*player)->Destroy(player);
26685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
26785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy Output Mix object */
26885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
26985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
27085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
27285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Triviint main(int argc, char* const argv[])
27385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
27485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    LOGV("Starting %s\n", argv[0]);
27585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult    result;
27785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf sl;
27885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
28085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            argv[0]);
28185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
28285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
28385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
28485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stops after 10s\n");
28585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
28685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc == 1) {
28785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s url\n", argv[0]);
288e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
28985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        exit(1);
29085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
29185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineOption EngineOption[] = {
29385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
29485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    };
29585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
29785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
29885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
30085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
30185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
30285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc > 1) {
30485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        TestPlayUri(sl, argv[1]);
30585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
30685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Shutdown OpenSL ES */
30885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*sl)->Destroy(sl);
30985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    exit(0);
31085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    return 0;
31285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
313