diff --git a/src/core/base.rs b/src/core/base.rs index cb651dc..ead8326 100644 --- a/src/core/base.rs +++ b/src/core/base.rs @@ -68,6 +68,19 @@ impl PlaybackHandle { } /// A trait for types that can be "played" via the system's audio output. +/// ```rust, no_run +/// use std::time::Duration; +/// +/// use klib::core::base::Playable; +/// use klib::core::{named_pitch::NamedPitch, note::Note, octave::Octave}; +/// +/// let handle = Note::new(NamedPitch::A, Octave::Four).play( +/// Duration::ZERO, +/// Duration::from_secs(1), +/// Duration::ZERO, +/// ); +/// std::thread::sleep(Duration::from_secs(1)); +/// ``` pub trait Playable { /// Plays the [`Playable`]. #[must_use = "Dropping the PlayableResult will stop the playback."] diff --git a/src/core/pitch.rs b/src/core/pitch.rs index c467704..d9969e5 100644 --- a/src/core/pitch.rs +++ b/src/core/pitch.rs @@ -2,6 +2,8 @@ // Traits. +use std::time::Duration; + use once_cell::sync::Lazy; use super::helpers::mel; @@ -35,6 +37,23 @@ pub trait HasMel: HasFrequency { } } +#[cfg(feature = "audio")] +use super::base::{Playable, PlaybackHandle, Res}; + +#[cfg(feature = "audio")] +impl Playable for T { + fn play(&self, delay: Duration, length: Duration, fade_in: Duration) -> Res { + use rodio::{source::SineWave, OutputStream, Sink, Source}; + + let (stream, stream_handle) = OutputStream::try_default()?; + let sink = Sink::try_new(&stream_handle)?; + let source = SineWave::new(self.frequency()).take_duration(length - delay).buffered().delay(delay).fade_in(fade_in).amplify(0.20); + sink.append(source); + + Ok(PlaybackHandle::new(stream, stream_handle, vec![sink])) + } +} + // Enum. /// An enum representing the pitch of a note.