Chromium Code Reviews| Index: media/base/audio_converter.cc |
| diff --git a/media/base/audio_converter.cc b/media/base/audio_converter.cc |
| index 48686046fd71178ef38416a153c24641c95d96ff..47259c51824b8d33e9db0e0618ce7adf1b1a8ba6 100644 |
| --- a/media/base/audio_converter.cc |
| +++ b/media/base/audio_converter.cc |
| @@ -27,7 +27,10 @@ AudioConverter::AudioConverter(const AudioParameters& input_params, |
| bool disable_fifo) |
| : chunk_size_(input_params.frames_per_buffer()), |
| downmix_early_(false), |
| - resampler_frame_delay_(0), |
| + initial_frames_delayed_(0), |
| + resampler_frames_delayed_(0), |
| + io_sample_rate_ratio_(input_params.sample_rate() / |
| + static_cast<double>(output_params.sample_rate())), |
| input_channel_count_(input_params.channels()) { |
| CHECK(input_params.IsValid()); |
| CHECK(output_params.IsValid()); |
| @@ -51,23 +54,12 @@ AudioConverter::AudioConverter(const AudioParameters& input_params, |
| << output_params.sample_rate(); |
| const int request_size = disable_fifo ? SincResampler::kDefaultRequestSize : |
| input_params.frames_per_buffer(); |
| - const double io_sample_rate_ratio = |
| - input_params.sample_rate() / |
| - static_cast<double>(output_params.sample_rate()); |
| resampler_.reset(new MultiChannelResampler( |
| downmix_early_ ? output_params.channels() : input_params.channels(), |
| - io_sample_rate_ratio, |
| - request_size, |
| + io_sample_rate_ratio_, request_size, |
| base::Bind(&AudioConverter::ProvideInput, base::Unretained(this)))); |
| } |
| - input_frame_duration_ = base::TimeDelta::FromMicroseconds( |
| - base::Time::kMicrosecondsPerSecond / |
| - static_cast<double>(input_params.sample_rate())); |
| - output_frame_duration_ = base::TimeDelta::FromMicroseconds( |
| - base::Time::kMicrosecondsPerSecond / |
| - static_cast<double>(output_params.sample_rate())); |
| - |
| // The resampler can be configured to work with a specific request size, so a |
| // FIFO is not necessary when resampling. |
| if (disable_fifo || resampler_) |
| @@ -123,9 +115,9 @@ void AudioConverter::PrimeWithSilence() { |
| } |
| } |
| -void AudioConverter::ConvertWithDelay(const base::TimeDelta& initial_delay, |
| +void AudioConverter::ConvertWithDelay(uint32_t initial_frames_delayed, |
| AudioBus* dest) { |
| - initial_delay_ = initial_delay; |
| + initial_frames_delayed_ = initial_frames_delayed; |
| if (transform_inputs_.empty()) { |
| dest->Zero(); |
| @@ -164,9 +156,10 @@ void AudioConverter::ConvertWithDelay(const base::TimeDelta& initial_delay, |
| } |
| void AudioConverter::Convert(AudioBus* dest) { |
| - ConvertWithDelay(base::TimeDelta::FromMilliseconds(0), dest); |
| + ConvertWithDelay(0, dest); |
| } |
| +// TODO - make that a uint32_t |
|
DaleCurtis
2016/05/24 20:27:02
?
chcunningham
2016/05/25 18:21:15
Woops. Was a note-to-self about fifo_frame_delay,
|
| void AudioConverter::SourceCallback(int fifo_frame_delay, AudioBus* dest) { |
| const bool needs_downmix = channel_mixer_ && downmix_early_; |
| @@ -188,15 +181,23 @@ void AudioConverter::SourceCallback(int fifo_frame_delay, AudioBus* dest) { |
| DCHECK_EQ(temp_dest->frames(), mixer_input_audio_bus_->frames()); |
| DCHECK_EQ(temp_dest->channels(), mixer_input_audio_bus_->channels()); |
| - // Calculate the buffer delay for this callback. |
| - base::TimeDelta buffer_delay = initial_delay_; |
| + // |total_frames_delayed| is reported to the *input* source in terms of the |
| + // *input* sample rate. |initial_frames_delayed_| is given in terms of the |
| + // output sample rate, so we scale by sample rate ratio (in/out). |
| + uint32_t total_frames_delayed = |
| + std::round(initial_frames_delayed_ * io_sample_rate_ratio_); |
| if (resampler_) { |
| - buffer_delay += base::TimeDelta::FromMicroseconds( |
| - resampler_frame_delay_ * output_frame_duration_.InMicroseconds()); |
| + // |resampler_frames_delayed_| tallies frames queued up inside the resampler |
| + // that are already converted to the output format. Scale by ratio to get |
| + // delay in terms of input sample rate. |
| + total_frames_delayed += |
| + std::round(resampler_frames_delayed_ * io_sample_rate_ratio_); |
| + LOG(ERROR) << __FUNCTION__ |
|
DaleCurtis
2016/05/24 20:27:02
Remove?
chcunningham
2016/05/25 18:21:15
Done.
|
| + << " reampler_frames_delayed:" << resampler_frames_delayed_ |
| + << " total frames_delayed:" << total_frames_delayed; |
| } |
| if (audio_fifo_) { |
| - buffer_delay += base::TimeDelta::FromMicroseconds( |
| - fifo_frame_delay * input_frame_duration_.InMicroseconds()); |
| + total_frames_delayed += fifo_frame_delay; |
| } |
| // If we only have a single input, avoid an extra copy. |
| @@ -205,8 +206,8 @@ void AudioConverter::SourceCallback(int fifo_frame_delay, AudioBus* dest) { |
| // Have each mixer render its data into an output buffer then mix the result. |
| for (auto* input : transform_inputs_) { |
| - const float volume = input->ProvideInput(provide_input_dest, buffer_delay); |
| - |
| + const float volume = |
| + input->ProvideInput(provide_input_dest, total_frames_delayed); |
| // Optimize the most common single input, full volume case. |
| if (input == transform_inputs_.front()) { |
| if (volume == 1.0f) { |
| @@ -243,7 +244,7 @@ void AudioConverter::SourceCallback(int fifo_frame_delay, AudioBus* dest) { |
| } |
| void AudioConverter::ProvideInput(int resampler_frame_delay, AudioBus* dest) { |
| - resampler_frame_delay_ = resampler_frame_delay; |
| + resampler_frames_delayed_ = resampler_frame_delay; |
| if (audio_fifo_) |
| audio_fifo_->Consume(dest, dest->frames()); |
| else |