mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 09:40:51 +01:00
Add Blitz IMA .str+wav [Zapper (PC)]
This commit is contained in:
parent
61b9e3743e
commit
dd31d1af33
@ -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);
|
||||||
|
@ -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 */
|
||||||
/* ************************************ */
|
/* ************************************ */
|
||||||
|
@ -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"},
|
||||||
|
@ -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 &&
|
||||||
|
@ -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++) {
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user