Skip to content

Commit 2bfda78

Browse files
committed
More enums, some tidy on registers.cc, dr. hell adsr
1 parent e1465ba commit 2bfda78

File tree

5 files changed

+229
-92
lines changed

5 files changed

+229
-92
lines changed

src/spu/adsr.cc

Lines changed: 89 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,100 +43,147 @@ enum ADSRState : int32_t {
4343
Decay = 1,
4444
Sustain = 2,
4545
Release = 3,
46+
Stopped = 4,
4647
};
4748

4849
inline int PCSX::SPU::ADSR::Attack(SPUCHAN *ch) {
49-
uint32_t disp;
50+
int rate = ch->ADSRX.get<exAttackRate>().value;
5051
int32_t EnvelopeVol = ch->ADSRX.get<exEnvelopeVol>().value;
52+
int32_t EnvelopeVolF = ch->ADSRX.get<exEnvelopeVolF>().value;
53+
const int32_t attack_mode_exp = ch->ADSRX.get<exAttackModeExp>().value;
5154

52-
if (ch->ADSRX.get<exAttackModeExp>().value && EnvelopeVol >= 0x60000000) {
53-
// Exponential Increase
54-
disp = -0x18 + 32;
55-
} else {
56-
// Linear Increase
57-
disp = -0x10 + 32;
55+
// Exponential increase
56+
if (attack_mode_exp && EnvelopeVol >= 0x6000) {
57+
rate += 8;
5858
}
5959

60-
EnvelopeVol += m_table[ch->ADSRX.get<exAttackRate>().value + disp];
60+
EnvelopeVolF++;
61+
if (EnvelopeVolF >= m_denominator[rate]) {
62+
EnvelopeVolF = 0;
63+
EnvelopeVol += m_numeratorIncrease[rate];
64+
}
6165

62-
if (EnvelopeVol < 0) {
63-
EnvelopeVol = 0x7FFFFFFF;
66+
if (EnvelopeVol >= 32767L) {
67+
EnvelopeVol = 32767L;
6468
ch->ADSRX.get<exState>().value = ADSRState::Decay;
6569
}
6670

6771
ch->ADSRX.get<exEnvelopeVol>().value = EnvelopeVol;
68-
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 21);
72+
ch->ADSRX.get<exEnvelopeVolF>().value = EnvelopeVolF;
73+
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 5);
74+
6975
return EnvelopeVol;
7076
}
7177

7278
inline int PCSX::SPU::ADSR::Decay(SPUCHAN *ch) {
73-
uint32_t disp;
79+
const int rate = ch->ADSRX.get<exDecayRate>().value * 4;
7480
int32_t EnvelopeVol = ch->ADSRX.get<exEnvelopeVol>().value;
81+
int32_t EnvelopeVolF = ch->ADSRX.get<exEnvelopeVolF>().value;
82+
const int32_t release_mode_exp = ch->ADSRX.get<exReleaseModeExp>().value;
83+
84+
EnvelopeVolF++;
85+
if (EnvelopeVolF >= m_denominator[rate]) {
86+
EnvelopeVolF = 0;
7587

76-
disp = m_tableDisp[(EnvelopeVol >> 28) & 0x7];
77-
EnvelopeVol -= m_table[ch->ADSRX.get<exDecayRate>().value + disp];
88+
if (release_mode_exp) {
89+
// Exponential decrease
90+
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
91+
} else {
92+
EnvelopeVol += m_numeratorDecrease[rate];
93+
}
94+
}
7895

79-
if (EnvelopeVol < 0) EnvelopeVol = 0;
96+
if (EnvelopeVol < 0) {
97+
EnvelopeVol = 0;
98+
}
8099

81-
// FF7 Cursor / Vagrant Story footsteps - use Neill's 4-bit accuracy
82-
if ((EnvelopeVol & 0x78000000) <= ch->ADSRX.get<exSustainLevel>().value) {
100+
if (((EnvelopeVol >> 11) & 0xf) <= ch->ADSRX.get<exSustainLevel>().value) {
83101
ch->ADSRX.get<exState>().value = ADSRState::Sustain;
84102
}
85103

86104
ch->ADSRX.get<exEnvelopeVol>().value = EnvelopeVol;
87-
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 21);
105+
ch->ADSRX.get<exEnvelopeVolF>().value = EnvelopeVolF;
106+
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 5);
107+
88108
return EnvelopeVol;
89109
}
90110

