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 #include <assert.h> 17 18 #include <android/log.h> 19 20 #include <SLES/OpenSLES.h> 21 #include <SLES/OpenSLES_Android.h> 22 23 #include "AudioRecorder.h" 24 25 #include "AudioSink.h" 26 #include "SystemParams.h" 27 #include "OpenSLESUtils.h" 28 29 #ifndef NULL 30 #define NULL 0 31 #endif 32 33 #define ARRAYSIZE(a) sizeof((a))/sizeof((a)[0]) 34 35 using namespace ndkaudio; 36 37 //static const char* const TAG = "AudioRecorder"; 38 39 #define NB_BUFFERS_IN_QUEUE 1 40 41 static void RecCallback(SLRecordItf /*recorderItf_*/, void * /*context*/, SLuint32 event) 42 { 43 if (SL_RECORDEVENT_HEADATNEWPOS & event) { 44 // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATNEWPOS"); 45 } 46 47 if (SL_RECORDEVENT_HEADATMARKER & event) { 48 // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATMARKER"); 49 } 50 51 if (SL_RECORDEVENT_BUFFER_FULL & event) { 52 // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_BUFFER_FULL"); 53 } 54 } 55 56 #define BUFFER_SIZE_IN_FRAMES 8192 57 58 static float* recBuffer = NULL; 59 60 static void RecBufferQueueCallback(SLAndroidSimpleBufferQueueItf /*queueItf*/, void * context) 61 { 62 AudioRecorder* recorder = (AudioRecorder*)context; 63 // __android_log_print(ANDROID_LOG_INFO, TAG, "RecBufferQueueCallback()"); 64 recorder->enqueBuffer(); 65 } 66 67 /* 68 * The OpenSL ES code was derived from: 69 * frameworks/wilhelm/tests/examples/slesTestRecBuffQueue.cpp 70 */ 71 AudioRecorder::AudioRecorder() 72 : sink_(NULL), 73 recording_(false), 74 sampleRate_(48000), 75 numChannels_(0), 76 numBufferSamples_(0), 77 engineObj_(NULL), 78 engineItf_(NULL), 79 recorderObj_(NULL), 80 recorderItf_(NULL), 81 recBuffQueueItf_(NULL), 82 configItf_(NULL) 83 {} 84 85 AudioRecorder::~AudioRecorder() {} 86 87 void AudioRecorder::Open(int numChannels, AudioSink* sink) { 88 sink_ = sink; 89 numChannels_ = numChannels; 90 // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder::Open() - numChannels:%d", numChannels); 91 92 SLresult result; 93 94 numBufferSamples_ = BUFFER_SIZE_IN_FRAMES * numChannels_; 95 recBuffer = new float[numBufferSamples_]; 96 97 SLEngineOption EngineOption[] = { 98 {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 99 }; 100 101 /* Create the OpenSL ES Engine object */ 102 result = slCreateEngine(&engineObj_, 1, EngineOption, 0, NULL, NULL); 103 assert(SL_RESULT_SUCCESS == result); 104 // __android_log_print(ANDROID_LOG_INFO, TAG, "slCreateEngine() - engineObj_:%p", engineObj_); 105 106 /* Realizing the SL Engine in synchronous mode. */ 107 result = (*engineObj_)->Realize(engineObj_, SL_BOOLEAN_FALSE); 108 assert(SL_RESULT_SUCCESS == result); 109 // __android_log_print(ANDROID_LOG_INFO, TAG, "(*engineObj_)->Realize()"); 110 111 result = (*engineObj_)->GetInterface(engineObj_, SL_IID_ENGINE, (void*)&engineItf_); 112 assert(SL_RESULT_SUCCESS == result); 113 // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() - engineItf_:%p", engineItf_); 114 115 // Configuration of the recorder 116 SLboolean required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 117 SLInterfaceID iidArray[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION}; 118 119 SLDataLocator_IODevice ioDevice; 120 ioDevice.locatorType = SL_DATALOCATOR_IODEVICE; 121 ioDevice.deviceType = SL_IODEVICE_AUDIOINPUT; 122 ioDevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT; 123 ioDevice.device = NULL; 124 125 SLDataSource recSource; 126 recSource.pLocator = (void *) &ioDevice; 127 recSource.pFormat = NULL; 128 129 /* Setup the (OpenSL ES) data sink */ 130 SLDataLocator_AndroidSimpleBufferQueue recBuffQueue; 131 recBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; 132 recBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE; 133 134 SLAndroidDataFormat_PCM_EX pcm; 135 pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; 136 pcm.numChannels = numChannels_; 137 pcm.sampleRate = sampleRate_ * 1000; // milliHz 138 pcm.bitsPerSample = 32; 139 pcm.containerSize = 32; 140 pcm.channelMask = chanCountToChanMask(numChannels_); 141 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 142 pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; 143 144 SLDataSink recDest; 145 recDest.pLocator = (void *) &recBuffQueue; 146 recDest.pFormat = (void * ) &pcm; 147 148 /* Create the audio recorder */ 149 result = (*engineItf_)->CreateAudioRecorder(engineItf_, &recorderObj_, &recSource, &recDest, 150 ARRAYSIZE(iidArray), iidArray, required); 151 assert(SL_RESULT_SUCCESS == result); 152 // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateAudioRecorder() - recorderObj_:%p", recorderObj_); 153 } 154 155 void AudioRecorder::Close() { 156 /* Shutdown OpenSL ES */ 157 (*engineObj_)->Destroy(engineObj_); 158 engineObj_ = 0; 159 } 160 161 void AudioRecorder::RealizeRecorder() { 162 SLresult result; 163 164 /* Realize the recorder in synchronous mode. */ 165 result = (*recorderObj_)->Realize(recorderObj_, SL_BOOLEAN_FALSE); 166 assert(SL_RESULT_SUCCESS == result); 167 // __android_log_print(ANDROID_LOG_INFO, TAG, "Recorder realized"); 168 169 /* Get the record interface which is implicit */ 170 result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_RECORD, (void*)&recorderItf_); 171 assert(SL_RESULT_SUCCESS == result); 172 // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recorderItf_:%p", recorderItf_); 173 174 /* Set up the recorder callback to get events during the recording */ 175 // __android_log_print(ANDROID_LOG_INFO, TAG, "SetMarkerPosition()"); 176 result = (*recorderItf_)->SetMarkerPosition(recorderItf_, 2000); 177 assert(SL_RESULT_SUCCESS == result); 178 179 // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPositionUpdatePeriod()"); 180 result = (*recorderItf_)->SetPositionUpdatePeriod(recorderItf_, 500); 181 assert(SL_RESULT_SUCCESS == result); 182 183 // __android_log_print(ANDROID_LOG_INFO, TAG, "SetCallbackEventsMask()"); 184 result = (*recorderItf_)->SetCallbackEventsMask(recorderItf_, SL_RECORDEVENT_HEADATMARKER | SL_RECORDEVENT_HEADATNEWPOS); 185 assert(SL_RESULT_SUCCESS == result); 186 187 // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Events"); 188 result = (*recorderItf_)->RegisterCallback(recorderItf_, RecCallback, NULL); 189 assert(SL_RESULT_SUCCESS == result); 190 191 /* Get the buffer queue interface which was explicitly requested */ 192 result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, (void*)&recBuffQueueItf_); 193 assert(SL_RESULT_SUCCESS == result); 194 // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recBuffQueueItf_:%p", recBuffQueueItf_); 195 196 result = (*recBuffQueueItf_)->RegisterCallback(recBuffQueueItf_, RecBufferQueueCallback, (void*)this); 197 assert(SL_RESULT_SUCCESS == result); 198 // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Buffers"); 199 } 200 201 void AudioRecorder::RealizeRoutingProxy() { 202 SLresult result; 203 // The Config interface (for routing) 204 result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf_); 205 // __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s", getSLErrStr(result)); 206 assert(SL_RESULT_SUCCESS == result); 207 } 208 209 void AudioRecorder::Start() { 210 SLresult result; 211 212 /* Enqueue buffers to map the region of memory allocated to store the recorded data */ 213 // __android_log_print(ANDROID_LOG_INFO, TAG, "Enqueueing buffer"); 214 //int bufferSizeInBytes = BUFFER_SIZE_IN_FRAMES * numChannels_ * sizeof(float); 215 216 enqueBuffer(); 217 218 /* ------------------------------------------------------ */ 219 /* Start recording */ 220 // __android_log_print(ANDROID_LOG_INFO, TAG, "Start Recording"); 221 recording_ = true; 222 result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_RECORDING); 223 assert(SL_RESULT_SUCCESS == result); 224 } 225 226 void AudioRecorder::Stop() { 227 recording_ = false; 228 229 SLresult result; 230 result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_STOPPED); 231 } 232 233 SLresult AudioRecorder::enqueBuffer() { 234 SLresult result; 235 int bufferSizeInBytes = numBufferSamples_ * sizeof(float); 236 // __android_log_print(ANDROID_LOG_INFO, TAG, "Enque %d bytes", bufferSizeInBytes); 237 result = (*recBuffQueueItf_)->Enqueue(recBuffQueueItf_, recBuffer, bufferSizeInBytes); 238 assert(SL_RESULT_SUCCESS == result); 239 240 return result; 241 } 242 243 float* AudioRecorder::GetRecordBuffer() { 244 return recBuffer; 245 } 246