rs_audio/
note.rs

1use rodio::source::SineWave;
2
3use crate::WaveForm;
4
5/**
6This struct represents a note.<br><br>
7It is the building block for all songs made with rs-audio.<br>
8```
9use rs_audio::*;
10
11let note: Note = Note {
12    freq: 440.0,
13    dur: 3.0,
14    vol: 0.20,
15    wave: WaveForm::Sine,
16};
17
18let default_note = Note::default(); // This outputs the same note as the one above.
19```
20*/
21#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
22pub struct Note {
23    pub freq: f64, // frequency in hertz
24    pub dur: f64,  // duration in seconds
25
26    pub vol: f32, // the volume/amplituide (0.0 to 1.0)
27
28    pub wave: WaveForm, // the wave type (see below for types)
29}
30
31impl Default for Note {
32    /**
33    Generates a default sine wave. <br><br>It has a frequency for 440 Hertz, lasts 3 seconds, and its volume is 0.20.<br><br>
34    Usage:
35    ```
36    use rs_audio::*;
37
38    let default_note: Note = Note::default();
39    ```
40    */
41    fn default() -> Self {
42        Note {
43            freq: 440.0,
44            dur: 3.0,
45            vol: 0.20,
46            wave: WaveForm::Sine,
47        }
48    }
49}
50
51impl Note {
52    /**
53    Creates a rest (silence) note.<br><br>
54    Usage:
55    ```
56    use rs_audio::*;
57    let rest_note = Note::rest(2.0); // a 2 second rest
58    ```
59    */
60    pub fn rest(dur: f64) -> Self {
61        Note {
62            freq: 0.0,
63            dur,
64            vol: 0.0,
65            wave: WaveForm::Rest,
66        }
67    }
68
69    pub(crate) fn to_approx_sine(&self) -> SineWave {
70        /*
71        this emulates sines, squares, sawtooths and triangles as rodio sine waves
72        it's not extremely accurate but it works
73        */
74        let effective_freq = match self.wave {
75            WaveForm::Sine => self.freq,
76            WaveForm::Square => self.freq * 1.27, // adds odd harmonics
77            WaveForm::Sawtooth => self.freq * 1.5, // rich harmonics
78            WaveForm::Triangle => self.freq * 1.16, // soft harmonics
79            WaveForm::Rest => 0.0,                // silence
80        };
81
82        SineWave::new(effective_freq as f32)
83    }
84}