Skip to content

Commit 17bc87d

Browse files
authored
Merge pull request #16 from wizenink/staging-0.5.0
Staging 0.5.0
2 parents c86b3e5 + cd7018c commit 17bc87d

File tree

20 files changed

+1172
-62
lines changed

20 files changed

+1172
-62
lines changed

.github/workflows/rust.yml

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,40 @@ env:
1010
CARGO_TERM_COLOR: always
1111

1212
jobs:
13-
build:
14-
13+
# Test with default features (std + rustfft)
14+
test-rustfft:
1515
runs-on: ubuntu-latest
16-
1716
steps:
1817
- uses: actions/checkout@v4
19-
- name: Build
18+
- name: Build with rustfft (default)
2019
run: cargo build --verbose
21-
- name: Run tests
20+
- name: Run tests with rustfft
2221
run: cargo test --verbose
22+
- name: Run tests with rayon
23+
run: cargo test --verbose --features rayon
24+
25+
# Test with microfft backend (no_std)
26+
test-microfft:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
- name: Build with microfft (no_std)
31+
run: cargo build --no-default-features --features microfft-backend --verbose
32+
- name: Run tests with microfft
33+
run: cargo test --no-default-features --features microfft-backend --verbose
34+
- name: Check lib compiles in no_std
35+
run: cargo check --no-default-features --features microfft-backend --lib
36+
37+
# Compare both backends to ensure identical behavior
38+
backend-comparison:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v4
42+
- name: Run backend comparison script
43+
run: ./scripts/compare_backends.sh
44+
- name: Upload comparison results
45+
if: always()
46+
uses: actions/upload-artifact@v4
47+
with:
48+
name: backend-comparison-results
49+
path: results_*.txt

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
/target
2+
*.png
3+
results_microfft.txt
4+
results_rustfft.txt
5+
no_std_test/target

Cargo.lock

Lines changed: 16 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
[package]
22
name = "stft-rs"
3-
description = "Simple, streaming-friendly STFT implementation with mel spectrogram support"
4-
version = "0.4.1"
3+
description = "Simple, streaming-friendly, no_std compliant STFT implementation with mel spectrogram support"
4+
version = "0.5.0"
55
edition = "2024"
66
authors = ["David Maseda Neira <david.masedan@gmail.com>"]
77
license = "MIT"
88
repository = "https://github.com/wizenink/stft-rs"
9+
categories = ["no-std", "mathematics", "science"]
910

1011
[dependencies]
11-
ndarray = "0.17.1"
12-
num-traits = "0.2"
13-
rustfft = "6.4.1"
12+
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
13+
rustfft = { version = "6.4.1", optional = true }
14+
microfft = { version = "0.6.0", optional = true }
1415
rayon = { version = "1.11", optional = true }
1516

1617
[features]
17-
default = ["rayon"]
18+
default = ["std"]
19+
std = ["num-traits/std", "rustfft-backend"]
20+
rustfft-backend = ["dep:rustfft"]
21+
microfft-backend = ["dep:microfft"]
22+
rayon = ["rustfft-backend", "dep:rayon"]
1823

1924
[dev-dependencies]
2025
criterion = { version = "0.7.0", features = ["html_reports"] }

README.md

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ High-quality, streaming-friendly STFT/iSTFT implementation in Rust working with
1212
- **Batch Processing**: Process entire audio buffers at once
1313
- **Streaming Support**: Incremental processing for real-time applications
1414
- **High Quality**: >138 dB SNR reconstruction
15+
- **no_std Support**: Run on embedded systems without the standard library! 🚀
16+
- **Dual FFT Backends**: Choose the right backend for your environment
17+
- `rustfft` (default): Full-featured for std environments, supports f32/f64 and any FFT size
18+
- `microfft`: Lightweight for no_std/embedded, f32 only, power-of-2 sizes up to 4096
1519
- **Dual Reconstruction Modes**:
1620
- **OLA** (Overlap-Add): Optimal for spectral processing
1721
- **WOLA** (Weighted Overlap-Add): Standard implementation
@@ -112,7 +116,7 @@ use stft_rs::prelude::*;
112116

