Skip to content

Commit 4c61bbf

Browse files
committed
Refactor project
1 parent cf9b035 commit 4c61bbf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2507
-2257
lines changed

core/core.go

-28
This file was deleted.

core/gb/apu/apu.go

+17-20
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import (
88
)
99

1010
type APU struct {
11-
cycles int64 // 8.3MHzのマスターサイクル単位
11+
cycles int64 // 8MHzのマスターサイクル単位
1212
*psg.PSG
1313
sampleWriter io.Writer
1414

15-
samples [547 * 2]uint8 // [[left, right]...], 547 = 32768 / 60
15+
samples [547 * 2]int16 // [[left, right]...], 547 = 32768 / 60
1616
sampleCount uint16
1717
}
1818

@@ -34,24 +34,21 @@ func (a *APU) Reset(hasBIOS bool) {
3434
a.sampleCount = 0
3535
}
3636

37-
// cycles は 8.3MHzのマスターサイクル単位
38-
func (a *APU) Tick(cycles int64) {
39-
if cycles > 0 {
40-
for i := int64(0); i < cycles; i++ {
41-
a.cycles++
42-
if a.cycles%2 == 0 {
43-
a.PSG.Step()
44-
}
45-
if a.cycles%256 == 0 { // 32768Hzにダウンサンプリングしたい = 32768Hzごとにサンプルを生成したい = 256マスターサイクルごとにサンプルを生成する (8MHz / 32768Hz = 256)
46-
if int(a.sampleCount) < len(a.samples)/2 {
47-
left, right := a.PSG.Sample()
48-
lvolume, rvolume := a.PSG.Volume()
49-
left = uint8(int(left) * int(lvolume+1) / 8)
50-
right = uint8(int(right) * int(rvolume+1) / 8)
51-
a.samples[a.sampleCount*2] = left >> 1
52-
a.samples[a.sampleCount*2+1] = right >> 1
53-
a.sampleCount++
54-
}
37+
func (a *APU) Run(cycles8MHz int64) {
38+
for i := int64(0); i < cycles8MHz; i++ {
39+
a.cycles++
40+
if a.cycles%2 == 0 {
41+
a.PSG.Step()
42+
}
43+
if a.cycles%256 == 0 { // 32768Hzにダウンサンプリングしたい = 32768Hzごとにサンプルを生成したい = 256マスターサイクルごとにサンプルを生成する (8MHz / 32768Hz = 256)
44+
if int(a.sampleCount) < len(a.samples)/2 {
45+
left, right := a.PSG.Sample()
46+
lvolume, rvolume := a.PSG.Volume()
47+
lsample, rsample := (int(left)*512)-16384, (int(right)*512)-16384
48+
lsample, rsample = (lsample*int(lvolume+1))/8, (rsample*int(rvolume+1))/8
49+
a.samples[a.sampleCount*2] = int16(lsample)
50+
a.samples[a.sampleCount*2+1] = int16(rsample)
51+
a.sampleCount++
5552
}
5653
}
5754
}

core/gb/apu/psg/ch_noise.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ func newNoiseChannel() *noise {
3232
}
3333
}
3434

35+
func (ch *noise) reset() {
36+
ch.enabled = false
37+
ch.length = 0
38+
ch.stop = false
39+
ch.envelope.reset()
40+
ch.lfsr = 0
41+
ch.divisor, ch.octave = 0, 0
42+
ch.period = 0
43+
ch.narrow = false
44+
ch.output = 0
45+
}
46+
3547
func (ch *noise) clock64Hz() {
3648
if ch.enabled {
3749
ch.envelope.update()
@@ -89,7 +101,7 @@ func (ch *noise) getOutput() uint8 {
89101

90102
func (ch *noise) tryRestart() {
91103
ch.enabled = ch.dacEnable()
92-
ch.envelope.reset()
104+
ch.envelope.reload()
93105
if ch.length == 0 {
94106
ch.length = 64
95107
}

core/gb/apu/psg/ch_square.go

+27-16
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,51 @@ import (
55
"io"
66
)
77

8-
var squareDutyTable = [4][8]int{
8+
var squareDutyTable = [4][8]uint8{
99
{0, 0, 0, 0, 0, 0, 0, 1}, // 12.5%
1010
{1, 0, 0, 0, 0, 0, 0, 1}, // 25%
1111
{1, 0, 0, 0, 0, 1, 1, 1}, // 50%
1212
{0, 1, 1, 1, 1, 1, 1, 0}, // 75%
1313
}
1414

1515
type square struct {
16-
enabled bool
16+
enabled bool // NR52.0(ch1), NR52.1(ch2)
1717

18-
length int32 // 音の残り再生時間
19-
stop bool // .length が 0 になったときに 音を止めるかどうか(NR14's bit6)
18+
length int32 // NR11.0-5; 音の残り再生時間
19+
stop bool // NR14.6; .length が 0 になったときに音を止めるかどうか
2020

2121
envelope *envelope
2222
sweep *sweep
2323

24-
duty uint8 // NR11's bit7-6, (squareDutyTable の index)
24+
duty uint8 // NR11.6-7, (squareDutyTable の index)
2525
dutyCounter uint8 // 0 ~ 7
2626

27-
period int32 // GBでは周波数を指定するのではなく、周期の長さを指定する, 実際の周波数は ((4194304/32)/(2048-period)) Hz (64~131072 Hz -> 65536~32 APUサイクル)
28-
freqCounter int32
27+
period uint16 // NR13.0-7, NR14.0-2; GBでは周波数を指定するのではなく、周期の長さを指定する
28+
freqCounter uint16
2929
}
3030

3131
func newSquareChannel(hasSweep bool) *square {
3232
ch := &square{
3333
envelope: newEnvelope(),
3434
}
3535

36-
// スイープ機能があるのは ch1 のみなので区別する必要がある
37-
if hasSweep {
36+
if hasSweep { // スイープ機能があるのは ch1 のみなので区別する必要がある
3837
ch.sweep = newSweep(ch)
3938
}
4039
return ch
4140
}
4241

42+
func (ch *square) reset() {
43+
ch.enabled = false
44+
ch.length, ch.stop = 0, false
45+
ch.envelope.reset()
46+
if ch.sweep != nil {
47+
ch.sweep.reset()
48+
}
49+
ch.duty, ch.dutyCounter = 0, 0
50+
ch.period, ch.freqCounter = 0, 0
51+
}
52+
4353
func (ch *square) clock64Hz() {
4454
if ch.enabled {
4555
ch.envelope.update()
@@ -55,7 +65,7 @@ func (ch *square) clock128Hz() {
5565
func (ch *square) clock256Hz() {
5666
if ch.stop && ch.length > 0 {
5767
ch.length--
58-
if ch.length <= 0 {
68+
if ch.length == 0 {
5969
ch.enabled = false
6070
}
6171
}
@@ -64,9 +74,10 @@ func (ch *square) clock256Hz() {
6474
func (ch *square) clockTimer() {
6575
if ch.freqCounter > 0 {
6676
ch.freqCounter--
67-
} else {
68-
ch.freqCounter = ch.dutyStepCycle()
69-
ch.dutyCounter = (ch.dutyCounter + 1) % 8
77+
if ch.freqCounter == 0 {
78+
ch.freqCounter = ch.dutyStepCycle()
79+
ch.dutyCounter = (ch.dutyCounter + 1) & 7
80+
}
7081
}
7182
}
7283

@@ -81,7 +92,7 @@ func (ch *square) getOutput() uint8 {
8192
}
8293

8394
// デューティ比の1ステップの長さをAPUサイクル数で返す
84-
func (ch *square) dutyStepCycle() int32 {
95+
func (ch *square) dutyStepCycle() uint16 {
8596
// hz := (1048576 / (2048 - ch.period)) // freqency
8697
// return 4194304 / hz
8798
return 4 * (2048 - ch.period)
@@ -94,9 +105,9 @@ func (ch *square) dacEnable() bool {
94105
func (ch *square) tryRestart() {
95106
ch.enabled = ch.dacEnable()
96107
ch.freqCounter = ch.dutyStepCycle()
97-
ch.envelope.reset()
108+
ch.envelope.reload()
98109
if ch.sweep != nil {
99-
ch.sweep.reset()
110+
ch.sweep.reload()
100111
}
101112
if ch.length == 0 {
102113
ch.length = 64

core/gb/apu/psg/ch_wave.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type wave struct {
2020
window int8 // 0 ~ 31
2121

2222
// For GBA
23-
bank uint8 // 0 or 1 (NR30's bit6)
23+
bank uint8 // NR30.6
2424
usedBank uint8 // 現在演奏中のバンク、modeが1の場合は、 .bank の値と必ずしも一致しないので
2525
mode uint8 //  0: 16バイト(32サンプル)を演奏に使い、裏のバンクでは読み書きを行う、 1: 32バイト(64サンプル)を全部演奏に使う
2626
}
@@ -29,6 +29,17 @@ func newWaveChannel() *wave {
2929
return &wave{}
3030
}
3131

32+
func (ch *wave) reset() {
33+
ch.enabled = false
34+
ch.dacEnable = false
35+
ch.stop, ch.length = false, 0
36+
ch.volume = 0
37+
ch.period, ch.freqCounter = 0, 0
38+
clear(ch.samples[:])
39+
ch.window = 0
40+
ch.bank, ch.usedBank, ch.mode = 0, 0, 0
41+
}
42+
3243
func (ch *wave) clock256Hz() {
3344
if ch.stop && ch.length > 0 {
3445
ch.length--

0 commit comments

Comments
 (0)