-
Notifications
You must be signed in to change notification settings - Fork 0
/
songmodel.h
145 lines (108 loc) · 2.32 KB
/
songmodel.h
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <vector>
#include <glibmm.h>
class Scale {
public:
int get_display_offset_for_note(int note) const;
int get_note_for_display_offset(int offset) const;
int has_note(int note) const
{
return !(get_display_offset_for_note(note)&1);
}
Glib::ustring get_note_name(int note) const;
};
class Chord {
public:
enum class Quality {
Major,
Minor,
Major6,
Minor6,
Major7,
Minor7,
Dominant7,
Sus2,
Sus4,
Diminished
};
Chord();
auto begin() const
{
return notes.begin();
}
auto end() const
{
return notes.end();
}
bool has_note(int note) const
{
return notes.find(uint8_t(note%12))!=notes.npos;
}
int get_root() const
{
return root;
}
void set_root(int);
Quality get_quality() const
{
return quality;
}
void set_quality(Quality);
Glib::ustring get_name(const Scale&) const;
private:
int root=0;
Quality quality=Quality::Major;
std::basic_string<uint8_t> notes;
void update();
};
struct Syllable {
Glib::ustring text;
Chord chord;
int note=12;
};
struct TimePoint {
int time;
Syllable* syllable;
TimePoint(int time, Syllable* syl):time(time), syllable(syl) {}
~TimePoint()
{
delete syllable;
}
TimePoint(const TimePoint&) = delete;
TimePoint(TimePoint&& other)
{
time=other.time;
syllable=other.syllable;
other.syllable=nullptr;
}
TimePoint& operator=(const TimePoint&) = delete;
TimePoint& operator=(TimePoint&& other)
{
time=other.time;
syllable=other.syllable;
other.syllable=nullptr;
return *this;
}
};
class Song {
public:
Song();
const Scale& get_scale() const
{
return scale;
}
TimePoint& operator[](int i)
{
return syllables[i];
}
int length() const
{
return syllables.size();
}
void insert(int pos, TimePoint&& tp);
void remove(int pos);
int find(const Syllable*) const;
int find_index_before_time(int time) const;
private:
Scale scale;
std::vector<TimePoint> syllables;
};