#[cfg(feature = "processing")]
use std::time::Duration;
#[cfg(feature = "processing")]
use audio_samples::{
AudioProcessing, AudioSampleResult, AudioSamples, AudioStatistics, NormalizationConfig,
sine_wave,
};
#[cfg(not(feature = "processing"))]
fn main() {
eprintln!("This example requires the 'processing' feature.");
}
#[cfg(feature = "processing")]
#[inline]
pub fn main() -> AudioSampleResult<()> {
use audio_samples::{AudioEditing, sample_rate};
let sample_rate_hz = sample_rate!(44100);
let audio: AudioSamples<'static, f64> =
sine_wave(440.0, Duration::from_secs(1), sample_rate_hz, 0.8);
println!("Input: peak={:.4} rms={:.4}", audio.peak(), audio.rms());
let audio = audio.scale(0.5);
println!("Scaled: peak={:.4} rms={:.4}", audio.peak(), audio.rms());
let audio = audio.remove_dc_offset()?;
let audio = audio.normalize(NormalizationConfig::peak(1.0))?;
println!(
"Normalized (Peak): peak={:.4} rms={:.4}",
audio.peak(),
audio.rms()
);
assert!(
(audio.peak() - 1.0).abs() < 1e-3,
"peak-normalize should make |peak| == 1.0, got {}",
audio.peak()
);
let audio = audio.clip(-0.7, 0.7)?;
println!("Clipped: peak={:.4} rms={:.4}", audio.peak(), audio.rms());
assert!(
audio.peak() <= 0.7 + 1e-6,
"after clip(-0.7, 0.7) peak must not exceed 0.7, got {}",
audio.peak()
);
let num_samples = audio.samples_per_channel().get() as usize;
let window = spectrograms::hanning_window(core::num::NonZeroUsize::new(num_samples).unwrap());
let audio = audio.apply_window(&window)?;
println!("Windowed: peak={:.4} rms={:.4}", audio.peak(), audio.rms());
let taps = vec![1.0 / 9.0; 9];
let audio = audio.apply_filter(non_empty_slice::NonEmptySlice::from_slice(&taps).unwrap())?;
println!(
"Filtered (moving avg): len={} peak={:.4} rms={:.4}",
audio.samples_per_channel(),
audio.peak(),
audio.rms()
);
let ulaw = audio.mu_compress(255.0)?.mu_expand(255.0)?;
println!(
"µ-law round-trip: peak={:.4} rms={:.4}",
ulaw.peak(),
ulaw.rms()
);
let lp = sine_wave::<f64>(440.0, Duration::from_secs(1), sample_rate_hz, 0.6);
let hi = sine_wave::<f64>(5_000.0, Duration::from_secs(1), sample_rate_hz, 0.2);
let mixed = AudioSamples::mix(
non_empty_slice::NonEmptySlice::from_slice(&[lp, hi]).unwrap(),
None,
)?;
println!("Two-tone: peak={:.4} rms={:.4}", mixed.peak(), mixed.rms());
let lp = mixed.low_pass_filter(1_000.0)?;
println!("Low-pass 1kHz: peak={:.4} rms={:.4}", lp.peak(), lp.rms());
assert!(
lp.rms() < mixed.rms(),
"low-pass should attenuate the two-tone signal: {} !< {}",
lp.rms(),
mixed.rms()
);
assert!(
(ulaw.peak() - audio.peak()).abs() < 0.1,
"µ-law round-trip peak drifted too far: {} vs {}",
ulaw.peak(),
audio.peak()
);
Ok(())
}