Skip to main content
Symphonia provides several examples demonstrating common use cases, from basic decoding to advanced audio processing. All examples are available in the GitHub repository.

Basic Examples

The Symphonia repository includes two foundational examples that demonstrate core functionality:

Getting Started

Basic audio decoding example showing the fundamental decode loop

Basic Interleaved

Demonstrates decoding and interleaving samples for playback

Example 1: Getting Started

File: getting-started.rs This example demonstrates the complete workflow for decoding an audio file:
  • Opening a media source
  • Probing the format
  • Creating a decoder
  • Decoding packets in a loop
  • Error handling

Key Concepts

use symphonia::core::codecs::{DecoderOptions, CODEC_TYPE_NULL};
use symphonia::core::errors::Error;
use symphonia::core::formats::FormatOptions;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;

// Open the media source
let src = std::fs::File::open(path).expect("failed to open media");
let mss = MediaSourceStream::new(Box::new(src), Default::default());

// Create a probe hint using the file's extension
let mut hint = Hint::new();
hint.with_extension("mp3");

// Probe the media source
let probed = symphonia::default::get_probe()
    .format(&hint, mss, &FormatOptions::default(), &MetadataOptions::default())
    .expect("unsupported format");

let mut format = probed.format;

// Find the first audio track
let track = format
    .tracks()
    .iter()
    .find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
    .expect("no supported audio tracks");

// Create a decoder for the track
let mut decoder = symphonia::default::get_codecs()
    .make(&track.codec_params, &DecoderOptions::default())
    .expect("unsupported codec");

let track_id = track.id;

The Decode Loop

loop {
    // Get the next packet from the format
    let packet = match format.next_packet() {
        Ok(packet) => packet,
        Err(Error::ResetRequired) => {
            // Track list changed (e.g., chained OGG streams)
            unimplemented!();
        }
        Err(err) => {
            // Unrecoverable error
            panic!("{}", err);
        }
    };

    // Check for new metadata
    while !format.metadata().is_latest() {
        format.metadata().pop();
        // Process metadata here
    }

    // Skip packets from other tracks
    if packet.track_id() != track_id {
        continue;
    }

    // Decode the packet
    match decoder.decode(&packet) {
        Ok(_decoded) => {
            // Process decoded audio samples
        }
        Err(Error::IoError(_)) => continue,
        Err(Error::DecodeError(_)) => continue,
        Err(err) => panic!("{}", err),
    }
}
This example forms the basis for most Symphonia applications. Master this pattern before moving to more advanced use cases.

Example 2: Basic Interleaved

File: basic-interleaved.rs This example demonstrates how to decode audio and convert it to an interleaved format suitable for playback or processing.

What You’ll Learn

  • Using SampleBuffer for format conversion
  • Interleaving multi-channel audio
  • Converting to different sample formats (e.g., f32)
  • Preparing audio for playback

Key Code Snippet

use symphonia::core::audio::SampleBuffer;
use symphonia::core::codecs::DecoderOptions;
use symphonia::core::formats::FormatOptions;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;

let file = Box::new(File::open(Path::new(&args[1])).unwrap());
let mss = MediaSourceStream::new(file, Default::default());

let probed = symphonia::default::get_probe()
    .format(&Hint::new(), mss, &FormatOptions::default(), &MetadataOptions::default())
    .unwrap();

let mut format = probed.format;
let track = format.default_track().unwrap();
let mut decoder = symphonia::default::get_codecs()
    .make(&track.codec_params, &DecoderOptions::default())
    .unwrap();

let track_id = track.id;
let mut sample_buf = None;

loop {
    let packet = format.next_packet().unwrap();
    if packet.track_id() != track_id {
        continue;
    }

    match decoder.decode(&packet) {
        Ok(audio_buf) => {
            // Create sample buffer on first packet
            if sample_buf.is_none() {
                let spec = *audio_buf.spec();
                let duration = audio_buf.capacity() as u64;
                sample_buf = Some(SampleBuffer::<f32>::new(duration, spec));
            }

            // Copy decoded audio to sample buffer in interleaved format
            if let Some(buf) = &mut sample_buf {
                buf.copy_interleaved_ref(audio_buf);
                
                // Access samples as &[f32]
                let samples = buf.samples();
                // Now ready for playback or processing
            }
        }
        Err(Error::DecodeError(_)) => (),
        Err(_) => break,
    }
}

Understanding SampleBuffer

SampleBuffer provides several important capabilities:
  • Format Conversion: Converts audio to a specified sample type (f32, i16, etc.)
  • Interleaving: Converts planar audio to interleaved format
  • Playback Ready: Output is ready for audio APIs expecting interleaved samples
Most audio playback APIs (CPAL, SDL, PortAudio) expect interleaved samples. This example shows the standard pattern for preparing audio for these APIs.

Running the Examples

Clone the repository and run the examples:
git clone https://github.com/pdeljanov/Symphonia.git
cd Symphonia

# Run getting-started example
cargo run --example getting-started /path/to/audio.mp3

# Run basic-interleaved example
cargo run --example basic-interleaved /path/to/audio.flac
Ensure you have the necessary feature flags enabled for your audio format. For example, MP3 support requires the mp3 feature flag.

Symphonia-Play Tool

For a complete, production-ready example, see symphonia-play, a full-featured audio player demonstrating:
  • Format and codec detection
  • Audio output with multiple backend support
  • Metadata reading and display
  • Seeking support
  • Error handling and recovery
  • Gapless playback
  • Verification and validation modes

Installing Symphonia-Play

cargo install symphonia-play

Using Symphonia-Play

# Play an audio file
symphonia-play audio.flac

# Decode only (benchmark mode)
symphonia-play --decode-only audio.mp3

# Display detailed information
symphonia-play --probe audio.ogg
symphonia-play is excellent for testing your audio files and understanding how Symphonia handles different formats and codecs.

Symphonia-Check Tool

The symphonia-check tool validates Symphonia’s decoded output against reference decoders:
cargo install symphonia-check

# Validate against FFmpeg
symphonia-check audio.flac
False positives are not uncommon with symphonia-check due to legitimate differences in decoder implementations. Always verify findings manually.

Advanced Use Cases

For more advanced scenarios, refer to:

Getting Started Guide

Comprehensive guide covering advanced topics

API Documentation

Complete API reference with detailed examples

Symphonia-Play Source

Production-ready player implementation

GitHub Repository

Full source code and additional resources

Common Patterns

Seeking

// Seek to a specific time (in time base units)
let seek_to = SeekTo::Time { 
    time: Time::from_seconds(30.0), 
    track_id: Some(track_id) 
};
format.seek(SeekMode::Accurate, seek_to)?;

Reading Metadata

// Access metadata tags
if let Some(metadata_rev) = format.metadata().current() {
    for tag in metadata_rev.tags() {
        println!("{}: {}", tag.std_key, tag.value);
    }
}

Multi-Track Handling

// Get all audio tracks
let audio_tracks: Vec<_> = format
    .tracks()
    .iter()
    .filter(|t| t.codec_params.codec != CODEC_TYPE_NULL)
    .collect();

// Create decoders for each track
for track in audio_tracks {
    let decoder = symphonia::default::get_codecs()
        .make(&track.codec_params, &DecoderOptions::default())?;
    // Store and use decoder
}

Next Steps

1

Start with getting-started.rs

Understand the basic decode loop and error handling
2

Learn interleaving with basic-interleaved.rs

Master sample format conversion for playback
3

Explore symphonia-play

Study a complete implementation with all features
4

Build your application

Apply these patterns to your specific use case

Getting Help

If you need assistance:

Build docs developers (and LLMs) love