Skip to main content
Signal specifications define the characteristics of an audio signal including sample rate and channel configuration.

SignalSpec

SignalSpec describes the fundamental properties of an audio signal.
pub struct SignalSpec {
    pub rate: u32,
    pub channels: Channels,
}
rate
u32
Sample rate in hertz (Hz). Common values: 44100, 48000, 96000
channels
Channels
Channel configuration as a bitmask

Creating SignalSpec

new

pub fn new(rate: u32, channels: Channels) -> Self
Creates a SignalSpec with the specified sample rate and channel configuration.
rate
u32
required
Sample rate in Hz
channels
Channels
required
Channel bitmask
Example:
use symphonia::core::audio::{SignalSpec, Channels};

let spec = SignalSpec::new(
    48000,
    Channels::FRONT_LEFT | Channels::FRONT_RIGHT
);

new_with_layout

pub fn new_with_layout(rate: u32, layout: Layout) -> Self
Creates a SignalSpec using a standard channel layout.
rate
u32
required
Sample rate in Hz
layout
Layout
required
Standard channel layout (Mono, Stereo, etc.)
Example:
use symphonia::core::audio::{SignalSpec, Layout};

let stereo_spec = SignalSpec::new_with_layout(48000, Layout::Stereo);
let mono_spec = SignalSpec::new_with_layout(44100, Layout::Mono);
let surround_spec = SignalSpec::new_with_layout(48000, Layout::FivePointOne);

Channels

Channels is a bitmask representing the audio channels in a signal. The first 18 channels are compatible with Microsoft’s WAVEFORMATEXTENSIBLE structure.
pub struct Channels: u32

Standard Channel Flags

FRONT_LEFT
0x0001
Front-left (left) or Mono channel
FRONT_RIGHT
0x0002
Front-right (right) channel
FRONT_CENTRE
0x0004
Front-centre (center) channel
LFE1
0x0008
Low frequency effects channel 1 (subwoofer)
REAR_LEFT
0x0010
Rear-left (surround rear left) channel
REAR_RIGHT
0x0020
Rear-right (surround rear right) channel
FRONT_LEFT_CENTRE
0x0040
Front left-of-centre channel
FRONT_RIGHT_CENTRE
0x0080
Front right-of-centre channel
REAR_CENTRE
0x0100
Rear-centre (surround rear centre) channel
SIDE_LEFT
0x0200
Side left (surround left) channel
SIDE_RIGHT
0x0400
Side right (surround right) channel

Additional Channel Flags

Channels also supports additional positions:
  • TOP_CENTRE, TOP_FRONT_LEFT, TOP_FRONT_CENTRE, TOP_FRONT_RIGHT
  • TOP_REAR_LEFT, TOP_REAR_CENTRE, TOP_REAR_RIGHT
  • REAR_LEFT_CENTRE, REAR_RIGHT_CENTRE
  • FRONT_LEFT_WIDE, FRONT_RIGHT_WIDE
  • FRONT_LEFT_HIGH, FRONT_CENTRE_HIGH, FRONT_RIGHT_HIGH
  • LFE2 - Second low frequency channel

Channels Methods

count

pub fn count(self) -> usize
Returns the number of channels in the bitmask. Example:
let channels = Channels::FRONT_LEFT | Channels::FRONT_RIGHT;
assert_eq!(channels.count(), 2);

let surround = Channels::FRONT_LEFT | Channels::FRONT_RIGHT 
             | Channels::FRONT_CENTRE | Channels::LFE1
             | Channels::REAR_LEFT | Channels::REAR_RIGHT;
assert_eq!(surround.count(), 6);

iter

pub fn iter(&self) -> ChannelsIter
Returns an iterator over individual channels in the bitmask. Example:
let channels = Channels::FRONT_LEFT | Channels::FRONT_RIGHT;

for channel in channels.iter() {
    println!("Channel: {:?}", channel);
}
// Output:
// Channel: FRONT_LEFT
// Channel: FRONT_RIGHT

Layout

Layout provides common channel configurations as convenient presets.
pub enum Layout {
    Mono,
    Stereo,
    TwoPointOne,
    FivePointOne,
}

Layout Variants

Mono
Single centre channel
  • Channels: FRONT_LEFT
Stereo
Left and right channels
  • Channels: FRONT_LEFT | FRONT_RIGHT
TwoPointOne
Stereo with subwoofer
  • Channels: FRONT_LEFT | FRONT_RIGHT | LFE1
