audio-blocks
Real-time safe abstractions over audio data with support for all common layouts.
Quick Start
Install:
Basic planar usage (most common for DSP):
use *;
// Create a planar block - each channel gets its own buffer
let mut block = new;
// Process per channel
for channel in block.channels_mut
Generic function that accepts any layout:
Block Types
Three layouts supported:
Planar - [[ch0, ch0, ch0], [ch1, ch1, ch1]]
Each channel has its own buffer. Standard for real-time DSP.
Sequential - [ch0, ch0, ch0, ch1, ch1, ch1]
All samples for channel 0, then all samples for channel 1.
Interleaved - [ch0, ch1, ch0, ch1, ch0, ch1]
Channels alternate sample-by-sample. Common in audio APIs.
Core Traits
Write functions that accept any layout:
Generic across float types:
Creating Blocks
Owned Blocks
let mut block = new;
let mut block = new;
let mut block = new;
Allocation only happens here. Never create owned blocks in real-time contexts.
Views (zero-allocation)
let block = from_slice;
let block = from_slice;
let block = from_slice;
From raw pointers:
let block = unsafe ;
Planar requires adapter:
let mut adapter = unsafe ;
let block = adapter.planar_view;
Common Operations
use AudioBlockOps;
block.copy_from_block;
block.fill_with;
block.clear;
block.for_each;
Working with Slices
Convert generic blocks to concrete types for slice access:
Direct slice access on concrete types:
let mut block = new;
let channel: & = block.channel;
let raw_data: & = block.raw_data;
let mut block = new;
let frame: & = block.frame;
let raw_data: & = block.raw_data;
Trait API Reference
AudioBlock
Size and layout:
;
;
;
Sample access:
;
Iteration:
;
;
;
;
Generic view (zero-allocation):
;
Downcast to concrete type:
;
;
;
AudioBlockMut
Everything from AudioBlock plus:
Resizing:
;
;
;
Mutable access:
;
;
+ '_;
;
+ '_;
Generic view (zero-allocation):
;
Downcast to concrete type:
;
;
;
Operations:
;
;
;
;
;
;
Advanced: Variable Buffer Sizes
Blocks separate allocated capacity from visible size. Resize visible portion without reallocation:
let mut block = new; // Allocate 512 frames
block.set_active_num_frames; // Use only 256
Create views with limited visibility:
let view = from_slice_limited;
Auto-resize when copying:
Query allocation:
block.num_channels_allocated;
block.num_frames_allocated;
Advanced: Access Non-Visible Samples
For operations that can safely process all allocated memory:
block.for_each_including_non_visible;
block.enumerate_including_non_visible;
Direct memory access:
let data: & = block.raw_data; // Includes non-visible samples
Performance
Iterator performance varies by layout:
- Sequential/Planar: Channel iteration faster
- Interleaved (many channels): Frame iteration faster
raw_data() access is fastest but exposes non-visible samples. For simple operations like gain, processing all samples (including non-visible) can be more efficient.
Check layout before optimization:
match block.layout
no_std Support
Disable default features. Owned blocks require alloc or std feature.