-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHarmony.cpp
112 lines (94 loc) · 2.97 KB
/
Harmony.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/** @file Harmony.cpp
*
* Harmony implements Notes, Scales, Modes
* the intent is to keep this library as clean
* as possible to allow implementation on hardware
* platforms such as ARM MBED OS.
* No exceptions are used as the platform does not
* support it.
*
* TODO: Chords, Inversions, Progressions
*
* @author Jan-Willem Smaal <[email protected]>
* @date 13/12/2020
* @copyright APACHE-2.0
*/
#include "Harmony.hpp"
#include "Mode.hpp"
// Given a scale find the first, third and fifth note of that scale in
// each mode.
// First select the mode
// then iterate over the notes.
ChordProgression::ChordProgression
(
Scale &scl,
unsigned int modenum,
Type progType )
: scale(scl), fullrangemode(scl.modes[modenum])
{
Mode mode = scale.modes[modenum];
std::vector<Note> secondoctave;
std::cout << "ChordProgression::"
<< scale.Text()
<< "|" << mode.Name() << "|"
<< std::endl;
// We need to add another octave to the modes of this scale
for(Note note: mode.notes) {
Note note2{note.number + 12}; // octave is 12 semi-tones.
secondoctave.push_back(note2);
}
// append the vector we just created to the existing mode.
mode.notes.insert(mode.notes.end(),
secondoctave.begin(),
secondoctave.end());
// What mode to choose?
switch(progType) {
case Type::II_V_I:
std::cout << "II V I progression" << std::endl;
std::cout << "|"
<< mode.notes[Offset::II + 0].Name() << "|"
<< mode.notes[Offset::II + 2].Name() << "|"
<< mode.notes[Offset::II + 4].Name() << "|"
<< mode.notes[Offset::II + 6].Name() << std::endl;
// In order to do these progressions we need
// to have two octaves at least in the scale.
std::cout << "|"
<< mode.notes[Offset::V + 0].Name() << "|"
<< mode.notes[Offset::V + 2].Name() << "|"
<< mode.notes[Offset::V + 4].Name() << "|"
<< mode.notes[Offset::V + 6].Name() << std::endl;
std::cout << "|"
<< mode.notes[Offset::I + 0].Name() << "|"
<< mode.notes[Offset::I + 2].Name() << "|"
<< mode.notes[Offset::I + 4].Name() << "|"
<< mode.notes[Offset::I + 6].Name() << std::endl;
break;
case Type::V_of_V:
break;
case Type::I_VI_II_V:
break;
case Type::III_VI_II_V:
break;
case Type::I_II_III_IV:
break;
default:
break;
};
// Find the lowest note number in the scale mode used
// e.g. for a D major scale C# is the lowest note in the octave.
// This can be found by substracting 12 (an octave) from
// every note in the scale mode and making sure it's higher than 0.
for(Note note: mode.notes) {
// int j = (unsigned int)note.number % 12;
// std::cout << "[" << j << "](" << (unsigned int) note.number;
note.number = (unsigned int)note.number % 12;
// std::cout << "[" << j << "]"<< note.Name() << ".";
}
mode.Order(Mode::NoteOrder::HIGH_TO_LOW);
for(Note note: mode.notes) {
std::cout << note.Text()
<< "(" << (unsigned int) note.number << ")";
}
std::cout << std::endl;
};
/* EOF */