Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added `FixedSource` which mirrors `Source` but does not allow the sample rate or
channel count to change.
- Added `ConstSource` which is like `FixedSource` except the sample rate and
channel count are fixed at compile time.
- Added `Skippable::skipped` function to check if the inner source was skipped.
- All sources now implement `ExactSizeIterator` when their inner source does.
- All sources now implement `Iterator::size_hint()`.
Expand All @@ -21,6 +25,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Breaking: `amplify` now takes a `Factor` which can be linear, decibels or
normalized.
- Breaking: removed `amplify_decibel` and `amplify_normalized`
- Breaking: `Microphone` now implements `FixedSource`
- Breaking: `Done` now calls a callback instead of decrementing an `Arc<AtomicUsize>`.
- Updated `cpal` to v0.18.
- Clarified `Source::current_span_len()` documentation to specify it returns total span length.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ required-features = ["playback", "wav"]

[[example]]
name = "microphone"
required-features = ["playback", "recording", "wav_output"]
required-features = ["playback", "recording"]

[[example]]
name = "mix_multiple_sources"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
[![Crates.io Downloads](https://img.shields.io/crates/d/rodio.svg)](https://crates.io/crates/rodio)
[![Build Status](https://github.com/RustAudio/rodio/workflows/CI/badge.svg)](https://github.com/RustAudio/rodio/actions)

> [!WARNING]
> We are currently rewriting Rodio's core audio engine. The current state should
> be working but under documented. This is expected to take at least a month.
> For the latest unreleased work pre engine rewrite see [this
> checkout](https://github.com/RustAudio/rodio/tree/c5f1e94290922fe4ee963ce6f85754ea6ba36243).
> To follow our progress see the [tracking
> issue](https://github.com/RustAudio/rodio/issues/901)

Rust playback library.

Playback is handled by [cpal](https://github.com/RustAudio/cpal). Format decoding is handled by [Symphonia](https://github.com/pdeljanov/Symphonia) by default, or by optional format-specific decoders:
Expand Down
3 changes: 2 additions & 1 deletion benches/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use divan::Bencher;
use rodio::Source;

mod shared;
use rodio::effects::amplify::Factor;
use shared::music_wav;

fn main() {
Expand Down Expand Up @@ -40,7 +41,7 @@ fn fade_out(bencher: Bencher) {
fn amplify(bencher: Bencher) {
bencher
.with_inputs(music_wav)
.bench_values(|source| source.amplify(0.8).for_each(divan::black_box_drop))
.bench_values(|source| source.amplify(Factor::Linear(0.8)).for_each(divan::black_box_drop))
}

#[divan::bench]
Expand Down
5 changes: 3 additions & 2 deletions benches/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::time::Duration;

use divan::Bencher;
use rodio::ChannelCount;
use rodio::effects::amplify::Factor;
use rodio::{source::UniformSourceIterator, Source};

mod shared;
Expand All @@ -17,7 +18,7 @@ fn long(bencher: Bencher) {
bencher.with_inputs(music_wav).bench_values(|source| {
let mut take_dur = source
.high_pass(300)
.amplify(1.2)
.amplify(Factor::Linear(1.2))
.speed(0.9)
.automatic_gain_control(Default::default())
.delay(Duration::from_secs_f32(0.5))
Expand All @@ -41,7 +42,7 @@ fn long(bencher: Bencher) {
fn short(bencher: Bencher) {
bencher.with_inputs(music_wav).bench_values(|source| {
source
.amplify(1.2)
.amplify(Factor::Linear(1.2))
.low_pass(200)
.for_each(divan::black_box_drop)
})
Expand Down
1 change: 1 addition & 0 deletions codebook.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ words = [
"stddev",
"tpdf",
"tpdf's",
"unsafelessly",
"voss",
]
3 changes: 2 additions & 1 deletion examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rodio::effects::amplify::Factor;
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
Expand All @@ -22,7 +23,7 @@ fn main() -> Result<(), Box<dyn Error>> {
{
// Generate sine wave.
let wave = SineWave::new(740.0)
.amplify(0.2)
.amplify(Factor::Linear(0.2))
.take_duration(Duration::from_secs(3));
mixer.add(wave);
}
Expand Down
3 changes: 2 additions & 1 deletion examples/custom_config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use cpal::traits::HostTrait;
use cpal::{BufferSize, SampleFormat};
use rodio::effects::amplify::Factor;
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
Expand All @@ -25,7 +26,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let mixer = stream_handle.mixer();

let wave = SineWave::new(740.0)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(Duration::from_secs(1));
mixer.add(wave);

Expand Down
3 changes: 2 additions & 1 deletion examples/distortion.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rodio::effects::amplify::Factor;
use rodio::source::{SineWave, Source};
use std::error::Error;
use std::thread;
Expand All @@ -10,7 +11,7 @@ fn main() -> Result<(), Box<dyn Error>> {

// Create a sine wave source and apply distortion
let distorted = SineWave::new(440.0)
.amplify(0.2)
.amplify(Factor::Linear(0.2))
.distortion(4.0, 0.3)
.take_duration(Duration::from_secs(3));

Expand Down
3 changes: 2 additions & 1 deletion examples/error_callback.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cpal::traits::HostTrait;
use rodio::effects::amplify::Factor;
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
Expand Down Expand Up @@ -29,7 +30,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let mixer = stream_handle.mixer();

let wave = SineWave::new(740.0)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(Duration::from_secs(30));
mixer.add(wave);

Expand Down
9 changes: 5 additions & 4 deletions examples/limit_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! This example shows how to use the LimitSettings struct with the builder
//! to configure audio limiting parameters.

use rodio::effects::amplify::Factor;
use rodio::source::{LimitSettings, SineWave, Source};
use rodio::Sample;
use std::time::Duration;
Expand Down Expand Up @@ -33,7 +34,7 @@ fn main() {

// Create a sine wave at 440 Hz
let sine_wave = SineWave::new(440.0)
.amplify(2.0) // Amplify to cause limiting
.amplify(Factor::Linear(2.0)) // Amplify to cause limiting
.take_duration(Duration::from_millis(100));

// Apply limiting with default settings (simplest usage)
Expand All @@ -52,7 +53,7 @@ fn main() {

// Create another sine wave for custom limiting
let sine_wave2 = SineWave::new(880.0)
.amplify(1.8)
.amplify(Factor::Linear(1.8))
.take_duration(Duration::from_millis(50));

// Apply the custom settings from Example 2
Expand Down Expand Up @@ -102,7 +103,7 @@ fn main() {
println!("Example 6: Limiting with -6dB threshold");

// Create a sine wave that will definitely trigger limiting
const AMPLITUDE: Sample = 2.5; // High amplitude to ensure limiting occurs
const AMPLITUDE: Factor = Factor::Linear(2.5); // High amplitude to ensure limiting occurs
let test_sine = SineWave::new(440.0)
.amplify(AMPLITUDE)
.take_duration(Duration::from_millis(100)); // 100ms = ~4410 samples
Expand Down Expand Up @@ -138,7 +139,7 @@ fn main() {
" {}dB threshold limiting results:",
strict_limiting.threshold
);
println!(" Original max amplitude: {AMPLITUDE}");
println!(" Original max amplitude: {AMPLITUDE:?}");
println!(" Target threshold: {target_linear:.3}");
println!(" Early peak (0-500 samples): {early_peak:.3}");
println!(" Mid peak (1000-1500 samples): {mid_peak:.3}");
Expand Down
3 changes: 2 additions & 1 deletion examples/limit_wav.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rodio::effects::amplify::Factor;
use rodio::{source::LimitSettings, Source};
use std::error::Error;

Expand All @@ -7,7 +8,7 @@ fn main() -> Result<(), Box<dyn Error>> {

let file = std::fs::File::open("assets/music.wav")?;
let source = rodio::Decoder::try_from(file)?
.amplify(3.0)
.amplify(Factor::Linear(3.0))
.limit(LimitSettings::default());

player.append(source);
Expand Down
4 changes: 2 additions & 2 deletions examples/microphone.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use inquire::Select;
use rodio::microphone::{self, MicrophoneBuilder};
use rodio::Source;
use rodio::FixedSource;
use std::error::Error;
use std::thread;
use std::time::Duration;
Expand All @@ -22,7 +22,7 @@ fn main() -> Result<(), Box<dyn Error>> {

println!("Playing the recording");
let mut output = rodio::DeviceSinkBuilder::open_default_sink()?;
output.mixer().add(recording);
output.mixer().add(recording.into_dynamic_source());

thread::sleep(Duration::from_secs(5));

Expand Down
9 changes: 5 additions & 4 deletions examples/mix_multiple_sources.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rodio::effects::amplify::Factor;
use rodio::mixer;
use rodio::source::{SineWave, Source};
use rodio::Float;
Expand All @@ -19,16 +20,16 @@ fn main() -> Result<(), Box<dyn Error>> {
// E4, G4, and A4 respectively.
let source_c = SineWave::new(261.63)
.take_duration(NOTE_DURATION)
.amplify(NOTE_AMPLITUDE);
.amplify(Factor::Linear(NOTE_AMPLITUDE));
let source_e = SineWave::new(329.63)
.take_duration(NOTE_DURATION)
.amplify(NOTE_AMPLITUDE);
.amplify(Factor::Linear(NOTE_AMPLITUDE));
let source_g = SineWave::new(392.0)
.take_duration(NOTE_DURATION)
.amplify(NOTE_AMPLITUDE);
.amplify(Factor::Linear(NOTE_AMPLITUDE));
let source_a = SineWave::new(440.0)
.take_duration(NOTE_DURATION)
.amplify(NOTE_AMPLITUDE);
.amplify(Factor::Linear(NOTE_AMPLITUDE));

// Add sources C, E, G, and A to the mixer controller.
controller.add(source_c);
Expand Down
14 changes: 8 additions & 6 deletions examples/signal_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use std::error::Error;
use std::num::NonZero;

use rodio::effects::amplify::Factor;

fn main() -> Result<(), Box<dyn Error>> {
use rodio::source::{chirp, Function, SignalGenerator, Source};
use std::thread;
Expand All @@ -17,7 +19,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 1000 Hz tone");
stream_handle.mixer().add(
SignalGenerator::new(sample_rate, 1000.0, Function::Sine)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand All @@ -26,7 +28,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 10,000 Hz tone");
stream_handle.mixer().add(
SignalGenerator::new(sample_rate, 10000.0, Function::Sine)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand All @@ -35,7 +37,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 440 Hz Triangle Wave");
stream_handle.mixer().add(
SignalGenerator::new(sample_rate, 440.0, Function::Triangle)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand All @@ -44,7 +46,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 440 Hz Sawtooth Wave");
stream_handle.mixer().add(
SignalGenerator::new(sample_rate, 440.0, Function::Sawtooth)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand All @@ -53,7 +55,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 440 Hz Square Wave");
stream_handle.mixer().add(
SignalGenerator::new(sample_rate, 440.0, Function::Square)
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand All @@ -62,7 +64,7 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("Playing 20-10000 Hz Sweep");
stream_handle.mixer().add(
chirp(sample_rate, 20.0, 10000.0, Duration::from_secs(1))
.amplify(0.1)
.amplify(Factor::Linear(0.1))
.take_duration(test_signal_duration),
);

Expand Down
3 changes: 2 additions & 1 deletion examples/stereo.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Plays a tone alternating between right and left ears, with right being first.

use rodio::effects::amplify::Factor;
use rodio::Source;
use std::error::Error;

Expand All @@ -8,7 +9,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/RL.ogg")?;
player.append(rodio::Decoder::try_from(file)?.amplify(0.2));
player.append(rodio::Decoder::try_from(file)?.amplify(Factor::Linear(0.2)));

player.sleep_until_end();

Expand Down
Loading
Loading