1use super::{
2 traits::{
3 Wrapper, VecWrapper, ModeTrait, AsScaleTry, AsSteps, AddInterval, ToPC, AsPCs,
4 AsRelativeIntervals, AsEnharmonicNotes, AsEnharmonicNotesWithStart, Cyclic,
5 ToEnharmonicNote, ToNote, ModeIteratorSpawner, AsChord, AsRootedChord, ScaleIteratorSpawner
6 },
7 Note, _Note, Interval, PCs, Intervals, EnharmonicNote, Chord, RootedChord
8};
9
10pub type Mode = usize;
27pub type Notes = Vec<Note>;
29
30#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub struct Scale(pub(crate) Notes);
43
44#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub struct Steps(pub(crate) Intervals);
67
68impl Scale{
69 pub fn as_octave_steps(&self) -> Option<Steps>{
85 if self.is_empty(){ return None; }
86 let mut res = Vec::new();
87 let mut last = self[0];
88 let mut sum = Interval::ROOT;
89 for note in self.iter().skip(1){
90 let diff = *note - last;
91 if diff.0 < 0 { return None; }
92 if diff.0 == 0 { continue; }
93 res.push(diff);
94 last = *note;
95 sum += diff;
96 }
97 if sum > Interval::OCTAVE { return None; }
98 if sum == Interval::OCTAVE {
99 return Some(Steps(res));
100 }
101 res.push(Interval::OCTAVE - sum);
102 Some(Steps(res))
103 }
104}
105
106impl Steps{
107 pub fn mode_nr_of_this(&self, mode: &Steps) -> Option<(usize, Steps)>{
125 if mode.len() != self.len() {
126 return None;
127 }
128 let len = self.len();
129 let mut copy = self.clone();
130 for i in 0..=len{
131 if copy.0 == mode.0{
132 return Some((i, copy));
133 }
134 copy.next_mode_mut();
135 }
136 None
137 }
138}
139
140ImplVecWrapper!(Scale, Note);
141ImplVecWrapper!(Steps, Interval);
142
143impl Wrapper for Scale{
144 type Inner = Notes;
145
146 fn wrap(scale: Self::Inner) -> Option<Self>{
147 if scale.is_empty(){
148 None
149 } else {
150 Some(Self(scale))
151 }
152 }
153
154 fn unwrap(self) -> Self::Inner{
155 self.0
156 }
157}
158
159impl Wrapper for Steps{
160 type Inner = Intervals;
161
162 fn wrap(steps: Self::Inner) -> Option<Self>{
163 if steps.is_empty(){
164 None
165 } else {
166 Some(Self(steps))
167 }
168 }
169
170 fn unwrap(self) -> Self::Inner{
171 self.0
172 }
173}
174
175impl ModeTrait for Scale{
176 fn next_mode_mut(&mut self){
177 self.0.rotate_left(1);
178 }
179
180 fn next_mode(mut self) -> Self{
181 self.next_mode_mut();
182 self
183 }
184
185 fn mode(mut self, mode: Mode) -> Self{
186 let len = self.len();
187 self.0.rotate_left(mode % len);
188 Scale(self.0)
189 }
190}
191
192impl ModeTrait for Steps{
193 fn next_mode_mut(&mut self){
194 self.0.rotate_left(1);
195 }
196
197 fn next_mode(mut self) -> Self{
198 self.next_mode_mut();
199 self
200 }
201
202 fn mode(mut self, mode: Mode) -> Self{
203 let len = self.len();
204 self.0.rotate_left(mode % len);
205 Steps(self.0)
206 }
207}
208
209impl AsSteps for Scale{
210 fn as_steps(&self, complete_octave_cycle: bool) -> Steps{
211 if self.0.is_empty() { return Steps::default(); }
212 let mut last = self[0];
213 let mut intervals = Vec::new();
214 for note in self.iter().skip(1){
215 let diff = *note - last;
216 intervals.push(diff);
217 last = *note;
218 }
219 if complete_octave_cycle {
220 intervals.push(self[0] - last + Interval::OCTAVE);
221 }
222 Steps(intervals)
223 }
224}
225
226impl AsPCs for Scale{
227 fn as_pcs(&self) -> PCs{
228 let mut res = Vec::new();
229 for n in &self.0{
230 res.push(n.to_pc());
231 }
232 res
233 }
234}
235
236impl AsChord for Scale{
237 fn as_chord(&self) -> Chord{
238 if self.is_empty() { return Chord(Vec::new()); }
239 let root = self[0];
240 let mut intervals = vec![];
241 for note in self.iter().skip(1){
242 let mut diff = note.0 as i32 - root.0 as i32;
243 if diff == 0 { continue; }
244 if diff < 0 {
245 diff = (diff % 12) + 12;
246 }
247 intervals.push(Note(diff as _Note));
248 }
249 intervals.sort();
250 Chord(intervals)
251 }
252}
253
254fn as_enharmonic_notes_with_start_heptatonic(scale: &Scale, start: Option<EnharmonicNote>)
284 -> Vec<EnharmonicNote>
285{
286 let mut res = Vec::new();
287 if scale.is_empty() { return res; }
288 let (skip, mut target_letter) = if let Some(en) = start{
289 if en.to_note() != scale[0] { return res; }
290 res.push(en);
291 (1, en.next().letter)
292 } else {
293 (0, scale[0].to_enharmonic_note().letter)
294 };
295 for note in scale.iter().skip(skip){
296 let en = note.to_enharmonic_note();
297 let new_en = if en.letter == target_letter {
298 en
299 } else {
300 en.spelled_as(target_letter)
301 };
302 res.push(new_en);
303 target_letter = target_letter.next();
304 }
305 res
306}
307
308impl AsEnharmonicNotes for Scale{
309 fn as_enharmonic_notes(&self) -> Vec<EnharmonicNote>{
310 as_enharmonic_notes_with_start_heptatonic(self, None)
311 }
312}
313
314impl AsEnharmonicNotesWithStart for Scale{
315 fn as_enharmonic_notes_with_start(&self, start: Option<EnharmonicNote>) -> Vec<EnharmonicNote>{
316 as_enharmonic_notes_with_start_heptatonic(self, start)
317 }
318}
319
320impl AsRootedChord for Scale{
321 fn as_rooted_chord(&self) -> RootedChord{
322 if self.is_empty() { RootedChord{ root: Note::ZERO, chord: Chord(vec![]) } }
323 else if self.len() == 1 { RootedChord{ root: self[0], chord: Chord(vec![]) } }
324 else { RootedChord::from_chord(self[0], self.as_chord()) }
325 }
326}
327
328impl AsScaleTry for Steps{
329 fn as_scale_try(&self, mut note: Note) -> Option<Scale>{
330 let mut vec = vec![note];
331 if self.is_empty(){
332 return Some(Scale(vec));
333 }
334 for step in self.iter().take(self.len() - 1){
335 note = note.add_interval(*step)?;
336 vec.push(note);
337 }
338 Some(Scale(vec))
339 }
340}
341
342impl AsRelativeIntervals for Steps{
343 fn as_relative_intervals(&self, reference: &Self) -> Option<Intervals>{
344 if self.0.len() != reference.0.len() { return None; }
345 if self.0.is_empty() { return None; }
346 let mut acc_a = Interval(0);
347 let mut acc_b = Interval(0);
348 let mut res = Vec::new();
349 for i in 0..self.0.len(){
350 let diff = acc_a - acc_b;
351 res.push(diff);
352 acc_a += self[i];
353 acc_b += reference[i];
354 }
355 Some(res)
356 }
357}
358
359impl AsChord for Steps{
360 fn as_chord(&self) -> Chord{
361 if self.is_empty() { return Chord(Vec::new()); }
362 let mut intervals = vec![];
363 let mut acc = 0;
364 for step in self.iter(){
365 acc += step.0;
366 if acc == 0 { continue; }
367 intervals.push(Note((((acc % 12) + 12) % 12) as _Note));
368 }
369 let chord = Chord(intervals);
370 chord.normalized()
371 }
372}
373
374pub struct ScaleIterator<'a>{
389 scale: &'a [Interval],
390 current: usize,
391 len: usize,
392 root: Note,
393}
394
395impl<'a> Iterator for ScaleIterator<'a>{
396 type Item = Note;
397
398 fn next(&mut self) -> Option<Note>{
399 if self.current >= self.len{
400 self.current = 0;
401 }
402 let res = self.root;
403 self.root = self.root.add_interval(self.scale[self.current])?;
404 self.current += 1;
405 Some(res)
406 }
407}
408
409impl ScaleIteratorSpawner for Steps{
410 fn scale_iter(&self, root: Note) -> ScaleIterator{
411 ScaleIterator{
412 scale: &self.0,
413 current: 0,
414 len: self.len(),
415 root,
416 }
417 }
418}
419
420pub struct ModeIterator<T: ModeTrait + VecWrapper>{
437 wrapper: T,
438 current: usize,
439 len: usize,
440}
441
442impl<T: Clone + ModeTrait + VecWrapper> Iterator for ModeIterator<T>{
444 type Item = T;
445
446 fn next(&mut self) -> Option<T>{
447 if self.current >= self.len{
448 return Option::None;
449 }
450 let res = self.wrapper.clone();
451 self.wrapper.next_mode_mut();
452 self.current += 1;
453 Option::Some(res)
454 }
455}
456
457impl<T: ModeTrait + VecWrapper> ModeIteratorSpawner<T> for T{
458 fn mode_iter(self) -> ModeIterator<T>{
459 let len = self.len();
460 ModeIterator{
461 wrapper: self,
462 current: 0,
463 len,
464 }
465 }
466}
467
468#[cfg(test)]
469mod tests{
470 use super::super::*;
471
472 #[test]
473 fn scale_wrap(){
474 assert_eq!(Scale::wrap(vec![]), None);
475 assert_eq!(Scale::wrap(vec![Note(0), Note(1)]), Some(Scale(vec![Note(0), Note(1)])));
476 }
477
478 #[test]
479 fn scale_unwrap(){
480 assert_eq!(Scale(vec![Note(0), Note(1)]).unwrap(), vec![Note(0), Note(1)]);
481 }
482
483 #[test]
484 fn steps_wrap(){
485 assert_eq!(Steps::wrap(vec![]), None);
486 assert_eq!(
487 Steps::wrap(vec![Interval(0), Interval(1)]), Some(Steps(vec![Interval(0), Interval(1)]))
488 );
489 }
490
491 #[test]
492 fn steps_unwrap(){
493 assert_eq!(Steps(vec![Interval(2), Interval(1)]).unwrap(), vec![Interval(2), Interval(1)]);
494 }
495
496 #[test]
497 fn scale_len(){
498 assert_eq!(Scale(vec![Note(0), Note(1)]).len(), 2);
499 }
500
501 #[test]
502 fn scale_is_empty(){
503 assert!(!Scale(vec![Note(0)]).is_empty());
504 }
505
506 #[test]
507 fn test_scale_iter(){
508 let scale = Scale(vec![Note(0), Note(1), Note(2)]);
509 let mut iter = scale.iter();
510 assert_eq!(iter.next(), Some(&Note(0)));
511 assert_eq!(iter.next(), Some(&Note(1)));
512 assert_eq!(iter.next(), Some(&Note(2)));
513 assert_eq!(iter.next(), None);
514 }
515
516 #[test]
517 fn scale_contains(){
518 let scale = Scale(vec![Note(0), Note(1), Note(2)]);
519 assert!(scale.contains(&Note(0)));
520 assert!(scale.contains(&Note(1)));
521 assert!(scale.contains(&Note(2)));
522 assert!(!scale.contains(&Note(3)));
523 }
524
525 #[test]
526 fn scale_contains_all(){
527 let scale = Scale(vec![Note(0), Note(1), Note(2)]);
528 assert!(scale.contains_all(&[Note(0)]));
529 assert!(scale.contains_all(&[Note(0), Note(1)]));
530 assert!(scale.contains_all(&[Note(0), Note(1), Note(2)]));
531 assert!(!scale.contains_all(&[Note(0), Note(1), Note(2), Note(3)]));
532 }
533
534 #[test]
535 fn scale_contains_any(){
536 let scale = Scale(vec![Note(0), Note(1), Note(2)]);
537 assert!(scale.contains_any(&[Note(0)]));
538 assert!(scale.contains_any(&[Note(1)]));
539 assert!(scale.contains_any(&[Note(2)]));
540 assert!(scale.contains_any(&[Note(3245), Note(2)]));
541 assert!(!scale.contains_any(&[Note(3)]));
542 }
543
544 #[test]
545 fn scale_as_subs(){
546 let (c, d, e) = (Note::C1, Note::D1, Note::E1);
547 let scale = Scale(vec![c, d, e]);
548 assert_eq!(
549 scale.as_subs(None),
550 vec![
551 Scale(vec![]),
552 Scale(vec![c]),
553 Scale(vec![d]),
554 Scale(vec![e]),
555 Scale(vec![c, d]),
556 Scale(vec![d, c]),
557 Scale(vec![c, e]),
558 Scale(vec![e, c]),
559 Scale(vec![d, e]),
560 Scale(vec![e, d]),
561 Scale(vec![c, d, e]),
562 Scale(vec![c, e, d]),
563 Scale(vec![d, c, e]),
564 Scale(vec![d, e, c]),
565 Scale(vec![e, c, d]),
566 Scale(vec![e, d, c]),
567 ]
568 );
569 }
570
571 #[test]
572 fn scale_indexing(){
573 let (c, d, e) = (Note::C1, Note::D1, Note::E1);
574 let mut scale = Scale(vec![c, d, e]);
575 assert_eq!(scale[0], c);
576 assert_eq!(scale[1], d);
577 assert_eq!(scale[2], e);
578 scale[0] = d;
579 assert_eq!(scale[0], d);
580 }
581
582 #[test]
583 fn steps_len(){
584 assert_eq!(Steps(vec![Interval(1), Interval(2)]).len(), 2);
585 }
586
587 #[test]
588 fn steps_is_empty(){
589 assert!(!Steps(vec![Interval(1)]).is_empty());
590 }
591
592 #[test]
593 fn steps_iter(){
594 let steps = Steps(vec![Interval(1), Interval(2), Interval(3)]);
595 let mut iter = steps.iter();
596 assert_eq!(iter.next(), Some(&Interval(1)));
597 assert_eq!(iter.next(), Some(&Interval(2)));
598 assert_eq!(iter.next(), Some(&Interval(3)));
599 assert_eq!(iter.next(), None);
600 }
601
602 #[test]
603 fn scale_next_mode_mut(){
604 let mut scale = Scale(vec![Note(0), Note(1), Note(2)]);
605 scale.next_mode_mut();
606 assert_eq!(scale, Scale(vec![Note(1), Note(2), Note(0)]));
607 scale.next_mode_mut();
608 assert_eq!(scale, Scale(vec![Note(2), Note(0), Note(1)]));
609 scale.next_mode_mut();
610 assert_eq!(scale, Scale(vec![Note(0), Note(1), Note(2)]));
611 let clone = scale.clone();
612 scale.next_mode_mut();
613 assert_eq!(scale, clone.next_mode());
614 }
615
616 #[test]
617 fn scale_next_mode(){
618 let mut scale = Scale(vec![Note(0), Note(1), Note(2)]);
619 scale = scale.next_mode();
620 assert_eq!(scale, Scale(vec![Note(1), Note(2), Note(0)]));
621 scale = scale.next_mode();
622 assert_eq!(scale, Scale(vec![Note(2), Note(0), Note(1)]));
623 scale = scale.next_mode();
624 assert_eq!(scale, Scale(vec![Note(0), Note(1), Note(2)]));
625 let mut clone = scale.clone();
626 clone.next_mode_mut();
627 assert_eq!(scale.next_mode(), clone);
628 }
629
630 #[test]
631 fn scale_mode(){
632 let scale = Scale(vec![Note(0), Note(1), Note(2)]);
633 assert_eq!(scale.clone().mode(0), scale);
634 assert_eq!(scale.clone().mode(1), Scale(vec![Note(1), Note(2), Note(0)]));
635 assert_eq!(scale.clone().mode(2), Scale(vec![Note(2), Note(0), Note(1)]));
636 assert_eq!(scale.clone().mode(3), scale);
637 assert_eq!(scale.clone().mode(1), scale.next_mode());
638 }
639
640 #[test]
641 fn steps_next_mode_mut(){
642 let mut steps = Steps(vec![Interval(1), Interval(2), Interval(3)]);
643 steps.next_mode_mut();
644 assert_eq!(steps, Steps(vec![Interval(2), Interval(3), Interval(1)]));
645 steps.next_mode_mut();
646 assert_eq!(steps, Steps(vec![Interval(3), Interval(1), Interval(2)]));
647 steps.next_mode_mut();
648 assert_eq!(steps, Steps(vec![Interval(1), Interval(2), Interval(3)]));
649 let clone = steps.clone();
650 steps.next_mode_mut();
651 assert_eq!(steps, clone.next_mode());
652 }
653
654 #[test]
655 fn steps_next_mode(){
656 let mut steps = Steps(vec![Interval(1), Interval(2), Interval(3)]);
657 steps = steps.next_mode();
658 assert_eq!(steps, Steps(vec![Interval(2), Interval(3), Interval(1)]));
659 steps = steps.next_mode();
660 assert_eq!(steps, Steps(vec![Interval(3), Interval(1), Interval(2)]));
661 steps = steps.next_mode();
662 assert_eq!(steps, Steps(vec![Interval(1), Interval(2), Interval(3)]));
663 let mut clone = steps.clone();
664 clone.next_mode_mut();
665 assert_eq!(steps.next_mode(), clone);
666 }
667
668 #[test]
669 fn steps_mode(){
670 let steps = Steps(vec![Interval(1), Interval(2), Interval(3)]);
671 assert_eq!(steps.clone().mode(0), steps);
672 assert_eq!(steps.clone().mode(1), Steps(vec![Interval(2), Interval(3), Interval(1)]));
673 assert_eq!(steps.clone().mode(2), Steps(vec![Interval(3), Interval(1), Interval(2)]));
674 assert_eq!(steps.clone().mode(3), steps);
675 assert_eq!(steps.clone().mode(1), steps.next_mode());
676 }
677
678 #[test]
679 fn steps_as_scale(){
680 assert_eq!(
681 Steps(vec![]).as_scale_try(Note(123)),
682 Some(Scale(vec![Note(123)]))
683 );
684 assert_eq!( Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
686 Interval(2), Interval(2), Interval(1)])
687 .as_scale_try(PC::C.to_note()).unwrap().iter().map(|n| n.to_pc()).collect::<Vec<_>>(),
688 vec![PC::C, PC::D, PC::E, PC::F, PC::G, PC::A, PC::B]
689 );
690 assert_eq!( Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
692 Interval(2), Interval(2), Interval(1)]).mode(5)
693 .to_scale_try(PC::A.to_note()).unwrap().iter().map(|n| n.to_pc()).collect::<Vec<_>>(),
694 vec![PC::A, PC::B, PC::C, PC::D, PC::E, PC::F, PC::G]
695 );
696 }
697
698 #[test]
699 fn scale_as_steps(){
700 assert_eq!( Scale(vec![Note::C1, Note::D1, Note::E1, Note::F1, Note::G1, Note::A2, Note::B2])
702 .as_steps(true),
703 Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
704 Interval(2), Interval(2), Interval(1)])
705 );
706 assert_eq!(
707 Scale(vec![Note::A1, Note::B1, Note::C1, Note::D1, Note::E1, Note::F1, Note::G1])
708 .as_steps(true),
709 Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
710 Interval(2), Interval(2), Interval(1)]).mode(5)
711 );
712 assert_eq!(
713 Scale(vec![Note::A1, Note::B1, Note::A1, Note::B1]).to_steps(true),
714 Steps(vec![Interval(2), Interval(-2), Interval(2), Interval(10)])
715 );
716 assert_eq!(
717 Scale(vec![Note::A1, Note::B1, Note::A1, Note::B1]).to_steps(false),
718 Steps(vec![Interval(2), Interval(-2), Interval(2)])
719 );
720 }
721
722 #[test]
723 fn scale_as_pcs(){
724 assert_eq!(
725 Scale(vec![Note::C1, Note::E1, Note::G1, Note::C2]).as_pcs(),
726 vec![PC::C, PC::E, PC::G, PC::C]
727 );
728 assert_eq!(
729 Scale(vec![Note::A1, Note::C1, Note::D1, Note::F1, Note::A2]).to_pcs(),
730 vec![PC::A, PC::C, PC::D, PC::F, PC::A]
731 );
732 }
733
734 #[test]
735 fn scale_as_chord(){
736 assert_eq!(Scale(vec![]).to_chord(), Chord(vec![]));
737 assert_eq!(
738 Scale(vec![Note::C1, Note::E1, Note::G1]).as_chord(),
739 Chord::new(MAJOR)
740 );
741 assert_eq!(
742 Scale(vec![Note::C1, Note::B1, Note::E1, Note::G1]).as_chord(),
743 Chord::new(MAJOR_SEVENTH_CHORD)
744 );
745 assert_eq!(
746 Scale(vec![Note::C1, Note::E1, Note::G1, Note::B2]).as_chord(),
747 Chord::new(MAJOR_SEVENTH_CHORD)
748 );
749 }
750
751 #[test]
752 fn mode_nr_of_this(){
753 let major = Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
754 Interval(2), Interval(2), Interval(1)]);
755 let minor = major.clone().mode(5);
756 assert_eq!(
757 major.mode_nr_of_this(&minor),
758 Some((5, Steps(vec![
759 Interval(2), Interval(1), Interval(2), Interval(2),
760 Interval(1), Interval(2), Interval(2)
761 ])))
762 );
763 assert_eq!(
764 Steps(vec![Interval(1), Interval(1)]).mode_nr_of_this(&Steps(vec![Interval(1)])),
765 None
766 );
767 assert_eq!(
768 Steps(vec![Interval(1), Interval(2)])
769 .mode_nr_of_this(&Steps(vec![Interval(2), Interval(2)])),
770 None
771 );
772 }
773
774 #[test]
775 fn steps_as_relative_intervals(){
776 let a = Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
777 Interval(2), Interval(2), Interval(1)]);
778 let b = Steps(vec![Interval(3), Interval(2), Interval(1), Interval(1),
779 Interval(2), Interval(2), Interval(1)]);
780 assert_eq!(
781 a.to_relative_intervals(&b),
782 Some(vec![Interval(0), Interval(-1), Interval(-1), Interval(-1),
783 Interval(0), Interval(0), Interval(0)])
784 );
785
786 let scalea = vec![PC::C, PC::D, PC::E, PC::F, PC::G, PC::A, PC::B]
787 .to_scale_try(Note(1)).unwrap().to_steps(true);
788 let scaleb = vec![PC::A, PC::B, PC::C, PC::D, PC::E, PC::F, PC::G]
789 .to_scale_try(Note(1)).unwrap().to_steps(true);
790 assert_eq!(
791 scaleb.to_relative_intervals(&scalea),
792 Some(vec![Interval(0), Interval(0), Interval(-1), Interval(0),
793 Interval(0), Interval(-1), Interval(-1)])
794 );
795 }
796
797 #[test]
798 fn steps_as_chord(){
799 assert_eq!(Steps(vec![]).to_chord(), Chord(vec![]));
800 assert_eq!(
801 Steps(vec![
802 Interval(4), Interval(3), Interval(4)
803 ]).to_chord(),
804 Chord::new(MAJOR_SEVENTH_CHORD)
805 );
806 assert_eq!(
807 Steps(vec![
808 Interval(0), Interval(4), Interval(3), Interval(4)
809 ]).to_chord(),
810 Chord::new(MAJOR_SEVENTH_CHORD)
811 );
812 }
813
814 #[test]
815 fn scale_as_enharmonic_notes(){
816 assert_eq!(Scale(vec![]).to_enharmonic_notes(), vec![]);
817 assert_eq!(
818 Scale(vec![
819 Note(0), Note(1), Note(2), Note(3)
820 ]).to_enharmonic_notes(),
821 vec![
822 EnharmonicNote{ letter: Letter::A, accidental: Interval(0) },
823 EnharmonicNote{ letter: Letter::B, accidental: Interval(-1) },
824 EnharmonicNote{ letter: Letter::C, accidental: Interval(-1) },
825 EnharmonicNote{ letter: Letter::D, accidental: Interval(-2) },
826 ]
827 );
828 }
829
830 #[test]
831 fn scale_as_enharmonic_notes_with_start(){
832 assert_eq!(
833 Scale(vec![]).to_enharmonic_notes_with_start(
834 Some(EnharmonicNote{ letter: Letter::A, accidental: Interval(0) })
835 ),
836 vec![]
837 );
838 let scale = Scale(vec![Note(0), Note(1), Note(2), Note(3)]);
839 assert_eq!(
840 scale.clone().to_enharmonic_notes(),
841 scale.to_enharmonic_notes_with_start(
842 Some(EnharmonicNote{ letter: Letter::A, accidental: Interval(0) })
843 )
844 );
845 assert_eq!(
846 Scale(vec![
847 Note(10), Note(11), Note(12), Note(13)
848 ]).to_enharmonic_notes_with_start(
849 Some(EnharmonicNote { letter: Letter::G, accidental: Interval(0) })
850 ),
851 vec![
852 EnharmonicNote { letter: Letter::G, accidental: Interval(0) },
853 EnharmonicNote { letter: Letter::A, accidental: Interval(-1) },
854 EnharmonicNote { letter: Letter::B, accidental: Interval(-2) },
855 EnharmonicNote { letter: Letter::C, accidental: Interval(-2) }
856 ]
857 );
858 assert_eq!(
859 Scale(vec![
860 Note(10), Note(11), Note(12), Note(13)
861 ]).to_enharmonic_notes_with_start(
862 Some(EnharmonicNote { letter: Letter::F, accidental: Interval(2) })
863 ),
864 vec![
865 EnharmonicNote { letter: Letter::F, accidental: Interval(2) },
866 EnharmonicNote { letter: Letter::G, accidental: Interval(1) },
867 EnharmonicNote { letter: Letter::A, accidental: Interval(0) },
868 EnharmonicNote { letter: Letter::B, accidental: Interval(-1) }
869 ]
870 );
871 assert_eq!(
872 Scale(vec![
873 Note(10), Note(11), Note(12), Note(13)
874 ]).to_enharmonic_notes_with_start(
875 Some(EnharmonicNote { letter: Letter::F, accidental: Interval(0) })
876 ),
877 vec![]
878 );
879 }
880
881 #[test]
882 fn mode_iterator(){
883 let mut iter = Steps(vec![Interval(1), Interval(2), Interval(3)]).mode_iter();
884 assert_eq!(iter.next(), Some(Steps(vec![Interval(1), Interval(2), Interval(3)])));
885 assert_eq!(iter.next(), Some(Steps(vec![Interval(2), Interval(3), Interval(1)])));
886 assert_eq!(iter.next(), Some(Steps(vec![Interval(3), Interval(1), Interval(2)])));
887 assert_eq!(iter.next(), None);
888 }
889
890 #[test]
891 fn scale_iterator(){
892 let major = crate::libr::ionian::steps();
893 let mut iter = major.scale_iter(Note::C1);
894 assert_eq!(iter.next(), Some(Note::C1));
895 assert_eq!(iter.next(), Some(Note::D1));
896 assert_eq!(iter.next(), Some(Note::E1));
897 assert_eq!(iter.next(), Some(Note::F1));
898 assert_eq!(iter.next(), Some(Note::G1));
899 assert_eq!(iter.next(), Some(Note::A2));
900 assert_eq!(iter.next(), Some(Note::B2));
901 assert_eq!(iter.next(), Some(Note::C2));
902 assert_eq!(iter.next(), Some(Note::D2));
903 }
904
905 #[test]
906 fn scale_as_octave_steps(){
907 assert_eq!( Scale(vec![Note::C1, Note::D1, Note::E1, Note::F1, Note::G1, Note::A2, Note::B2])
909 .as_octave_steps(),
910 Some(Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
911 Interval(2), Interval(2), Interval(1)]))
912 );
913 assert_eq!(
914 Scale(vec![Note::A1, Note::B1, Note::C1, Note::D1, Note::E1, Note::F1, Note::G1])
915 .as_octave_steps(),
916 Some(Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
917 Interval(2), Interval(2), Interval(1)]).mode(5))
918 );
919 assert_eq!(
920 Scale(vec![Note::A1, Note::B1, Note::A1, Note::B1]).as_octave_steps(),
921 None
922 );
923 assert_eq!(
924 Scale(vec![Note::A1, Note::B1, Note::A1, Note::B1]).as_octave_steps(),
925 None
926 );
927 assert_eq!( Scale(vec![Note::C1, Note::D1, Note::E1, Note::F1, Note::G1, Note::A2, Note::B2, Note::C2])
929 .as_octave_steps(),
930 Some(Steps(vec![Interval(2), Interval(2), Interval(1), Interval(2),
931 Interval(2), Interval(2), Interval(1)]))
932 );
933 }
934}