Index: media/base/audio_converter.cc |
diff --git a/media/base/audio_converter.cc b/media/base/audio_converter.cc |
index 48686046fd71178ef38416a153c24641c95d96ff..2e761125cb6cebefcca7cc70bf5f1e5c0dbbe967 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,7 +156,7 @@ void AudioConverter::ConvertWithDelay(const base::TimeDelta& initial_delay, |
} |
void AudioConverter::Convert(AudioBus* dest) { |
- ConvertWithDelay(base::TimeDelta::FromMilliseconds(0), dest); |
+ ConvertWithDelay(0, dest); |
} |
void AudioConverter::SourceCallback(int fifo_frame_delay, AudioBus* dest) { |
@@ -188,15 +180,20 @@ 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_); |
} |
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 +202,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 +240,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 |