Reduce allocations

This commit is contained in:
JasonLG1979 2023-06-26 05:11:30 -05:00
parent 8e6d452765
commit 98f1fe84dd
3 changed files with 37 additions and 40 deletions

View file

@ -10,32 +10,26 @@ use crate::{
struct NoNormalisation; struct NoNormalisation;
impl NoNormalisation { impl NoNormalisation {
fn normalise(samples: &[f64], volume: f64) -> Vec<f64> { fn normalise(mut samples: Vec<f64>, volume: f64) -> Vec<f64> {
if volume < 1.0 { if volume < 1.0 {
let mut output = Vec::with_capacity(samples.len()); samples.iter_mut().for_each(|sample| *sample *= volume);
output.extend(samples.iter().map(|sample| sample * volume));
output
} else {
samples.to_vec()
} }
samples
} }
} }
struct BasicNormalisation; struct BasicNormalisation;
impl BasicNormalisation { impl BasicNormalisation {
fn normalise(samples: &[f64], volume: f64, factor: f64) -> Vec<f64> { fn normalise(mut samples: Vec<f64>, volume: f64, factor: f64) -> Vec<f64> {
if volume < 1.0 || factor < 1.0 { if volume < 1.0 || factor < 1.0 {
let mut output = Vec::with_capacity(samples.len()); samples
.iter_mut()
output.extend(samples.iter().map(|sample| sample * factor * volume)); .for_each(|sample| *sample *= factor * volume);
output
} else {
samples.to_vec()
} }
samples
} }
} }
@ -85,11 +79,9 @@ impl DynamicNormalisation {
self.peak = 0.0; self.peak = 0.0;
} }
fn normalise(&mut self, samples: &[f64], volume: f64, factor: f64) -> Vec<f64> { fn normalise(&mut self, mut samples: Vec<f64>, volume: f64, factor: f64) -> Vec<f64> {
let mut output = Vec::with_capacity(samples.len()); samples.iter_mut().for_each(|sample| {
*sample *= factor;
output.extend(samples.iter().map(|sample| {
let mut sample = sample * factor;
// Feedforward limiter in the log domain // Feedforward limiter in the log domain
// After: Giannoulis, D., Massberg, M., & Reiss, J.D. (2012). Digital Dynamic // After: Giannoulis, D., Massberg, M., & Reiss, J.D. (2012). Digital Dynamic
@ -154,13 +146,13 @@ impl DynamicNormalisation {
// the default threshold, so that would clip. // the default threshold, so that would clip.
// steps 7-8: conversion into level and multiplication into gain stage // steps 7-8: conversion into level and multiplication into gain stage
sample *= db_to_ratio(-self.peak); *sample *= db_to_ratio(-self.peak);
} }
sample * volume *sample *= volume
})); });
output samples
} }
} }
@ -204,7 +196,7 @@ impl Normalisation {
} }
} }
fn normalise(&mut self, samples: &[f64], volume: f64, factor: f64) -> Vec<f64> { fn normalise(&mut self, samples: Vec<f64>, volume: f64, factor: f64) -> Vec<f64> {
use Normalisation::*; use Normalisation::*;
match self { match self {
@ -236,7 +228,7 @@ impl Normaliser {
} }
} }
pub fn normalise(&mut self, samples: &[f64]) -> AudioPacket { pub fn normalise(&mut self, samples: Vec<f64>) -> AudioPacket {
let volume = self.volume_getter.attenuation_factor(); let volume = self.volume_getter.attenuation_factor();
AudioPacket::Samples(self.normalisation.normalise(samples, volume, self.factor)) AudioPacket::Samples(self.normalisation.normalise(samples, volume, self.factor))

View file

@ -469,22 +469,27 @@ impl StereoInterleavedResampler {
fn interleave_samples(left_samples: &[f64], right_samples: &[f64]) -> Vec<f64> { fn interleave_samples(left_samples: &[f64], right_samples: &[f64]) -> Vec<f64> {
// Re-interleave the resampled channels. // Re-interleave the resampled channels.
left_samples let mut output = Vec::with_capacity(left_samples.len() + right_samples.len());
.iter()
.zip(right_samples.iter()) output.extend(
.flat_map(|(&x, &y)| vec![x, y]) left_samples
.collect() .iter()
.zip(right_samples.iter())
.flat_map(|(&left, &right)| std::iter::once(left).chain(std::iter::once(right))),
);
output
} }
fn deinterleave_samples(samples: &[f64]) -> (Vec<f64>, Vec<f64>) { fn deinterleave_samples(samples: &[f64]) -> (Vec<f64>, Vec<f64>) {
// Split the stereo interleaved samples into left and right channels. // Split the stereo interleaved samples into left and right channels.
let (left_samples, right_samples): (Vec<f64>, Vec<f64>) = samples let samples_len = samples.len() / 2;
.chunks(2)
.map(|chunk| { let mut left_samples = Vec::with_capacity(samples_len);
let [left_sample, right_sample] = [chunk[0], chunk[1]]; let mut right_samples = Vec::with_capacity(samples_len);
(left_sample, right_sample)
}) left_samples.extend(samples.iter().step_by(2));
.unzip(); right_samples.extend(samples.iter().skip(1).step_by(2));
(left_samples, right_samples) (left_samples, right_samples)
} }

View file

@ -70,7 +70,7 @@ impl SamplePipeline {
if let AudioPacket::Samples(samples) = packet { if let AudioPacket::Samples(samples) = packet {
self.resampler self.resampler
.resample(&samples) .resample(&samples)
.map(|processed_samples| self.normaliser.normalise(&processed_samples)) .map(|processed_samples| self.normaliser.normalise(processed_samples))
.map(|new_packet| self.sink.write(new_packet, &mut self.converter)) .map(|new_packet| self.sink.write(new_packet, &mut self.converter))
.transpose()?; .transpose()?;
} else { } else {