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