OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/audio/android/opensles_input.h" | 5 #include "media/audio/android/opensles_input.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "media/audio/android/audio_manager_android.h" | 8 #include "media/audio/android/audio_manager_android.h" |
9 | 9 |
| 10 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \ |
| 11 do { \ |
| 12 SLresult err = (op); \ |
| 13 if (err != SL_RESULT_SUCCESS) { \ |
| 14 DLOG(ERROR) << #op << " failed: " << err; \ |
| 15 return __VA_ARGS__; \ |
| 16 } \ |
| 17 } while (0) |
| 18 |
10 namespace media { | 19 namespace media { |
11 | 20 |
12 OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager, | 21 OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager, |
13 const AudioParameters& params) | 22 const AudioParameters& params) |
14 : audio_manager_(audio_manager), | 23 : audio_manager_(audio_manager), |
15 callback_(NULL), | 24 callback_(NULL), |
16 recorder_(NULL), | 25 recorder_(NULL), |
17 simple_buffer_queue_(NULL), | 26 simple_buffer_queue_(NULL), |
18 active_queue_(0), | 27 active_queue_(0), |
19 buffer_size_bytes_(0), | 28 buffer_size_bytes_(0), |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 audio_data_[i], | 86 audio_data_[i], |
78 buffer_size_bytes_); | 87 buffer_size_bytes_); |
79 if (SL_RESULT_SUCCESS != err) { | 88 if (SL_RESULT_SUCCESS != err) { |
80 HandleError(err); | 89 HandleError(err); |
81 return; | 90 return; |
82 } | 91 } |
83 } | 92 } |
84 | 93 |
85 // Start the recording by setting the state to |SL_RECORDSTATE_RECORDING|. | 94 // Start the recording by setting the state to |SL_RECORDSTATE_RECORDING|. |
86 err = (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING); | 95 err = (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING); |
87 DCHECK_EQ(SL_RESULT_SUCCESS, err); | |
88 if (SL_RESULT_SUCCESS != err) | 96 if (SL_RESULT_SUCCESS != err) |
89 HandleError(err); | 97 HandleError(err); |
90 } | 98 } |
91 | 99 |
92 void OpenSLESInputStream::Stop() { | 100 void OpenSLESInputStream::Stop() { |
93 if (!started_) | 101 if (!started_) |
94 return; | 102 return; |
95 | 103 |
96 // Stop recording by setting the record state to |SL_RECORDSTATE_STOPPED|. | 104 // Stop recording by setting the record state to |SL_RECORDSTATE_STOPPED|. |
97 SLresult err = (*recorder_)->SetRecordState(recorder_, | 105 LOG_ON_FAILURE_AND_RETURN( |
98 SL_RECORDSTATE_STOPPED); | 106 (*recorder_)->SetRecordState(recorder_, |
99 if (SL_RESULT_SUCCESS != err) { | 107 SL_RECORDSTATE_STOPPED)); |
100 DLOG(WARNING) << "SetRecordState() failed to set the state to stop"; | |
101 } | |
102 | 108 |
103 // Clear the buffer queue to get rid of old data when resuming recording. | 109 // Clear the buffer queue to get rid of old data when resuming recording. |
104 err = (*simple_buffer_queue_)->Clear(simple_buffer_queue_); | 110 LOG_ON_FAILURE_AND_RETURN( |
105 if (SL_RESULT_SUCCESS != err) { | 111 (*simple_buffer_queue_)->Clear(simple_buffer_queue_)); |
106 DLOG(WARNING) << "Clear() failed to clear the buffer queue"; | |
107 } | |
108 | 112 |
109 started_ = false; | 113 started_ = false; |
110 } | 114 } |
111 | 115 |
112 void OpenSLESInputStream::Close() { | 116 void OpenSLESInputStream::Close() { |
113 // Stop the stream if it is still recording. | 117 // Stop the stream if it is still recording. |
114 Stop(); | 118 Stop(); |
115 | 119 |
116 // Explicitly free the player objects and invalidate their associated | 120 // Explicitly free the player objects and invalidate their associated |
117 // interfaces. They have to be done in the correct order. | 121 // interfaces. They have to be done in the correct order. |
(...skipping 29 matching lines...) Expand all Loading... |
147 NOTIMPLEMENTED(); | 151 NOTIMPLEMENTED(); |
148 return false; | 152 return false; |
149 } | 153 } |
150 | 154 |
151 bool OpenSLESInputStream::CreateRecorder() { | 155 bool OpenSLESInputStream::CreateRecorder() { |
152 // Initializes the engine object with specific option. After working with the | 156 // Initializes the engine object with specific option. After working with the |
153 // object, we need to free the object and its resources. | 157 // object, we need to free the object and its resources. |
154 SLEngineOption option[] = { | 158 SLEngineOption option[] = { |
155 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) } | 159 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) } |
156 }; | 160 }; |
157 SLresult err = slCreateEngine(engine_object_.Receive(), | 161 LOG_ON_FAILURE_AND_RETURN(slCreateEngine(engine_object_.Receive(), |
158 1, | 162 1, |
159 option, | 163 option, |
160 0, | 164 0, |
161 NULL, | 165 NULL, |
162 NULL); | 166 NULL), |
163 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 167 false); |
164 if (SL_RESULT_SUCCESS != err) | |
165 return false; | |
166 | 168 |
167 // Realize the SL engine object in synchronous mode. | 169 // Realize the SL engine object in synchronous mode. |
168 err = engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE); | 170 LOG_ON_FAILURE_AND_RETURN(engine_object_->Realize(engine_object_.Get(), |
169 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 171 SL_BOOLEAN_FALSE), |
170 if (SL_RESULT_SUCCESS != err) | 172 false); |
171 return false; | |
172 | 173 |
173 // Get the SL engine interface which is implicit. | 174 // Get the SL engine interface which is implicit. |
174 SLEngineItf engine; | 175 SLEngineItf engine; |
175 err = engine_object_->GetInterface( | 176 LOG_ON_FAILURE_AND_RETURN(engine_object_->GetInterface(engine_object_.Get(), |
176 engine_object_.Get(), SL_IID_ENGINE, &engine); | 177 SL_IID_ENGINE, |
177 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 178 &engine), |
178 if (SL_RESULT_SUCCESS != err) | 179 false); |
179 return false; | |
180 | 180 |
181 // Audio source configuration. | 181 // Audio source configuration. |
182 SLDataLocator_IODevice mic_locator = { | 182 SLDataLocator_IODevice mic_locator = { |
183 SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, | 183 SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, |
184 SL_DEFAULTDEVICEID_AUDIOINPUT, NULL | 184 SL_DEFAULTDEVICEID_AUDIOINPUT, NULL |
185 }; | 185 }; |
186 SLDataSource audio_source = { &mic_locator, NULL }; | 186 SLDataSource audio_source = { &mic_locator, NULL }; |
187 | 187 |
188 // Audio sink configuration. | 188 // Audio sink configuration. |
189 SLDataLocator_AndroidSimpleBufferQueue buffer_queue = { | 189 SLDataLocator_AndroidSimpleBufferQueue buffer_queue = { |
190 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // Locator type. | 190 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // Locator type. |
191 static_cast<SLuint32>(kNumOfQueuesInBuffer) // Number of buffers. | 191 static_cast<SLuint32>(kNumOfQueuesInBuffer) // Number of buffers. |
192 }; | 192 }; |
193 SLDataSink audio_sink = { &buffer_queue, &format_ }; | 193 SLDataSink audio_sink = { &buffer_queue, &format_ }; |
194 | 194 |
195 // Create an audio recorder. | 195 // Create an audio recorder. |
196 const SLuint32 number_of_interfaces = 1; | 196 const SLInterfaceID interface_id[] = { |
197 const SLInterfaceID interface_id[number_of_interfaces] = { | 197 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, |
198 SL_IID_ANDROIDSIMPLEBUFFERQUEUE | 198 SL_IID_ANDROIDCONFIGURATION |
199 }; | 199 }; |
200 const SLboolean interface_required[number_of_interfaces] = { | 200 const SLboolean interface_required[] = { |
| 201 SL_BOOLEAN_TRUE, |
201 SL_BOOLEAN_TRUE | 202 SL_BOOLEAN_TRUE |
202 }; | 203 }; |
203 err = (*engine)->CreateAudioRecorder(engine, | 204 // Create AudioRecorder and specify SL_IID_ANDROIDCONFIGURATION. |
204 recorder_object_.Receive(), | 205 LOG_ON_FAILURE_AND_RETURN( |
205 &audio_source, | 206 (*engine)->CreateAudioRecorder(engine, |
206 &audio_sink, | 207 recorder_object_.Receive(), |
207 number_of_interfaces, | 208 &audio_source, |
208 interface_id, | 209 &audio_sink, |
209 interface_required); | 210 arraysize(interface_id), |
210 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 211 interface_id, |
211 if (SL_RESULT_SUCCESS != err) { | 212 interface_required), |
212 DLOG(ERROR) << "CreateAudioRecorder failed with error code " << err; | 213 false); |
213 return false; | 214 |
214 } | 215 SLAndroidConfigurationItf recorder_config; |
| 216 LOG_ON_FAILURE_AND_RETURN( |
| 217 recorder_object_->GetInterface(recorder_object_.Get(), |
| 218 SL_IID_ANDROIDCONFIGURATION, |
| 219 &recorder_config), |
| 220 false); |
| 221 |
| 222 SLint32 stream_type = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; |
| 223 LOG_ON_FAILURE_AND_RETURN( |
| 224 (*recorder_config)->SetConfiguration(recorder_config, |
| 225 SL_ANDROID_KEY_RECORDING_PRESET, |
| 226 &stream_type, sizeof(SLint32)), |
| 227 false); |
215 | 228 |
216 // Realize the recorder object in synchronous mode. | 229 // Realize the recorder object in synchronous mode. |
217 err = recorder_object_->Realize(recorder_object_.Get(), SL_BOOLEAN_FALSE); | 230 LOG_ON_FAILURE_AND_RETURN( |
218 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 231 recorder_object_->Realize(recorder_object_.Get(), |
219 if (SL_RESULT_SUCCESS != err) { | 232 SL_BOOLEAN_FALSE), |
220 DLOG(ERROR) << "Recprder Realize() failed with error code " << err; | 233 false); |
221 return false; | |
222 } | |
223 | 234 |
224 // Get an implicit recorder interface. | 235 // Get an implicit recorder interface. |
225 err = recorder_object_->GetInterface(recorder_object_.Get(), | 236 LOG_ON_FAILURE_AND_RETURN( |
226 SL_IID_RECORD, | 237 recorder_object_->GetInterface(recorder_object_.Get(), |
227 &recorder_); | 238 SL_IID_RECORD, |
228 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 239 &recorder_), |
229 if (SL_RESULT_SUCCESS != err) | 240 false); |
230 return false; | |
231 | 241 |
232 // Get the simple buffer queue interface. | 242 // Get the simple buffer queue interface. |
233 err = recorder_object_->GetInterface(recorder_object_.Get(), | 243 LOG_ON_FAILURE_AND_RETURN( |
234 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, | 244 recorder_object_->GetInterface(recorder_object_.Get(), |
235 &simple_buffer_queue_); | 245 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, |
236 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 246 &simple_buffer_queue_), |
237 if (SL_RESULT_SUCCESS != err) | 247 false); |
238 return false; | |
239 | 248 |
240 // Register the input callback for the simple buffer queue. | 249 // Register the input callback for the simple buffer queue. |
241 // This callback will be called when receiving new data from the device. | 250 // This callback will be called when receiving new data from the device. |
242 err = (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_, | 251 LOG_ON_FAILURE_AND_RETURN( |
243 SimpleBufferQueueCallback, | 252 (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_, |
244 this); | 253 SimpleBufferQueueCallback, |
245 DCHECK_EQ(SL_RESULT_SUCCESS, err); | 254 this), |
| 255 false); |
246 | 256 |
247 return (SL_RESULT_SUCCESS == err); | 257 return true; |
248 } | 258 } |
249 | 259 |
250 void OpenSLESInputStream::SimpleBufferQueueCallback( | 260 void OpenSLESInputStream::SimpleBufferQueueCallback( |
251 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) { | 261 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) { |
252 OpenSLESInputStream* stream = | 262 OpenSLESInputStream* stream = |
253 reinterpret_cast<OpenSLESInputStream*>(instance); | 263 reinterpret_cast<OpenSLESInputStream*>(instance); |
254 stream->ReadBufferQueue(); | 264 stream->ReadBufferQueue(); |
255 } | 265 } |
256 | 266 |
257 void OpenSLESInputStream::ReadBufferQueue() { | 267 void OpenSLESInputStream::ReadBufferQueue() { |
(...skipping 28 matching lines...) Expand all Loading... |
286 void OpenSLESInputStream::ReleaseAudioBuffer() { | 296 void OpenSLESInputStream::ReleaseAudioBuffer() { |
287 if (audio_data_[0]) { | 297 if (audio_data_[0]) { |
288 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { | 298 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { |
289 delete [] audio_data_[i]; | 299 delete [] audio_data_[i]; |
290 audio_data_[i] = NULL; | 300 audio_data_[i] = NULL; |
291 } | 301 } |
292 } | 302 } |
293 } | 303 } |
294 | 304 |
295 void OpenSLESInputStream::HandleError(SLresult error) { | 305 void OpenSLESInputStream::HandleError(SLresult error) { |
296 DLOG(FATAL) << "OpenSLES error " << error; | 306 DLOG(FATAL) << "OpenSLES Input error " << error; |
297 if (callback_) | 307 if (callback_) |
298 callback_->OnError(this); | 308 callback_->OnError(this); |
299 } | 309 } |
300 | 310 |
301 } // namespace media | 311 } // namespace media |
OLD | NEW |