mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Better decode for PSX & PSV ADPCM
This commit is contained in:
parent
c40d364e87
commit
b715cb023b
@ -173,25 +173,25 @@ void decode_hevag(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspaci
|
||||
if (shift_factor > 12)
|
||||
shift_factor = 9; /* ? */
|
||||
|
||||
shift_factor = 20 - shift_factor;
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0, scale = 0;
|
||||
int32_t sample = 0;
|
||||
|
||||
if (flag < 0x07) { /* with flag 0x07 decoded sample must be 0 */
|
||||
uint8_t nibbles = frame[0x02 + i/2];
|
||||
|
||||
scale = i&1 ? /* low nibble first */
|
||||
sample = (i&1 ? /* low nibble first */
|
||||
get_high_nibble_signed(nibbles):
|
||||
get_low_nibble_signed(nibbles);
|
||||
sample = (hist1 * hevag_coefs[coef_index][0] +
|
||||
hist2 * hevag_coefs[coef_index][1] +
|
||||
hist3 * hevag_coefs[coef_index][2] +
|
||||
hist4 * hevag_coefs[coef_index][3] ) / 32;
|
||||
sample = (sample + (scale << (20 - shift_factor)) + 128) >> 8;
|
||||
sample = clamp16(sample);
|
||||
get_low_nibble_signed(nibbles)) << shift_factor; /*scale*/
|
||||
sample = ((hist1 * hevag_coefs[coef_index][0] +
|
||||
hist2 * hevag_coefs[coef_index][1] +
|
||||
hist3 * hevag_coefs[coef_index][2] +
|
||||
hist4 * hevag_coefs[coef_index][3]) >> 5) + sample;
|
||||
sample >>= 8;
|
||||
}
|
||||
|
||||
outbuf[sample_count] = sample;
|
||||
outbuf[sample_count] = clamp16(sample); /*clamping*/
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist4 = hist3;
|
||||
|
@ -93,22 +93,22 @@ void decode_psx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing,
|
||||
VGM_ASSERT_ONCE(flag > 7,"PS-ADPCM: unknown flag at %x\n", (uint32_t)frame_offset); /* meta should use PSX-badflags */
|
||||
|
||||
|
||||
shift_factor = 20 - shift_factor;
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0;
|
||||
|
||||
if (flag < 0x07) { /* with flag 0x07 decoded sample must be 0 */
|
||||
uint8_t nibbles = frame[0x02 + i/2];
|
||||
|
||||
sample = i&1 ? /* low nibble first */
|
||||
(nibbles >> 4) & 0x0f :
|
||||
(nibbles >> 0) & 0x0f;
|
||||
sample = (int16_t)((sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
sample = (int32_t)(sample + ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2);
|
||||
sample = clamp16(sample);
|
||||
|
||||
sample = (i&1 ? /* low nibble first */
|
||||
get_high_nibble_signed(nibbles):
|
||||
get_low_nibble_signed(nibbles)) << shift_factor; /*scale*/
|
||||
sample = sample + (int32_t)((ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2) * 256.0f);
|
||||
sample >>= 8;
|
||||
}
|
||||
|
||||
outbuf[sample_count] = sample;
|
||||
outbuf[sample_count] = clamp16(sample); /*clamping*/
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
@ -133,7 +133,6 @@ void decode_psx_configurable(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int cha
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int32_t hist2 = stream->adpcm_history2_32;
|
||||
int extended_mode = (config == 1);
|
||||
int float_mode = (config == 1);
|
||||
|
||||
|
||||
/* external interleave (variable size), mono */
|
||||
@ -148,35 +147,52 @@ void decode_psx_configurable(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int cha
|
||||
coef_index = (frame[0] >> 4) & 0xf;
|
||||
shift_factor = (frame[0] >> 0) & 0xf;
|
||||
|
||||
/* upper filters only used in few PS3 games, normally 0 */
|
||||
if (!extended_mode) {
|
||||
if (extended_mode) { /*float logic*/
|
||||
shift_factor = 20 - shift_factor;
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0;
|
||||
uint8_t nibbles = frame[0x01 + i/2];
|
||||
|
||||
sample = (i&1 ? /* low nibble first */
|
||||
get_high_nibble_signed(nibbles):
|
||||
get_low_nibble_signed(nibbles)) << shift_factor; /*scale*/
|
||||
sample = sample + (int32_t)((ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2) * 256.0f);
|
||||
sample >>= 8;
|
||||
|
||||
outbuf[sample_count] = clamp16(sample); /*clamping*/
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = sample;
|
||||
}
|
||||
}
|
||||
else { /*int logic*/
|
||||
/* upper filters only used in few PS3 games, normally 0 */
|
||||
VGM_ASSERT_ONCE(coef_index > 5 || shift_factor > 12, "PS-ADPCM: incorrect coefs/shift at %x\n", (uint32_t)frame_offset);
|
||||
if (coef_index > 5)
|
||||
coef_index = 0;
|
||||
if (shift_factor > 12)
|
||||
shift_factor = 9; /* supposedly, from Nocash PSX docs */
|
||||
}
|
||||
|
||||
shift_factor = 18 - shift_factor;
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0;
|
||||
uint8_t nibbles = frame[0x01 + i/2];
|
||||
|
||||
sample = (i&1 ? /* low nibble first */
|
||||
get_high_nibble_signed(nibbles):
|
||||
get_low_nibble_signed(nibbles)) << shift_factor; /*scale*/
|
||||
sample = sample + (ps_adpcm_coefs_i[coef_index][0]*hist1 + ps_adpcm_coefs_i[coef_index][1]*hist2);
|
||||
sample >>= 6;
|
||||
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0;
|
||||
uint8_t nibbles = frame[0x01 + i/2];
|
||||
outbuf[sample_count] = clamp16(sample); /*clamping*/
|
||||
sample_count += channelspacing;
|
||||
|
||||
sample = i&1 ? /* low nibble first */
|
||||
(nibbles >> 4) & 0x0f :
|
||||
(nibbles >> 0) & 0x0f;
|
||||
sample = (int16_t)((sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
sample = float_mode ?
|
||||
(int32_t)(sample + ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2) :
|
||||
sample + ((ps_adpcm_coefs_i[coef_index][0]*hist1 + ps_adpcm_coefs_i[coef_index][1]*hist2) >> 6);
|
||||
sample = clamp16(sample);
|
||||
|
||||
outbuf[sample_count] = sample;
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = sample;
|
||||
hist2 = hist1;
|
||||
hist1 = sample;
|
||||
}
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
@ -192,7 +208,6 @@ void decode_psx_pivotal(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channe
|
||||
uint8_t coef_index, shift_factor;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int32_t hist2 = stream->adpcm_history2_32;
|
||||
float scale;
|
||||
|
||||
|
||||
/* external interleave (variable size), mono */
|
||||
@ -213,21 +228,19 @@ void decode_psx_pivotal(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channe
|
||||
if (shift_factor > 12) /* same */
|
||||
shift_factor = 12;
|
||||
|
||||
scale = (float)(1.0 / (double)(1 << shift_factor));
|
||||
|
||||
|
||||
shift_factor = 20 - shift_factor;
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t sample = 0;
|
||||
uint8_t nibbles = frame[0x01 + i/2];
|
||||
|
||||
sample = !(i&1) ? /* low nibble first */
|
||||
(nibbles >> 0) & 0x0f :
|
||||
(nibbles >> 4) & 0x0f;
|
||||
sample = (int16_t)((sample << 12) & 0xf000); /* 16b sign extend + default scale */
|
||||
sample = sample*scale + ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2; /* actually substracts negative coefs but whatevs */
|
||||
sample = (i&1 ? /* low nibble first */
|
||||
get_high_nibble_signed(nibbles):
|
||||
get_low_nibble_signed(nibbles)) << shift_factor; /*scale*/
|
||||
sample = sample + (int32_t)((ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2) * 256.0f); /* actually substracts negative coefs but whatevs */
|
||||
sample >>= 8;
|
||||
|
||||
outbuf[sample_count] = clamp16(sample);
|
||||
outbuf[sample_count] = clamp16(sample); /*clamping*/
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user