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

Side by Side Diff: content/renderer/media/webrtc_local_audio_source_provider.cc

Issue 23691038: Switch LiveAudio to source provider solution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Tommi's comments and added unittest Created 7 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
6
7 #include "base/logging.h"
8 #include "content/renderer/render_thread_impl.h"
9 #include "media/audio/audio_parameters.h"
10 #include "media/base/audio_fifo.h"
11 #include "media/base/audio_hardware_config.h"
12 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h"
13
14 using WebKit::WebVector;
15
16 namespace content {
17
18 static const size_t kMaxNumberOfBuffer = 10;
19 static const size_t kWebAudioRenderBufferSize = 128;
20
21 WebRtcLocalAudioSourceProvider::WebRtcLocalAudioSourceProvider()
22 : audio_delay_ms_(0),
23 volume_(1),
24 key_pressed_(false),
25 is_enabled_(false),
26 use_sink_params_for_testing_(false) {
tommi (sloooow) - chröme 2013/09/10 16:00:38 I don't like mixing test code and production code
no longer working on chromium 2013/09/11 10:22:07 How about now?
27 }
28
29 WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() {
30 if (audio_converter_.get())
31 audio_converter_->RemoveInput(this);
32 }
33
34 void WebRtcLocalAudioSourceProvider::Initialize(
35 const media::AudioParameters& source_params) {
36 DCHECK(thread_checker_.CalledOnValidThread());
37 if (!use_sink_params_for_testing_) {
38 // Use the native audio output hardware sample-rate for the sink.
39 media::AudioHardwareConfig* hardware_config =
40 RenderThreadImpl::current()->GetAudioHardwareConfig();
41 int sample_rate = hardware_config->GetOutputSampleRate();
42 sink_params_.Reset(
43 source_params.format(), media::CHANNEL_LAYOUT_STEREO, 2, 0,
44 sample_rate, source_params.bits_per_sample(),
45 kWebAudioRenderBufferSize);
46 }
47
48 base::AutoLock auto_lock(lock_);
49 source_params_ = source_params;
50 // Create the audio converter with |disable_fifo| as false so that the
51 // converter will request source_params.frames_per_buffer() each time.
52 // This will not increase the complexity as there is only one client to
53 // the converter.
54 audio_converter_.reset(
55 new media::AudioConverter(source_params, sink_params_, false));
56 audio_converter_->AddInput(this);
57 fifo_.reset(new media::AudioFifo(
58 source_params.channels(),
59 kMaxNumberOfBuffer * source_params.frames_per_buffer()));
60 }
61
62 void WebRtcLocalAudioSourceProvider::DeliverData(
63 media::AudioBus* audio_source,
64 int audio_delay_milliseconds,
65 int volume,
66 bool key_pressed) {
67 base::AutoLock auto_lock(lock_);
68 if (!is_enabled_)
69 return;
70
71 DCHECK(fifo_.get());
72
73 if (fifo_->frames() + audio_source->frames() <= fifo_->max_frames()) {
74 fifo_->Push(audio_source);
75 } else {
76 // This can happen if the data in FIFO is too slowed to be consumed or
77 // WebAudio stops consuming data.
78 DLOG(WARNING) << "Local source provicer FIFO is full" << fifo_->frames();
79 }
80
81 // Cache the values for GetAudioProcessingParams().
82 last_fill_ = base::TimeTicks::Now();
83 audio_delay_ms_ = audio_delay_milliseconds;
84 volume_ = volume;
85 key_pressed_ = key_pressed;
86 }
87
88 void WebRtcLocalAudioSourceProvider::GetAudioProcessingParams(
89 int* delay_ms, int* volume, bool* key_pressed) {
90 int elapsed_ms = 0;
91 if (!last_fill_.is_null()) {
92 elapsed_ms = static_cast<int>(
93 (base::TimeTicks::Now() - last_fill_).InMilliseconds());
94 }
95 *delay_ms = audio_delay_ms_ + elapsed_ms + static_cast<int>(
96 1000 * fifo_->frames() / source_params_.sample_rate() + 0.5);
97 *volume = volume_;
98 *key_pressed = key_pressed_;
99 }
100
101 void WebRtcLocalAudioSourceProvider::setClient(
102 WebKit::WebAudioSourceProviderClient* client) {
103 NOTIMPLEMENTED();
104 }
105
106 void WebRtcLocalAudioSourceProvider::provideInput(
107 const WebVector<float*>& audio_data, size_t number_of_frames) {
108 DCHECK_EQ(number_of_frames, kWebAudioRenderBufferSize);
109 if (!bus_wrapper_ ||
110 static_cast<size_t>(bus_wrapper_->channels()) != audio_data.size()) {
111 bus_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size());
112 }
113
114 bus_wrapper_->set_frames(number_of_frames);
115 for (size_t i = 0; i < audio_data.size(); ++i)
116 bus_wrapper_->SetChannelData(i, audio_data[i]);
117
118 base::AutoLock auto_lock(lock_);
119 DCHECK(audio_converter_.get());
120 DCHECK(fifo_.get());
121 is_enabled_ = true;
122 audio_converter_->Convert(bus_wrapper_.get());
123 }
124
125 double WebRtcLocalAudioSourceProvider::ProvideInput(
126 media::AudioBus* audio_bus, base::TimeDelta buffer_delay) {
127 if (fifo_->frames() >= audio_bus->frames()) {
128 fifo_->Consume(audio_bus, 0, audio_bus->frames());
129 } else {
130 audio_bus->Zero();
131 if (!last_fill_.is_null()) {
132 DLOG(WARNING) << "Underrun, FIFO has data " << fifo_->frames()
133 << " samples but " << audio_bus->frames()
134 << " samples are needed";
135 }
136 }
137
138 return 1.0;
139 }
140
141 void WebRtcLocalAudioSourceProvider::SetSinkParamsForTesting(
142 const media::AudioParameters& sink_params) {
143 DCHECK(thread_checker_.CalledOnValidThread());
144 sink_params_ = sink_params;
145 use_sink_params_for_testing_ = true;
146 }
147
148 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698