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

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

Issue 2793123003: Enable float audio output on L+ Android devices. (Closed)
Patch Set: Use __ANDROID_API__. Created 3 years, 8 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
« no previous file with comments | « media/audio/android/opensles_output.h ('k') | no next file » | 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_output.h" 5 #include "media/audio/android/opensles_output.h"
6 6
7 #include "base/android/build_info.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
8 #include "base/macros.h" 9 #include "base/macros.h"
9 #include "base/time/time.h" 10 #include "base/time/time.h"
10 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event.h"
11 #include "media/audio/android/audio_manager_android.h" 12 #include "media/audio/android/audio_manager_android.h"
13 #include "media/base/audio_sample_types.h"
12 #include "media/base/audio_timestamp_helper.h" 14 #include "media/base/audio_timestamp_helper.h"
13 15
14 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \ 16 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \
15 do { \ 17 do { \
16 SLresult err = (op); \ 18 SLresult err = (op); \
17 if (err != SL_RESULT_SUCCESS) { \ 19 if (err != SL_RESULT_SUCCESS) { \
18 DLOG(ERROR) << #op << " failed: " << err; \ 20 DLOG(ERROR) << #op << " failed: " << err; \
19 return __VA_ARGS__; \ 21 return __VA_ARGS__; \
20 } \ 22 } \
21 } while (0) 23 } while (0)
22 24
23 namespace media { 25 namespace media {
24 26
25 OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager, 27 OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager,
26 const AudioParameters& params, 28 const AudioParameters& params,
27 SLint32 stream_type) 29 SLint32 stream_type)
28 : audio_manager_(manager), 30 : audio_manager_(manager),
29 stream_type_(stream_type), 31 stream_type_(stream_type),
30 callback_(NULL), 32 callback_(NULL),
31 player_(NULL), 33 player_(NULL),
32 simple_buffer_queue_(NULL), 34 simple_buffer_queue_(NULL),
33 audio_data_(), 35 audio_data_(),
34 active_buffer_index_(0), 36 active_buffer_index_(0),
35 bytes_per_frame_(params.GetBytesPerFrame()),
36 buffer_size_bytes_(params.GetBytesPerBuffer()),
37 started_(false), 37 started_(false),
38 muted_(false), 38 muted_(false),
39 volume_(1.0), 39 volume_(1.0),
40 samples_per_second_(params.sample_rate()), 40 samples_per_second_(params.sample_rate()),
41 have_float_output_(base::android::BuildInfo::GetInstance()->sdk_int() >=
42 base::android::SDK_VERSION_LOLLIPOP),
43 bytes_per_frame_(have_float_output_ ? params.channels() * sizeof(float)
44 : params.GetBytesPerFrame()),
45 buffer_size_bytes_(have_float_output_
46 ? bytes_per_frame_ * params.frames_per_buffer()
47 : params.GetBytesPerBuffer()),
41 delay_calculator_(samples_per_second_) { 48 delay_calculator_(samples_per_second_) {
42 DVLOG(2) << "OpenSLESOutputStream::OpenSLESOutputStream(" 49 DVLOG(2) << "OpenSLESOutputStream::OpenSLESOutputStream("
43 << "stream_type=" << stream_type << ")"; 50 << "stream_type=" << stream_type << ")";
51
52 audio_bus_ = AudioBus::Create(params);
53
54 if (have_float_output_) {
55 float_format_.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
56 float_format_.numChannels = static_cast<SLuint32>(params.channels());
57 // Despite the name, this field is actually the sampling rate in millihertz.
58 float_format_.sampleRate =
59 static_cast<SLuint32>(samples_per_second_ * 1000);
60 float_format_.bitsPerSample = 32;
61 float_format_.containerSize = 32;
62 float_format_.endianness = SL_BYTEORDER_LITTLEENDIAN;
63 float_format_.channelMask =
64 ChannelCountToSLESChannelMask(params.channels());
65 float_format_.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
66 return;
67 }
68
44 format_.formatType = SL_DATAFORMAT_PCM; 69 format_.formatType = SL_DATAFORMAT_PCM;
45 format_.numChannels = static_cast<SLuint32>(params.channels()); 70 format_.numChannels = static_cast<SLuint32>(params.channels());
46 // Despite the name, this field is actually the sampling rate in millihertz :| 71 // Despite the name, this field is actually the sampling rate in millihertz :|
47 format_.samplesPerSec = static_cast<SLuint32>(samples_per_second_ * 1000); 72 format_.samplesPerSec = static_cast<SLuint32>(samples_per_second_ * 1000);
48 format_.bitsPerSample = params.bits_per_sample(); 73 format_.bitsPerSample = params.bits_per_sample();
49 format_.containerSize = params.bits_per_sample(); 74 format_.containerSize = params.bits_per_sample();
50 format_.endianness = SL_BYTEORDER_LITTLEENDIAN; 75 format_.endianness = SL_BYTEORDER_LITTLEENDIAN;
51 format_.channelMask = ChannelCountToSLESChannelMask(params.channels()); 76 format_.channelMask = ChannelCountToSLESChannelMask(params.channels());
52 audio_bus_ = AudioBus::Create(params);
53 } 77 }
54 78
55 OpenSLESOutputStream::~OpenSLESOutputStream() { 79 OpenSLESOutputStream::~OpenSLESOutputStream() {
56 DVLOG(2) << "OpenSLESOutputStream::~OpenSLESOutputStream()"; 80 DVLOG(2) << "OpenSLESOutputStream::~OpenSLESOutputStream()";
57 DCHECK(thread_checker_.CalledOnValidThread()); 81 DCHECK(thread_checker_.CalledOnValidThread());
58 DCHECK(!engine_object_.Get()); 82 DCHECK(!engine_object_.Get());
59 DCHECK(!player_object_.Get()); 83 DCHECK(!player_object_.Get());
60 DCHECK(!output_mixer_.Get()); 84 DCHECK(!output_mixer_.Get());
61 DCHECK(!player_); 85 DCHECK(!player_);
62 DCHECK(!simple_buffer_queue_); 86 DCHECK(!simple_buffer_queue_);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 false); 258 false);
235 259
236 // Realizing the output mix object in synchronous mode. 260 // Realizing the output mix object in synchronous mode.
237 LOG_ON_FAILURE_AND_RETURN( 261 LOG_ON_FAILURE_AND_RETURN(
238 output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE), false); 262 output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE), false);
239 263
240 // Audio source configuration. 264 // Audio source configuration.
241 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = { 265 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = {
242 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 266 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
243 static_cast<SLuint32>(kMaxNumOfBuffersInQueue)}; 267 static_cast<SLuint32>(kMaxNumOfBuffersInQueue)};
244 SLDataSource audio_source = {&simple_buffer_queue, &format_}; 268 SLDataSource audio_source;
269 if (have_float_output_)
270 audio_source = {&simple_buffer_queue, &float_format_};
271 else
272 audio_source = {&simple_buffer_queue, &format_};
245 273
246 // Audio sink configuration. 274 // Audio sink configuration.
247 SLDataLocator_OutputMix locator_output_mix = {SL_DATALOCATOR_OUTPUTMIX, 275 SLDataLocator_OutputMix locator_output_mix = {SL_DATALOCATOR_OUTPUTMIX,
248 output_mixer_.Get()}; 276 output_mixer_.Get()};
249 SLDataSink audio_sink = {&locator_output_mix, NULL}; 277 SLDataSink audio_sink = {&locator_output_mix, NULL};
250 278
251 // Create an audio player. 279 // Create an audio player.
252 const SLInterfaceID interface_id[] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME, 280 const SLInterfaceID interface_id[] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME,
253 SL_IID_ANDROIDCONFIGURATION}; 281 SL_IID_ANDROIDCONFIGURATION};
254 const SLboolean interface_required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, 282 const SLboolean interface_required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 callback_->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus_.get()); 394 callback_->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus_.get());
367 if (frames_filled <= 0) { 395 if (frames_filled <= 0) {
368 // Audio source is shutting down, or halted on error. 396 // Audio source is shutting down, or halted on error.
369 return; 397 return;
370 } 398 }
371 399
372 // Note: If the internal representation ever changes from 16-bit PCM to 400 // Note: If the internal representation ever changes from 16-bit PCM to
373 // raw float, the data must be clipped and sanitized since it may come 401 // raw float, the data must be clipped and sanitized since it may come
374 // from an untrusted source such as NaCl. 402 // from an untrusted source such as NaCl.
375 audio_bus_->Scale(muted_ ? 0.0f : volume_); 403 audio_bus_->Scale(muted_ ? 0.0f : volume_);
376 audio_bus_->ToInterleaved(frames_filled, format_.bitsPerSample / 8, 404 if (!have_float_output_) {
377 audio_data_[active_buffer_index_]); 405 audio_bus_->ToInterleaved(frames_filled, format_.bitsPerSample / 8,
406 audio_data_[active_buffer_index_]);
407 } else {
408 audio_bus_->ToInterleaved<Float32SampleTypeTraits>(
409 frames_filled,
410 reinterpret_cast<float*>(audio_data_[active_buffer_index_]));
411 }
378 412
379 delay_calculator_.AddFrames(frames_filled); 413 delay_calculator_.AddFrames(frames_filled);
380 const int num_filled_bytes = frames_filled * bytes_per_frame_; 414 const int num_filled_bytes = frames_filled * bytes_per_frame_;
381 DCHECK_LE(static_cast<size_t>(num_filled_bytes), buffer_size_bytes_); 415 DCHECK_LE(static_cast<size_t>(num_filled_bytes), buffer_size_bytes_);
382 416
383 // Enqueue the buffer for playback. 417 // Enqueue the buffer for playback.
384 err = (*simple_buffer_queue_) 418 err = (*simple_buffer_queue_)
385 ->Enqueue(simple_buffer_queue_, audio_data_[active_buffer_index_], 419 ->Enqueue(simple_buffer_queue_, audio_data_[active_buffer_index_],
386 num_filled_bytes); 420 num_filled_bytes);
387 if (SL_RESULT_SUCCESS != err) 421 if (SL_RESULT_SUCCESS != err)
388 HandleError(err); 422 HandleError(err);
389 423
390 active_buffer_index_ = (active_buffer_index_ + 1) % kMaxNumOfBuffersInQueue; 424 active_buffer_index_ = (active_buffer_index_ + 1) % kMaxNumOfBuffersInQueue;
391 } 425 }
392 426
393 void OpenSLESOutputStream::SetupAudioBuffer() { 427 void OpenSLESOutputStream::SetupAudioBuffer() {
394 DCHECK(thread_checker_.CalledOnValidThread()); 428 DCHECK(thread_checker_.CalledOnValidThread());
395 DCHECK(!audio_data_[0]); 429 DCHECK(!audio_data_[0]);
396 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) { 430 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i)
397 audio_data_[i] = new uint8_t[buffer_size_bytes_]; 431 audio_data_[i] = new uint8_t[buffer_size_bytes_];
398 }
399 } 432 }
400 433
401 void OpenSLESOutputStream::ReleaseAudioBuffer() { 434 void OpenSLESOutputStream::ReleaseAudioBuffer() {
402 DCHECK(thread_checker_.CalledOnValidThread()); 435 DCHECK(thread_checker_.CalledOnValidThread());
403 if (audio_data_[0]) { 436 if (audio_data_[0]) {
404 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) { 437 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) {
405 delete[] audio_data_[i]; 438 delete[] audio_data_[i];
406 audio_data_[i] = NULL; 439 audio_data_[i] = NULL;
407 } 440 }
408 } 441 }
409 } 442 }
410 443
411 void OpenSLESOutputStream::HandleError(SLresult error) { 444 void OpenSLESOutputStream::HandleError(SLresult error) {
412 DLOG(ERROR) << "OpenSLES Output error " << error; 445 DLOG(ERROR) << "OpenSLES Output error " << error;
413 if (callback_) 446 if (callback_)
414 callback_->OnError(this); 447 callback_->OnError(this);
415 } 448 }
416 449
417 } // namespace media 450 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/android/opensles_output.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698