-
Notifications
You must be signed in to change notification settings - Fork 1
/
module.go
138 lines (104 loc) · 2.25 KB
/
module.go
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
package xm
import (
"github.com/quasilyte/xm/internal/xmdb"
"github.com/quasilyte/xm/xmfile"
)
type module struct {
instruments []instrument
patterns []pattern
patternOrder []*pattern
effectTab []noteEffect
noteTab []patternNote
sampleRate float64
bpm float64
ticksPerRow int
// These values store the defaults for the stream.
samplesPerTick float64
bytesPerTick int
secondsPerRow float64
}
type moduleConfig struct {
sampleRate uint
bpm uint
tempo uint
subSamples bool
}
type pattern struct {
numChannels int
numRows int
notes []uint16
}
type patternNote struct {
inst *instrument
period float64
raw float64
flags patternNoteFlags
effect effectKey // Can be empty, see effectKey.IsEmpty()
}
func (n *patternNote) Kind() patternNoteKind {
return patternNoteKind(n.flags >> (64 - 2))
}
type patternNoteKind int
const (
noteEmpty patternNoteKind = iota
noteGhostInstrument
noteGhost
noteNormal
)
type patternNoteFlags uint64
const (
noteHasNotePortamento = 1 << iota
noteHasArpeggio
noteHasVibrato
noteValid
noteBadInstrument
noteInitialized
)
func (f patternNoteFlags) Contains(v patternNoteFlags) bool {
return f&v != 0
}
type noteEffect struct {
op xmdb.EffectOp
rawValue uint8
arp [3]uint8
floatValue float64
}
type instrument struct {
samples []int16
finetune int8
relativeNote int8
volume float64
panning float64
sampleStepMultiplier float64
volumeEnvelope envelope
panningEnvelope envelope
volumeFadeoutStep float64
loopType xmfile.SampleLoopType
loopLength float64
loopStart float64
loopEnd float64
numSubSamples int
id int
sample16bit bool
}
type envelope struct {
flags xmfile.EnvelopeFlags
sustainPoint uint8
loopEndPoint uint8
loopStartPoint uint8
sustainFrame int
loopEndFrame int
loopLength int
points []envelopePoint
}
type envelopePoint struct {
frame int
value float64
}
type effectKey uint16
func makeEffectKey(index, length uint) effectKey {
return effectKey((uint16(index) << 2) | (uint16(length) & 0b11))
}
func (k effectKey) IsEmpty() bool { return k == 0 }
func (k effectKey) Len() uint { return uint(k & 0b11) }
func (k effectKey) Index() uint { return uint(k >> 2) }