1 /* 2 * Copyright (C) 2016 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 #include <assert.h> 18 19 #include <android/log.h> 20 21 #include <SLES/OpenSLES.h> 22 #include <SLES/OpenSLES_Android.h> 23 24 #include "AudioPlayer.h" 25 26 #include "AudioSource.h" 27 #include "SystemParams.h" 28 #include "OpenSLESUtils.h" 29 30 #ifndef NULL 31 #define NULL 0 32 #endif 33 34 /* 35 * OpenSL ES Stuff 36 */ 37 static const char* TAG = "AudioPlayer"; 38 39 // engine interfaces 40 static SLObjectItf engineObject = 0; 41 static SLEngineItf engineItf; 42 43 // output mix interfaces 44 static SLObjectItf outputMixObject = 0; 45 46 // this callback handler is called every time a buffer finishes playing 47 static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf /*bq*/, void *context) 48 { 49 // __android_log_print(ANDROID_LOG_INFO, TAG, "bqPlayerCallback()"); 50 ((ndkaudio::AudioPlayer*)context)->enqueBuffer(); 51 } 52 53 static void OpenSLEngine() { 54 SLresult result; 55 56 // create engine 57 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 58 assert(SL_RESULT_SUCCESS == result); 59 // __android_log_print(ANDROID_LOG_INFO, TAG, "OpenSLEngine() - engineObject:%p", engineObject); 60 61 // realize the engine 62 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 63 // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() engine result:%s", getSLErrStr(result)); 64 assert(SL_RESULT_SUCCESS == result); 65 66 // get the engine interface, which is needed in order to create other objects 67 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf); 68 // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() engine:%p result:%s", engineItf, getSLErrStr(result)); 69 assert(SL_RESULT_SUCCESS == result); 70 71 // get the output mixer 72 result = (*engineItf)->CreateOutputMix(engineItf, &outputMixObject, 0, 0, 0); 73 // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateOutputMix() mix:%p result:%s", outputMixObject, getSLErrStr(result)); 74 assert(SL_RESULT_SUCCESS == result); 75 76 // realize the output mix 77 result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 78 // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() result:%s", getSLErrStr(result)); 79 assert(SL_RESULT_SUCCESS == result); 80 } 81 82 static void CloseSLEngine() { 83 __android_log_print(ANDROID_LOG_INFO, TAG, "CloseSLEngine()"); 84 85 // destroy output mix object, and invalidate all associated interfaces 86 if (outputMixObject != NULL) { 87 (*outputMixObject)->Destroy(outputMixObject); 88 outputMixObject = NULL; 89 } 90 91 if (engineObject != NULL) { 92 (*engineObject)->Destroy(engineObject); 93 engineObject = NULL; 94 engineItf = NULL; 95 } 96 } 97 98 /* 99 * AudioPlayer 100 */ 101 namespace ndkaudio { 102 103 AudioPlayer::AudioPlayer() { 104 source_ = NULL; 105 106 sampleRate_ = SystemParams::getSampleRate(); 107 numChannels_ = 1; 108 109 numPlayBuffFrames_ = SystemParams::getNumBufferFrames(); 110 111 playing_ = false; 112 113 time_ = 0; 114 115 bqPlayerObject_ = NULL; 116 bq_ = NULL; 117 bqPlayerPlay_ = NULL; 118 configItf_ = NULL; 119 120 OpenSLEngine(); 121 } 122 123 AudioPlayer::~AudioPlayer() { 124 CloseSLEngine(); 125 126 delete[] playBuff_; 127 playBuff_ = 0; 128 } 129 130 SLresult AudioPlayer::Open(int numChannels, AudioSource* source) { 131 source_ = source; 132 133 SLresult result; 134 135 numChannels_ = numChannels; 136 137 int internalBuffFactor = 1; 138 139 playBuff_ = 140 new float[numPlayBuffFrames_ * numChannels_ * internalBuffFactor]; 141 playBuffSizeInBytes_ = numPlayBuffFrames_ * numChannels_ * sizeof(float) 142 * internalBuffFactor; 143 144 sampleRate_ = SystemParams::getSampleRate(); 145 146 // __android_log_print(ANDROID_LOG_INFO, TAG, 147 // "AudioPlayer::Open(chans:%d, rate:%d)", numChannels, 148 // sampleRate_); 149 150 // configure audio source 151 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { 152 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType 153 1}; // numBuffers 154 155 // SLuint32 chanMask = SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT; 156 SLAndroidDataFormat_PCM_EX format_pcm = {SL_ANDROID_DATAFORMAT_PCM_EX, // formatType 157 (SLuint32) numChannels_, // numChannels 158 (SLuint32)(sampleRate_ * 1000), // milliSamplesPerSec 159 32, // bitsPerSample 160 32, // containerSize; 161 (SLuint32) chanCountToChanMask(numChannels_), // channelMask 162 SL_BYTEORDER_LITTLEENDIAN, // endianness 163 SL_ANDROID_PCM_REPRESENTATION_FLOAT}; // representation 164 SLDataSource audioSrc = {&loc_bufq, &format_pcm}; 165 166 // configure audio sink 167 SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, 168 outputMixObject}; 169 SLDataSink audioSnk = {&loc_outmix, NULL}; 170 171 const SLInterfaceID ids[] = 172 {SL_IID_BUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION}; 173 const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 174 175 // The Player 176 result = (*engineItf)->CreateAudioPlayer(engineItf, &bqPlayerObject_, 177 &audioSrc, &audioSnk, 178 sizeof(ids) / sizeof(ids[0]), ids, 179 req); 180 // __android_log_print(ANDROID_LOG_INFO, TAG, 181 // "CreateAudioPlayer() result:%s, bqPlayerObject_:%p", 182 // getSLErrStr(result), bqPlayerObject_); 183 assert(SL_RESULT_SUCCESS == result); 184 185 return result; 186 } 187 188 void AudioPlayer::Close() { 189 __android_log_write(ANDROID_LOG_INFO, TAG, "CloseSLPlayer()"); 190 191 if (bqPlayerObject_ != NULL) { 192 (*bqPlayerObject_)->Destroy(bqPlayerObject_); 193 bqPlayerObject_ = NULL; 194 195 // invalidate any interfaces 196 bqPlayerPlay_ = NULL; 197 bq_ = NULL; 198 } 199 } 200 201 SLresult AudioPlayer::RealizePlayer() { 202 SLresult result; 203 204 // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer::RealizePlayer()"); 205 206 result = (*bqPlayerObject_)->Realize(bqPlayerObject_, SL_BOOLEAN_FALSE); 207 // __android_log_print(ANDROID_LOG_INFO, TAG, 208 // "Realize player object result:%s", getSLErrStr(result)); 209 assert(SL_RESULT_SUCCESS == result); 210 211 result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_, SL_IID_PLAY, 212 &bqPlayerPlay_); 213 // __android_log_print(ANDROID_LOG_INFO, TAG, 214 // "get player interface result:%s, bqPlayerPlay_:%p", 215 // getSLErrStr(result), bqPlayerPlay_); 216 assert(SL_RESULT_SUCCESS == result); 217 218 // The BufferQueue 219 result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_, 220 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 221 &bq_); 222 // __android_log_print(ANDROID_LOG_INFO, TAG, 223 // "get bufferqueue interface:%p result:%s", bq_, 224 // getSLErrStr(result)); 225 assert(SL_RESULT_SUCCESS == result); 226 227 // The register BufferQueue callback 228 result = (*bq_)->RegisterCallback(bq_, bqPlayerCallback, this); 229 // __android_log_print(ANDROID_LOG_INFO, TAG, "register callback result:%s", 230 // getSLErrStr(result)); 231 assert(SL_RESULT_SUCCESS == result); 232 233 return result; 234 } 235 236 SLresult AudioPlayer::RealizeRoutingProxy() { 237 SLresult result; 238 239 // The Config interface (for routing) 240 result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_, 241 SL_IID_ANDROIDCONFIGURATION, 242 (void*) &configItf_); 243 // __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s", 244 // getSLErrStr(result)); 245 assert(SL_RESULT_SUCCESS == result); 246 247 return result; 248 } 249 250 SLresult AudioPlayer::Start() { 251 // __android_log_print(ANDROID_LOG_INFO, TAG, "Start()"); 252 playing_ = true; 253 254 // set the player's state to playing 255 SLresult result = (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_, 256 SL_PLAYSTATE_PLAYING); 257 // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPlayState() result:%s", getSLErrStr(result)); 258 assert(SL_RESULT_SUCCESS == result); 259 260 enqueBuffer(); 261 262 return result; 263 } 264 265 void AudioPlayer::Stop() { 266 // __android_log_print(ANDROID_LOG_INFO, TAG, "Stop()"); 267 playing_ = false; 268 } 269 270 SLresult AudioPlayer::enqueBuffer() { 271 // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer::enqueBuffer()"); 272 if (playing_) { 273 //long dataSizeInSamples = source_->getData(time_++, playBuff_, 274 // numPlayBuffFrames_, 275 // source_->getNumChannels()); 276 return (*bq_)->Enqueue(bq_, playBuff_, playBuffSizeInBytes_); 277 } else { 278 (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_, SL_PLAYSTATE_STOPPED); 279 return 0; 280 } 281 } 282 283 } // namespace ndkaudio 284 285