1use std::fmt::{Display, Error, Formatter};
4
5#[cfg(feature = "wasm")]
6use wasm_bindgen::prelude::*;
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11use crate::core::octave::{HasOctave, Octave};
12
13pub trait HasIntervals {
17 fn intervals(&self) -> &'static [Interval];
19}
20
21pub trait HasEnharmonicDistance {
23 fn enharmonic_distance(&self) -> i8;
31}
32
33pub trait CanReduceFrame {
35 fn reduce_frame(self) -> Self;
37}
38
39#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Ord, PartialOrd)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44#[repr(u8)]
45#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = KordInterval))]
46pub enum Interval {
47 PerfectUnison,
49 DiminishedSecond,
51
52 AugmentedUnison,
54 MinorSecond,
56
57 MajorSecond,
59 DiminishedThird,
61
62 AugmentedSecond,
64 MinorThird,
66
67 MajorThird,
69 DiminishedFourth,
71
72 AugmentedThird,
74 PerfectFourth,
76
77 AugmentedFourth,
79 DiminishedFifth,
81
82 PerfectFifth,
84 DiminishedSixth,
86
87 AugmentedFifth,
89 MinorSixth,
91
92 MajorSixth,
94 DiminishedSeventh,
96
97 AugmentedSixth,
99 MinorSeventh,
101
102 MajorSeventh,
104 DiminishedOctave,
106
107 AugmentedSeventh,
109 PerfectOctave,
111
112 MinorNinth,
114 MajorNinth,
116 AugmentedNinth,
118
119 DiminishedEleventh,
121 PerfectEleventh,
123 AugmentedEleventh,
125
126 MinorThirteenth,
128 MajorThirteenth,
130 AugmentedThirteenth,
132
133 PerfectOctaveAndPerfectFifth,
135 TwoPerfectOctaves,
137 TwoPerfectOctavesAndMajorThird,
139 TwoPerfectOctavesAndPerfectFifth,
141 TwoPerfectOctavesAndMinorSeventh,
143 ThreePerfectOctaves,
145 ThreePerfectOctavesAndMajorSecond,
147 ThreePerfectOctavesAndMajorThird,
149 ThreePerfectOctavesAndAugmentedFourth,
151 ThreePerfectOctavesAndPerfectFifth,
153 ThreePerfectOctavesAndMinorSixth,
155 ThreePerfectOctavesAndMinorSeventh,
157 ThreePerfectOctavesAndMajorSeventh,
159}
160
161impl HasEnharmonicDistance for Interval {
164 fn enharmonic_distance(&self) -> i8 {
165 match self {
166 Interval::PerfectUnison => 0,
167 Interval::DiminishedSecond => -12,
168
169 Interval::AugmentedUnison => 7,
170 Interval::MinorSecond => -5,
171
172 Interval::MajorSecond => 2,
173 Interval::DiminishedThird => -10,
174
175 Interval::AugmentedSecond => 9,
176 Interval::MinorThird => -3,
177
178 Interval::MajorThird => 4,
179 Interval::DiminishedFourth => -8,
180
181 Interval::AugmentedThird => 11,
182 Interval::PerfectFourth => -1,
183
184 Interval::AugmentedFourth => 6,
185 Interval::DiminishedFifth => -6,
186
187 Interval::PerfectFifth => 1,
188 Interval::DiminishedSixth => -11,
189
190 Interval::AugmentedFifth => 8,
191 Interval::MinorSixth => -4,
192
193 Interval::MajorSixth => 3,
194 Interval::DiminishedSeventh => -9,
195
196 Interval::AugmentedSixth => 10,
197 Interval::MinorSeventh => -2,
198
199 Interval::MajorSeventh => 5,
200 Interval::DiminishedOctave => -7,
201
202 Interval::AugmentedSeventh => 12,
203 Interval::PerfectOctave => 0,
204
205 Interval::MinorNinth => -5,
206 Interval::MajorNinth => 2,
207 Interval::AugmentedNinth => 9,
208
209 Interval::DiminishedEleventh => -8,
210 Interval::PerfectEleventh => -1,
211 Interval::AugmentedEleventh => 6,
212
213 Interval::MinorThirteenth => -4,
214 Interval::MajorThirteenth => 3,
215 Interval::AugmentedThirteenth => 10,
216
217 Interval::PerfectOctaveAndPerfectFifth => 1,
218 Interval::TwoPerfectOctaves => 0,
219 Interval::TwoPerfectOctavesAndMajorThird => 4,
220 Interval::TwoPerfectOctavesAndPerfectFifth => 1,
221 Interval::TwoPerfectOctavesAndMinorSeventh => -2,
222 Interval::ThreePerfectOctaves => 0,
223 Interval::ThreePerfectOctavesAndMajorSecond => 2,
224 Interval::ThreePerfectOctavesAndMajorThird => 4,
225 Interval::ThreePerfectOctavesAndAugmentedFourth => 6,
226 Interval::ThreePerfectOctavesAndPerfectFifth => 1,
227 Interval::ThreePerfectOctavesAndMinorSixth => -4,
228 Interval::ThreePerfectOctavesAndMinorSeventh => -2,
229 Interval::ThreePerfectOctavesAndMajorSeventh => 5,
230 }
231 }
232}
233
234impl HasOctave for Interval {
235 fn octave(&self) -> Octave {
236 match self {
237 Interval::PerfectUnison => Octave::Zero,
238 Interval::DiminishedSecond => Octave::Zero,
239
240 Interval::AugmentedUnison => Octave::Zero,
241 Interval::MinorSecond => Octave::Zero,
242
243 Interval::MajorSecond => Octave::Zero,
244 Interval::DiminishedThird => Octave::Zero,
245
246 Interval::AugmentedSecond => Octave::Zero,
247 Interval::MinorThird => Octave::Zero,
248
249 Interval::MajorThird => Octave::Zero,
250 Interval::DiminishedFourth => Octave::Zero,
251
252 Interval::AugmentedThird => Octave::Zero,
253 Interval::PerfectFourth => Octave::Zero,
254
255 Interval::AugmentedFourth => Octave::Zero,
256 Interval::DiminishedFifth => Octave::Zero,
257
258 Interval::PerfectFifth => Octave::Zero,
259 Interval::DiminishedSixth => Octave::Zero,
260
261 Interval::AugmentedFifth => Octave::Zero,
262 Interval::MinorSixth => Octave::Zero,
263
264 Interval::MajorSixth => Octave::Zero,
265 Interval::DiminishedSeventh => Octave::Zero,
266
267 Interval::AugmentedSixth => Octave::Zero,
268 Interval::MinorSeventh => Octave::Zero,
269
270 Interval::MajorSeventh => Octave::Zero,
271 Interval::DiminishedOctave => Octave::Zero,
272
273 Interval::AugmentedSeventh => Octave::One,
274 Interval::PerfectOctave => Octave::One,
275
276 Interval::MinorNinth => Octave::One,
277 Interval::MajorNinth => Octave::One,
278 Interval::AugmentedNinth => Octave::One,
279
280 Interval::DiminishedEleventh => Octave::One,
281 Interval::PerfectEleventh => Octave::One,
282 Interval::AugmentedEleventh => Octave::One,
283
284 Interval::MinorThirteenth => Octave::One,
285 Interval::MajorThirteenth => Octave::One,
286 Interval::AugmentedThirteenth => Octave::One,
287
288 Interval::PerfectOctaveAndPerfectFifth => Octave::One,
289 Interval::TwoPerfectOctaves => Octave::Two,
290 Interval::TwoPerfectOctavesAndMajorThird => Octave::Two,
291 Interval::TwoPerfectOctavesAndPerfectFifth => Octave::Two,
292 Interval::TwoPerfectOctavesAndMinorSeventh => Octave::Two,
293 Interval::ThreePerfectOctaves => Octave::Three,
294 Interval::ThreePerfectOctavesAndMajorSecond => Octave::Three,
295 Interval::ThreePerfectOctavesAndMajorThird => Octave::Three,
296 Interval::ThreePerfectOctavesAndAugmentedFourth => Octave::Three,
297 Interval::ThreePerfectOctavesAndPerfectFifth => Octave::Three,
298 Interval::ThreePerfectOctavesAndMinorSixth => Octave::Three,
299 Interval::ThreePerfectOctavesAndMinorSeventh => Octave::Three,
300 Interval::ThreePerfectOctavesAndMajorSeventh => Octave::Three,
301 }
302 }
303}
304
305impl Display for Interval {
306 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
307 match self {
308 Interval::PerfectUnison => write!(f, "PerfectUnison"),
309 Interval::DiminishedSecond => write!(f, "DiminishedSecond"),
310
311 Interval::AugmentedUnison => write!(f, "AugmentedUnison"),
312 Interval::MinorSecond => write!(f, "MinorSecond"),
313
314 Interval::MajorSecond => write!(f, "MajorSecond"),
315 Interval::DiminishedThird => write!(f, "DiminishedThird"),
316
317 Interval::AugmentedSecond => write!(f, "AugmentedSecond"),
318 Interval::MinorThird => write!(f, "MinorThird"),
319
320 Interval::MajorThird => write!(f, "MajorThird"),
321 Interval::DiminishedFourth => write!(f, "DiminishedFourth"),
322
323 Interval::AugmentedThird => write!(f, "AugmentedThird"),
324 Interval::PerfectFourth => write!(f, "PerfectFourth"),
325
326 Interval::AugmentedFourth => write!(f, "AugmentedFourth"),
327 Interval::DiminishedFifth => write!(f, "DiminishedFifth"),
328
329 Interval::PerfectFifth => write!(f, "PerfectFifth"),
330 Interval::DiminishedSixth => write!(f, "DiminishedSixth"),
331
332 Interval::AugmentedFifth => write!(f, "AugmentedFifth"),
333 Interval::MinorSixth => write!(f, "MinorSixth"),
334
335 Interval::MajorSixth => write!(f, "MajorSixth"),
336 Interval::DiminishedSeventh => write!(f, "DiminishedSeventh"),
337
338 Interval::AugmentedSixth => write!(f, "AugmentedSixth"),
339 Interval::MinorSeventh => write!(f, "MinorSeventh"),
340
341 Interval::MajorSeventh => write!(f, "MajorSeventh"),
342 Interval::DiminishedOctave => write!(f, "DiminishedOctave"),
343
344 Interval::AugmentedSeventh => write!(f, "AugmentedSeventh"),
345 Interval::PerfectOctave => write!(f, "PerfectOctave"),
346
347 Interval::MinorNinth => write!(f, "MinorNinth"),
348 Interval::MajorNinth => write!(f, "MajorNinth"),
349 Interval::AugmentedNinth => write!(f, "AugmentedNinth"),
350
351 Interval::DiminishedEleventh => write!(f, "DiminishedEleventh"),
352 Interval::PerfectEleventh => write!(f, "PerfectEleventh"),
353 Interval::AugmentedEleventh => write!(f, "AugmentedEleventh"),
354
355 Interval::MinorThirteenth => write!(f, "MinorThirteenth"),
356 Interval::MajorThirteenth => write!(f, "MajorThirteenth"),
357 Interval::AugmentedThirteenth => write!(f, "AugmentedThirteenth"),
358
359 Interval::PerfectOctaveAndPerfectFifth => write!(f, "PerfectOctaveAndPerfectFifth"),
360 Interval::TwoPerfectOctaves => write!(f, "TwoPerfectOctaves"),
361 Interval::TwoPerfectOctavesAndMajorThird => write!(f, "TwoPerfectOctavesAndMajorThird"),
362 Interval::TwoPerfectOctavesAndPerfectFifth => write!(f, "TwoPerfectOctavesAndPerfectFifth"),
363 Interval::TwoPerfectOctavesAndMinorSeventh => write!(f, "TwoPerfectOctavesAndMinorSeventh"),
364 Interval::ThreePerfectOctaves => write!(f, "ThreePerfectOctaves"),
365 Interval::ThreePerfectOctavesAndMajorSecond => write!(f, "ThreePerfectOctavesAndMajorSecond"),
366 Interval::ThreePerfectOctavesAndMajorThird => write!(f, "ThreePerfectOctavesAndMajorThird"),
367 Interval::ThreePerfectOctavesAndAugmentedFourth => write!(f, "ThreePerfectOctavesAndAugmentedFourth"),
368 Interval::ThreePerfectOctavesAndPerfectFifth => write!(f, "ThreePerfectOctavesAndPerfectFifth"),
369 Interval::ThreePerfectOctavesAndMinorSixth => write!(f, "ThreePerfectOctavesAndMinorSixth"),
370 Interval::ThreePerfectOctavesAndMinorSeventh => write!(f, "ThreePerfectOctavesAndMinorSeventh"),
371 Interval::ThreePerfectOctavesAndMajorSeventh => write!(f, "ThreePerfectOctavesAndMajorSeventh"),
372 }
373 }
374}
375
376pub static ALL_INTERVALS: [Interval; 48] = [
380 Interval::PerfectUnison,
381 Interval::DiminishedSecond,
382 Interval::AugmentedUnison,
383 Interval::MinorSecond,
384 Interval::MajorSecond,
385 Interval::DiminishedThird,
386 Interval::AugmentedSecond,
387 Interval::MinorThird,
388 Interval::MajorThird,
389 Interval::DiminishedFourth,
390 Interval::AugmentedThird,
391 Interval::PerfectFourth,
392 Interval::AugmentedFourth,
393 Interval::DiminishedFifth,
394 Interval::PerfectFifth,
395 Interval::DiminishedSixth,
396 Interval::AugmentedFifth,
397 Interval::MinorSixth,
398 Interval::MajorSixth,
399 Interval::DiminishedSeventh,
400 Interval::AugmentedSixth,
401 Interval::MinorSeventh,
402 Interval::MajorSeventh,
403 Interval::DiminishedOctave,
404 Interval::AugmentedSeventh,
405 Interval::PerfectOctave,
406 Interval::MinorNinth,
407 Interval::MajorNinth,
408 Interval::AugmentedNinth,
409 Interval::DiminishedEleventh,
410 Interval::PerfectEleventh,
411 Interval::AugmentedEleventh,
412 Interval::MinorThirteenth,
413 Interval::MajorThirteenth,
414 Interval::AugmentedThirteenth,
415 Interval::PerfectOctaveAndPerfectFifth,
416 Interval::TwoPerfectOctaves,
417 Interval::TwoPerfectOctavesAndMajorThird,
418 Interval::TwoPerfectOctavesAndPerfectFifth,
419 Interval::TwoPerfectOctavesAndMinorSeventh,
420 Interval::ThreePerfectOctaves,
421 Interval::ThreePerfectOctavesAndMajorSecond,
422 Interval::ThreePerfectOctavesAndMajorThird,
423 Interval::ThreePerfectOctavesAndAugmentedFourth,
424 Interval::ThreePerfectOctavesAndPerfectFifth,
425 Interval::ThreePerfectOctavesAndMinorSixth,
426 Interval::ThreePerfectOctavesAndMinorSeventh,
427 Interval::ThreePerfectOctavesAndMajorSeventh,
428];
429
430pub static PRIMARY_HARMONIC_SERIES: [Interval; 13] = [
432 Interval::PerfectOctave,
433 Interval::PerfectOctaveAndPerfectFifth,
434 Interval::TwoPerfectOctaves,
435 Interval::TwoPerfectOctavesAndMajorThird,
436 Interval::TwoPerfectOctavesAndPerfectFifth,
437 Interval::TwoPerfectOctavesAndMinorSeventh,
438 Interval::ThreePerfectOctavesAndMajorSecond,
439 Interval::ThreePerfectOctavesAndMajorThird,
440 Interval::ThreePerfectOctavesAndAugmentedFourth,
441 Interval::ThreePerfectOctavesAndPerfectFifth,
442 Interval::ThreePerfectOctavesAndMinorSixth,
443 Interval::ThreePerfectOctavesAndMinorSeventh,
444 Interval::ThreePerfectOctavesAndMajorSeventh,
445];