26 #ifndef AUDIO_SOUNDFONT_PSXSPU_H 27 #define AUDIO_SOUNDFONT_PSXSPU_H 29 #include "audio/soundfont/common.h" 30 #include "common/str.h" 31 #include "common/util.h" 32 #include "audio/soundfont/vgminstrset.h" 33 #include "audio/soundfont/vgmsamp.h" 34 #include "audio/soundfont/vgmitem.h" 45 #if defined __BORLANDC__ 48 typedef unsigned char b8;
57 static unsigned long RateTable[160];
58 static bool bRateTableInitialized = 0;
76 double LinAmpDecayTimeToLinDBDecayTime(
double secondsToFullAtten,
int linearVolumeRange);
79 static inline void InitADSR() {
80 unsigned long r, rs, rd;
84 memset(RateTable, 0,
sizeof(
unsigned long) * 160);
91 for (i = 32; i < 160; i++) {
107 inline int RoundToZero(
int val) {
114 void PSXConvADSR(T *realADSR,
unsigned short ADSR1,
unsigned short ADSR2,
bool bPS2) {
115 uint8 Am = (ADSR1 & 0x8000) >> 15;
116 uint8 Ar = (ADSR1 & 0x7F00) >> 8;
117 uint8 Dr = (ADSR1 & 0x00F0) >> 4;
118 uint8 Sl = ADSR1 & 0x000F;
119 uint8 Rm = (ADSR2 & 0x0020) >> 5;
120 uint8 Rr = ADSR2 & 0x001F;
124 uint8 Sm = (ADSR2 & 0x8000) >> 15;
125 uint8 Sd = (ADSR2 & 0x4000) >> 14;
126 uint8 Sr = (ADSR2 >> 6) & 0x7F;
128 PSXConvADSR(realADSR, Am, Ar, Dr, Sl, Sm, Sd, Sr, Rm, Rr, bPS2);
132 void PSXConvADSR(T *realADSR, uint8 Am, uint8 Ar, uint8 Dr, uint8 Sl, uint8 Sm,
133 uint8 Sd, uint8 Sr, uint8 Rm, uint8 Rr,
bool bPS2) {
135 if (((Am & ~0x01) != 0) || ((Ar & ~0x7F) != 0) || ((Dr & ~0x0F) != 0) || ((Sl & ~0x0F) != 0) ||
136 ((Rm & ~0x01) != 0) || ((Rr & ~0x1F) != 0) || ((Sm & ~0x01) != 0) || ((Sd & ~0x01) != 0) ||
137 ((Sr & ~0x7F) != 0)) {
138 error(
"ADSR parameter(s) out of range");
142 double sampleRate = bPS2 ? 48000 : 44100;
145 double samples = 0.0;
147 unsigned long remainder;
151 if (!bRateTableInitialized) {
153 bRateTableInitialized =
true;
163 if ((Ar ^ 0x7F) < 0x10)
167 rate = RateTable[RoundToZero((Ar ^ 0x7F) - 0x10) + 32];
168 samples = ceil(0x7FFFFFFF / (
double) rate);
169 }
else if (Am == 1) {
170 rate = RateTable[RoundToZero((Ar ^ 0x7F) - 0x10) + 32];
171 samples = (
unsigned long)(0x60000000 / rate);
172 remainder = 0x60000000 % rate;
173 rate = RateTable[RoundToZero((Ar ^ 0x7F) - 0x18) + 32];
174 samples += ceil(MAX<double>(0, 0x1FFFFFFF - (
long) remainder) / (
double) rate);
176 timeInSecs = samples / sampleRate;
177 realADSR->_attack_time = timeInSecs;
182 envelope_level = 0x7FFFFFFF;
184 bool bSustainLevFound =
false;
185 uint32 realSustainLevel = 0x7FFFFFFF;
187 for (l = 0; envelope_level > 0; l++) {
188 if (4 * (Dr ^ 0x1F) < 0x18)
190 switch ((envelope_level >> 28) & 0x7) {
192 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 0) + 32];
195 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 4) + 32];
198 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 6) + 32];
201 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 8) + 32];
204 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 9) + 32];
207 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 10) + 32];
210 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 11) + 32];
213 envelope_level -= RateTable[RoundToZero((4 * (Dr ^ 0x1F)) - 0x18 + 12) + 32];
216 if (!bSustainLevFound && ((envelope_level >> 27) & 0xF) <= Sl) {
217 realSustainLevel = envelope_level;
218 bSustainLevFound =
true;
222 timeInSecs = samples / sampleRate;
223 realADSR->_decay_time = timeInSecs;
227 envelope_level = 0x7FFFFFFF;
230 realADSR->_sustain_time = -1;
233 realADSR->_sustain_time = -1;
237 rate = RateTable[RoundToZero((Sr ^ 0x7F) - 0x0F) + 32];
238 samples = ceil(0x7FFFFFFF / (
double) rate);
242 while (envelope_level > 0) {
243 long envelope_level_diff;
244 long envelope_level_target;
246 switch ((envelope_level >> 28) & 0x7) {
249 envelope_level_target = 0x00000000;
250 envelope_level_diff =
251 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 0) + 32];
254 envelope_level_target = 0x0fffffff;
255 envelope_level_diff =
256 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 4) + 32];
259 envelope_level_target = 0x1fffffff;
260 envelope_level_diff =
261 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 6) + 32];
264 envelope_level_target = 0x2fffffff;
265 envelope_level_diff =
266 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 8) + 32];
269 envelope_level_target = 0x3fffffff;
270 envelope_level_diff =
271 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 9) + 32];
274 envelope_level_target = 0x4fffffff;
275 envelope_level_diff =
276 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 10) + 32];
279 envelope_level_target = 0x5fffffff;
280 envelope_level_diff =
281 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 11) + 32];
284 envelope_level_target = 0x6fffffff;
285 envelope_level_diff =
286 RateTable[RoundToZero((Sr ^ 0x7F) - 0x1B + 12) + 32];
291 (envelope_level - envelope_level_target + (envelope_level_diff - 1)) /
293 envelope_level -= (envelope_level_diff * steps);
298 timeInSecs = samples / sampleRate;
299 realADSR->_sustain_time =
300 LinAmpDecayTimeToLinDBDecayTime(timeInSecs, 0x800);
309 realSustainLevel = 0x07FFFFFF;
310 realADSR->_sustain_level = realSustainLevel / (double) 0x7FFFFFFF;
314 if ((realADSR->_decay_time < 2 || (Dr == 0x0F && Sl >= 0x0C)) && Sr < 0x7E && Sd == 1) {
315 realADSR->_sustain_level = 0;
316 realADSR->_decay_time = realADSR->_sustain_time;
325 envelope_level = 0x7FFFFFFF;
329 rate = RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x0C) + 32];
332 samples = ceil((
double) envelope_level / (
double) rate);
335 }
else if (Rm == 1) {
336 if ((Rr ^ 0x1F) * 4 < 0x18)
338 for (l = 0; envelope_level > 0; l++) {
339 switch ((envelope_level >> 28) & 0x7) {
341 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 0) + 32];
344 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 4) + 32];
347 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 6) + 32];
350 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 8) + 32];
353 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 9) + 32];
356 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 10) + 32];
359 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 11) + 32];
362 envelope_level -= RateTable[RoundToZero((4 * (Rr ^ 0x1F)) - 0x18 + 12) + 32];
368 timeInSecs = samples / sampleRate;
375 realADSR->_release_time =
376 LinAmpDecayTimeToLinDBDecayTime(timeInSecs, 0x800);
409 uint32 dataLen, uint8 nChannels, uint16 theBPS, uint32 theRate,
416 double GetCompressionRatio()
override;
418 void ConvertToStdWave(uint8 *buf)
override;
421 void DecompVAGBlk(int16 *pSmp,
VAGBlk *pVBlk, f32 *prev1, f32 *prev2);
425 bool _setLoopOnConversion;
428 #endif // AUDIO_SOUNDFONT_PSXSPU_H
Definition: vgminstrset.h:45
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1