Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: media/audio/android/opensles_input.cc

Issue 17491007: Enable audio volume control on Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: rebase and update description Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/android/opensles_input.h ('k') | media/audio/android/opensles_output.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « media/audio/android/opensles_input.h ('k') | media/audio/android/opensles_output.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698