Commit 9a0aa1a7 authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

Optimize sample-accurate path for AudioDelayDspKernel::Process

* Replace modulo operations with test and subtraction
* Remove clamping

Using spotify.github.io/web-audio-bench, without this CL we have:

TEST			μs	MIN	Q1	MEDIAN	Q3	MAX
Baseline		393	383	390	393	400	403
DelayAutomation-a-rate	1053	1018	1050	1053	1065	1102

With this CL:
Baseline		393	387	393	393	397	400
DelayAutomation-a-rate	485	437	443	485	487	513

The optimized version takes about half the time.

Bug: 1012198
Change-Id: I643cbf137038714aad5fa2fb66299a8412e667bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1864415Reviewed-by: default avatarAndrew MacPherson <andrew.macpherson@soundtrap.com>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707026}
parent 4b6d73e6
......@@ -89,37 +89,44 @@ void AudioDelayDSPKernel::Process(const float* source,
float* delay_times = delay_times_.Data();
CalculateSampleAccurateValues(delay_times, frames_to_process);
int w_index = write_index_;
for (unsigned i = 0; i < frames_to_process; ++i) {
double delay_time = delay_times[i];
// TODO(crbug.com/1013345): Don't need this if that bug is fixed
if (std::isnan(delay_time))
delay_time = max_time;
else
delay_time = clampTo(delay_time, 0.0, max_time);
double desired_delay_frames = delay_time * sample_rate;
double read_position =
write_index_ + buffer_length - desired_delay_frames;
double read_position = w_index + buffer_length - desired_delay_frames;
if (read_position >= buffer_length)
read_position -= buffer_length;
// Linearly interpolate in-between delay times.
int read_index1 = static_cast<int>(read_position);
int read_index2 = (read_index1 + 1) % buffer_length;
int read_index2 = read_index1 + 1;
if (read_index2 >= static_cast<int>(buffer_length))
read_index2 -= buffer_length;
double interpolation_factor = read_position - read_index1;
double input = static_cast<float>(*source++);
buffer[write_index_] = static_cast<float>(input);
write_index_ = (write_index_ + 1) % buffer_length;
buffer[w_index] = *source++;
++w_index;
if (w_index >= static_cast<int>(buffer_length))
w_index -= buffer_length;
double sample1 = buffer[read_index1];
double sample2 = buffer[read_index2];
float sample1 = buffer[read_index1];
float sample2 = buffer[read_index2];
double output = (1.0 - interpolation_factor) * sample1 +
interpolation_factor * sample2;
double output =
(1 - interpolation_factor) * sample1 + interpolation_factor * sample2;
*destination++ = static_cast<float>(output);
}
write_index_ = w_index;
} else {
// This is basically the same as above, but optimized for the case where the
// delay time is constant for the current render.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment