use opus_rs::{Application, OpusDecoder, OpusEncoder};
use std::f32::consts::PI;
fn main() {
println!("=== Opus Stereo Example ===\n");
println!("--- SILK-only stereo (16kHz VoIP) ---");
test_silk_stereo(16000, 320, 24000);
println!("\n--- CELT stereo (48kHz Audio) ---");
test_celt_stereo(48000, 960, 32000);
println!("\n--- Stereo round-trip test ---");
test_stereo_roundtrip();
println!("\n=== All stereo examples completed! ===");
}
fn test_silk_stereo(sample_rate: i32, frame_size: usize, bitrate: i32) {
let channels = 2;
let mut encoder = OpusEncoder::new(sample_rate, channels, Application::Voip)
.expect("Failed to create encoder");
encoder.bitrate_bps = bitrate;
let mut input = vec![0.0f32; frame_size * channels];
for i in 0..frame_size {
let t = i as f32 / sample_rate as f32;
input[i * 2] = (2.0 * PI * 300.0 * t).sin() * 0.5;
input[i * 2 + 1] = (2.0 * PI * 500.0 * t).sin() * 0.5;
}
let mut output = vec![0u8; 500];
let n = encoder.encode(&input, frame_size, &mut output)
.expect("Encode failed");
let stereo_bit = (output[0] >> 2) & 1;
println!(" Encoded {} bytes, stereo bit: {}", n, stereo_bit);
let mut decoder = OpusDecoder::new(sample_rate, channels).unwrap();
let mut pcm = vec![0.0f32; frame_size * channels];
let samples = decoder.decode(&output[..n], frame_size, &mut pcm)
.expect("Decode failed");
let mut left_energy = 0.0f32;
let mut right_energy = 0.0f32;
for i in 0..samples {
left_energy += pcm[i * 2].abs();
right_energy += pcm[i * 2 + 1].abs();
}
println!(" Decoded {} samples", samples);
println!(" Left energy: {:.2}, Right energy: {:.2}", left_energy, right_energy);
}
fn test_celt_stereo(sample_rate: i32, frame_size: usize, bitrate: i32) {
let channels = 2;
let mut encoder = OpusEncoder::new(sample_rate, channels, Application::Audio)
.expect("Failed to create encoder");
encoder.bitrate_bps = bitrate;
let mut input = vec![0.0f32; frame_size * channels];
for i in 0..frame_size {
let t = i as f32 / sample_rate as f32;
input[i * 2] = (2.0 * PI * 440.0 * t).sin() * 0.5;
input[i * 2 + 1] = (2.0 * PI * 880.0 * t).sin() * 0.5;
}
let mut output = vec![0u8; 1500];
let n = encoder.encode(&input, frame_size, &mut output)
.expect("Encode failed");
let stereo_bit = (output[0] >> 2) & 1;
println!(" Encoded {} bytes, stereo bit: {}", n, stereo_bit);
let mut decoder = OpusDecoder::new(sample_rate, channels).unwrap();
let mut pcm = vec![0.0f32; frame_size * channels];
let samples = decoder.decode(&output[..n], frame_size, &mut pcm)
.expect("Decode failed");
let mut left_energy = 0.0f32;
let mut right_energy = 0.0f32;
for i in 0..samples {
left_energy += pcm[i * 2].abs();
right_energy += pcm[i * 2 + 1].abs();
}
println!(" Decoded {} samples", samples);
println!(" Left energy: {:.2}, Right energy: {:.2}", left_energy, right_energy);
}
fn test_stereo_roundtrip() {
let sample_rate = 16000;
let channels = 2;
let frame_size = 320;
let num_frames = 3;
let mut encoder = OpusEncoder::new(sample_rate, channels, Application::Voip)
.expect("Failed to create encoder");
encoder.bitrate_bps = 24000;
let total_samples = frame_size * num_frames * channels;
let mut input = vec![0.0f32; total_samples];
for frame in 0..num_frames {
for i in 0..frame_size {
let t = ((frame * frame_size) + i) as f32 / sample_rate as f32;
let idx = (frame * frame_size + i) * channels;
let freq = 200.0 + (frame as f32 * 150.0);
input[idx] = (2.0 * PI * freq * t).sin() * 0.5;
input[idx + 1] = (2.0 * PI * freq * t).sin() * 0.5;
}
}
println!(" Encoding {} frames...", num_frames);
let mut encoded_frames: Vec<Vec<u8>> = Vec::new();
for frame in 0..num_frames {
let frame_start = frame * frame_size * channels;
let frame_input = &input[frame_start..frame_start + frame_size * channels];
let mut frame_output = vec![0u8; 400];
let n = encoder.encode(frame_input, frame_size, &mut frame_output)
.expect("Encode frame failed");
encoded_frames.push(frame_output[..n].to_vec());
println!(" Frame {}: {} bytes", frame, n);
}
println!(" Decoding {} frames...", num_frames);
let mut decoder = OpusDecoder::new(sample_rate, channels).unwrap();
let mut pcm = vec![0.0f32; total_samples];
for frame in 0..num_frames {
let frame_start = frame * frame_size * channels;
let samples = decoder.decode(&encoded_frames[frame], frame_size, &mut pcm[frame_start..])
.expect("Decode frame failed");
println!(" Frame {}: {} samples", frame, samples);
}
let mut total_energy = 0.0f32;
for i in 0..total_samples {
total_energy += pcm[i].abs();
}
println!(" Total output energy: {:.2}", total_energy);
println!(" Round-trip test: {}", if total_energy > 0.0 { "PASSED" } else { "FAILED" });
}