mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 13:42:34 +00:00
de53b87a06
`experimental` flag removes some API, just keep the example minimally functional in that case.
54 lines
2 KiB
Rust
54 lines
2 KiB
Rust
use rodio::source::Source;
|
|
use rodio::Decoder;
|
|
use std::fs::File;
|
|
use std::io::BufReader;
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use std::sync::Arc;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
fn main() {
|
|
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
|
|
let sink = rodio::Sink::try_new(&handle).unwrap();
|
|
|
|
// Decode the sound file into a source
|
|
let file = BufReader::new(File::open("assets/music.flac").unwrap());
|
|
let source = Decoder::new(file).unwrap();
|
|
|
|
// Apply automatic gain control to the source
|
|
let agc_source = source.automatic_gain_control(1.0, 4.0, 0.005, 5.0);
|
|
|
|
// Make it so that the source checks if automatic gain control should be
|
|
// enabled or disabled every 5 milliseconds. We must clone `agc_enabled`,
|
|
// or we would lose it when we move it into the periodic access.
|
|
let agc_enabled = Arc::new(AtomicBool::new(true));
|
|
|
|
#[cfg(not(feature = "experimental"))]
|
|
{
|
|
let agc_enabled_clone = agc_enabled.clone();
|
|
let controlled = agc_source.periodic_access(Duration::from_millis(5), move |agc_source| {
|
|
agc_source.set_enabled(agc_enabled_clone.load(Ordering::Relaxed));
|
|
});
|
|
|
|
// Add the source now equipped with automatic gain control and controlled via
|
|
// periodic_access to the sink for playback.
|
|
sink.append(controlled);
|
|
}
|
|
#[cfg(feature = "experimental")]
|
|
{
|
|
sink.append(agc_source);
|
|
}
|
|
|
|
// After 5 seconds of playback disable automatic gain control using the
|
|
// shared AtomicBool `agc_enabled`. You could do this from another part
|
|
// of the program since `agc_enabled` is of type Arc<AtomicBool> which
|
|
// is freely clone-able and move-able.
|
|
//
|
|
// Note that disabling the AGC takes up to 5 millis because periodic_access
|
|
// controls the source every 5 millis.
|
|
thread::sleep(Duration::from_secs(5));
|
|
agc_enabled.store(false, Ordering::Relaxed);
|
|
|
|
// Keep the program running until playback is complete
|
|
sink.sleep_until_end();
|
|
}
|