1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
//! Declares the most basic traits concerning [`Signals`](Signal).
use crate::{freq::Freq, sample::Sample};
/// A trait for a stream of data [`Samples`](Sample), generated every frame.
///
/// This data can either be audio data, meaning [`Mono`](crate::sample::Mono) or
/// [`Stereo`](crate::sample::Stereo), or envelope data
/// [`Env`](crate::sample::Env).
///
/// ## Implementing the trait
///
/// In order to implement this trait on your custom type, you only need to
/// define three methods:
///
/// - [`get`](Signal::get): Gets the next sample from the signal.
/// - [`advance`](Signal::advance): Advances the state of the signal by a frame.
/// - [`retrigger`](Signal::retrigger): Resets the signal to its initial state.
///
/// ## Example
///
/// The following example is a simplified implementation of
/// [`NoiseGen`](crate::prelude::NoiseGen).
///
/// ```
/// # use pointillism::prelude::*;
/// /// A signal that produces random envelope data.
/// struct NoiseGen {
///     /// The current random value.
///     current: Env,
/// }
///
/// impl Signal for NoiseGen {
///     // This signal produces envelope data.
///     type Sample = Env;
///
///     // Returns the current value.
///     fn get(&self) -> Env {
///         self.current
///     }
///
///     // Updates the current value.
///     fn advance(&mut self) {
///         self.current = Env::rand();
///     }
///     
///     // Retriggering a random signal amounts to choosing a new random value.
///     fn retrigger(&mut self) {         
///         self.current = Env::rand();
///     }
/// }
/// ```
pub trait Signal {
    /// The type of sample generated by the signal.
    type Sample: Sample;
    /// Gets the next sample from the signal.
    ///
    /// This should return the same result when called repeatedly, as long as
    /// the signal isn't modified, and `advance` or `retrigger` is not called.
    fn get(&self) -> Self::Sample;
    /// Advances the state of the signal by a frame.
    fn advance(&mut self);
    /// Resets the signal to its initial state.
    fn retrigger(&mut self);
    /// Gets the next sample and advances the state of the signal.
    fn next(&mut self) -> Self::Sample {
        let res = self.get();
        self.advance();
        res
    }
}
/// A trait for a signal with a "main" frequency.
///
/// Not to be confused with [`Freq`].
///
/// This is implemented both for signals that have a frequency parameter such as
/// [`LoopGen`](crate::generators::LoopGen), as well as straightforward wrappers
/// for these signals.
pub trait Frequency: Signal {
    /// The "main" frequency of the signal.
    fn freq(&self) -> Freq;
    /// A mutable reference to the "main" frequency of the signal.
    fn freq_mut(&mut self) -> &mut Freq;
}
/// A trait for a signal with a "base" signal.
///
/// This is often a generator in a chain of effects.
///
/// This is implemented both for basic signals that don't depend on others, as
/// well as straightforward wrappers of these.
pub trait Base: Signal {
    /// The "base" signal type.
    type Base: Signal;
    /// A reference to the "base" signal.
    fn base(&self) -> &Self::Base;
    /// A mutable reference to the "base" signal.
    fn base_mut(&mut self) -> &mut Self::Base;
}
/// Represents a signal that ends.
///
/// Is used in [`Polyphony`](crate::prelude::Polyphony) so that a synth can be
/// cleared from memory when it stops.
///
/// If a signal never ends, it should not implement this trait. If you really
/// want to use such a signal within a `Polyphony` object, wrap it in the
/// [`Trailing`](crate::prelude::Trailing) structure.
pub trait Done: Signal {
    /// Returns whether the signal has stopped producing any sound altogether.
    ///
    /// If this returns `true` once, it must return `true` in all successive
    /// times, unless retriggered. Further, if this returns `true`, then getting
    /// a sample from the signal must always return zero.
    fn is_done(&self) -> bool;
}
/// Represents a signal that can be stopped.
///
/// Note that stopping a signal doesn't mean it will immediately stop producing
/// sound. Use [`Panic`] for this purpose.
pub trait Stop: Signal {
    /// Releases a note.
    fn stop(&mut self);
}
/// Represents a signal that can be stopped abruptly.
///
/// All sound or envelope data will stop being produced once the `panic` method
/// is called.
///
/// Depending on how your code is structured, it might be easier to simply stop
/// calling `next` on your signal.
pub trait Panic: Signal {
    /// Stops all subsequent sound.
    fn panic(&mut self);
}