use num_traits::Float;
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
#[cfg(feature = "std")]
use std::vec;
use crate::PadMode;
pub fn apply_padding<T: Float>(signal: &[T], pad_amount: usize, mode: PadMode) -> Vec<T> {
let total_len = signal.len() + 2 * pad_amount;
let mut padded = vec![T::zero(); total_len];
padded[pad_amount..pad_amount + signal.len()].copy_from_slice(signal);
match mode {
PadMode::Reflect => {
for i in 0..pad_amount {
if i + 1 < signal.len() {
padded[pad_amount - 1 - i] = signal[i + 1];
}
}
let n = signal.len();
for i in 0..pad_amount {
if n >= 2 && n - 2 >= i {
padded[pad_amount + n + i] = signal[n - 2 - i];
}
}
}
PadMode::Zero => {}
PadMode::Edge => {
if !signal.is_empty() {
for i in 0..pad_amount {
padded[i] = signal[0];
}
for i in 0..pad_amount {
padded[pad_amount + signal.len() + i] = signal[signal.len() - 1];
}
}
}
}
padded
}
pub fn deinterleave<T: Float>(data: &[T], num_channels: usize) -> Vec<Vec<T>> {
assert!(num_channels > 0, "num_channels must be greater than 0");
assert_eq!(
data.len() % num_channels,
0,
"data length ({}) must be divisible by num_channels ({})",
data.len(),
num_channels
);
if data.is_empty() {
return vec![Vec::new(); num_channels];
}
let samples_per_channel = data.len() / num_channels;
let mut channels = vec![Vec::with_capacity(samples_per_channel); num_channels];
for (i, &sample) in data.iter().enumerate() {
channels[i % num_channels].push(sample);
}
channels
}
pub fn deinterleave_into<T: Float>(data: &[T], num_channels: usize, output: &mut [Vec<T>]) {
assert!(num_channels > 0, "num_channels must be greater than 0");
assert_eq!(
output.len(),
num_channels,
"output must have exactly {} channels, got {}",
num_channels,
output.len()
);
assert_eq!(
data.len() % num_channels,
0,
"data length ({}) must be divisible by num_channels ({})",
data.len(),
num_channels
);
if data.is_empty() {
for channel in output.iter_mut() {
channel.clear();
}
return;
}
let samples_per_channel = data.len() / num_channels;
for channel in output.iter_mut() {
channel.clear();
channel.reserve(samples_per_channel);
}
for (i, &sample) in data.iter().enumerate() {
output[i % num_channels].push(sample);
}
}
pub fn interleave<T: Float>(channels: &[Vec<T>]) -> Vec<T> {
assert!(!channels.is_empty(), "channels must not be empty");
if channels[0].is_empty() {
return Vec::new();
}
let num_channels = channels.len();
let samples_per_channel = channels[0].len();
for (i, channel) in channels.iter().enumerate() {
assert_eq!(
channel.len(),
samples_per_channel,
"Channel {} has length {}, expected {}",
i,
channel.len(),
samples_per_channel
);
}
let mut interleaved = Vec::with_capacity(samples_per_channel * num_channels);
for sample_idx in 0..samples_per_channel {
for channel in channels {
interleaved.push(channel[sample_idx]);
}
}
interleaved
}
pub fn interleave_into<T: Float>(channels: &[Vec<T>], output: &mut Vec<T>) {
assert!(!channels.is_empty(), "channels must not be empty");
if channels[0].is_empty() {
output.clear();
return;
}
let num_channels = channels.len();
let samples_per_channel = channels[0].len();
for (i, channel) in channels.iter().enumerate() {
assert_eq!(
channel.len(),
samples_per_channel,
"Channel {} has length {}, expected {}",
i,
channel.len(),
samples_per_channel
);
}
output.clear();
output.reserve(samples_per_channel * num_channels);
for sample_idx in 0..samples_per_channel {
for channel in channels {
output.push(channel[sample_idx]);
}
}
}