OLD | NEW |
---|---|
(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 } | |
27 | |
28 WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() { | |
29 if (audio_converter_.get()) | |
30 audio_converter_->RemoveInput(this); | |
31 } | |
32 | |
33 void WebRtcLocalAudioSourceProvider::Initialize( | |
34 const media::AudioParameters& source_params) { | |
35 DCHECK(thread_checker_.CalledOnValidThread()); | |
36 // Use the native audio output hardware sample-rate for the sink. | |
37 media::AudioHardwareConfig* hardware_config = | |
tommi (sloooow) - chröme
2013/09/06 11:20:30
FYI this needs to change probably before you can l
no longer working on chromium
2013/09/10 12:43:15
As discussed offline, we have to keep this for now
| |
38 RenderThreadImpl::current()->GetAudioHardwareConfig(); | |
39 int sample_rate = hardware_config->GetOutputSampleRate(); | |
40 media::AudioParameters sink_params( | |
41 source_params.format(), media::CHANNEL_LAYOUT_STEREO, | |
42 sample_rate, source_params.bits_per_sample(), kWebAudioRenderBufferSize); | |
43 | |
44 base::AutoLock auto_lock(lock_); | |
45 source_params_ = source_params; | |
46 audio_converter_.reset( | |
47 new media::AudioConverter(source_params, sink_params, true)); | |
48 audio_converter_->AddInput(this); | |
49 fifo_.reset(new media::AudioFifo( | |
50 source_params.channels(), | |
51 kMaxNumberOfBuffer * source_params.frames_per_buffer())); | |
52 } | |
53 | |
54 void WebRtcLocalAudioSourceProvider::DeliverData( | |
55 media::AudioBus* audio_source, | |
56 int audio_delay_milliseconds, | |
57 int volume, | |
58 bool key_pressed) { | |
59 base::AutoLock auto_lock(lock_); | |
60 if (!is_enabled_) | |
61 return; | |
62 | |
63 DCHECK(fifo_.get()); | |
64 | |
65 if (fifo_->frames() + audio_source->frames() <= fifo_->max_frames()) { | |
66 fifo_->Push(audio_source); | |
67 } else { | |
68 // This can happen if the data in FIFO is too slowed to be consumed or | |
69 // WebAudio stops consuming data. | |
70 DLOG(WARNING) << "Local source provicer FIFO is full" << fifo_->frames(); | |
71 } | |
72 | |
73 // Cache the values for GetStreamInfo(). | |
tommi (sloooow) - chröme
2013/09/06 11:20:30
if you change the function name, please also updat
no longer working on chromium
2013/09/10 12:43:15
Done.
| |
74 last_fill_ = base::TimeTicks::Now(); | |
75 audio_delay_ms_ = audio_delay_milliseconds; | |
76 volume_ = volume; | |
77 key_pressed_ = key_pressed; | |
78 } | |
79 | |
80 void WebRtcLocalAudioSourceProvider::GetStreamInfo( | |
81 int* delay_ms, int* volume, bool* key_pressed) { | |
82 int elapsed_ms = 0; | |
83 if (!last_fill_.is_null()) { | |
tommi (sloooow) - chröme
2013/09/06 11:20:30
there's no locking here. add a thread check?
no longer working on chromium
2013/09/10 12:43:15
I have already added a thread check for the Initia
| |
84 elapsed_ms = static_cast<int>( | |
85 (base::TimeTicks::Now() - last_fill_).InMilliseconds()); | |
86 } | |
87 *delay_ms = audio_delay_ms_ + elapsed_ms + | |
88 static_cast<int>(1000 * fifo_->frames() / source_params_.sample_rate()); | |
89 *volume = volume_; | |
90 *key_pressed = key_pressed_; | |
91 } | |
92 | |
93 void WebRtcLocalAudioSourceProvider::setClient( | |
94 WebKit::WebAudioSourceProviderClient* client) { | |
95 NOTIMPLEMENTED(); | |
96 } | |
97 | |
98 void WebRtcLocalAudioSourceProvider::provideInput( | |
99 const WebVector<float*>& audio_data, size_t number_of_frames) { | |
100 DCHECK_EQ(number_of_frames, kWebAudioRenderBufferSize); | |
101 if (!bus_wrapper_ || | |
102 static_cast<size_t>(bus_wrapper_->channels()) != audio_data.size()) { | |
103 bus_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size()); | |
104 } | |
105 | |
106 bus_wrapper_->set_frames(number_of_frames); | |
107 for (size_t i = 0; i < audio_data.size(); ++i) | |
108 bus_wrapper_->SetChannelData(i, audio_data[i]); | |
109 | |
110 base::AutoLock auto_lock(lock_); | |
111 DCHECK(audio_converter_.get()); | |
112 DCHECK(fifo_.get()); | |
113 is_enabled_ = true; | |
114 audio_converter_->Convert(bus_wrapper_.get()); | |
115 } | |
116 | |
117 double WebRtcLocalAudioSourceProvider::ProvideInput( | |
118 media::AudioBus* audio_bus, base::TimeDelta buffer_delay) { | |
119 if (fifo_->frames() >= audio_bus->frames()) { | |
120 fifo_->Consume(audio_bus, 0, audio_bus->frames()); | |
121 } else { | |
122 DLOG(WARNING) << "Underrun, FIFO has data " << fifo_->frames() | |
123 << " samples but " << audio_bus->frames() | |
124 << " samples are needed"; | |
125 fifo_->Consume(audio_bus, 0, fifo_->frames()); | |
126 } | |
127 | |
128 return 1.0; | |
129 } | |
130 | |
131 } // namespace content | |
OLD | NEW |