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;
impl NoNormalisation {
fn normalise(samples: &[f64], volume: f64) -> Vec<f64> {
fn normalise(mut samples: Vec<f64>, volume: f64) -> Vec<f64> {
if volume < 1.0 {
let mut output = Vec::with_capacity(samples.len());
output.extend(samples.iter().map(|sample| sample * volume));
output
} else {
samples.to_vec()
samples.iter_mut().for_each(|sample| *sample *= volume);
}
samples
}
}
struct 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 {
let mut output = Vec::with_capacity(samples.len());
output.extend(samples.iter().map(|sample| sample * factor * volume));
output
} else {
samples.to_vec()
samples
.iter_mut()
.for_each(|sample| *sample *= factor * volume);
}
samples
}
}
@ -85,11 +79,9 @@ impl DynamicNormalisation {
self.peak = 0.0;
}
fn normalise(&mut self, samples: &[f64], volume: f64, factor: f64) -> Vec<f64> {
let mut output = Vec::with_capacity(samples.len());
output.extend(samples.iter().map(|sample| {
let mut sample = sample * factor;
fn normalise(&mut self, mut samples: Vec<f64>, volume: f64, factor: f64) -> Vec<f64> {
samples.iter_mut().for_each(|sample| {
*sample *= factor;
// Feedforward limiter in the log domain
// After: Giannoulis, D., Massberg, M., & Reiss, J.D. (2012). Digital Dynamic
@ -154,13 +146,13 @@ impl DynamicNormalisation {
// the default threshold, so that would clip.
// 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::*;
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();
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> {
// Re-interleave the resampled channels.
left_samples
.iter()
.zip(right_samples.iter())
.flat_map(|(&x, &y)| vec![x, y])
.collect()
let mut output = Vec::with_capacity(left_samples.len() + right_samples.len());
output.extend(
left_samples
.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>) {
// Split the stereo interleaved samples into left and right channels.
let (left_samples, right_samples): (Vec<f64>, Vec<f64>) = samples
.chunks(2)
.map(|chunk| {
let [left_sample, right_sample] = [chunk[0], chunk[1]];
(left_sample, right_sample)
})
.unzip();
let samples_len = samples.len() / 2;
let mut left_samples = Vec::with_capacity(samples_len);
let mut right_samples = Vec::with_capacity(samples_len);
left_samples.extend(samples.iter().step_by(2));
right_samples.extend(samples.iter().skip(1).step_by(2));
(left_samples, right_samples)
}

View file

@ -70,7 +70,7 @@ impl SamplePipeline {
if let AudioPacket::Samples(samples) = packet {
self.resampler
.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))
.transpose()?;
} else {