Commit b274d7cd authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

More micro-opts for AudioDelayDspKernel

Benchmarks (https://spotify.github.io/web-audio-bench/) using default
number of runs and duration:

Without this CL:
TEST	                μs	MIN	Q1	MEDIAN	Q3	MAX
Baseline	        708	708	792	804	817	1595
Delay-default	        372	372	472	499	536	4723
Delay-0.1	        409	409	498	527	559	1639
DelayAutomation-a-rate	640	640	814	842	874	1018
DelayAutomation-k-rate	415	415	500	524	559	1676

With this CL
TEST	                μs	MIN	Q1	MEDIAN	Q3	MAX
Baseline	        767	767	793	804	821	1295
Delay-default	        262	262	332	354	388	3840
Delay-0.1	        284	284	355	382	415	1773
DelayAutomation-a-rate	640	640	741	761	797	1012
DelayAutomation-k-rate	264	264	367	388	421	1812

So we see that delay tests are improved by about 30%, except for the
a-rate case.  The changes for a-rate didn't have any measurable impact.

Bug: 1054416
Change-Id: I4d3428fad6a13fd0632e09f7c03dca051ae09b87
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1867377
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743362}
parent 13bb90fd
...@@ -79,14 +79,14 @@ double AudioDelayDSPKernel::DelayTime(float sample_rate) { ...@@ -79,14 +79,14 @@ double AudioDelayDSPKernel::DelayTime(float sample_rate) {
void AudioDelayDSPKernel::Process(const float* source, void AudioDelayDSPKernel::Process(const float* source,
float* destination, float* destination,
uint32_t frames_to_process) { uint32_t frames_to_process) {
size_t buffer_length = buffer_.size(); int buffer_length = buffer_.size();
float* buffer = buffer_.Data(); float* buffer = buffer_.Data();
DCHECK(buffer_length); DCHECK(buffer_length);
DCHECK(source); DCHECK(source);
DCHECK(destination); DCHECK(destination);
DCHECK_GE(write_index_, 0); DCHECK_GE(write_index_, 0);
DCHECK_LT(static_cast<size_t>(write_index_), buffer_length); DCHECK_LT(write_index_, buffer_length);
float sample_rate = this->SampleRate(); float sample_rate = this->SampleRate();
double max_time = MaxDelayTime(); double max_time = MaxDelayTime();
...@@ -112,28 +112,25 @@ void AudioDelayDSPKernel::Process(const float* source, ...@@ -112,28 +112,25 @@ void AudioDelayDSPKernel::Process(const float* source,
// Linearly interpolate in-between delay times. // Linearly interpolate in-between delay times.
int read_index1 = static_cast<int>(read_position); int read_index1 = static_cast<int>(read_position);
DCHECK_GE(read_index1, 0); DCHECK_GE(read_index1, 0);
DCHECK_LT(static_cast<size_t>(read_index1), buffer_length); DCHECK_LT(read_index1, buffer_length);
int read_index2 = read_index1 + 1; int read_index2 = read_index1 + 1;
if (read_index2 >= static_cast<int>(buffer_length)) if (read_index2 >= buffer_length)
read_index2 -= buffer_length; read_index2 -= buffer_length;
DCHECK_GE(read_index2, 0); DCHECK_GE(read_index2, 0);
DCHECK_LT(static_cast<size_t>(read_index2), buffer_length); DCHECK_LT(read_index2, buffer_length);
double interpolation_factor = read_position - read_index1;
buffer[w_index] = *source++; buffer[w_index] = *source++;
++w_index; float interpolation_factor = read_position - read_index1;
if (w_index >= static_cast<int>(buffer_length))
w_index -= buffer_length;
float sample1 = buffer[read_index1]; float sample1 = buffer[read_index1];
float sample2 = buffer[read_index2]; float sample2 = buffer[read_index2];
double output = ++w_index;
(1 - interpolation_factor) * sample1 + interpolation_factor * sample2; if (w_index >= buffer_length)
w_index -= buffer_length;
*destination++ = static_cast<float>(output); *destination++ = sample1 + interpolation_factor * (sample2 - sample1);
} }
write_index_ = w_index; write_index_ = w_index;
...@@ -152,7 +149,8 @@ void AudioDelayDSPKernel::Process(const float* source, ...@@ -152,7 +149,8 @@ void AudioDelayDSPKernel::Process(const float* source,
// Make sure the delay time is in a valid range. // Make sure the delay time is in a valid range.
delay_time = clampTo(delay_time, 0.0, max_time); delay_time = clampTo(delay_time, 0.0, max_time);
double desired_delay_frames = delay_time * sample_rate; double desired_delay_frames = delay_time * sample_rate;
double read_position = write_index_ + buffer_length - desired_delay_frames; int w_index = write_index_;
double read_position = w_index + buffer_length - desired_delay_frames;
if (read_position >= buffer_length) if (read_position >= buffer_length)
read_position -= buffer_length; read_position -= buffer_length;
...@@ -161,34 +159,34 @@ void AudioDelayDSPKernel::Process(const float* source, ...@@ -161,34 +159,34 @@ void AudioDelayDSPKernel::Process(const float* source,
// interpolation. // interpolation.
int read_index1 = static_cast<int>(read_position); int read_index1 = static_cast<int>(read_position);
int read_index2 = (read_index1 + 1) % buffer_length; int read_index2 = (read_index1 + 1) % buffer_length;
double interp_factor = read_position - read_index1; float interp_factor = read_position - read_index1;
int w_index = write_index_; float* w = &buffer[w_index];
float* r1 = &buffer[read_index1];
float* r2 = &buffer[read_index2];
float* buffer_end = &buffer[buffer_length];
for (unsigned i = 0; i < frames_to_process; ++i) { for (unsigned i = 0; i < frames_to_process; ++i) {
// Copy the latest sample into the buffer. Needed because // Copy the latest sample into the buffer. Needed because
// w_index could be the same as read_index1 or read_index2. // w_index could be the same as read_index1 or read_index2.
buffer[w_index] = *source++; *w++ = *source++;
float sample1 = buffer[read_index1]; float sample1 = *r1++;
float sample2 = buffer[read_index2]; float sample2 = *r2++;
// Update the indices and wrap them to the beginning of the buffer if // Update the indices and wrap them to the beginning of the buffer if
// needed. // needed.
++w_index; if (w >= buffer_end)
++read_index1; w = buffer;
++read_index2; if (r1 >= buffer_end)
if (w_index >= static_cast<int>(buffer_length)) r1 = buffer;
w_index -= buffer_length; if (r2 >= buffer_end)
if (read_index1 >= static_cast<int>(buffer_length)) r2 = buffer;
read_index1 -= buffer_length;
if (read_index2 >= static_cast<int>(buffer_length))
read_index2 -= buffer_length;
// Linearly interpolate between samples. // Linearly interpolate between samples.
*destination++ = (1 - interp_factor) * sample1 + interp_factor * sample2; *destination++ = sample1 + interp_factor * (sample2 - sample1);
} }
write_index_ = w_index; write_index_ = w - buffer;
} }
} }
......
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