Add Blitz IMA .str+wav [Zapper (PC)]

This commit is contained in:
bnnm 2019-02-23 00:12:58 +01:00
parent 61b9e3743e
commit dd31d1af33
6 changed files with 91 additions and 4 deletions

View File

@ -22,6 +22,7 @@ void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
void decode_wv6_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_wv6_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_alp_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_alp_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_blitz_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);

View File

@ -236,6 +236,33 @@ static void ffta2_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
if (*step_index > 88) *step_index=88; if (*step_index > 88) *step_index=88;
} }
/* Yet another IMA expansion, from the exe */
static void blitz_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
int sample_nibble, sample_decoded, step, delta;
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf; /* ADPCM code */
sample_decoded = *hist1; /* predictor value */
step = ADPCMTable[*step_index]; /* current step */
/* table has 2 different values, not enough to bother adding the full table */
if (step == 22385)
step = 22358;
else if (step == 24623)
step = 24633;
delta = (sample_nibble & 0x07);
if (sample_nibble & 8) delta = -delta;
delta = (step >> 1) + delta * step; /* custom */
sample_decoded += delta;
/* somehow the exe tries to clamp hist, but actually doesn't (bug?),
* not sure if pcm buffer would be clamped outside though */
*hist1 = sample_decoded;//clamp16(sample_decoded);
*step_index += IMA_IndexTable[sample_nibble];
if (*step_index < 0) *step_index=0;
if (*step_index > 88) *step_index=88;
}
/* ************************************ */ /* ************************************ */
/* DVI/IMA */ /* DVI/IMA */
/* ************************************ */ /* ************************************ */
@ -403,6 +430,28 @@ void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspa
stream->adpcm_step_index = step_index; stream->adpcm_step_index = step_index;
} }
/* Blitz IMA, IMA with custom nibble expand */
void decode_blitz_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i, sample_count;
int32_t hist1 = stream->adpcm_history1_32;
int step_index = stream->adpcm_step_index;
//external interleave
//no header
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
off_t byte_offset = stream->offset + i/2;
int nibble_shift = (i&1?4:0); //low nibble first
blitz_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
outbuf[sample_count] = (short)(hist1);
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_index;
}
/* ************************************ */ /* ************************************ */
/* MS-IMA */ /* MS-IMA */
/* ************************************ */ /* ************************************ */

View File

