1pub fn midi_pitch_to_frequency(pitch: f64) -> f64 {
8 (2.0_f64).powf((pitch - 69.0) / 12.0) * 440.0
9}
10
11pub fn frequency_to_midi_pitch(frequency: f64) -> f64 {
15 (frequency / 440.0).log2() * 12.0 + 69.0
16}
17
18pub fn midi_pitch_to_tone_period(pitch: f64, clock_rate: f64) -> u16 {
22 frequency_to_tone_period(midi_pitch_to_frequency(pitch), clock_rate)
23}
24
25pub fn midi_pitch_to_envelope_period(pitch: f64, clock_rate: f64) -> u16 {
29 frequency_to_envelope_period(midi_pitch_to_frequency(pitch), clock_rate)
30}
31
32pub fn tone_period_to_midi_pitch(period: u16, clock_rate: f64) -> f64 {
37 frequency_to_midi_pitch(tone_period_to_frequency(period, clock_rate))
38}
39
40pub fn envelope_period_to_midi_pitch(period: u16, clock_rate: f64) -> f64 {
45 frequency_to_midi_pitch(envelope_period_to_frequency(period, clock_rate))
46}
47
48pub fn frequency_to_tone_period(frequency: f64, clock_rate: f64) -> u16 {
50 (clock_rate / (16.0 * frequency)).round() as u16
51}
52
53pub fn frequency_to_envelope_period(frequency: f64, clock_rate: f64) -> u16 {
55 (clock_rate / (256.0 * frequency)).round() as u16
56}
57
58pub fn tone_period_to_frequency(period: u16, clock_rate: f64) -> f64 {
60 clock_rate / (period as f64 * 16.0)
61}
62
63pub fn envelope_period_to_frequency(period: u16, clock_rate: f64) -> f64 {
65 clock_rate / (period as f64 * 256.0)
66}
67
68#[cfg(test)]
69mod tests {
70 #[test]
71 fn midi_pitch_to_frequency() {
72 assert_eq!(super::midi_pitch_to_frequency(81.0), 880.0);
73 assert_eq!(super::midi_pitch_to_frequency(69.0), 440.0);
74 assert_eq!(super::midi_pitch_to_frequency(57.0), 220.0);
75 }
76
77 #[test]
78 fn frequency_to_midi_pitch() {
79 assert_eq!(super::frequency_to_midi_pitch(880.0), 81.0);
80 assert_eq!(super::frequency_to_midi_pitch(440.0), 69.0);
81 assert_eq!(super::frequency_to_midi_pitch(220.0), 57.0);
82 }
83
84 #[test]
85 fn tone_period_midi_conversion() {
86 let period = super::midi_pitch_to_tone_period(57.0, 4400000.0);
87 let pitch = super::tone_period_to_midi_pitch(period, 4400000.0);
88
89 assert_eq!(pitch, 57.0);
90
91 let frequency = super::tone_period_to_midi_pitch(100, 4400000.0);
92 let period = super::midi_pitch_to_tone_period(frequency, 4400000.0);
93
94 assert_eq!(period, 100);
95 }
96
97 #[test]
98 fn envelope_period_midi_conversion() {
99 let period = super::midi_pitch_to_envelope_period(21.0, 4400000.0);
100 let pitch = super::envelope_period_to_midi_pitch(period, 4400000.0);
101
102 assert_eq!(pitch, 21.0);
103
104 let frequency = super::envelope_period_to_midi_pitch(100, 4400000.0);
105 let period = super::midi_pitch_to_envelope_period(frequency, 4400000.0);
106
107 assert_eq!(period, 100);
108 }
109
110 #[test]
111 fn tone_period_conversion() {
112 let period = super::frequency_to_tone_period(100.0, 1000000.0);
113 let frequency = super::tone_period_to_frequency(period, 1000000.0);
114
115 println!("{} {}", period, frequency);
116
117 assert_eq!(frequency, 100.0);
118
119 let frequency = super::tone_period_to_frequency(100, 1000000.0);
120 let period = super::frequency_to_tone_period(frequency, 1000000.0);
121
122 assert_eq!(period, 100);
123 }
124
125 #[test]
126 fn envelop_period_conversion() {
127 let period = super::frequency_to_envelope_period(1.25, 1000000.0);
128 let frequency = super::envelope_period_to_frequency(period, 1000000.0);
129
130 println!("{} {}", period, frequency);
131
132 assert_eq!(frequency, 1.25);
133
134 let frequency = super::envelope_period_to_frequency(100, 1000000.0);
135 let period = super::frequency_to_envelope_period(frequency, 1000000.0);
136
137 assert_eq!(period, 100);
138 }
139}