91111
inline int PCSX::SPU::ADSR::Sustain(SPUCHAN *ch) {
92-
uint32_t disp;
112+
int rate = ch->ADSRX.get<exSustainRate>().value;
93113
int32_t EnvelopeVol = ch->ADSRX.get<exEnvelopeVol>().value;
114+
int32_t EnvelopeVolF = ch->ADSRX.get<exEnvelopeVolF>().value;
115+
const int32_t sustain_mode_exp = ch->ADSRX.get<exSustainModeExp>().value;
116+
const int32_t sustain_increase = ch->ADSRX.get<exSustainIncrease>().value;
117+
118+
if (sustain_increase) {
119+
// Exponential increase
120+
if (sustain_mode_exp && (EnvelopeVol >= 0x6000)) {
121+
rate += 8;
122+
}
94123

95-
if (ch->ADSRX.get<exSustainIncrease>().value) {
96-
disp = -0x10 + 32;
97-
if (ch->ADSRX.get<exSustainModeExp>().value) {
98-
if (EnvelopeVol >= 0x60000000) disp = -0x18 + 32;
124+
EnvelopeVolF++;
125+
if (EnvelopeVolF >= m_denominator[rate]) {
126+
EnvelopeVolF = 0;
127+
EnvelopeVol += m_numeratorIncrease[rate];
99128
}
100-
EnvelopeVol += m_table[ch->ADSRX.get<exSustainRate>().value + disp];
101129

102-
if (EnvelopeVol < 0) {
103-
EnvelopeVol = 0x7FFFFFFF;
130+
if (EnvelopeVol > 32767L) {
131+
EnvelopeVol = 32767L;
104132
}
133+
105134
} else {
106-
if (ch->ADSRX.get<exSustainModeExp>().value) {
107-
disp = m_tableDisp[((EnvelopeVol >> 28) & 0x7) + 8];
108-
} else {
109-
disp = -0x0F + 32;
135+
EnvelopeVolF++;
136+
if (EnvelopeVolF >= m_denominator[rate]) {
137+
EnvelopeVolF = 0;
138+
139+
// Exponential decrease
140+
if (sustain_mode_exp) {
141+
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
142+
} else {
143+
EnvelopeVol += m_numeratorDecrease[rate];
144+
}
110145
}
111-
EnvelopeVol -= m_table[ch->ADSRX.get<exSustainRate>().value + disp];
112146

113-
if (EnvelopeVol < 0) {
147+
if (EnvelopeVol < 0L) {
114148
EnvelopeVol = 0;
115149
}
116150
}
151+
117152
ch->ADSRX.get<exEnvelopeVol>().value = EnvelopeVol;
118-
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 21);
153+
ch->ADSRX.get<exEnvelopeVolF>().value = EnvelopeVolF;
154+
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 5);
155+
119156
return EnvelopeVol;
120157
}
121158

122159
inline int PCSX::SPU::ADSR::Release(SPUCHAN *ch) {
123-
uint32_t disp;
160+
int rate = ch->ADSRX.get<exReleaseRate>().value * 4;
124161
int32_t EnvelopeVol = ch->ADSRX.get<exEnvelopeVol>().value;
162+
int32_t EnvelopeVolF = ch->ADSRX.get<exEnvelopeVolF>().value;
163+
const int32_t release_mode_exp = ch->ADSRX.get<exReleaseModeExp>().value;
125164

126-
if (ch->ADSRX.get<exReleaseModeExp>().value) {
127-
disp = m_tableDisp[(EnvelopeVol >> 28) & 0x7];
128-
} else {
129-
disp = -0x0C + 32;
165+
EnvelopeVolF++;
166+
if (EnvelopeVolF >= m_denominator[rate]) {
167+
EnvelopeVolF = 0;
168+
169+
// Exponential decrease
170+
if (release_mode_exp) {
171+
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
172+
} else {
173+
EnvelopeVol += m_numeratorDecrease[rate];
174+
}
130175
}
131-
EnvelopeVol -= m_table[ch->ADSRX.get<exReleaseRate>().value + disp];
132176

133-
if (EnvelopeVol < 0) {
177+
if (EnvelopeVol < 0L) {
178+
ch->ADSRX.get<exState>().value = ADSRState::Stopped;
134179
EnvelopeVol = 0;
135180
ch->data.get<Chan::On>().value = false;
136181
}
137182

138183
ch->ADSRX.get<exEnvelopeVol>().value = EnvelopeVol;
139-
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 21);
184+
ch->ADSRX.get<exEnvelopeVolF>().value = EnvelopeVolF;
185+
ch->ADSRX.get<exVolume>().value = (EnvelopeVol >>= 5);
186+
140187
return EnvelopeVol;
141188
}
142189

@@ -174,6 +221,7 @@ void PCSX::SPU::ADSR::start(SPUCHAN *pChannel) // MIX ADSR
174221
pChannel->ADSRX.get<exVolume>().value = 1; // and init some adsr vars
175222
pChannel->ADSRX.get<exState>().value = ADSRState::Attack;
176223
pChannel->ADSRX.get<exEnvelopeVol>().value = 0;
224+
pChannel->ADSRX.get<exEnvelopeVolF>().value = 0;
177225
}
178226

179227
int PCSX::SPU::ADSR::mix(SPUCHAN *ch) {

src/spu/adsr.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,45 @@ class ADSR {
5858

5959
const Table m_table;
6060

61+
// 0-47 1
62+
// 48-127 1 << ((RATE >> 2) - 11)
63+
int32_t m_denominator[128] = {
64+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
66+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
67+
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
68+
4, 4, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 32,
69+
32, 32, 32, 64, 64, 64, 64, 128, 128, 128, 128, 256, 256,
70+
256, 256, 512, 512, 512, 512, 1024, 1024, 1024, 1024, 2048, 2048, 2048,
71+
2048, 4096, 4096, 4096, 4096, 8192, 8192, 8192, 8192, 16384, 16384, 16384, 16384,
72+
32768, 32768, 32768, 32768, 65536, 65536, 65536, 65536, 131072, 131072, 131072, 131072, 262144,
73+
262144, 262144, 262144, 524288, 524288, 524288, 524288, 1048576, 1048576, 1048576, 1048576};
74+
75+
// 0-47 (7 - (RATE & 3)) << (11 - (RATE >> 2))
76+
// 48-127 7 - (RATE & 3)
77+
int32_t m_numeratorIncrease[128] = {
78+
14336, 12288, 10240, 8192, 7168, 6144, 5120, 4096, 3584, 3072, 2560, 2048, 1792, 1536, 1280, 1024,
79+
896, 768, 640, 512, 448, 384, 320, 256, 224, 192, 160, 128, 112, 96, 80, 64,
80+
56, 48, 40, 32, 28, 24, 20, 16, 14, 12, 10, 8, 7, 6, 5, 4,
81+
7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
82+
7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
83+
7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
84+
7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
85+
7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4};
86+
87+
// 0-47 (-8 + (RATE & 3)) << (11 - (RATE >> 2))
88+
// 48-127 -8 + (RATE & 3)
89+
int32_t m_numeratorDecrease[128] = {
90+
-16384, -14336, -12288, -10240, -8192, -7168, -6144, -5120, -4096, -3584, -3072, -2560, -2048, -1792, -1536,
91+
-1280, -1024, -896, -768, -640, -512, -448, -384, -320, -256, -224, -192, -160, -128, -112,
92+
-96, -80, -64, -56, -48, -40, -32, -28, -24, -20, -16, -14, -12, -10, -8,
93+
-7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5,
94+
-8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6,
95+
-5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7,
96+
-6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8,
97+
-7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5, -8, -7, -6, -5,
98+
-8, -7, -6, -5, -8, -7, -6, -5};
99+
61100
int Attack(SPUCHAN* ch);
62101
int Decay(SPUCHAN* ch);
63102
int Sustain(SPUCHAN* ch);

src/spu/interface.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,27 @@ class impl final : public SPUInterface {
101101

102102
struct StatusFlags {
103103
enum : uint16_t {
104-
// 5-0 Current SPU Mode(same as SPUCNT.Bit5 - 0, but, applied a bit delayed)
105-
CDAudioEnable = 1 << 0, // 0 0x0001 (0=Off, 1=On) (for CD-DA and XA-ADPCM)
106-
ExternalAudioEnable = 1 << 1, // 1 0x0002 (0=Off, 1=On)
107-
CDReverbEnable = 1 << 2, // 2 0x0004 (0=Off, 1=On) (for CD-DA and XA-ADPCM)
108-
ExternalReverbEnable = 1 << 3, // 3 0x0008 (0=Off, 1=On)
109-
RAMTransferMode = 0x0030, // 5-4 0x0030 RAM Transfer Mode (0=Stop, 1=ManualWrite, 2=DMAwrite, 3=DMAread)
104+
SPUMode = 0x3f, // 5-0 Current SPU Mode(same as SPUCNT.Bit5 - 0, but, applied a bit delayed)
110105
IRQFlag = 1 << 6, // 6 0x0040 IRQ9 Flag (0=No, 1=Interrupt Request)
111106
DMARWRequest = 1 << 7, // 7 Data Transfer DMA Read/Write Request seems to be same as SPUCNT.Bit5
112107
DMAWriteRequest = 1 << 8, // 8 Data Transfer DMA Write Request (0=No, 1=Yes)
113108
DMAReadRequest = 1 << 9, // 9 Data Transfer DMA Read Request (0=No, 1=Yes)
114109
DMABusy = 1 << 10, // 10 Data Transfer Busy Flag (0=Ready, 1=Busy)
115-
CBIndex = 11 << 11, // 11 Writing to First/Second half of Capture Buffers
110+
CBIndex = 11 << 11, // 11 Writing to First/Second half of Capture Buffers (0=First, 1=Second)
111+
// 15-12 Unknown/Unused (seems to be usually zero)
112+
};
113+
};
114+
115+
struct VolumeFlags {
116+
enum : uint16_t {
117+
VolumeMode = 1 << 15, // 15 1=Sweep Mode
118+
SweepMode = 1 << 14, // 14 0=Linear, 1=Exponential
119+
SweepDirection = 1 << 13, // 13 0=Increase, 1=Decrease
120+
SweepPhase = 1 << 12, // 12 0=Positive, 1=Negative
121+
Unknown = 0xf80, // 7-11 Not used? (should be zero)
122+
SweepShift = 0x7c, // 6-2 0..1Fh = Fast..Slow
123+
SweepStep = 0x3 // 1-0 0..3 = "+7,+6,+5,+4" or "-8,-7,-6,-5") (inc/dec)
124+
116125
};
117126
};
118127

0 commit comments

Comments
 (0)