diff --git a/playback/src/normaliser.rs b/playback/src/normaliser.rs
index a72f61ae..8ee6d10f 100644
--- a/playback/src/normaliser.rs
+++ b/playback/src/normaliser.rs
@@ -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))
diff --git a/playback/src/resampler.rs b/playback/src/resampler.rs
index e847fdaa..3e66791c 100644
--- a/playback/src/resampler.rs
+++ b/playback/src/resampler.rs
@@ -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)
     }
diff --git a/playback/src/sample_pipeline.rs b/playback/src/sample_pipeline.rs
index 5b15cb2e..b6bffb89 100644
--- a/playback/src/sample_pipeline.rs
+++ b/playback/src/sample_pipeline.rs
@@ -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 {