113117
This exports:
114118

115-
- Core types: `BatchStft`, `BatchIstft`, `StreamingStft`, `StreamingIstft`, `StftConfig`, `StftConfigBuilder`, `Spectrum`, `SpectrumFrame`
119+
- Core types: `BatchStft`, `BatchIstft`, `StreamingStft`, `StreamingIstft`, `StftConfig`, `StftConfigBuilder`, `Spectrum`, `SpectrumFrame`, `Complex`
116120
- Type aliases: `StftConfigF32/F64`, `StftConfigBuilderF32/F64`, `BatchStftF32/F64`, `BatchIstftF32/F64`, `StreamingStftF32/F64`, `StreamingIstftF32/F64`, `SpectrumF32/F64`, `SpectrumFrameF32/F64`
117121
- Mel types: `MelConfig`, `MelSpectrum`, `BatchMelSpectrogram`, `StreamingMelSpectrogram`, `MelScale`, `MelNorm` (+ F32/F64 aliases)
118122
- Enums: `ReconstructionMode`, `WindowType`, `PadMode`
@@ -404,10 +408,58 @@ let channels = deinterleave(&interleaved, 2);
404408
let interleaved = interleave(&channels);
405409
```
406410

407-
Disable parallel processing: `cargo build --no-default-features`
408-
409411
See `examples/multichannel_stereo.rs` and `examples/multichannel_midside.rs` for more.
410412

413+
## Embedded / no_std Support
414+
415+
stft-rs can run on embedded systems without the standard library! Perfect for audio processing on microcontrollers, DSPs, and bare-metal environments.
416+
417+
### Using the microfft Backend for no_std
418+
419+
```toml
420+
[dependencies]
421+
stft-rs = { version = "0.5.0", default-features = false, features = ["microfft-backend"] }
422+
```
423+
424+
**Important notes:**
425+
426+
- microfft backend only supports f32 (not f64)
427+
- FFT sizes must be power-of-2 from 2 to 4096
428+
- Requires an allocator (uses `alloc` crate)
429+
430+
### Example no_std Configuration
431+
432+
```rust
433+
#![no_std]
434+
435+
extern crate alloc;
436+
use alloc::vec::Vec;
437+
use stft_rs::prelude::*;
438+
439+
// Works great on embedded!
440+
let config = StftConfigF32::builder()
441+
.fft_size(2048) // Must be power-of-2
442+
.hop_size(512)
443+
.build()
444+
.expect("Valid config");
445+
446+
let stft = BatchStftF32::new(config.clone());
447+
let istft = BatchIstftF32::new(config);
448+
449+
let signal: Vec<f32> = Vec::from_slice(&audio_buffer);
450+
let spectrum = stft.process(&signal);
451+
let reconstructed = istft.process(&spectrum);
452+
```
453+
454+
### Feature Flags
455+
456+
- `std` (default): Standard library support with rustfft backend
457+
- `rustfft-backend`: Use rustfft for FFT (supports f32/f64, any size)
458+
- `microfft-backend`: Use microfft for no_std (f32 only, power-of-2 sizes)
459+
- `rayon`: Enable parallel multi-channel processing (requires std)
460+
461+
**Note:** You cannot enable both `rustfft-backend` and `microfft-backend` at the same time.
462+
411463
## Performance Characteristics
412464

413465
- **Batch Mode**: Optimized for throughput, minimal allocations
@@ -517,8 +569,18 @@ Tests verify:
517569

518570
## Dependencies
519571

520-
- `rustfft`: High-performance FFT implementation
521-
- `ndarray`: Only for internal padding operations (minimal usage)
572+
Core dependencies:
573+
574+
- `num-traits`: Generic numeric traits (no_std compatible with `libm`)
575+
576+
FFT backends (mutually exclusive):
577+
578+
- `rustfft` (default): High-performance FFT for std environments
579+
- `microfft` (optional): Lightweight FFT for no_std/embedded
580+
581+
Optional dependencies:
582+
583+
- `rayon`: Parallel multi-channel processing (requires std)
522584

523585
## License
524586

0 commit comments

Comments
 (0)