Index: content/renderer/media/webrtc_audio_device_impl.cc |
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc |
index 0a34cd323b807be47e28d408748e702d5f40f9db..8db9a444295d2cef0d6d7bb73d2585367bd160b4 100644 |
--- a/content/renderer/media/webrtc_audio_device_impl.cc |
+++ b/content/renderer/media/webrtc_audio_device_impl.cc |
@@ -121,11 +121,11 @@ void WebRtcAudioDeviceImpl::OnSetFormat( |
DVLOG(1) << "WebRtcAudioDeviceImpl::OnSetFormat()"; |
} |
-void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data, |
- int number_of_channels, |
- int number_of_frames, |
+void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus, |
+ int sample_rate, |
int audio_delay_milliseconds) { |
- DCHECK_LE(number_of_frames, output_buffer_size()); |
+ render_buffer_.resize(audio_bus->frames() * audio_bus->channels()); |
+ |
{ |
base::AutoLock auto_lock(lock_); |
DCHECK(audio_transport_callback_); |
@@ -133,37 +133,42 @@ void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data, |
output_delay_ms_ = audio_delay_milliseconds; |
} |
- const int channels = number_of_channels; |
- DCHECK_LE(channels, output_channels()); |
- |
- int samples_per_sec = output_sample_rate(); |
- int samples_per_10_msec = (samples_per_sec / 100); |
- int bytes_per_sample = output_audio_parameters_.bits_per_sample() / 8; |
+ int samples_per_10_msec = (sample_rate / 100); |
+ int bytes_per_sample = sizeof(render_buffer_[0]); |
const int bytes_per_10_msec = |
- channels * samples_per_10_msec * bytes_per_sample; |
- |
- uint32_t num_audio_samples = 0; |
- int accumulated_audio_samples = 0; |
+ audio_bus->channels() * samples_per_10_msec * bytes_per_sample; |
+ DCHECK_EQ(audio_bus->frames() % samples_per_10_msec, 0); |
// Get audio samples in blocks of 10 milliseconds from the registered |
// webrtc::AudioTransport source. Keep reading until our internal buffer |
// is full. |
- while (accumulated_audio_samples < number_of_frames) { |
+ uint32_t num_audio_samples = 0; |
+ int accumulated_audio_samples = 0; |
+ int16* audio_data = &render_buffer_[0]; |
+ while (accumulated_audio_samples < audio_bus->frames()) { |
// Get 10ms and append output to temporary byte buffer. |
audio_transport_callback_->NeedMorePlayData(samples_per_10_msec, |
bytes_per_sample, |
- channels, |
- samples_per_sec, |
+ audio_bus->channels(), |
+ sample_rate, |
audio_data, |
num_audio_samples); |
accumulated_audio_samples += num_audio_samples; |
audio_data += bytes_per_10_msec; |
} |
-} |
-void WebRtcAudioDeviceImpl::SetRenderFormat(const AudioParameters& params) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- output_audio_parameters_ = params; |
+ // De-interleave each channel and convert to 32-bit floating-point |
+ // with nominal range -1.0 -> +1.0 to match the callback format. |
+ audio_bus->FromInterleaved(&render_buffer_[0], |
+ audio_bus->frames(), |
+ bytes_per_sample); |
+ |
+ // Pass the render data to the observers. |
tommi (sloooow) - chröme
2014/01/31 13:58:32
this is terminology again but are observers in thi
no longer working on chromium
2014/02/02 16:50:16
Yes, it is. I have already explained in the header
tommi (sloooow) - chröme
2014/02/04 14:39:14
Observers aren't participants, so this is not an o
|
+ base::AutoLock auto_lock(lock_); |
+ for (RenderDataObservers::const_iterator it = render_data_observers_.begin(); |
+ it != render_data_observers_.end(); ++it) { |
+ (*it)->RenderData(audio_bus, sample_rate, audio_delay_milliseconds); |
+ } |
} |
void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) { |
@@ -369,7 +374,7 @@ int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const { |
int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const { |
DCHECK(initialized_); |
- *available = (output_channels() == 2); |
+ *available = renderer_ ? (renderer_->channels() == 2) : false; |
tommi (sloooow) - chröme
2014/01/31 13:58:32
nit: can also do this
*available = renderer_ && re
no longer working on chromium
2014/02/02 16:50:16
Done.
|
return 0; |
} |
@@ -412,7 +417,7 @@ int32_t WebRtcAudioDeviceImpl::RecordingSampleRate( |
int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( |
uint32_t* samples_per_sec) const { |
- *samples_per_sec = static_cast<uint32_t>(output_sample_rate()); |
+ *samples_per_sec = renderer_ ? renderer_->sample_rate() : 0; |
return 0; |
} |
@@ -465,6 +470,23 @@ WebRtcAudioDeviceImpl::GetDefaultCapturer() const { |
return NULL; |
} |
+void WebRtcAudioDeviceImpl::AddRenderDataObserver( |
+ WebRtcAudioRendererSource* observer) { |
+ DCHECK(observer); |
tommi (sloooow) - chröme
2014/01/31 13:58:32
nice to see the dchecks on observer and std::find.
|
+ base::AutoLock auto_lock(lock_); |
+ DCHECK(std::find(render_data_observers_.begin(), |
+ render_data_observers_.end(), |
+ observer) == render_data_observers_.end()); |
+ render_data_observers_.push_back(observer); |
+} |
+ |
+void WebRtcAudioDeviceImpl::RemoveRenderDataObserver( |
+ WebRtcAudioRendererSource* observer) { |
+ DCHECK(observer); |
+ base::AutoLock auto_lock(lock_); |
+ render_data_observers_.remove(observer); |
+} |
+ |
bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer( |
int* session_id, |
int* output_sample_rate, |