Skip to content

Commit 8053742

Browse files
committed
Compile time envelope tables
1 parent 2b88c71 commit 8053742

File tree

2 files changed

+61
-104
lines changed

2 files changed

+61
-104
lines changed

src/spu/adsr.cc

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,51 @@
3535

3636
#include "spu/adsr.h"
3737

38+
#include <stdint.h>
39+
40+
#include <utility>
41+
3842
#include "spu/externals.h"
3943
#include "spu/interface.h"
4044

41-
enum ADSRState : int32_t {
42-
Attack = 0,
43-
Decay = 1,
44-
Sustain = 2,
45-
Release = 3,
46-
Stopped = 4,
45+
namespace EnvelopeTables {
46+
// Generate ADSR envelope tables at compile time with some magic(thanks Nic)
47+
template <std::size_t N>
48+
struct Table {
49+
int32_t data[N];
50+
};
51+
52+
template <std::size_t N, typename Generator, std::size_t... Is>
53+
constexpr Table<N> generateTable(std::index_sequence<Is...>) {
54+
return {{Generator::calculateValue(Is)...}};
55+
}
56+
57+
template <std::size_t N, typename Generator>
58+
constexpr Table<N> generateTable() {
59+
return generateTable<N, Generator>(std::make_index_sequence<128>{});
60+
}
61+
62+
struct DenominatorGenerator {
63+
static constexpr int32_t calculateValue(std::size_t rate) { return (rate < 48) ? 1 : (1 << ((rate >> 2) - 11)); }
64+
};
65+
66+
struct NumeratorIncreaseGenerator {
67+
static constexpr int32_t calculateValue(std::size_t rate) {
68+
return (rate < 48) ? (7 - (rate & 3)) << (11 - (rate >> 2)) : (7 - (rate & 3));
69+
}
70+
};
71+
72+
struct NumeratorDecreaseGenerator {
73+
static constexpr int32_t calculateValue(std::size_t rate) {
74+
return (rate < 48) ? (-8 + (rate & 3)) << (11 - (rate >> 2)) : (-8 + (rate & 3));
75+
}
4776
};
4877

78+
constexpr auto denominator = generateTable<128, DenominatorGenerator>();
79+
constexpr auto numerator_increase = generateTable<128, NumeratorIncreaseGenerator>();
80+
constexpr auto numerator_decrease = generateTable<128, NumeratorDecreaseGenerator>();
81+
} // namespace EnvelopeTables
82+
4983
inline int PCSX::SPU::ADSR::Attack(SPUCHAN *ch) {
5084
int rate = ch->ADSRX.get<exAttackRate>().value;
5185
int32_t EnvelopeVol = ch->ADSRX.get<exEnvelopeVol>().value;
@@ -58,9 +92,9 @@ inline int PCSX::SPU::ADSR::Attack(SPUCHAN *ch) {
5892
}
5993

6094
EnvelopeVolF++;
61-
if (EnvelopeVolF >= m_denominator[rate]) {
95+
if (EnvelopeVolF >= EnvelopeTables::denominator.data[rate]) {
6296
EnvelopeVolF = 0;
63-
EnvelopeVol += m_numeratorIncrease[rate];
97+
EnvelopeVol += EnvelopeTables::numerator_increase.data[rate];
6498
}
6599

66100
if (EnvelopeVol >= 32767L) {
@@ -82,14 +116,14 @@ inline int PCSX::SPU::ADSR::Decay(SPUCHAN *ch) {
82116
const int32_t release_mode_exp = ch->ADSRX.get<exReleaseModeExp>().value;
83117

84118
EnvelopeVolF++;
85-
if (EnvelopeVolF >= m_denominator[rate]) {
119+
if (EnvelopeVolF >= EnvelopeTables::denominator.data[rate]) {
86120
EnvelopeVolF = 0;
87121

88122
if (release_mode_exp) {
89123
// Exponential decrease
90-
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
124+
EnvelopeVol += (EnvelopeTables::numerator_decrease.data[rate] * EnvelopeVol) >> 15;
91125
} else {
92-
EnvelopeVol += m_numeratorDecrease[rate];
126+
EnvelopeVol += EnvelopeTables::numerator_decrease.data[rate];
93127
}
94128
}
95129

@@ -122,9 +156,9 @@ inline int PCSX::SPU::ADSR::Sustain(SPUCHAN *ch) {
122156
}
123157

124158
EnvelopeVolF++;
125-
if (EnvelopeVolF >= m_denominator[rate]) {
159+
if (EnvelopeVolF >= EnvelopeTables::denominator.data[rate]) {
126160
EnvelopeVolF = 0;
127-
EnvelopeVol += m_numeratorIncrease[rate];
161+
EnvelopeVol += EnvelopeTables::numerator_increase.data[rate];
128162
}
129163

130164
if (EnvelopeVol > 32767L) {
@@ -133,14 +167,14 @@ inline int PCSX::SPU::ADSR::Sustain(SPUCHAN *ch) {
133167

134168
} else {
135169
EnvelopeVolF++;
136-
if (EnvelopeVolF >= m_denominator[rate]) {
170+
if (EnvelopeVolF >= EnvelopeTables::denominator.data[rate]) {
137171
EnvelopeVolF = 0;
138172

139173
// Exponential decrease
140174
if (sustain_mode_exp) {
141-
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
175+
EnvelopeVol += (EnvelopeTables::numerator_decrease.data[rate] * EnvelopeVol) >> 15;
142176
} else {
143-
EnvelopeVol += m_numeratorDecrease[rate];
177+
EnvelopeVol += EnvelopeTables::numerator_decrease.data[rate];
144178
}
145179
}
146180

@@ -163,14 +197,14 @@ inline int PCSX::SPU::ADSR::Release(SPUCHAN *ch) {
163197
const int32_t release_mode_exp = ch->ADSRX.get<exReleaseModeExp>().value;
164198

165199
EnvelopeVolF++;
166-
if (EnvelopeVolF >= m_denominator[rate]) {
200+
if (EnvelopeVolF >= EnvelopeTables::denominator.data[rate]) {
167201
EnvelopeVolF = 0;
168202

169203
// Exponential decrease
170204
if (release_mode_exp) {
171-
EnvelopeVol += (m_numeratorDecrease[rate] * EnvelopeVol) >> 15;
205+
EnvelopeVol += (EnvelopeTables::numerator_decrease.data[rate] * EnvelopeVol) >> 15;
172206
} else {
173-
EnvelopeVol += m_numeratorDecrease[rate];
207+
EnvelopeVol += EnvelopeTables::numerator_decrease.data[rate];
174208
}
175209
}
176210

@@ -187,35 +221,6 @@ inline int PCSX::SPU::ADSR::Release(SPUCHAN *ch) {
187221
return EnvelopeVol;
188222
}
189223

190-
// Init ADSR
191-
PCSX::SPU::ADSR::Table::Table() {
192-
memset(m_table, 0,
193-
sizeof(uint32_t) * 160); // build the rate table according to Neill's rules (see at bottom of file)
194-
195-
uint32_t r = 3;
196-
uint32_t rs = 1;
197-
uint32_t rd = 0;
198-
199-
// we start at pos 32 with the real values... everything before is 0
200-
for (int i = 32; i < 160; i++) {
201-
if (r < 0x3FFFFFFF) {
202-
r += rs;
203-
rd++;
204-
205-
if (rd == 5) {
206-
rd = 1;
207-
rs *= 2;
208-
}
209-
}
210-
211-
if (r > 0x3FFFFFFF) {
212-
r = 0x3FFFFFFF;
213-
}
214-
215-
m_table[i] = r;
216-
}
217-
}
218-
219224
void PCSX::SPU::ADSR::start(SPUCHAN *pChannel) // MIX ADSR
220225
{
221226
pChannel->ADSRX.get<exVolume>().value = 1; // and init some adsr vars

src/spu/adsr.h

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -39,64 +39,16 @@ class ADSR {
3939
int mix(SPUCHAN* pChannel);
4040

4141
private:
42-
static inline const uint32_t m_tableDisp[] = {
43-
-0x18 + 0 + 32, -0x18 + 4 + 32, -0x18 + 6 + 32, -0x18 + 8 + 32, // release/decay
44-
-0x18 + 9 + 32, -0x18 + 10 + 32, -0x18 + 11 + 32, -0x18 + 12 + 32,
45-
46-
-0x1B + 0 + 32, -0x1B + 4 + 32, -0x1B + 6 + 32, -0x1B + 8 + 32, // sustain
47-
-0x1B + 9 + 32, -0x1B + 10 + 32, -0x1B + 11 + 32, -0x1B + 12 + 32,
48-
};
49-
50-
class Table {
51-
public:
52-
Table();
53-
const uint32_t& operator[](size_t index) const { return m_table[index]; }
54-
55-
private:
56-
uint32_t m_table[160];
42+
struct ADSRState {
43+
enum : int32_t {
44+
Attack = 0,
45+
Decay = 1,
46+
Sustain = 2,
47+
Release = 3,
48+
Stopped = 4,
49+
};
5750
};
5851

59-
const Table m_table;
60-
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-
10052
int Attack(SPUCHAN* ch);
10153
int Decay(SPUCHAN* ch);
10254
int Sustain(SPUCHAN* ch);

0 commit comments

Comments
 (0)