slesTest_playMuteSolo.cpp revision ec3a5a5555af3ed612b70dc54ef96998a9256b9a
1f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/*
2f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi *
4f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * you may not use this file except in compliance with the License.
6f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * You may obtain a copy of the License at
7f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi *
8f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi *
10f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * See the License for the specific language governing permissions and
14f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi * limitations under the License.
15f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi */
16f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
17f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define LOG_NDEBUG 0
18f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define LOG_TAG "slesTest_playMuteSolo"
19f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
20d1490dce2ac1aaef4dc0a87847205f8af688802aGlenn Kasten#ifdef ANDROID
21f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <utils/Log.h>
22d1490dce2ac1aaef4dc0a87847205f8af688802aGlenn Kasten#else
23d1490dce2ac1aaef4dc0a87847205f8af688802aGlenn Kasten#define LOGV printf
24d1490dce2ac1aaef4dc0a87847205f8af688802aGlenn Kasten#endif
25d1490dce2ac1aaef4dc0a87847205f8af688802aGlenn Kasten
26f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <getopt.h>
27f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <stdlib.h>
28f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <stdio.h>
29f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <string.h>
30f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <unistd.h>
31f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#include <sys/time.h>
32f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
332dc537a086811c9a97e1f925ace16be7d0b0fcb4Glenn Kasten#include "SLES/OpenSLES.h"
34f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
35f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
36f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 3
37f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
38f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define TEST_MUTE 0
39f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define TEST_SOLO 1
40f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
4166f75c45c9aea410b1f913d76995661e72571b67Glenn Kastentypedef struct {
4266f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    int testMode;
4366f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLPlayItf playItf;
4466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLMuteSoloItf muteSoloItf;
4566f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten} Context;
4666f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten
47f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//-----------------------------------------------------------------
48f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* Exits the application if an error is encountered */
49f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
50f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
51f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
52f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{
53f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
54f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        fprintf(stdout, "%lu error code encountered at line %d, exiting\n", result, line);
55f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        exit(1);
56f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
57f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi}
58f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
59f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//-----------------------------------------------------------------
60f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* PlayItf callback for an audio player, will be called for every SL_PLAYEVENT_HEADATNEWPOS event */
61f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid PlayEventCallback( SLPlayItf caller,  void *pContext, SLuint32 event)
62f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{
6366f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    Context *context = (Context *) pContext;
6466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLPlayItf playItf = context->playItf;
6566f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLMuteSoloItf muteSolo = context->muteSoloItf;
66f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLuint8 numChannels = 0;
67f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLresult res = (*muteSolo)->GetNumChannels(muteSolo, &numChannels); ExitOnError(res);
68f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    //fprintf(stdout, "Content has %d channel(s)\n", numChannels);
6966f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLmillisecond position;
7066f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    res = (*playItf)->GetPosition(playItf, &position); ExitOnError(res);
7166f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    printf("position=%u\n", (unsigned) position);
72f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
7366f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    switch (context->testMode) {
74f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        case TEST_MUTE: {
75f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            //---------------------------------------------------
76f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
77f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                SLboolean leftMuted = SL_BOOLEAN_TRUE;
78f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->GetChannelMute(muteSolo, 0, &leftMuted); ExitOnError(res);
79f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                // swap channel mute
80f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 0,
81f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
82f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                ExitOnError(res);
83f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->SetChannelMute(muteSolo, 1,
84f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                       leftMuted == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
85f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                ExitOnError(res);
86f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                if (leftMuted == SL_BOOLEAN_TRUE) { // we've swapped the channel mute above
87f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                    fprintf(stdout, "channel 0: playing, channel 1: muted\n");
88f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                } else {
89f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                    fprintf(stdout, "channel 0: muted, channel 1: playing\n");
90f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                }
91f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            }
92f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            } break;
93f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
94f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        case TEST_SOLO: {
95f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            //---------------------------------------------------
96f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            if (numChannels > 1) { // SLMuteSoloItf only works if more than one channel
97f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                SLboolean leftSoloed = SL_BOOLEAN_TRUE;
98f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->GetChannelSolo(muteSolo, 0, &leftSoloed); ExitOnError(res);
99f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                // swap channel solo
100f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 0,
101f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE);
102f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                ExitOnError(res);
103f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                res = (*muteSolo)->SetChannelSolo(muteSolo, 1,
104f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                        leftSoloed == SL_BOOLEAN_TRUE ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
105f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                ExitOnError(res);
106f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                if (leftSoloed == SL_BOOLEAN_TRUE) { // we've swapped the channel solo above
107f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                    fprintf(stdout, "channel 0: normal, channel 1: soloed\n");
108f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                } else {
109f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                    fprintf(stdout, "channel 0: soloed, channel 1: normal\n");
110f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi                }
111f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            }
112f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            } break;
113f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
114f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        default:
115f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            break;
116f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
117f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi}
118f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
119f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//-----------------------------------------------------------------
120f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
121f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi/* Play an audio URIs, mute and solo channels  */
122f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivivoid TestPlayUri( SLObjectItf sl, const char* path)
123f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{
124f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLresult  result;
125f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLEngineItf EngineItf;
126f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
127f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
128f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLObjectItf  player, outputMix;
129f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
130f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Source of audio data to play */
131f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLDataSource      audioSource;
132f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLDataLocator_URI uri;
133f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLDataFormat_MIME mime;
134f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
135f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Data sinks for the audio player */
136f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLDataSink               audioSink;
137f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
138f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
139f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Play, Volume and PrefetchStatus interfaces for the audio player */
140f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLPlayItf           playItf;
141f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLMuteSoloItf       muteSoloItf;
142f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLPrefetchStatusItf prefetchItf;
143f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
144f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
145f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
146f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
147f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
148f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
149f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
150f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
151f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
152f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
153f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
154f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
155f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
156f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
157f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* ------------------------------------------------------ */
158f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Configuration of the output mix  */
159f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
160f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
161f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required);
162f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi     ExitOnError(result);
163f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
164f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
165f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
166f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
167f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
168f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Setup the data sink structure */
169f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
170f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
171f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
172f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    audioSink.pFormat             = NULL;
173f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
174f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* ------------------------------------------------------ */
175f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Configuration of the player  */
176f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
177f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
178f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
179f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
180f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    iidArray[0] = SL_IID_MUTESOLO;
181f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
182f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    iidArray[1] = SL_IID_PREFETCHSTATUS;
183f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
184f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Setup the data source structure for the URI */
185f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    uri.locatorType = SL_DATALOCATOR_URI;
186f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    uri.URI         =  (SLchar*) path;
187f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
188f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
189f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
190f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
191f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
192f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
193f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
194f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    audioSource.pLocator = (void*)&uri;
195f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
196f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Create the audio player */
19723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2,
198f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            iidArray, required);
199f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
200f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
201f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Realize the player in synchronous mode. */
202f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
203f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
204f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
205f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
206f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
207f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
208f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
209f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
210f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
211f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
212f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
213f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
214f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
215ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    // Attempt to get the channel count before it is necessarily known.
216ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    // This may fail depending on the platform.
217ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    SLuint8 numChannels = 123;
218ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
219ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    printf("GetNumChannels after Realize but before pre-fetch: result=%lu, numChannels=%u\n",
220ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten        result, numChannels);
221ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten
22266f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    /* Initialize a context for use by the callback */
22366f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    Context             context;
22466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    context.playItf = playItf;
22566f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    context.muteSoloItf = muteSoloItf;
22666f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    context.testMode = TEST_MUTE;
22766f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten
228f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /*  Setup to receive playback events on position updates */
22966f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    result = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void *) &context);
230f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
231f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATNEWPOS);
232f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
233f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*playItf)->SetPositionUpdatePeriod(playItf, 1000);
234f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
235f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
236f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
237f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
238f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* ------------------------------------------------------ */
239f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Playback and test */
240f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
241f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Start the data prefetching by setting the player to the paused state */
242f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
243f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
244f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
245f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Wait until there's data to play */
246f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
247f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
248f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        usleep(100 * 1000);
249f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
250f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
251f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
252f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Query the number of channels */
253ec3a5a5555af3ed612b70dc54ef96998a9256b9aGlenn Kasten    numChannels = 123;
254f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
255f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
256f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "Content has %d channel(s)\n", numChannels);
257f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
258f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    if (numChannels == 1) {
259f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        fprintf(stdout, "SLMuteSolotItf only works one content with more than one channel. Bye\n");
260f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        goto destroyKillKill;
261f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    } else {
262f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        /* Mute left channel */
2631a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_TRUE);
2641a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten        ExitOnError(result);
2651a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten        result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE);
2661a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten        ExitOnError(result);
267f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
268f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
269f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Run the test for 10s */
270f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* see PlayEventCallback() for more of the test of the SLMuteSoloItf interface */
271f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "\nTesting mute functionality:\n");
27266f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    context.testMode = TEST_MUTE;
273f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); ExitOnError(result);
274f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
275f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 0, SL_BOOLEAN_FALSE); ExitOnError(result);
276f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*muteSoloItf)->SetChannelMute(muteSoloItf, 1, SL_BOOLEAN_FALSE); ExitOnError(result);
277f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "\nTesting solo functionality:\n");
27866f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    context.testMode = TEST_SOLO;
279f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    usleep( 5 * 1000 * 1000);
280f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
281f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Make sure player is stopped */
282f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
283f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
284f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
285f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
286f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel TrividestroyKillKill:
287f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
288f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Destroy the players */
289f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    (*player)->Destroy(player);
290f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
291f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Destroy Output Mix object */
292f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
293f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi}
294f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
295f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi//-----------------------------------------------------------------
296f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Triviint main(int argc, char* const argv[])
297f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi{
298f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    LOGV("Starting %s\n", argv[0]);
299f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
300f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLresult    result;
301f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLObjectItf sl;
302f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
303f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
304f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            argv[0]);
305f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
306f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
307f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
308f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    fprintf(stdout, "Stops after 10s\n");
309f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
310f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    if (argc == 1) {
311f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        fprintf(stdout, "Usage: \t%s url\n", argv[0]);
31215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
313f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        exit(1);
314f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
315f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
316f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    SLEngineOption EngineOption[] = {
317f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
318f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    };
319f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
320f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
321f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
322f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
323f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
324f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
325f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    ExitOnError(result);
326f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
327f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    if (argc > 1) {
328f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi        TestPlayUri(sl, argv[1]);
329f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    }
330f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
331f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    /* Shutdown OpenSL ES */
332f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    (*sl)->Destroy(sl);
333f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    exit(0);
334f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi
335f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi    return 0;
336f5a72df81e05deb7afb56410aa4ecf370b2df141Jean-Michel Trivi}
337