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}