mod mel;
mod stft;
mod window;
pub use mel::{build_mel_filterbank, mel_spectrogram, mfcc, MelConfig};
pub use stft::{
istft, magnitude_spectrogram, phase_spectrogram, power_spectrogram, stft, StreamingFft,
};
pub use window::{
blackman, cola_normalization, hamming, hann, kaiser, rectangular, WindowFunction,
};
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::kernel::Float;
#[derive(Clone, Debug)]
pub struct RingBuffer<T: Float> {
data: Vec<T>,
write_pos: usize,
len: usize,
capacity: usize,
}
impl<T: Float> RingBuffer<T> {
pub fn new(capacity: usize) -> Self {
Self {
data: vec![T::ZERO; capacity],
write_pos: 0,
len: 0,
capacity,
}
}
pub fn push(&mut self, value: T) {
self.data[self.write_pos] = value;
self.write_pos = (self.write_pos + 1) % self.capacity;
if self.len < self.capacity {
self.len += 1;
}
}
pub fn push_slice(&mut self, values: &[T]) {
for &v in values {
self.push(v);
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn is_full(&self) -> bool {
self.len == self.capacity
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn read_last(&self, output: &mut [T]) -> usize {
let n = output.len().min(self.len);
if n == 0 {
return 0;
}
let start = if self.len == self.capacity {
self.write_pos
} else {
0
};
for i in 0..n {
let read_idx = (start + (self.len - n) + i) % self.capacity;
output[i] = self.data[read_idx];
}
n
}
pub fn clear(&mut self) {
self.len = 0;
self.write_pos = 0;
}
pub fn advance(&mut self, n: usize) {
if n >= self.len {
self.clear();
} else {
self.len -= n;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ring_buffer_basic() {
let mut buf: RingBuffer<f64> = RingBuffer::new(4);
buf.push(1.0);
buf.push(2.0);
buf.push(3.0);
assert_eq!(buf.len(), 3);
assert!(!buf.is_full());
let mut out = [0.0; 4];
let n = buf.read_last(&mut out);
assert_eq!(n, 3);
assert_eq!(&out[..3], &[1.0, 2.0, 3.0]);
}
#[test]
fn test_ring_buffer_wrap() {
let mut buf: RingBuffer<f64> = RingBuffer::new(4);
buf.push_slice(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
assert_eq!(buf.len(), 4);
assert!(buf.is_full());
let mut out = [0.0; 4];
buf.read_last(&mut out);
assert_eq!(&out, &[3.0, 4.0, 5.0, 6.0]);
}
#[test]
fn test_ring_buffer_advance() {
let mut buf: RingBuffer<f64> = RingBuffer::new(8);
buf.push_slice(&[1.0, 2.0, 3.0, 4.0]);
buf.advance(2);
assert_eq!(buf.len(), 2);
}
}