slesTest_playMuteSolo.cpp revision c2303eb5497c488db786dcb2b8514db229452536
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#include <stdlib.h>
1885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <stdio.h>
1985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <string.h>
2085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <unistd.h>
2185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#include <sys/time.h>
2285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23ee21d26b4b66d0f19b826685b3070497523994d5Glenn Kasten#include "SLES/OpenSLES.h"
2485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
2585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
2685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3
2785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
2885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_MUTE 0
2985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_SOLO 1
3085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
318c065779232fdd89abace68d2fc7bea786a010d7Glenn Kastentypedef struct {
328c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    int testMode;
338c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLPlayItf playItf;
348c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLMuteSoloItf muteSoloItf;
358c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten} Context;
368c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten
3785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
3885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Exits the application if an error is encountered */
3985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
4085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
4185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
4285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
4385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
4485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "%lu error code encountered at line %d, exiting\n", result, line);
45c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
4685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
4785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
4885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
4985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
5085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* PlayItf callback for an audio player, will be called for every SL_PLAYEVENT_HEADATNEWPOS event */
5185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid PlayEventCallback( SLPlayItf caller,  void *pContext, SLuint32 event)
5285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
538c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    Context *context = (Context *) pContext;
548c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLPlayItf playItf = context->playItf;
558c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLMuteSoloItf muteSolo = context->muteSoloItf;
5685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint8 numChannels = 0;
5785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult res = (*muteSolo)->GetNumChannels(muteSolo, &numChannels); ExitOnError(res);
5885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    //fprintf(stdout, "Content has %d channel(s)\n", numChannels);
598c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLmillisecond position;
608c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    res = (*playItf)->GetPosition(playItf, &position); ExitOnError(res);
618c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    printf("position=%u\n", (unsigned) position);
6285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
638c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    switch (context->testMode) {
6485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_MUTE: {
6585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
6685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
6785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftMuted = SL_BOOLEAN_TRUE;
6885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelMute(muteSolo, 0, &leftMuted); ExitOnError(res);
6985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel mute
7085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 0,
7185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
7285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
7385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 1,
7485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
7585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
7685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftMuted == SL_BOOLEAN_TRUE) { // we've swapped the channel mute above
7785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: playing, channel 1: muted\n");
7885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
7985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: muted, channel 1: playing\n");
8085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
8185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
8285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
8385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
8485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_SOLO: {
8585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
8685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
8785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftSoloed = SL_BOOLEAN_TRUE;
8885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelSolo(muteSolo, 0, &leftSoloed); ExitOnError(res);
8985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel solo
9085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 0,
9185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
9285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
9385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 1,
9485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
9585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
9685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftSoloed == SL_BOOLEAN_TRUE) { // we've swapped the channel solo above
9785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: normal, channel 1: soloed\n");
9885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
9985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: soloed, channel 1: normal\n");
10085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
10185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
10285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
10385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
10485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        default:
10585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            break;
10685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
10785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
10885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
10985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
11085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Play an audio URIs, mute and solo channels  */
11285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path)
11385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
11485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult  result;
11585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineItf EngineItf;
11685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
11885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf  player, outputMix;
11985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Source of audio data to play */
12185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSource      audioSource;
12285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_URI uri;
12385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataFormat_MIME mime;
12485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Data sinks for the audio player */
12685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSink               audioSink;
12785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
12885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Play, Volume and PrefetchStatus interfaces for the audio player */
13085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPlayItf           playItf;
13185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLMuteSoloItf       muteSoloItf;
13285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPrefetchStatusItf prefetchItf;
13385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
13585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
13685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
13885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
13985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
14085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
14285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
14385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
14485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
14585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
14685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
14885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the output mix  */
14985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
151c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required);
15285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     ExitOnError(result);
15385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
15585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
15685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
15785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data sink structure */
15985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
16085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
16185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
16285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pFormat             = NULL;
16385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
16585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the player  */
16685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
16885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
16985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
17085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[0] = SL_IID_MUTESOLO;
17185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
17285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
17385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
17485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data source structure for the URI */
17585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
17685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
17785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
17885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
17985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
18085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
18185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
18285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
18385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
18485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pLocator = (void*)&uri;
18585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
18685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create the audio player */
1874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2,
18885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            iidArray, required);
18985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
19085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the player in synchronous mode. */
19285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
19385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
19485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
19685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
19785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
19885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
20085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
20385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
205f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    // Attempt to get the channel count before it is necessarily known.
206f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    // This may fail depending on the platform.
207f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    SLuint8 numChannels = 123;
208f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
209f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    printf("GetNumChannels after Realize but before pre-fetch: result=%lu, numChannels=%u\n",
210f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten        result, numChannels);
211f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten
2128c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    /* Initialize a context for use by the callback */
2138c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    Context             context;
2148c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.playItf = playItf;
2158c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.muteSoloItf = muteSoloItf;
2168c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_MUTE;
2178c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten
21885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  Setup to receive playback events on position updates */
2198c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void *) &context);
22085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATNEWPOS);
22285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPositionUpdatePeriod(playItf, 1000);
22485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
22685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
22785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
22885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
22985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Playback and test */
23085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Start the data prefetching by setting the player to the paused state */
23285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
23385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
23485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Wait until there's data to play */
23685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
23785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
23885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        usleep(100 * 1000);
23985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
24085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
24185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
24285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Query the number of channels */
243f6f5ceb363286d5ebef2c2e70c8a5aa135d5d1eeGlenn Kasten    numChannels = 123;
24485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
24585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
24685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Content has %d channel(s)\n", numChannels);
24785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
24885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (numChannels == 1) {
24985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "SLMuteSolotItf only works one content with more than one channel. Bye\n");
25085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        goto destroyKillKill;
25185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    } else {
25285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        /* Mute left channel */
25301e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_TRUE);
25401e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        ExitOnError(result);
25501e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE);
25601e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        ExitOnError(result);
25785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
25885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
25985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Run the test for 10s */
26085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* see PlayEventCallback() for more of the test of the SLMuteSoloItf interface */
26185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting mute functionality:\n");
2628c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_MUTE;
26385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); ExitOnError(result);
26485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
26585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_FALSE); ExitOnError(result);
26685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
26785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting solo functionality:\n");
2688c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_SOLO;
26985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
27085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Make sure player is stopped */
27285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
27385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
27485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
27585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel TrividestroyKillKill:
27785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy the players */
27985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*player)->Destroy(player);
28085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
28185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy Output Mix object */
28285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
28385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
28485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
28585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
28685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Triviint main(int argc, char* const argv[])
28785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
28885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult    result;
28985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf sl;
29085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
29285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            argv[0]);
29385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
29485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
29585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
29685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stops after 10s\n");
29785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc == 1) {
29985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s url\n", argv[0]);
300e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
301c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
30285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
30385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineOption EngineOption[] = {
30585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
30685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    };
30785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
30985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
31085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
31285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
31385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
31485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc > 1) {
31685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        TestPlayUri(sl, argv[1]);
31785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
31885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Shutdown OpenSL ES */
32085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*sl)->Destroy(sl);
32185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
322c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten    return EXIT_SUCCESS;
32385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
324