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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//! Declares the [`Signal`] trait and implements it for simple types.

use std::marker::PhantomData;

use crate::sample::*;
use crate::Map;

/// A trait for a stream of data, generated every frame.
///
/// This data can either be audio data, or envelope data.
pub trait Signal {
    /// The type of sample generated by the signal.
    type Sample: Sample;

    /// Gets the next sample from the signal.
    fn get(&self) -> Self::Sample;

    /// Advances the state of the signal to the next sample.
    fn advance(&mut self);

    /// Resets the stream 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
    }
}

/// Represents a signal that can be stopped.
pub trait StopSignal: Signal {
    /// Releases a note.
    fn stop(&mut self);

    /// Returns whether the signal has stopped producing any sound altogether.
    fn is_done(&self) -> bool;
}

/// A trailing signal. It can be stopped, but won't actually stop producing an
/// output.
pub struct Trailing<S: Signal> {
    /// The inner signal.
    pub sgn: S,
}

impl<S: Signal> Trailing<S> {
    pub fn new(sgn: S) -> Self {
        Self { sgn }
    }
}

impl<S: Signal> Signal for Trailing<S> {
    type Sample = S::Sample;

    fn get(&self) -> Self::Sample {
        self.sgn.get()
    }

    fn advance(&mut self) {
        self.sgn.advance();
    }

    fn retrigger(&mut self) {
        self.sgn.retrigger();
    }
}

impl<S: Signal> StopSignal for Trailing<S> {
    fn stop(&mut self) {}

    fn is_done(&self) -> bool {
        false
    }
}

/// Maps a signal to another via a specified map.
#[derive(Clone, Copy, Debug)]
pub struct MapSgn<S: Signal, Y: Sample, F: Map<S::Sample, Y>> {
    /// The signal being mapped.
    pub sgn: S,

    /// The map being applied.
    pub map: F,

    /// Dummy variable.
    phantom: PhantomData<Y>,
}

impl<S: Signal, Y: Sample, F: Map<S::Sample, Y>> MapSgn<S, Y, F> {
    /// Initializes a generic [`MapSgn`].
    ///
    /// There are many type aliases for specific subtypes of [`MapSgn`], and
    /// these will often provide more convenient instantiations via `new`.
    pub const fn new_generic(sgn: S, map: F) -> Self {
        Self {
            sgn,
            map,
            phantom: PhantomData,
        }
    }
}

impl<S: Signal, Y: Sample, F: Map<S::Sample, Y>> Signal for MapSgn<S, Y, F> {
    type Sample = Y;

    fn get(&self) -> Y {
        self.map.eval(self.sgn.get())
    }

    fn advance(&mut self) {
        self.sgn.advance()
    }

    fn retrigger(&mut self) {
        self.sgn.retrigger();
    }
}

impl<S: StopSignal, Y: Sample, F: Map<S::Sample, Y>> StopSignal for MapSgn<S, Y, F> {
    fn stop(&mut self) {
        self.sgn.stop();
    }

    fn is_done(&self) -> bool {
        self.sgn.is_done()
    }
}

/// Applies a function pointwise to the entries of a [`Sample`].
#[derive(Clone, Debug)]
pub struct Pointwise<S: Sample, F: Map<f64, f64>> {
    /// The function to apply.
    pub func: F,

    /// Dummy value.
    phantom: PhantomData<S>,
}

impl<S: Sample, F: Map<f64, f64>> Pointwise<S, F> {
    /// Initializes a new [`Pointwise`] function.
    pub const fn new(func: F) -> Self {
        Self {
            func,
            phantom: PhantomData,
        }
    }
}

impl<S: Sample, F: Map<f64, f64>> Map<S, S> for Pointwise<S, F> {
    fn eval(&self, x: S) -> S {
        x.map(|y| self.func.eval(y))
    }
}

/// Maps a signal through a pointwise function.
pub type PointwiseMapSgn<S, F> =
    MapSgn<S, <S as Signal>::Sample, Pointwise<<S as Signal>::Sample, F>>;

impl<S: Signal, F: Map<f64, f64>> PointwiseMapSgn<S, F> {
    /// Initializes a new [`PointwiseMapSgn`].
    pub const fn new_pointwise(sgn: S, func: F) -> Self {
        Self::new_generic(sgn, Pointwise::new(func))
    }

    /// Returns a reference to the original signal.
    pub fn sgn(&self) -> &S {
        &self.sgn
    }

    /// Returns a mutable reference to the original signal.
    pub fn sgn_mut(&mut self) -> &mut S {
        &mut self.sgn
    }

    /// Returns a reference to the function modifying the signal.
    pub const fn func(&self) -> &F {
        &self.map.func
    }

    /// Returns a mutable reference to the function modifying the signal.
    pub  fn func_mut(&mut self) -> &mut F {
        &mut self.map.func
    }
}

/// A map which converts an envelope into mono audio.
#[derive(Clone, Copy, Debug, Default)]
pub struct EnvToMono;

impl Map<Env, Mono> for EnvToMono {
    fn eval(&self, x: Env) -> Mono {
        x.into()
    }
}

/// Plays an envelope as a [`Mono`] audio file.
///
/// For very low-frequency envelopes, this might lead to undesirable sounds.
pub type EnvGen<S> = MapSgn<S, Mono, EnvToMono>;

impl<S: Signal<Sample = Env>> EnvGen<S> {
    /// Initializes a new [`EnvGen`].
    pub fn new_env(sgn: S) -> Self {
        Self::new_generic(sgn, EnvToMono)
    }
}