From 5c3a47c7201ebe7fbbd240fa926dc70f53cd01da Mon Sep 17 00:00:00 2001 From: halleyscometsw Date: Fri, 25 Jul 2008 19:02:29 +0000 Subject: [PATCH] add coding_PSX_badflags git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@374 51a99a44-fe44-0410-b1ba-c3e57ba2b86b --- src/coding/coding.h | 2 ++ src/coding/psx_decoder.c | 36 ++++++++++++++++++++++++++++++++++++ src/vgmstream.c | 15 ++++++++++++++- src/vgmstream.h | 1 + 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/coding/coding.h b/src/coding/coding.h index 2f2594e5..b5f1a958 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -34,6 +34,8 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); void init_get_high_nibble(VGMSTREAM * vgmstream); diff --git a/src/coding/psx_decoder.c b/src/coding/psx_decoder.c index 9df0e028..95f60588 100644 --- a/src/coding/psx_decoder.c +++ b/src/coding/psx_decoder.c @@ -94,3 +94,39 @@ void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelsp stream->adpcm_history1_32=hist1; stream->adpcm_history2_32=hist2; } + +/* some TAITO games have garbage (?) in their flags, this decoder + * just ignores that byte */ +void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { + + int predict_nr, shift_factor, sample; + int32_t hist1=stream->adpcm_history1_32; + int32_t hist2=stream->adpcm_history2_32; + + short scale; + int i; + int32_t sample_count; + + int framesin = first_sample/28; + + predict_nr = read_8bit(stream->offset+framesin*16,stream->streamfile) >> 4; + shift_factor = read_8bit(stream->offset+framesin*16,stream->streamfile) & 0xf; + first_sample = first_sample % 28; + + for (i=first_sample,sample_count=0; ioffset+(framesin*16)+2+i/2,stream->streamfile); + + scale = ((i&1 ? + sample_byte >> 4 : + sample_byte & 0x0f)<<12); + + sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]); + + outbuf[sample_count] = clamp16(sample); + hist2=hist1; + hist1=sample; + } + stream->adpcm_history1_32=hist1; + stream->adpcm_history2_32=hist2; +} + diff --git a/src/vgmstream.c b/src/vgmstream.c index b7b05ada..cd6e7fc9 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -436,6 +436,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) { case coding_NGC_AFC: return 16; case coding_PSX: + case coding_PSX_badflags: case coding_invert_PSX: case coding_XA: return 28; @@ -491,6 +492,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) { case coding_NGC_AFC: return 9; case coding_PSX: + case coding_PSX_badflags: case coding_invert_PSX: return 16; case coding_XA: @@ -629,6 +631,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to samples_to_do); } break; + case coding_PSX_badflags: + for (chan=0;chanchannels;chan++) { + decode_psx_badflags(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, + vgmstream->channels,vgmstream->samples_into_block, + samples_to_do); + } + break; case coding_invert_PSX: for (chan=0;chanchannels;chan++) { decode_invert_psx(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, @@ -777,7 +786,8 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) { vgmstream->meta_type == meta_DSP_RS03 || vgmstream->meta_type == meta_DSP_CSTR || vgmstream->coding_type == coding_PSX || - vgmstream->coding_type == coding_invert_PSX) { + vgmstream->coding_type == coding_invert_PSX || + vgmstream->coding_type == coding_PSX_badflags) { int i; for (i=0;ichannels;i++) { vgmstream->loop_ch[i].adpcm_history1_16 = vgmstream->ch[i].adpcm_history1_16; @@ -921,6 +931,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case coding_PSX: snprintf(temp,TEMPSIZE,"Playstation 4-bit ADPCM"); break; + case coding_PSX_badflags: + snprintf(temp,TEMPSIZE,"Playstation 4-bit ADPCM with bad flags"); + break; case coding_invert_PSX: snprintf(temp,TEMPSIZE,"Inverted (?) Playstation 4-bit ADPCM"); break; diff --git a/src/vgmstream.h b/src/vgmstream.h index cf07c64d..8863e167 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -44,6 +44,7 @@ typedef enum { coding_NGC_AFC, /* NGC ADPCM, called AFC */ coding_PSX, /* PSX & PS2 ADPCM */ coding_invert_PSX, /* PSX ADPCM with first byte of frame inverted */ + coding_PSX_badflags, /* with garbage in the flags byte */ coding_XA, /* PSX CD-XA */ coding_XBOX, /* XBOX IMA */ coding_EAXA, /* EA/XA ADPCM */