@ -609,6 +609,7 @@ static const coding_info coding_info_list[] = {
{coding_WV6_IMA, "Gorilla Systems WV6 4-bit IMA ADPCM"}, {coding_WV6_IMA, "Gorilla Systems WV6 4-bit IMA ADPCM"},
{coding_ALP_IMA, "High Voltage ALP 4-bit IMA ADPCM"}, {coding_ALP_IMA, "High Voltage ALP 4-bit IMA ADPCM"},
{coding_FFTA2_IMA, "Final Fantasy Tactics A2 4-bit IMA ADPCM"}, {coding_FFTA2_IMA, "Final Fantasy Tactics A2 4-bit IMA ADPCM"},
{coding_BLITZ_IMA, "Blitz Games 4-bit IMA ADPCM"},
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"}, {coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
{coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"}, {coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
@ -902,8 +903,8 @@ static const meta_info meta_info_list[] = {
{meta_RSD6WMA, "Radical RSD6/WMA header"}, {meta_RSD6WMA, "Radical RSD6/WMA header"},
{meta_DC_ASD, "ASD Header"}, {meta_DC_ASD, "ASD Header"},
{meta_NAOMI_SPSD, "Naomi SPSD header"}, {meta_NAOMI_SPSD, "Naomi SPSD header"},
{meta_FFXI_BGW, "BGW BGMStream header"}, {meta_FFXI_BGW, "Square Enix .BGW header"},
{meta_FFXI_SPW, "SPW SeWave header"}, {meta_FFXI_SPW, "Square Enix .SPW header"},
{meta_PS2_ASS, "SystemSoft .ASS header"}, {meta_PS2_ASS, "SystemSoft .ASS header"},
{meta_NUB_IDSP, "Namco NUB IDSP header"}, {meta_NUB_IDSP, "Namco NUB IDSP header"},
{meta_IDSP_NL, "Next Level IDSP header"}, {meta_IDSP_NL, "Next Level IDSP header"},
@ -996,7 +997,7 @@ static const meta_info meta_info_list[] = {
{meta_PS2_B1S, "B1S header"}, {meta_PS2_B1S, "B1S header"},
{meta_PS2_WAD, "WAD header"}, {meta_PS2_WAD, "WAD header"},
{meta_DSP_XIII, "XIII dsp header"}, {meta_DSP_XIII, "XIII dsp header"},
{meta_DSP_CABELAS, "Cabelas games dsp header"}, {meta_DSP_CABELAS, "Cabelas games .DSP header"},
{meta_PS2_ADM, "Dragon Quest V .ADM raw header"}, {meta_PS2_ADM, "Dragon Quest V .ADM raw header"},
{meta_PS2_LPCM, "LPCM header"}, {meta_PS2_LPCM, "LPCM header"},
{meta_PS2_VMS, "VMS Header"}, {meta_PS2_VMS, "VMS Header"},

View File

@ -2,7 +2,7 @@
#include "../coding/coding.h" #include "../coding/coding.h"
typedef enum { PSX, DSP, XBOX, WMA } strwav_codec; typedef enum { PSX, DSP, XBOX, WMA, IMA } strwav_codec;
typedef struct { typedef struct {
int32_t channels; int32_t channels;
int32_t sample_rate; int32_t sample_rate;
@ -126,6 +126,12 @@ VGMSTREAM * init_vgmstream_str_wav(STREAMFILE *streamFile) {
goto fail; /* only 2ch+..+2ch layout is known */ goto fail; /* only 2ch+..+2ch layout is known */
break; break;
case IMA:
vgmstream->coding_type = coding_BLITZ_IMA;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = strwav.interleave;
break;
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
case WMA: { case WMA: {
ffmpeg_codec_data *ffmpeg_data = NULL; ffmpeg_codec_data *ffmpeg_data = NULL;
@ -330,6 +336,27 @@ static int parse_header(STREAMFILE* streamHeader, strwav_header* strwav) {
return 1; return 1;
} }
/* Zapper: One Wicked Cricket! (PC)[2005] */
if ( read_32bitBE(0x04,streamHeader) == 0x00000900 &&
read_32bitLE(0x24,streamHeader) == read_32bitLE(0x114,streamHeader) && /* sample rate repeat */
read_32bitLE(0x28,streamHeader) == 0x10 &&
read_32bitLE(0x12c,streamHeader) == header_size /* ~0x130 */
) {
strwav->num_samples = read_32bitLE(0x20,streamHeader);
strwav->sample_rate = read_32bitLE(0x24,streamHeader);
strwav->flags = read_32bitLE(0x2c,streamHeader);
strwav->loop_start = read_32bitLE(0x54,streamHeader);
strwav->loop_end = read_32bitLE(0x30,streamHeader);
strwav->channels = read_32bitLE(0xF8,streamHeader) * (strwav->flags & 0x02 ? 2 : 1); /* tracks of 2/1ch */
strwav->loop_flag = strwav->flags & 0x01;
strwav->interleave = strwav->channels > 2 ? 0x8000 : 0x10000;
strwav->codec = IMA;
//;VGM_LOG("STR+WAV: header Zapper (PC)\n");
return 1;
}
/* Pac-Man World 3 (GC)[2005] */ /* Pac-Man World 3 (GC)[2005] */
/* SpongeBob SquarePants: Creature from the Krusty Krab (GC)[2006] */ /* SpongeBob SquarePants: Creature from the Krusty Krab (GC)[2006] */
if ( read_32bitBE(0x04,streamHeader) == 0x00000800 && if ( read_32bitBE(0x04,streamHeader) == 0x00000800 &&

View File

@ -1178,6 +1178,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_WV6_IMA: case coding_WV6_IMA:
case coding_ALP_IMA: case coding_ALP_IMA:
case coding_FFTA2_IMA: case coding_FFTA2_IMA:
case coding_BLITZ_IMA:
case coding_PCFX: case coding_PCFX:
return 2; return 2;
case coding_XBOX_IMA: case coding_XBOX_IMA:
@ -1356,6 +1357,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
case coding_WV6_IMA: case coding_WV6_IMA:
case coding_ALP_IMA: case coding_ALP_IMA:
case coding_FFTA2_IMA: case coding_FFTA2_IMA:
case coding_BLITZ_IMA:
case coding_PCFX: case coding_PCFX:
case coding_OKI16: case coding_OKI16:
return 0x01; return 0x01;
@ -1860,6 +1862,12 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
vgmstream->channels,vgmstream->samples_into_block,samples_to_do); vgmstream->channels,vgmstream->samples_into_block,samples_to_do);
} }
break; break;
case coding_BLITZ_IMA:
for (ch = 0; ch < vgmstream->channels; ch++) {
decode_blitz_ima(&vgmstream->ch[ch],buffer+samples_written*vgmstream->channels+ch,
vgmstream->channels,vgmstream->samples_into_block,samples_to_do);
}
break;
case coding_APPLE_IMA4: case coding_APPLE_IMA4:
for (ch = 0; ch < vgmstream->channels; ch++) { for (ch = 0; ch < vgmstream->channels; ch++) {

View File

@ -120,6 +120,7 @@ typedef enum {
coding_WV6_IMA, /* Gorilla Systems WV6 4-bit IMA ADPCM */ coding_WV6_IMA, /* Gorilla Systems WV6 4-bit IMA ADPCM */
coding_ALP_IMA, /* High Voltage ALP 4-bit IMA ADPCM */ coding_ALP_IMA, /* High Voltage ALP 4-bit IMA ADPCM */
coding_FFTA2_IMA, /* Final Fantasy Tactics A2 4-bit IMA ADPCM */ coding_FFTA2_IMA, /* Final Fantasy Tactics A2 4-bit IMA ADPCM */
coding_BLITZ_IMA, /* Blitz Games 4-bit IMA ADPCM */
coding_MS_IMA, /* Microsoft IMA ADPCM */ coding_MS_IMA, /* Microsoft IMA ADPCM */
coding_XBOX_IMA, /* XBOX IMA ADPCM */ coding_XBOX_IMA, /* XBOX IMA ADPCM */