slesTestSendToPresetReverb.cpp revision 086a6f51a7b12880ed114962136972f89ed70da2
100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi/*
200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi *
400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * you may not use this file except in compliance with the License.
600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * You may obtain a copy of the License at
700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi *
800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi *
1000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * See the License for the specific language governing permissions and
1400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * limitations under the License.
1500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi */
1600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
1747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#include <assert.h>
1800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <stdlib.h>
1900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <stdio.h>
2000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <string.h>
2100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <unistd.h>
2200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <sys/time.h>
2300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#include <fcntl.h>
2400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
25c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h>
2600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#ifdef ANDROID
27c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES_Android.h>
2800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif
2900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#define MAX_NUMBER_INTERFACES 4
3200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#define TIME_S_BETWEEN_SETTING_CHANGE 3
3400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi//-----------------------------------------------------------------
3600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi/* Exits the application if an error is encountered */
3700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
3800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line)
4000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi{
4100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    if (SL_RESULT_SUCCESS != result) {
4258432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten        fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line);
43c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
4400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
4500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi}
4600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
4747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten// Prefetch status callback
4847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten
4947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \
5047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
5147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten
5247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn KastenSLboolean errorInPrefetchCallback = SL_BOOLEAN_FALSE;
5347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten
54086a6f51a7b12880ed114962136972f89ed70da2Glenn Kastenvoid prefetch_callback(SLPrefetchStatusItf caller, void *context __unused, SLuint32 event)
5547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten{
5647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLresult result;
5747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLpermille level;
5847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*caller)->GetFillLevel(caller, &level);
5947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    ExitOnError(result);
6047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLuint32 status;
6147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*caller)->GetPrefetchStatus(caller, &status);
6247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    ExitOnError(result);
6347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE))
6447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
6547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        errorInPrefetchCallback = SL_BOOLEAN_TRUE;
6647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    }
6747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten}
6800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
6900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi//-----------------------------------------------------------------
7000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
7100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi/* Play an audio path and feed a global reverb  */
7200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivivoid TestSendToPresetReverb( SLObjectItf sl, const char* path, int preset, SLmillibel directLevel,
7347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        SLmillibel sendLevel, bool alwaysOn, bool useFd, bool loop)
7400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi{
7500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLresult  result;
7600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLEngineItf EngineItf;
7700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
7800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Objects this application uses: one player and an ouput mix */
7900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLObjectItf  player, outputMix;
8000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
8100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Source of audio data to play */
8200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLDataSource            audioSource;
8300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#ifdef ANDROID
8400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLDataLocator_AndroidFD locatorFd;
8500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif
8647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLDataLocator_URI       locatorUri;
8700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLDataFormat_MIME       mime;
8800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
8900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Data sinks for the audio player */
9000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLDataSink               audioSink;
9100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLDataLocator_OutputMix  locator_outputmix;
9200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
9300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Interfaces for the audio player */
9400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLPlayItf              playItf;
957c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    SLPrefetchStatusItf    prefetchItf;
9600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLEffectSendItf        effectSendItf;
9747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLSeekItf              seekItf;
9800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
9900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Interface for the output mix */
10000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLPresetReverbItf      reverbItf;
10100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
10200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLboolean required[MAX_NUMBER_INTERFACES];
10300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
10400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
10500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Get the SL Engine Interface which is implicit */
10600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
10700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
10800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
10900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Initialize arrays required[] and iidArray[] */
11000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
11100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        required[i] = SL_BOOLEAN_FALSE;
11200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        iidArray[i] = SL_IID_NULL;
11300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
11400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
11500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* ------------------------------------------------------ */
11600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Configuration of the output mix  */
11700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
11800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for required interfaces */
11900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
12000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    iidArray[0] = SL_IID_PRESETREVERB;
12100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
12200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Create Output Mix object to be used by the player */
12300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi     result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required);
12400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi     ExitOnError(result);
12500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
12600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Realize the Output Mix object in synchronous mode */
12700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
12800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
12900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
13000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Get the SLPresetReverbItf for the output mix */
13100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*outputMix)->GetInterface(outputMix, SL_IID_PRESETREVERB, (void*)&reverbItf);
13200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
13300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
13400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Setup the data sink structure */
13500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
13600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    locator_outputmix.outputMix   = outputMix;
13700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    audioSink.pLocator            = (void*)&locator_outputmix;
13800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    audioSink.pFormat             = NULL;
13900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
14000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Select the reverb preset */
14100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "\nUsing preset ");
14200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    switch(preset) {
14300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_NONE:
14400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            fprintf(stdout, "SL_REVERBPRESET_NONE, don't expect to hear reverb\n");
14500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            break;
14600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_SMALLROOM: fprintf(stdout, "SL_REVERBPRESET_SMALLROOM\n"); break;
14700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_MEDIUMROOM: fprintf(stdout, "SL_REVERBPRESET_MEDIUMROOM\n"); break;
14800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_LARGEROOM: fprintf(stdout, "SL_REVERBPRESET_LARGEROOM\n"); break;
14900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_MEDIUMHALL: fprintf(stdout, "SL_REVERBPRESET_MEDIUMHALL\n"); break;
15000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_LARGEHALL: fprintf(stdout, "SL_REVERBPRESET_LARGEHALL\n"); break;
15100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        case SL_REVERBPRESET_PLATE: fprintf(stdout, "SL_REVERBPRESET_PLATE\n"); break;
15200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        default:
15300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            fprintf(stdout, "unknown, use at your own risk\n"); break;
15400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
15500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*reverbItf)->SetPreset(reverbItf, preset);
15600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
15700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
15800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* ------------------------------------------------------ */
15900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Configuration of the player  */
16000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
16100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Set arrays required[] and iidArray[] for required interfaces */
16200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /*  (SLPlayItf is implicit) */
16300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    required[0] = SL_BOOLEAN_TRUE;
16400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    iidArray[0] = SL_IID_PREFETCHSTATUS;
16500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    required[1] = SL_BOOLEAN_TRUE;
16600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    iidArray[1] = SL_IID_EFFECTSEND;
16747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    required[2] = SL_BOOLEAN_TRUE;
16847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    iidArray[2] = SL_IID_SEEK;
16900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
17000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    locatorUri.locatorType = SL_DATALOCATOR_URI;
17100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    locatorUri.URI = (SLchar *) path;
17247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    audioSource.pLocator = (void*)&locatorUri;
17347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    if (useFd) {
17447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#ifdef ANDROID
17547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        /* Setup the data source structure for the URI */
17647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        locatorFd.locatorType = SL_DATALOCATOR_ANDROIDFD;
17747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        int fd = open(path, O_RDONLY);
17847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        if (fd == -1) {
17947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            perror(path);
18047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            exit(EXIT_FAILURE);
18147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        }
18247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        locatorFd.fd = (SLint32) fd;
18347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        locatorFd.length = SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE;
18447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        locatorFd.offset = 0;
18547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        audioSource.pLocator = (void*)&locatorFd;
18647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#else
18747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        fprintf(stderr, "option --fd is not supported\n");
18800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif
18947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    }
19000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
19100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    mime.formatType = SL_DATAFORMAT_MIME;
19200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /*     this is how ignored mime information is specified, according to OpenSL ES spec
19300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi     *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
19400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    mime.mimeType      = (SLchar*)NULL;
19500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
19600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
19700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    audioSource.pFormat  = (void*)&mime;
19800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
19900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Create the audio player */
20047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 3,
20100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            iidArray, required);
20200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
20300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
20400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Realize the player in synchronous mode. */
20500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
20600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "URI example: after Realize\n");
20700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
20800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Get the SLPlayItf, SLPrefetchStatusItf and SLEffectSendItf interfaces for the player*/
20900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
21000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
21100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
2127c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
2137c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    ExitOnError(result);
21447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*prefetchItf)->RegisterCallback(prefetchItf, prefetch_callback, NULL);
21547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    ExitOnError(result);
21647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*prefetchItf)->SetCallbackEventsMask(prefetchItf,
21747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
21847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    ExitOnError(result);
2197c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten
22000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*player)->GetInterface(player, SL_IID_EFFECTSEND, (void*)&effectSendItf);
22100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
22200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
22347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    result = (*player)->GetInterface(player, SL_IID_SEEK, (void*)&seekItf);
22447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    ExitOnError(result);
22547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten
22600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "Player configured\n");
22700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
22800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* ------------------------------------------------------ */
22900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Playback and test */
23000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
2317c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    /* Start the data prefetching by setting the player to the paused state */
2327c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
2337c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    ExitOnError(result);
2347c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten
2357c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    /* Wait until there's data to play */
2367c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
2377c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
23847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        if (errorInPrefetchCallback) {
23947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            fprintf(stderr, "Error during prefetch, exiting\n");
24047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            exit(EXIT_FAILURE);
24147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        }
2427c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        usleep(100 * 1000);
2437c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
2447c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        ExitOnError(result);
2457c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    }
2467c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten
24700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Get duration */
24800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
24900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*playItf)->GetDuration(playItf, &durationInMsec);
25000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
25100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    if (durationInMsec == SL_TIME_UNKNOWN) {
25247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        printf("Duration unknown, assuming 10 seconds\n");
2532246c698482ab6860906672229f0ae6d886e6302Glenn Kasten        durationInMsec = 10000;
25447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    } else {
25547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        printf("Duration is %.1f seconds\n", durationInMsec / 1000.0);
25600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
25700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
25800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Feed the output mix' reverb from the audio player using the given send level */
25900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*effectSendItf)->EnableEffectSend(effectSendItf, reverbItf, SL_BOOLEAN_TRUE,
26000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            sendLevel);
26100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
26200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
26300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*effectSendItf)->SetDirectLevel(effectSendItf, directLevel);
26400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
26500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "Set direct level to %dmB\n", directLevel);
26600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
26700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*effectSendItf)->SetSendLevel(effectSendItf, reverbItf, sendLevel);
26800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
26900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "Set send level to %dmB\n", sendLevel);
27000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
27147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    /* Enable looping */
27247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    if (loop) {
27347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        result = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, (SLmillisecond) 0, SL_TIME_UNKNOWN);
27447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        ExitOnError(result);
27547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    }
27647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten
27700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Start playback */
27800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
27900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
28000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
2817c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    /* Disable preset reverb every TIME_S_BETWEEN_SETTING_CHANGE seconds unless always on */
2827c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    SLboolean previousEnabled = SL_BOOLEAN_FALSE;
28347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    SLuint32 playState;
28447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    for (;;) {
28547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        result = (*playItf)->GetPlayState(playItf, &playState);
28647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        ExitOnError(result);
28747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        if (playState != SL_PLAYSTATE_PLAYING)
28847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            break;
2897c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        SLboolean enabled;
2907c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        enabled = alwaysOn || !previousEnabled;
2917c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        if (enabled != previousEnabled) {
2927c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten            result = (*reverbItf)->SetPreset(reverbItf, enabled ? preset : SL_REVERBPRESET_NONE);
293c2f5fd8659f405de1a4769dfb075b2b27b217bd8Glenn Kasten            fprintf(stdout, "SetPreset(%d)=%d\n", enabled ? preset : SL_REVERBPRESET_NONE, result);
29447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            ExitOnError(result);
2957c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten            previousEnabled = enabled;
2967c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten            if (enabled) {
2977c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten                fprintf(stdout, "Reverb on\n");
2987c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten            } else {
2997c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten                fprintf(stdout, "Reverb off\n");
3007c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten            }
30100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        }
30200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi        usleep(TIME_S_BETWEEN_SETTING_CHANGE * 1000 * 1000);
30300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
30400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
30500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Make sure player is stopped */
30647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    assert(playState == SL_PLAYSTATE_STOPPED);
30747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#if 0
30800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "Stopping playback\n");
30900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
31000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
31147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#endif
31200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
31300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Destroy the player */
31400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    (*player)->Destroy(player);
31500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
31600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Destroy Output Mix object */
31700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    (*outputMix)->Destroy(outputMix);
31800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
31900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#ifdef ANDROID
32047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    if (useFd)
32147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        close(locatorFd.fd);
32200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif
32300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi}
32400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
32500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi//-----------------------------------------------------------------
32600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Triviint main(int argc, char* const argv[])
32700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi{
3287c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    const char *programName = argv[0];
32900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLresult    result;
33000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLObjectItf sl;
33100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
3327c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    fprintf(stdout, "OpenSL ES test %s: exercises SLEffectSendItf ", programName);
33300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "on AudioPlayer and SLPresetReverbItf on OutputMix.\n");
33400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "Plays the sound file designated by the given path, ");
33500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "and sends a specified amount of energy to a global reverb\n");
33600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    fprintf(stdout, "(sendLevel in mB), with a given direct level (in mB).\n");
33747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    fprintf(stdout, "Every %d seconds, the reverb is turned on and off,\n",
33800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            TIME_S_BETWEEN_SETTING_CHANGE);
3397c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    fprintf(stdout, "unless the --always-on option is specified before the path.\n");
3407c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten
3417c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    bool alwaysOn = false;
34247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    bool useFd = false;
34347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    bool loop = false;
34447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    int i;
34547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    for (i = 1; i < argc; ++i) {
34647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        const char *arg = argv[i];
34747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        if (arg[0] != '-')
34847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            break;
34947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        if (!strcmp(arg, "--always-on")) {
35047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            alwaysOn = true;
35147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        } else if (!strcmp(arg, "--fd")) {
35247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            useFd = true;
35347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        } else if (!strcmp(arg, "--loop")) {
35447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            loop = true;
35547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        } else {
35647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            fprintf(stderr, "unknown option %s ignored\n", arg);
35747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        }
3587c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten    }
35900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
36047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    if (argc - i != 4) {
36147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten        fprintf(stdout, "Usage: \t%s [--always-on] [--fd] [--loop] path preset directLevel "
36247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten                "sendLevel\n", programName);
3637c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten        fprintf(stdout, "Example: \"%s /sdcard/my.mp3 6 -2000 0\" \n", programName);
364c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten        exit(EXIT_FAILURE);
36500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    }
36600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
36700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    SLEngineOption EngineOption[] = {
36800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi            {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
36900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    };
37000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
37100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
37200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
37300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
37400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Realizing the SL Engine in synchronous mode. */
37500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
37600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    ExitOnError(result);
37700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
37800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    // intentionally not checking that levels are of correct value
37947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten    TestSendToPresetReverb(sl, argv[i], atoi(argv[i+1]), (SLmillibel)atoi(argv[i+2]),
38047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten            (SLmillibel)atoi(argv[i+3]), alwaysOn, useFd, loop);
38100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
38200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    /* Shutdown OpenSL ES */
38300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi    (*sl)->Destroy(sl);
38400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi
385c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten    return EXIT_SUCCESS;
38600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi}
387