slesTestBassBoostPath.cpp revision 91bfd060b992810ca092f640f77f795bc3d008be
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifdef ANDROID 18#define LOG_NDEBUG 0 19#define LOG_TAG "slesTest_bassboost" 20 21#include <utils/Log.h> 22#else 23#define LOGV printf 24#endif 25 26#include <getopt.h> 27#include <stdlib.h> 28#include <stdio.h> 29#include <string.h> 30#include <unistd.h> 31#include <sys/time.h> 32#include <fcntl.h> 33 34#include "SLES/OpenSLES.h" 35#ifdef ANDROID 36#include "SLES/OpenSLES_Android.h" 37#endif 38 39 40#define MAX_NUMBER_INTERFACES 3 41#define MAX_NUMBER_OUTPUT_DEVICES 6 42 43#define TIME_S_BETWEEN_BB_ON_OFF 3 44 45//----------------------------------------------------------------- 46/* Exits the application if an error is encountered */ 47#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__) 48 49void ExitOnErrorFunc( SLresult result , int line) 50{ 51 if (SL_RESULT_SUCCESS != result) { 52 fprintf(stderr, "%lu error code encountered at line %d, exiting\n", result, line); 53 exit(1); 54 } 55} 56 57 58//----------------------------------------------------------------- 59 60/* Play an audio path by opening a file descriptor on that path */ 61void TestBassBoostPathFromFD( SLObjectItf sl, const char* path, int16_t boostStrength) 62{ 63 SLresult result; 64 SLEngineItf EngineItf; 65 66 /* Objects this application uses: one player and an ouput mix */ 67 SLObjectItf player, outputMix; 68 69 /* Source of audio data to play */ 70 SLDataSource audioSource; 71#ifdef ANDROID 72 SLDataLocator_AndroidFD locatorFd; 73#else 74 SLDataLocator_URI locatorUri; 75#endif 76 SLDataFormat_MIME mime; 77 78 /* Data sinks for the audio player */ 79 SLDataSink audioSink; 80 SLDataLocator_OutputMix locator_outputmix; 81 82 /* Play and PrefetchStatus interfaces for the audio player */ 83 SLPlayItf playItf; 84 SLPrefetchStatusItf prefetchItf; 85 SLBassBoostItf bbItf; 86 87 SLboolean required[MAX_NUMBER_INTERFACES]; 88 SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 89 90 /* Get the SL Engine Interface which is implicit */ 91 result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 92 ExitOnError(result); 93 94 /* Initialize arrays required[] and iidArray[] */ 95 for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 96 required[i] = SL_BOOLEAN_FALSE; 97 iidArray[i] = SL_IID_NULL; 98 } 99 100 /* ------------------------------------------------------ */ 101 /* Configuration of the output mix */ 102 103 /* Create Output Mix object to be used by the player */ 104 result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 1, iidArray, required); 105 ExitOnError(result); 106 107 /* Realize the Output Mix object in synchronous mode */ 108 result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 109 ExitOnError(result); 110 111 /* Setup the data sink structure */ 112 locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 113 locator_outputmix.outputMix = outputMix; 114 audioSink.pLocator = (void*)&locator_outputmix; 115 audioSink.pFormat = NULL; 116 117 /* ------------------------------------------------------ */ 118 /* Configuration of the player */ 119 120 /* Set arrays required[] and iidArray[] for SLPrefetchStatusItf interfaces */ 121 /* (SLPlayItf is implicit) */ 122 required[0] = SL_BOOLEAN_TRUE; 123 iidArray[0] = SL_IID_PREFETCHSTATUS; 124 required[1] = SL_BOOLEAN_TRUE; 125 iidArray[1] = SL_IID_BASSBOOST; 126 127#ifdef ANDROID 128 /* Setup the data source structure for the URI */ 129 locatorFd.locatorType = SL_DATALOCATOR_ANDROIDFD; 130 int fd = open(path, O_RDONLY); 131 if (fd == -1) { 132 ExitOnError(SL_RESULT_RESOURCE_ERROR); 133 } 134 locatorFd.fd = (SLint32) fd; 135 locatorFd.length = SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE; 136 locatorFd.offset = 0; 137#else 138 locatorUri.locatorType = SL_DATALOCATOR_URI; 139 locatorUri.URI = (SLchar *) path; 140#endif 141 142 mime.formatType = SL_DATAFORMAT_MIME; 143 /* this is how ignored mime information is specified, according to OpenSL ES spec 144 * in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */ 145 mime.mimeType = (SLchar*)NULL; 146 mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 147 148 audioSource.pFormat = (void*)&mime; 149#ifdef ANDROID 150 audioSource.pLocator = (void*)&locatorFd; 151#else 152 audioSource.pLocator = (void*)&locatorUri; 153#endif 154 155 /* Create the audio player */ 156 result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 2, 157 iidArray, required); 158 ExitOnError(result); 159 160 /* Realize the player in synchronous mode. */ 161 result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result); 162 fprintf(stdout, "URI example: after Realize\n"); 163 164 /* Get the SLPlayItf, SLPrefetchStatusItf and SLAndroidStreamTypeItf interfaces for the player*/ 165 result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 166 ExitOnError(result); 167 168 result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 169 ExitOnError(result); 170 171 result = (*player)->GetInterface(player, SL_IID_BASSBOOST, (void*)&bbItf); 172 ExitOnError(result); 173 174 fprintf(stdout, "Player configured\n"); 175 176 /* ------------------------------------------------------ */ 177 /* Playback and test */ 178 179 /* Start the data prefetching by setting the player to the paused state */ 180 result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 181 ExitOnError(result); 182 183 /* Wait until there's data to play */ 184 SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 185 while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) { 186 usleep(100 * 1000); 187 (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus); 188 ExitOnError(result); 189 } 190 191 /* Get duration */ 192 SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 193 result = (*playItf)->GetDuration(playItf, &durationInMsec); 194 ExitOnError(result); 195 if (durationInMsec == SL_TIME_UNKNOWN) { 196 durationInMsec = 5000; 197 } 198 199 /* Start playback */ 200 fprintf(stdout, "Starting to play\n"); 201 result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING ); 202 ExitOnError(result); 203 204 /* Configure BassBoost */ 205 SLboolean strengthSupported = SL_BOOLEAN_FALSE; 206 result = (*bbItf)->IsStrengthSupported(bbItf, &strengthSupported); 207 ExitOnError(result); 208 if (SL_BOOLEAN_FALSE == strengthSupported) { 209 fprintf(stdout, "BassBoost strength is not supported on this platform. Too bad!\n"); 210 } else { 211 fprintf(stdout, "BassBoost strength is supported, setting strength to %d\n", boostStrength); 212 result = (*bbItf)->SetStrength(bbItf, boostStrength); 213 ExitOnError(result); 214 } 215 216 SLpermille strength = 0; 217 result = (*bbItf)->GetRoundedStrength(bbItf, &strength); 218 ExitOnError(result); 219 fprintf(stdout, "Rounded strength of boost = %d\n", strength); 220 221 222 /* Switch BassBoost on/off every TIME_S_BETWEEN_BB_ON_OFF seconds */ 223 SLboolean enabled = SL_BOOLEAN_TRUE; 224 result = (*bbItf)->SetEnabled(bbItf, enabled); 225 ExitOnError(result); 226 for(unsigned int j=0 ; j<(durationInMsec/1000*TIME_S_BETWEEN_BB_ON_OFF) ; j++) { 227 usleep(TIME_S_BETWEEN_BB_ON_OFF * 1000 * 1000); 228 result = (*bbItf)->IsEnabled(bbItf, &enabled); 229 ExitOnError(result); 230 enabled = enabled == SL_BOOLEAN_TRUE ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE; 231 result = (*bbItf)->SetEnabled(bbItf, enabled); 232 if (SL_BOOLEAN_TRUE == enabled) { 233 fprintf(stdout, "BassBoost on\n"); 234 } else { 235 fprintf(stdout, "BassBoost off\n"); 236 } 237 ExitOnError(result); 238 } 239 240 /* Make sure player is stopped */ 241 fprintf(stdout, "Stopping playback\n"); 242 result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 243 ExitOnError(result); 244 245 /* Destroy the player */ 246 (*player)->Destroy(player); 247 248 /* Destroy Output Mix object */ 249 (*outputMix)->Destroy(outputMix); 250 251#ifdef ANDROID 252 close(fd); 253#endif 254} 255 256//----------------------------------------------------------------- 257int main(int argc, char* const argv[]) 258{ 259 LOGV("Starting %s\n", argv[0]); 260 261 SLresult result; 262 SLObjectItf sl; 263 264 fprintf(stdout, "OpenSL ES test %s: exercises SLBassBoostItf ", argv[0]); 265 fprintf(stdout, "and AudioPlayer with SLDataLocator_AndroidFD source / OutputMix sink\n"); 266 fprintf(stdout, "Plays the sound file designated by the given path, "); 267 fprintf(stdout, "and applies a bass boost effect of the specified strength,\n"); 268 fprintf(stdout, "where strength is a integer value between 0 and 1000.\n"); 269 fprintf(stdout, "Every %d seconds, the BassBoost will be turned on and off.\n", 270 TIME_S_BETWEEN_BB_ON_OFF); 271 272 if (argc < 3) { 273 fprintf(stdout, "Usage: \t%s path bass_boost_strength\n", argv[0]); 274 fprintf(stdout, "Example: \"%s /sdcard/my.mp3 1000\" \n", argv[0]); 275 exit(1); 276 } 277 278 SLEngineOption EngineOption[] = { 279 {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 280 }; 281 282 result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 283 ExitOnError(result); 284 285 /* Realizing the SL Engine in synchronous mode. */ 286 result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 287 ExitOnError(result); 288 289 // intentionally not checking that argv[2], the bassboost strength, is between 0 and 1000 290 TestBassBoostPathFromFD(sl, argv[1], (int16_t)atoi(argv[2])); 291 292 /* Shutdown OpenSL ES */ 293 (*sl)->Destroy(sl); 294 exit(0); 295 296 return 0; 297} 298