1
1
package psg
2
2
3
- import (
4
- "encoding/binary"
5
- "io"
6
- )
7
-
8
- type noise struct {
3
+ type Noise struct {
9
4
enabled bool // NR52.3
10
5
11
6
length uint8 // 音の残り再生時間
12
7
stop bool // NR44.6
13
8
14
- envelope * envelope
9
+ envelope * Envelope
15
10
16
- lfsr uint16 // Noiseの疑似乱数(lfsr: Linear Feedback Shift Register = 疑似乱数生成アルゴリズム)
11
+ LFSR uint16 // Noiseの疑似乱数(lfsr: Linear Feedback Shift Register = 疑似乱数生成アルゴリズム)
17
12
18
13
// この2つでノイズの周波数(疑似乱数の生成頻度)を決める
19
14
divisor uint8 // NR43.0-2; ノイズ周波数1(カウント指定)
@@ -25,40 +20,45 @@ type noise struct {
25
20
output uint8 // 0..15
26
21
}
27
22
28
- func newNoiseChannel () * noise {
29
- return & noise {
23
+ func newNoiseChannel () * Noise {
24
+ return & Noise {
30
25
envelope : newEnvelope (),
31
- lfsr : 0 ,
26
+ LFSR : 0 ,
32
27
}
33
28
}
34
29
35
- func (ch * noise ) reset () {
36
- ch .enabled = false
37
- ch .length , ch .stop = 0 , false
30
+ func (ch * Noise ) Reset () {
31
+ ch .TurnOff ()
38
32
ch .envelope .reset ()
39
- ch .lfsr = 0
33
+ ch .LFSR = 0
40
34
ch .divisor , ch .octave = 0 , 0
41
35
ch .period = 0
42
36
ch .narrow = false
43
37
ch .output = 0
44
38
}
45
39
46
- func (ch * noise ) reload () {
40
+ func (ch * Noise ) TurnOff () {
41
+ ch .enabled = false
42
+ ch .length , ch .stop , ch .divisor , ch .narrow , ch .octave = 0 , false , 0 , false , 0
43
+ ch .envelope .TurnOff ()
44
+ }
45
+
46
+ func (ch * Noise ) reload () {
47
47
ch .enabled = ch .dacEnable ()
48
48
ch .envelope .reload ()
49
- ch .lfsr = 0x7FFF
49
+ ch .LFSR = 0x7FFF
50
50
if ch .length == 0 {
51
51
ch .length = 64
52
52
}
53
53
}
54
54
55
- func (ch * noise ) clock64Hz () {
55
+ func (ch * Noise ) clock64Hz () {
56
56
if ch .enabled {
57
57
ch .envelope .update ()
58
58
}
59
59
}
60
60
61
- func (ch * noise ) clock256Hz () {
61
+ func (ch * Noise ) clock256Hz () {
62
62
if ch .stop && ch .length > 0 {
63
63
ch .length --
64
64
if ch .length == 0 {
@@ -67,7 +67,7 @@ func (ch *noise) clock256Hz() {
67
67
}
68
68
}
69
69
70
- func (ch * noise ) clockTimer () {
70
+ func (ch * Noise ) clockTimer () {
71
71
// ch.enabledに関わらず、乱数は生成される
72
72
ch .period --
73
73
if ch .period == 0 {
@@ -76,7 +76,7 @@ func (ch *noise) clockTimer() {
76
76
}
77
77
78
78
result := uint8 (0 )
79
- if (ch .lfsr & 1 ) == 0 {
79
+ if (ch .LFSR & 1 ) == 0 {
80
80
result = ch .envelope .volume
81
81
}
82
82
@@ -87,54 +87,70 @@ func (ch *noise) clockTimer() {
87
87
ch .output = result
88
88
}
89
89
90
- func (ch * noise ) update () {
90
+ func (ch * Noise ) update () {
91
91
if ch .octave < 14 {
92
- bit := ((ch .lfsr ^ (ch .lfsr >> 1 )) & 1 )
92
+ bit := ((ch .LFSR ^ (ch .LFSR >> 1 )) & 1 )
93
93
if ch .narrow {
94
- ch .lfsr = (ch .lfsr >> 1 ) ^ (bit << 6 )
94
+ ch .LFSR = (ch .LFSR >> 1 ) ^ (bit << 6 )
95
95
} else {
96
- ch .lfsr = (ch .lfsr >> 1 ) ^ (bit << 14 )
96
+ ch .LFSR = (ch .LFSR >> 1 ) ^ (bit << 14 )
97
97
}
98
98
}
99
99
}
100
100
101
101
var noisePeriodTable = []uint8 {4 , 8 , 16 , 24 , 32 , 40 , 48 , 56 }
102
102
103
- func (ch * noise ) calcFreqency () uint32 {
103
+ func (ch * Noise ) calcFreqency () uint32 {
104
104
return uint32 (noisePeriodTable [ch .divisor ]) << ch .octave
105
105
}
106
106
107
- func (ch * noise ) getOutput () uint8 {
107
+ // GetOutput gets 4bit sample (0..15)
108
+ func (ch * Noise ) GetOutput () uint8 {
108
109
if ch .enabled {
109
110
return ch .output
110
111
}
111
112
return 0
112
113
}
113
114
114
- func (ch * noise ) dacEnable () bool {
115
+ func (ch * Noise ) dacEnable () bool {
115
116
return ((ch .envelope .initialVolume != 0 ) || ch .envelope .direction )
116
117
}
117
118
118
- func (ch * noise ) serialize (s io.Writer ) {
119
- binary .Write (s , binary .LittleEndian , ch .enabled )
120
- binary .Write (s , binary .LittleEndian , ch .length )
121
- binary .Write (s , binary .LittleEndian , ch .stop )
122
- ch .envelope .serialize (s )
123
- binary .Write (s , binary .LittleEndian , ch .lfsr )
124
- binary .Write (s , binary .LittleEndian , ch .octave )
125
- binary .Write (s , binary .LittleEndian , ch .divisor )
126
- binary .Write (s , binary .LittleEndian , ch .period )
127
- binary .Write (s , binary .LittleEndian , ch .narrow )
119
+ type NoiseSnapshot struct {
120
+ Header uint64
121
+ Enabled bool
122
+ Length uint8
123
+ Stop bool
124
+ Envelope EnvelopeSnapshot
125
+ LFSR uint16
126
+ Divisor , Octave uint8
127
+ Period uint32
128
+ Narrow bool
129
+ Output uint8
130
+ Reserved [15 ]uint8
131
+ }
132
+
133
+ func (ch * Noise ) CreateSnapshot () NoiseSnapshot {
134
+ return NoiseSnapshot {
135
+ Enabled : ch .enabled ,
136
+ Length : ch .length ,
137
+ Stop : ch .stop ,
138
+ Envelope : ch .envelope .CreateSnapshot (),
139
+ LFSR : ch .LFSR ,
140
+ Divisor : ch .divisor ,
141
+ Octave : ch .octave ,
142
+ Period : ch .period ,
143
+ Narrow : ch .narrow ,
144
+ Output : ch .output ,
145
+ }
128
146
}
129
147
130
- func (ch * noise ) deserialize (s io.Reader ) {
131
- binary .Read (s , binary .LittleEndian , & ch .enabled )
132
- binary .Read (s , binary .LittleEndian , & ch .length )
133
- binary .Read (s , binary .LittleEndian , & ch .stop )
134
- ch .envelope .deserialize (s )
135
- binary .Read (s , binary .LittleEndian , & ch .lfsr )
136
- binary .Read (s , binary .LittleEndian , & ch .octave )
137
- binary .Read (s , binary .LittleEndian , & ch .divisor )
138
- binary .Read (s , binary .LittleEndian , & ch .period )
139
- binary .Read (s , binary .LittleEndian , & ch .narrow )
148
+ func (ch * Noise ) RestoreSnapshot (snap NoiseSnapshot ) {
149
+ ch .enabled = snap .Enabled
150
+ ch .length , ch .stop = snap .Length , snap .Stop
151
+ ch .envelope .RestoreSnapshot (snap .Envelope )
152
+ ch .LFSR = snap .LFSR
153
+ ch .divisor , ch .octave , ch .period = snap .Divisor , snap .Octave , snap .Period
154
+ ch .narrow = snap .Narrow
155
+ ch .output = snap .Output
140
156
}
0 commit comments