summaryrefslogtreecommitdiff
path: root/klangfarbrs/src/ignore
blob: 6c52a4b3e8b0cda60fbc664116db4863a692598d (plain)
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

pub mod test {
    use cpal;
    use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
    use dasp::{Sample};
    use dasp_signal::{self as signal, Signal};
    use std::sync::mpsc;

    pub fn test() -> Result<(), anyhow::Error> {
        let host = cpal::default_host();
        let device = host
            .default_output_device()
            .expect("failed to find a default output device");
        let config = device.default_output_config()?;

        match config.sample_format() {
            cpal::SampleFormat::F32 => run::<f32>(&device, &config.into())?,
            cpal::SampleFormat::I16 => run::<i16>(&device, &config.into())?,
            cpal::SampleFormat::U16 => run::<u16>(&device, &config.into())?,
        }

        Ok(())
    }

    fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
    where
        T: cpal::Sample,
    {
        // Create a signal chain to play back 1 second of each oscillator at A4.
        let base_freq = 440.0;
        let multipliers = [0.8, 1.0, 1.2, 1.7, 2.9, 4.5, 8.8, 1.9, 3.6];
        let freqs = multipliers.map(|m| signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * m));
        let _sines = freqs.map(|f| f.clone().sine());

        // Shitty naive implementation until Rust clicks.
        let hz_0 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 0.8);
        let hz_1 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 1.0);
        let hz_2 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 1.2);
        let hz_3 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 1.7);
        let hz_4 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 2.9);
        let hz_5 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 4.5);
        let hz_6 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 8.8);
        let hz_7 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 1.9);
        let hz_8 = signal::rate(config.sample_rate.0 as f64).const_hz(base_freq * 3.6);

        let sine_0 = hz_0.clone().sine().scale_amp(0.03);
        let sine_1 = hz_1.clone().sine();
        let sine_2 = hz_2.clone().sine().scale_amp(0.8);
        let sine_3 = hz_3.clone().sine().scale_amp(0.004);
        let sine_4 = hz_4.clone().sine().scale_amp(0.03);
        let sine_5 = hz_5.clone().sine().scale_amp(0.02);
        let sine_6 = hz_6.clone().sine().scale_amp(0.001);
        let sine_7 = hz_7.clone().sine().scale_amp(0.006);
        let sine_8 = hz_8.clone().sine().scale_amp(0.05);


        // let hz = signal::rate(config.sample_rate.0 as f64).const_hz(440.0);
        let one_sec = config.sample_rate.0 as usize;

        // let mut sin_a = hz
        //     .clone()
        //     .sine();

        // let mut sin_b = hz_b
        //     .clone()
        //     .sine();

        let mut synth = sine_0
            .add_amp(sine_1)
            .add_amp(sine_2)
            .add_amp(sine_3)
            .add_amp(sine_4)
            .add_amp(sine_5)
            .add_amp(sine_6)
            .add_amp(sine_7)
            .add_amp(sine_8)
            .take(one_sec)
            .map(|s| s.to_sample::<f32>() * 0.2);

        // let mut synth = sines[0]
        //     .add_amp(sines[1])
        //     .add_amp(sines[2])
        //     .add_amp(sines[3])
        //     .add_amp(sines[4])
        //     .add_amp(sines[5])
        //     .add_amp(sines[6])
        //     .add_amp(sines[7])
        //     .add_amp(sines[8])
        //     .take(one_sec)
        //     .map(|s| s.to_sample::<f32>() * 0.2);
        // let mut synth = sin_a.add_amp(sin_b).take(one_sec).map(|s| s.to_sample::<f32>() * 0.2);
        // let mut synth = hz
        //     .clone()
        //     .sine()
        //     .take(one_sec)
        //     .chain(hz.clone().saw().take(one_sec))
        //     .chain(hz.clone().square().take(one_sec))
        //     .chain(hz.clone().noise_simplex().take(one_sec))
        //     .chain(signal::noise(0).take(one_sec))
        //     .map(|s| s.to_sample::<f32>() * 0.2);

        // A channel for indicating when playback has completed.
        let (complete_tx, complete_rx) = mpsc::sync_channel(1);

        // Create and run the stream.
        let err_fn = |err| eprintln!("an error occurred on stream: {}", err);
        let channels = config.channels as usize;
        let stream = device.build_output_stream(
            config,
            move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
                write_data(data, channels, &complete_tx, &mut synth)
            },
            err_fn,
        )?;
        stream.play()?;

        // Wait for playback to complete.
        complete_rx.recv().unwrap();
        stream.pause()?;

        Ok(())
    }

    fn write_data<T>(
        output: &mut [T],
        channels: usize,
        complete_tx: &mpsc::SyncSender<()>,
        signal: &mut dyn Iterator<Item = f32>,
    ) where
        T: cpal::Sample,
    {
        for frame in output.chunks_mut(channels) {
            let sample = match signal.next() {
                None => {
                    complete_tx.try_send(()).ok();
                    0.0
                }
                Some(sample) => sample,
            };
            let value: T = cpal::Sample::from::<f32>(&sample);
            for sample in frame.iter_mut() {
                *sample = value;
            }
        }
    }

}