-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathnote.go
More file actions
163 lines (126 loc) · 3.98 KB
/
note.go
File metadata and controls
163 lines (126 loc) · 3.98 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package note
import "fmt"
type SpecialType int
const (
SpecialTypeEmpty = SpecialType(iota)
SpecialTypeRelease
SpecialTypeStop
SpecialTypeNormal
SpecialTypeStopOrRelease
SpecialTypeFadeout
SpecialTypeInvalid
)
// Note is a note or special effect related to the channel's voice playback system
type Note interface {
fmt.Stringer
Type() SpecialType
}
type baseNote struct{}
// EmptyNote is a special note effect that specifies no change in the current voice settings
type EmptyNote baseNote
func (n EmptyNote) String() string {
return "..."
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n EmptyNote) Type() SpecialType {
return SpecialTypeEmpty
}
// ReleaseNote is a special note effect that releases the currently playing voice (note-off)
type ReleaseNote baseNote
func (n ReleaseNote) String() string {
return "==="
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n ReleaseNote) Type() SpecialType {
return SpecialTypeRelease
}
// StopNote is a special note effect that stops the currently playing voice (note-cut)
type StopNote baseNote
func (n StopNote) String() string {
return "^^^"
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n StopNote) Type() SpecialType {
return SpecialTypeStop
}
type FadeoutNote baseNote
func (n FadeoutNote) String() string {
return "vvv"
}
func (n FadeoutNote) Type() SpecialType {
return SpecialTypeFadeout
}
// Normal is a standard note, which is a combination of key and octave
type Normal Semitone
func (n Normal) String() string {
st := Semitone(n)
return st.Key().String() + st.Octave().String()
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n Normal) Type() SpecialType {
return SpecialTypeNormal
}
// StopOrReleaseNote is a special note effect that denotes an S3M-style Stop note
// NOTE: ST3 treats a "stop" note like a combination of release (note-off) and stop (note-cut)
// For PCM, it is a stop, but for OPL2, it is a release
type StopOrReleaseNote baseNote
func (n StopOrReleaseNote) String() string {
return "^^."
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n StopOrReleaseNote) Type() SpecialType {
return SpecialTypeStopOrRelease
}
// InvalidNote is a special note effect that stops the currently playing voice (note-cut)
type InvalidNote baseNote
func (n InvalidNote) String() string {
return "???"
}
// Type returns the SpecialType enumerator reflecting the type of the note
func (n InvalidNote) Type() SpecialType {
return SpecialTypeInvalid
}
// CoalesceNoteSemitone will coalesce a note and an included semitone value.
// The intention is that a special note (note-off, fade-out, etc.) will take precedence
// over the semitone passed in, but if the semitone asks to override a normal note's
// semitone value, it will.
func CoalesceNoteSemitone(n Note, s Semitone) Note {
if s == UnchangedSemitone || IsSpecial(n) {
return n
}
return Normal(s)
}
// IsRelease returns true if the note is a release (Note-Off)
func IsRelease(n Note) bool {
return n != nil && n.Type() == SpecialTypeRelease
}
// IsStop returns true if the note is a stop (Note-Cut)
func IsStop(n Note) bool {
return n != nil && n.Type() == SpecialTypeStop
}
// IsEmpty returns true if the note is empty
func IsEmpty(n Note) bool {
return n == nil || n.Type() == SpecialTypeEmpty
}
// IsInvalid returns true if the note is invalid in any way
func IsInvalid(n Note) bool {
return n != nil && n.Type() == SpecialTypeInvalid
}
// IsSpecial returns true if the note is special in any way
func IsSpecial(n Note) bool {
return n != nil && n.Type() != SpecialTypeNormal
}
// Type returns the SpecialType enumerator reflecting the type of the note
func Type(n Note) SpecialType {
if n == nil {
return SpecialTypeEmpty
}
return n.Type()
}
// String returns the string representation of the note presented
func String(n Note) string {
if n == nil {
return EmptyNote{}.String()
}
return n.String()
}