slesTest_playMuteSolo.cpp revision 8c065779232fdd89abace68d2fc7bea786a010d7
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
33ee21d26b4b66d0f19b826685b3070497523994d5Glenn Kasten#include "SLES/OpenSLES.h"
3485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3
3785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
3885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_MUTE 0
3985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define TEST_SOLO 1
4085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
418c065779232fdd89abace68d2fc7bea786a010d7Glenn Kastentypedef struct {
428c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    int testMode;
438c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLPlayItf playItf;
448c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLMuteSoloItf muteSoloItf;
458c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten} Context;
468c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten
4785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
4885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Exits the application if an error is encountered */
4985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
5085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
5185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
5285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
5385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
5485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "%lu error code encountered at line %d, exiting\n", result, line);
5585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        exit(1);
5685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
5785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
5885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
5985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
6085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* PlayItf callback for an audio player, will be called for every SL_PLAYEVENT_HEADATNEWPOS event */
6185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid PlayEventCallback( SLPlayItf caller,  void *pContext, SLuint32 event)
6285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
638c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    Context *context = (Context *) pContext;
648c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLPlayItf playItf = context->playItf;
658c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLMuteSoloItf muteSolo = context->muteSoloItf;
6685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint8 numChannels = 0;
6785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult res = (*muteSolo)->GetNumChannels(muteSolo, &numChannels); ExitOnError(res);
6885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    //fprintf(stdout, "Content has %d channel(s)\n", numChannels);
698c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    SLmillisecond position;
708c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    res = (*playItf)->GetPosition(playItf, &position); ExitOnError(res);
718c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    printf("position=%u\n", (unsigned) position);
7285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
738c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    switch (context->testMode) {
7485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_MUTE: {
7585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
7685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
7785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftMuted = SL_BOOLEAN_TRUE;
7885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelMute(muteSolo, 0, &leftMuted); ExitOnError(res);
7985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel mute
8085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 0,
8185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
8285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
8385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 1,
8485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
8585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
8685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftMuted == SL_BOOLEAN_TRUE) { // we've swapped the channel mute above
8785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: playing, channel 1: muted\n");
8885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
8985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: muted, channel 1: playing\n");
9085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
9185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
9285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
9385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
9485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        case TEST_SOLO: {
9585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            //---------------------------------------------------
9685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
9785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                SLboolean leftSoloed = SL_BOOLEAN_TRUE;
9885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->GetChannelSolo(muteSolo, 0, &leftSoloed); ExitOnError(res);
9985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                // swap channel solo
10085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 0,
10185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
10285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
10385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 1,
10485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
10585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                ExitOnError(res);
10685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                if (leftSoloed == SL_BOOLEAN_TRUE) { // we've swapped the channel solo above
10785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: normal, channel 1: soloed\n");
10885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                } else {
10985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                    fprintf(stdout, "channel 0: soloed, channel 1: normal\n");
11085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi                }
11185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            }
11285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            } break;
11385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        default:
11585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            break;
11685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
11785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
11885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
11985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
12085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi/* Play an audio URIs, mute and solo channels  */
12285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path)
12385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
12485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult  result;
12585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineItf EngineItf;
12685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
12785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
12885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf  player, outputMix;
12985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Source of audio data to play */
13185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSource      audioSource;
13285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_URI uri;
13385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataFormat_MIME mime;
13485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Data sinks for the audio player */
13685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataSink               audioSink;
13785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
13885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
13985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Play, Volume and PrefetchStatus interfaces for the audio player */
14085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPlayItf           playItf;
14185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLMuteSoloItf       muteSoloItf;
14285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLPrefetchStatusItf prefetchItf;
14385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
14585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
14685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
14785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
14885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
14985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
15085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
15285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
15385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
15485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
15585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
15685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
15785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
15885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the output mix  */
15985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
16185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required);
16285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     ExitOnError(result);
16385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
16585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
16685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
16785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
16885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data sink structure */
16985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
17085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
17185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
17285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSink.pFormat             = NULL;
17385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
17485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
17585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Configuration of the player  */
17685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
17785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
17885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
17985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
18085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[0] = SL_IID_MUTESOLO;
18185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
18285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
18385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
18485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Setup the data source structure for the URI */
18585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
18685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
18785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
18885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
18985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
19085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
19185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
19285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
19485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    audioSource.pLocator = (void*)&uri;
19585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
19685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Create the audio player */
1974b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2,
19885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            iidArray, required);
19985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realize the player in synchronous mode. */
20285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
20385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
20485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
20685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
20785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
20885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
20985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
21085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
21185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
21285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
21385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
21485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
2158c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    /* Initialize a context for use by the callback */
2168c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    Context             context;
2178c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.playItf = playItf;
2188c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.muteSoloItf = muteSoloItf;
2198c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_MUTE;
2208c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten
22185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /*  Setup to receive playback events on position updates */
2228c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void *) &context);
22385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATNEWPOS);
22585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPositionUpdatePeriod(playItf, 1000);
22785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
22885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
22985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
23085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* ------------------------------------------------------ */
23285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Playback and test */
23385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Start the data prefetching by setting the player to the paused state */
23585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
23685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
23785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
23885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Wait until there's data to play */
23985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
24085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
24185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        usleep(100 * 1000);
24285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
24385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
24485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
24585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Query the number of channels */
24685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLuint8 numChannels = 0;
24785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
24885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
24985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Content has %d channel(s)\n", numChannels);
25085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
25185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (numChannels == 1) {
25285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "SLMuteSolotItf only works one content with more than one channel. Bye\n");
25385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        goto destroyKillKill;
25485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    } else {
25585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        /* Mute left channel */
25685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_TRUE); ExitOnError(result);
25785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
25885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
25985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
26085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Run the test for 10s */
26185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* see PlayEventCallback() for more of the test of the SLMuteSoloItf interface */
26285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting mute functionality:\n");
2638c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_MUTE;
26485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); ExitOnError(result);
26585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
26685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_FALSE); ExitOnError(result);
26785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
26885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "\nTesting solo functionality:\n");
2698c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten    context.testMode = TEST_SOLO;
27085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
27185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Make sure player is stopped */
27385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
27485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
27585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
27685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel TrividestroyKillKill:
27885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
27985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy the players */
28085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*player)->Destroy(player);
28185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
28285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Destroy Output Mix object */
28385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
28485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
28585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
28685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi//-----------------------------------------------------------------
28785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Triviint main(int argc, char* const argv[])
28885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi{
28985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    LOGV("Starting %s\n", argv[0]);
29085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLresult    result;
29285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLObjectItf sl;
29385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
29485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
29585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            argv[0]);
29685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
29785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
29885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
29985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    fprintf(stdout, "Stops after 10s\n");
30085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc == 1) {
30285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s url\n", argv[0]);
303e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
30485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        exit(1);
30585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
30685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
30785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    SLEngineOption EngineOption[] = {
30885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
30985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    };
31085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
31285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
31385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
31585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
31685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    ExitOnError(result);
31785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
31885bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    if (argc > 1) {
31985bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi        TestPlayUri(sl, argv[1]);
32085bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    }
32185bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
32285bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    /* Shutdown OpenSL ES */
32385bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    (*sl)->Destroy(sl);
32485bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    exit(0);
32585bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi
32685bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi    return 0;
32785bae78453492b42c7095cafc404a049e52bbc22Jean-Michel Trivi}
328