From b715cb023bcfe0c6d5adef723311af0feb6fa309 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Mon, 2 Mar 2020 17:28:56 +0300 Subject: [PATCH 1/2] Better decode for PSX & PSV ADPCM --- src/coding/psv_decoder.c | 20 ++++----- src/coding/psx_decoder.c | 93 +++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/coding/psv_decoder.c b/src/coding/psv_decoder.c index 6daf057a..bdb590ab 100644 --- a/src/coding/psv_decoder.c +++ b/src/coding/psv_decoder.c @@ -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; diff --git a/src/coding/psx_decoder.c b/src/coding/psx_decoder.c index d70f0612..4e582711 100644 --- a/src/coding/psx_decoder.c +++ b/src/coding/psx_decoder.c @@ -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; From 281c6ca73e066c523ee7d4a19ffeabd066d38696 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Wed, 4 Mar 2020 01:53:56 +0300 Subject: [PATCH 2/2] Revert changes for extended mode in SPU-ADPCM --- src/coding/psx_decoder.c | 60 +++++++++++++++------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/src/coding/psx_decoder.c b/src/coding/psx_decoder.c index 4e582711..00bb2810 100644 --- a/src/coding/psx_decoder.c +++ b/src/coding/psx_decoder.c @@ -133,6 +133,7 @@ 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 */ @@ -147,52 +148,35 @@ void decode_psx_configurable(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int cha coef_index = (frame[0] >> 4) & 0xf; shift_factor = (frame[0] >> 0) & 0xf; - 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 */ + /* upper filters only used in few PS3 games, normally 0 */ + if (!extended_mode) { 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; - outbuf[sample_count] = clamp16(sample); /*clamping*/ - sample_count += channelspacing; + /* decode nibbles */ + for (i = first_sample; i < first_sample + samples_to_do; i++) { + int32_t sample = 0; + uint8_t nibbles = frame[0x01 + i/2]; - hist2 = hist1; - hist1 = sample; - } + 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; } stream->adpcm_history1_32 = hist1;