FivePointOne
5.1 surround sound
  • Channels: FRONT_LEFT | FRONT_RIGHT | FRONT_CENTRE | REAR_LEFT | REAR_RIGHT | LFE1

into_channels

pub fn into_channels(self) -> Channels
Converts a Layout into its corresponding Channels bitmask. Example:
use symphonia::core::audio::Layout;

let stereo = Layout::Stereo.into_channels();
assert_eq!(stereo.count(), 2);

let surround = Layout::FivePointOne.into_channels();
assert_eq!(surround.count(), 6);

Common Patterns

Creating Custom Channel Configurations

use symphonia::core::audio::{SignalSpec, Channels};

// Quad surround (4.0)
let quad = Channels::FRONT_LEFT | Channels::FRONT_RIGHT
         | Channels::REAR_LEFT | Channels::REAR_RIGHT;
let spec = SignalSpec::new(48000, quad);

// 7.1 surround
let surround_7_1 = Channels::FRONT_LEFT | Channels::FRONT_RIGHT
                 | Channels::FRONT_CENTRE | Channels::LFE1
                 | Channels::REAR_LEFT | Channels::REAR_RIGHT
                 | Channels::SIDE_LEFT | Channels::SIDE_RIGHT;
let spec = SignalSpec::new(48000, surround_7_1);

Checking Channel Configuration

use symphonia::core::audio::Channels;

let channels = decoded.spec().channels;

// Check if stereo
if channels == (Channels::FRONT_LEFT | Channels::FRONT_RIGHT) {
    println!("Stereo audio");
}

// Check if mono
if channels == Channels::FRONT_LEFT {
    println!("Mono audio");
}

// Check channel count
match channels.count() {
    1 => println!("Mono"),
    2 => println!("Stereo"),
    6 => println!("5.1 Surround"),
    _ => println!("{} channels", channels.count()),
}

Iterating Channels

use symphonia::core::audio::{AudioBuffer, Signal};

let buffer: AudioBuffer<f32> = /* ... */;
let channels = buffer.spec().channels;

// Process each channel
for (idx, channel_flag) in channels.iter().enumerate() {
    let samples = buffer.chan(idx);
    println!("Channel {:?} has {} samples", channel_flag, samples.len());
    
    // Process samples for this channel
    for &sample in samples {
        // ...
    }
}

Matching Common Layouts

use symphonia::core::audio::{Channels, Layout};

let channels = decoded.spec().channels;

if channels == Layout::Stereo.into_channels() {
    // Optimized stereo processing
    let left = buffer.chan(0);
    let right = buffer.chan(1);
} else if channels == Layout::Mono.into_channels() {
    // Mono processing
    let mono = buffer.chan(0);
} else {
    // Generic multi-channel processing
    for ch in 0..channels.count() {
        let samples = buffer.chan(ch);
        // ...
    }
}

Working with Sample Rates

use symphonia::core::audio::SignalSpec;

let spec = decoded.spec();

// Common sample rates
match spec.rate {
    44100 => println!("CD quality"),
    48000 => println!("Professional audio"),
    88200 | 96000 => println!("High resolution"),
    _ => println!("Sample rate: {} Hz", spec.rate),
}

// Calculate duration
let frames = decoded.frames();
let duration_secs = frames as f64 / spec.rate as f64;
println!("Duration: {:.2} seconds", duration_secs);

Complete Example

use symphonia::core::audio::{SignalSpec, Layout, Channels};
use symphonia::core::audio::AudioBuffer;

fn process_audio(decoded: AudioBufferRef) {
    let spec = decoded.spec();
    
    println!("Sample rate: {} Hz", spec.rate);
    println!("Channels: {}", spec.channels.count());
    
    // Check for common layouts
    if spec.channels == Layout::Stereo.into_channels() {
        println!("Stereo audio detected");
        
        match decoded {
            AudioBufferRef::F32(buf) => {
                let left = buf.chan(0);
                let right = buf.chan(1);
                
                // Process stereo
                for (l, r) in left.iter().zip(right.iter()) {
                    // ...
                }
            }
            _ => { /* Handle other formats */ }
        }
    } else {
        println!("Multi-channel audio");
        
        // Generic processing
        for ch in 0..spec.channels.count() {
            println!("Processing channel {}", ch);
        }
    }
}

See Also

Build docs developers (and LLMs) love