Use as_chunks in favour of chunks_exact in convert_stereo_to_mono_audio

This commit is contained in:
Niko 2025-09-29 13:07:38 -07:00
parent fcd6a538e6
commit 4e2c466e79
No known key found for this signature in database

View file

@ -37,10 +37,12 @@ pub fn convert_integer_to_float_audio(
/// Convert 32-bit floating point stereo PCM audio to 32-bit floating point mono PCM audio. /// Convert 32-bit floating point stereo PCM audio to 32-bit floating point mono PCM audio.
/// ///
/// # Arguments /// # Arguments
/// * `samples` - The array of 32-bit floating point stereo PCM audio samples. /// * `input` - The array of 32-bit floating point stereo PCM audio samples.
/// * `output` - An output place to write all the mono samples.
/// ///
/// # Errors /// # Errors
/// * if `samples.len()` is odd /// * if `samples.len()` is odd ([`WhisperError::HalfSampleMissing`])
/// * if `input.len() / 2 < samples.len()` ([`WhisperError::InputOutputLengthMismatch`])
/// ///
/// # Returns /// # Returns
/// A vector of 32-bit floating point mono PCM audio samples. /// A vector of 32-bit floating point mono PCM audio samples.
@ -51,15 +53,24 @@ pub fn convert_integer_to_float_audio(
/// let samples = [0.0f32; 1024]; /// let samples = [0.0f32; 1024];
/// let mono = convert_stereo_to_mono_audio(&samples).expect("should be no half samples missing"); /// let mono = convert_stereo_to_mono_audio(&samples).expect("should be no half samples missing");
/// ``` /// ```
pub fn convert_stereo_to_mono_audio(samples: &[f32]) -> Result<Vec<f32>, WhisperError> { pub fn convert_stereo_to_mono_audio(input: &[f32], output: &mut [f32]) -> Result<(), WhisperError> {
if samples.len() & 1 != 0 { let (input, []) = input.as_chunks::<2>() else {
return Err(WhisperError::HalfSampleMissing(samples.len())); // we only hit this branch if the second binding was not empty
// or in other words, if input.len() % 2 != 0
return Err(WhisperError::HalfSampleMissing(input.len()));
};
if output.len() != input.len() {
return Err(WhisperError::InputOutputLengthMismatch {
input_len: input.len(),
output_len: output.len(),
});
} }
Ok(samples for ([left, right], output) in input.iter().zip(output) {
.chunks_exact(2) *output = (left + right) / 2.0;
.map(|x| (x[0] + x[1]) / 2.0) }
.collect())
Ok(())
} }
#[cfg(test)] #[cfg(test)]
@ -85,17 +96,54 @@ mod test {
samples samples
} }
#[test]
pub fn assert_stereo_to_mono_success() {
let samples = random_sample_data::<f32>();
let mut output = vec![0.0; samples.len() / 2];
let result = convert_stereo_to_mono_audio(&samples, &mut output);
assert!(result.is_ok());
}
#[test] #[test]
pub fn assert_stereo_to_mono_err() { pub fn assert_stereo_to_mono_err() {
let samples = random_sample_data::<f32>(); let samples = random_sample_data::<f32>();
let mono = convert_stereo_to_mono_audio(&samples); let mut output = vec![0.0; (samples.len() / 2) - 1];
assert!(mono.is_err()); let result = convert_stereo_to_mono_audio(&samples, &mut output);
assert!(
match result {
Err(WhisperError::InputOutputLengthMismatch {
input_len,
output_len,
}) => {
assert_eq!(
input_len,
samples.len() / 2,
"resulting input length is not half of num samples"
);
assert_eq!(
output_len,
output.len(),
"resulting output length is not the same as the output array"
);
true
}
_ => false,
},
"result was not a length mismatch: got {:?}",
result
);
} }
#[bench] #[bench]
pub fn bench_stereo_to_mono(b: &mut test::Bencher) { pub fn bench_stereo_to_mono(b: &mut test::Bencher) {
let samples = random_sample_data::<f32>(); let samples = random_sample_data::<f32>();
b.iter(|| black_box(convert_stereo_to_mono_audio(black_box(&samples)))); let mut output = vec![0.0; samples.len() / 2];
b.iter(|| {
black_box(convert_stereo_to_mono_audio(
black_box(&samples),
black_box(&mut output),
))
});
} }
#[bench] #[bench]