1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! # ruststft
//!
//! A complete short-time Fourier transform (STFT) toolkit for Rust:
//!
//! - **Forward STFT** over real-valued signals, in both *streaming* and *batch*
//! modes, backed by [`realfft`] (≈2× faster and half the memory of a full
//! complex FFT on real input).
//! - **Inverse STFT** with weighted overlap-add (WOLA) for perfect
//! reconstruction.
//! - A **rich window library** (Hann, Hamming, Blackman/-Harris, Nuttall,
//! Bartlett, triangular, Welch, cosine, Tukey, Kaiser, Gaussian, flat-top)
//! with both periodic (spectral-analysis) and symmetric (filter-design)
//! variants.
//! - **Spectrum helpers**: magnitude, power, phase and decibel conversions.
//! - Optional **mel** spectrograms and **MFCC**s (`mel` feature).
//! - Optional `ndarray` I/O (`ndarray`), parallel batch processing
//! (`rayon`) and configuration (de)serialization (`serde`).
//!
//! ## Quick start (batch)
//!
//! ```
//! # #[cfg(feature = "std")] {
//! use ruststft::{Stft, Window};
//!
//! // A 1 kHz tone sampled at 8 kHz.
//! let fs = 8_000.0;
//! let signal: Vec<f64> = (0..8_000)
//! .map(|n| (2.0 * std::f64::consts::PI * 1_000.0 * n as f64 / fs).sin())
//! .collect();
//!
//! let mut stft = Stft::builder()
//! .window(Window::<f64>::hann(1024))
//! .hop_size(256)
//! .build()
//! .unwrap();
//!
//! let spec = stft.spectrogram(&signal);
//! assert_eq!(spec.n_freqs(), 1024 / 2 + 1); // includes the Nyquist bin
//! # }
//! ```
//!
//! ## Streaming
//!
//! ```
//! # #[cfg(feature = "std")] {
//! use ruststft::{Stft, Window};
//!
//! let mut stft = Stft::builder()
//! .window(Window::<f32>::hann(1024))
//! .hop_size(512)
//! .build()
//! .unwrap();
//!
//! let mut column = vec![num_complex::Complex::new(0.0f32, 0.0); stft.n_freqs()];
//! let chunk: Vec<f32> = (0..3000).map(|x| x as f32).collect();
//!
//! stft.append(&chunk);
//! while stft.ready() {
//! stft.process_into(&mut column).unwrap();
//! // ... use `column` ...
//! stft.step();
//! }
//! # }
//! ```
//!
//! ## `no_std`
//!
//! The crate is `#![no_std]` (with `alloc`). The FFT-backed processors
//! ([`Stft`], [`Istft`], batch spectrograms) require the default `std`
//! feature because the underlying FFT backend needs `std`. The window
//! library, [`crate::mel`] filterbank/MFCC math and the
//! [`crate::spectrum`] helpers build without `std`.
extern crate alloc;
pub use ;
pub use StftError;
pub use Sample;
pub use ;
pub use Spectrogram;
pub use ;
pub use ;
// Re-export the complex number type so downstream users do not need to track
// the exact `num-complex` version themselves.
pub use Complex;
// Compile and run the README code examples as doctests (only during testing,
// so the rendered crate docs are unaffected). Keeps the README from rotting.
;