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 5447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kastenvoid prefetch_callback(SLPrefetchStatusItf caller, void *context, SLuint32 event) 5547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten{ 5647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLresult result; 5747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten assert(context == NULL); 5847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLpermille level; 5947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*caller)->GetFillLevel(caller, &level); 6047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 6147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLuint32 status; 6247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*caller)->GetPrefetchStatus(caller, &status); 6347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 6447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) 6547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 6647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten errorInPrefetchCallback = SL_BOOLEAN_TRUE; 6747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 6847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten} 6900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 7000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi//----------------------------------------------------------------- 7100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 7200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi/* Play an audio path and feed a global reverb */ 7300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivivoid TestSendToPresetReverb( SLObjectItf sl, const char* path, int preset, SLmillibel directLevel, 7447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLmillibel sendLevel, bool alwaysOn, bool useFd, bool loop) 7500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi{ 7600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLresult result; 7700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLEngineItf EngineItf; 7800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 7900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Objects this application uses: one player and an ouput mix */ 8000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLObjectItf player, outputMix; 8100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 8200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Source of audio data to play */ 8300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLDataSource audioSource; 8400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#ifdef ANDROID 8500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLDataLocator_AndroidFD locatorFd; 8600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif 8747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLDataLocator_URI locatorUri; 8800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLDataFormat_MIME mime; 8900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 9000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Data sinks for the audio player */ 9100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLDataSink audioSink; 9200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 9300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 9400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Interfaces for the audio player */ 9500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLPlayItf playItf; 967c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten SLPrefetchStatusItf prefetchItf; 9700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLEffectSendItf effectSendItf; 9847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLSeekItf seekItf; 9900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 10000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Interface for the output mix */ 10100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLPresetReverbItf reverbItf; 10200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 10300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 10400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 10500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 10600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 10700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 10800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 10900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 11000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 11100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 11200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 11300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 11400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 11500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 11600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* ------------------------------------------------------ */ 11700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Configuration of the output mix */ 11800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 11900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Set arrays required[] and iidArray[] for required interfaces */ 12000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 12100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi iidArray[0] = SL_IID_PRESETREVERB; 12200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 12300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Create Output Mix object to be used by the player */ 12400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required); 12500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 12600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 12700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Realize the Output Mix object in synchronous mode */ 12800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 12900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 13000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 13100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Get the SLPresetReverbItf for the output mix */ 13200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*outputMix)->GetInterface(outputMix, SL_IID_PRESETREVERB, (void*)&reverbItf); 13300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 13400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 13500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Setup the data sink structure */ 13600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 13700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi locator_outputmix.outputMix = outputMix; 13800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi audioSink.pLocator = (void*)&locator_outputmix; 13900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi audioSink.pFormat = NULL; 14000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 14100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Select the reverb preset */ 14200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "\nUsing preset "); 14300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi switch(preset) { 14400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_NONE: 14500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "SL_REVERBPRESET_NONE, don't expect to hear reverb\n"); 14600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi break; 14700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_SMALLROOM: fprintf(stdout, "SL_REVERBPRESET_SMALLROOM\n"); break; 14800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_MEDIUMROOM: fprintf(stdout, "SL_REVERBPRESET_MEDIUMROOM\n"); break; 14900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_LARGEROOM: fprintf(stdout, "SL_REVERBPRESET_LARGEROOM\n"); break; 15000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_MEDIUMHALL: fprintf(stdout, "SL_REVERBPRESET_MEDIUMHALL\n"); break; 15100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_LARGEHALL: fprintf(stdout, "SL_REVERBPRESET_LARGEHALL\n"); break; 15200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi case SL_REVERBPRESET_PLATE: fprintf(stdout, "SL_REVERBPRESET_PLATE\n"); break; 15300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi default: 15400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "unknown, use at your own risk\n"); break; 15500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 15600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*reverbItf)->SetPreset(reverbItf, preset); 15700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 15800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 15900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* ------------------------------------------------------ */ 16000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Configuration of the player */ 16100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 16200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Set arrays required[] and iidArray[] for required interfaces */ 16300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* (SLPlayItf is implicit) */ 16400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 16500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi iidArray[0] = SL_IID_PREFETCHSTATUS; 16600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 16700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi iidArray[1] = SL_IID_EFFECTSEND; 16847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten required[2] = SL_BOOLEAN_TRUE; 16947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten iidArray[2] = SL_IID_SEEK; 17000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 17100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi locatorUri.locatorType = SL_DATALOCATOR_URI; 17200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi locatorUri.URI = (SLchar *) path; 17347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten audioSource.pLocator = (void*)&locatorUri; 17447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (useFd) { 17547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#ifdef ANDROID 17647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten /* Setup the data source structure for the URI */ 17747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten locatorFd.locatorType = SL_DATALOCATOR_ANDROIDFD; 17847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten int fd = open(path, O_RDONLY); 17947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (fd == -1) { 18047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten perror(path); 18147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten exit(EXIT_FAILURE); 18247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 18347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten locatorFd.fd = (SLint32) fd; 18447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten locatorFd.length = SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE; 18547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten locatorFd.offset = 0; 18647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten audioSource.pLocator = (void*)&locatorFd; 18747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#else 18847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten fprintf(stderr, "option --fd is not supported\n"); 18900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif 19047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 19100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 19200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 19300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* this is how ignored mime information is specified, according to OpenSL ES spec 19400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi * in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */ 19500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 19600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 19700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 19800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi audioSource.pFormat = (void*)&mime; 19900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 20000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Create the audio player */ 20147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 3, 20200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi iidArray, required); 20300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 20400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 20500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Realize the player in synchronous mode. */ 20600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result); 20700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 20800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 20900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Get the SLPlayItf, SLPrefetchStatusItf and SLEffectSendItf interfaces for the player*/ 21000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 21100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 21200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 2137c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 2147c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten ExitOnError(result); 21547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*prefetchItf)->RegisterCallback(prefetchItf, prefetch_callback, NULL); 21647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 21747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 21847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE); 21947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 2207c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten 22100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*player)->GetInterface(player, SL_IID_EFFECTSEND, (void*)&effectSendItf); 22200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 22300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 22447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*player)->GetInterface(player, SL_IID_SEEK, (void*)&seekItf); 22547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 22647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten 22700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "Player configured\n"); 22800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 22900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* ------------------------------------------------------ */ 23000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Playback and test */ 23100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 2327c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten /* Start the data prefetching by setting the player to the paused state */ 2337c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 2347c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten ExitOnError(result); 2357c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten 2367c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten /* Wait until there's data to play */ 2377c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 2387c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) { 23947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (errorInPrefetchCallback) { 24047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten fprintf(stderr, "Error during prefetch, exiting\n"); 24147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten exit(EXIT_FAILURE); 24247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 2437c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten usleep(100 * 1000); 2447c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus); 2457c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten ExitOnError(result); 2467c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten } 2477c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten 24800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Get duration */ 24900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 25000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*playItf)->GetDuration(playItf, &durationInMsec); 25100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 25200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 25347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten printf("Duration unknown, assuming 10 seconds\n"); 2542246c698482ab6860906672229f0ae6d886e6302Glenn Kasten durationInMsec = 10000; 25547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } else { 25647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten printf("Duration is %.1f seconds\n", durationInMsec / 1000.0); 25700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 25800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 25900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Feed the output mix' reverb from the audio player using the given send level */ 26000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*effectSendItf)->EnableEffectSend(effectSendItf, reverbItf, SL_BOOLEAN_TRUE, 26100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi sendLevel); 26200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 26300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 26400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*effectSendItf)->SetDirectLevel(effectSendItf, directLevel); 26500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 26600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "Set direct level to %dmB\n", directLevel); 26700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 26800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*effectSendItf)->SetSendLevel(effectSendItf, reverbItf, sendLevel); 26900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 27000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "Set send level to %dmB\n", sendLevel); 27100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 27247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten /* Enable looping */ 27347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (loop) { 27447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, (SLmillisecond) 0, SL_TIME_UNKNOWN); 27547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 27647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 27747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten 27800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Start playback */ 27900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 28000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 28100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 2827c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten /* Disable preset reverb every TIME_S_BETWEEN_SETTING_CHANGE seconds unless always on */ 2837c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten SLboolean previousEnabled = SL_BOOLEAN_FALSE; 28447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten SLuint32 playState; 28547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten for (;;) { 28647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten result = (*playItf)->GetPlayState(playItf, &playState); 28747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 28847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (playState != SL_PLAYSTATE_PLAYING) 28947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten break; 2907c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten SLboolean enabled; 2917c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten enabled = alwaysOn || !previousEnabled; 2927c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten if (enabled != previousEnabled) { 2937c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten result = (*reverbItf)->SetPreset(reverbItf, enabled ? preset : SL_REVERBPRESET_NONE); 294c2f5fd8659f405de1a4769dfb075b2b27b217bd8Glenn Kasten fprintf(stdout, "SetPreset(%d)=%d\n", enabled ? preset : SL_REVERBPRESET_NONE, result); 29547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten ExitOnError(result); 2967c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten previousEnabled = enabled; 2977c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten if (enabled) { 2987c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten fprintf(stdout, "Reverb on\n"); 2997c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten } else { 3007c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten fprintf(stdout, "Reverb off\n"); 3017c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten } 30200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 30300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi usleep(TIME_S_BETWEEN_SETTING_CHANGE * 1000 * 1000); 30400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 30500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 30600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Make sure player is stopped */ 30747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten assert(playState == SL_PLAYSTATE_STOPPED); 30847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#if 0 30900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "Stopping playback\n"); 31000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 31100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 31247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten#endif 31300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 31400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Destroy the player */ 31500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi (*player)->Destroy(player); 31600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 31700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Destroy Output Mix object */ 31800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi (*outputMix)->Destroy(outputMix); 31900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 32000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#ifdef ANDROID 32147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (useFd) 32247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten close(locatorFd.fd); 32300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi#endif 32400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi} 32500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 32600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi//----------------------------------------------------------------- 32700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Triviint main(int argc, char* const argv[]) 32800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi{ 3297c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten const char *programName = argv[0]; 33000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLresult result; 33100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLObjectItf sl; 33200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 3337c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten fprintf(stdout, "OpenSL ES test %s: exercises SLEffectSendItf ", programName); 33400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "on AudioPlayer and SLPresetReverbItf on OutputMix.\n"); 33500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "Plays the sound file designated by the given path, "); 33600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "and sends a specified amount of energy to a global reverb\n"); 33700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi fprintf(stdout, "(sendLevel in mB), with a given direct level (in mB).\n"); 33847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten fprintf(stdout, "Every %d seconds, the reverb is turned on and off,\n", 33900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi TIME_S_BETWEEN_SETTING_CHANGE); 3407c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten fprintf(stdout, "unless the --always-on option is specified before the path.\n"); 3417c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten 3427c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten bool alwaysOn = false; 34347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten bool useFd = false; 34447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten bool loop = false; 34547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten int i; 34647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten for (i = 1; i < argc; ++i) { 34747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten const char *arg = argv[i]; 34847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (arg[0] != '-') 34947c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten break; 35047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (!strcmp(arg, "--always-on")) { 35147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten alwaysOn = true; 35247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } else if (!strcmp(arg, "--fd")) { 35347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten useFd = true; 35447c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } else if (!strcmp(arg, "--loop")) { 35547c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten loop = true; 35647c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } else { 35747c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten fprintf(stderr, "unknown option %s ignored\n", arg); 35847c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten } 3597c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten } 36000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 36147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten if (argc - i != 4) { 36247c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten fprintf(stdout, "Usage: \t%s [--always-on] [--fd] [--loop] path preset directLevel " 36347c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten "sendLevel\n", programName); 3647c7511aa96e54d94df836357fbbf76c681f20a26Glenn Kasten fprintf(stdout, "Example: \"%s /sdcard/my.mp3 6 -2000 0\" \n", programName); 365c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten exit(EXIT_FAILURE); 36600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi } 36700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 36800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi SLEngineOption EngineOption[] = { 36900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 37000667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi }; 37100667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 37200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 37300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 37400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 37500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 37600667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 37700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi ExitOnError(result); 37800667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 37900667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi // intentionally not checking that levels are of correct value 38047c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten TestSendToPresetReverb(sl, argv[i], atoi(argv[i+1]), (SLmillibel)atoi(argv[i+2]), 38147c325b8fe4cd967886ee82070c1eb3d1bb0c18cGlenn Kasten (SLmillibel)atoi(argv[i+3]), alwaysOn, useFd, loop); 38200667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 38300667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi /* Shutdown OpenSL ES */ 38400667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi (*sl)->Destroy(sl); 38500667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi 386c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten return EXIT_SUCCESS; 38700667fcca51d62236b538e6857b7e6b923453569Jean-Michel Trivi} 388