mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-20 04:21:11 +01:00
Add .WV6 IMA [The Fairly OddParents: Breakin' Da Rules (PC)]
This commit is contained in:
parent
6a86414990
commit
16f2474a50
@ -15,22 +15,25 @@ void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
void g72x_init_state(struct g72x_state *state_ptr);
|
||||
|
||||
/* ima_decoder */
|
||||
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first);
|
||||
void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_wv6_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_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||
|
||||
void decode_xbox_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_xbox_ima_mch(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first);
|
||||
void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||
void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_apple_ima4(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_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_fsb_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_wwise_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_awc_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
size_t ima_bytes_to_samples(size_t bytes, int channels);
|
||||
|
@ -169,6 +169,25 @@ static void otns_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
||||
if (*step_index > 88) *step_index=88;
|
||||
}
|
||||
|
||||
/* Fairly OddParents (PC) .WV6: minor variation, reverse engineered from the .exe */
|
||||
static void wv6_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;
|
||||
sample_decoded = *hist1;
|
||||
step = ADPCMTable[*step_index];
|
||||
|
||||
delta = (sample_nibble & 0x7);
|
||||
delta = ((delta * step) >> 3) + ((delta * step) >> 2);
|
||||
if (sample_nibble & 8) delta = -delta;
|
||||
sample_decoded += delta;
|
||||
|
||||
*hist1 = 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 */
|
||||
/* ************************************ */
|
||||
@ -269,6 +288,28 @@ void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* WV6 IMA, DVI IMA with custom nibble expand */
|
||||
void decode_wv6_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?0:4); //high nibble first
|
||||
|
||||
wv6_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 */
|
||||
/* ************************************ */
|
||||
|
@ -422,6 +422,7 @@ static const char* extension_list[] = {
|
||||
"wsd",
|
||||
"wsi",
|
||||
"wv2", //txth/reserved [Slave Zero (PC)]
|
||||
"wv6",
|
||||
"wve",
|
||||
"wvs",
|
||||
|
||||
@ -528,6 +529,10 @@ static const coding_info coding_info_list[] = {
|
||||
{coding_DVI_IMA, "Intel DVI 4-bit IMA ADPCM"},
|
||||
{coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_3DS_IMA, "3DS IMA 4-bit ADPCM"},
|
||||
{coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"},
|
||||
{coding_OTNS_IMA, "Omikron: The Nomad Soul 4-bit IMA ADPCM"},
|
||||
{coding_WV6_IMA, "Gorilla Systems WV6 4-bit IMA ADPCM"},
|
||||
|
||||
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
||||
{coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
|
||||
{coding_XBOX_IMA_mch, "XBOX 4-bit IMA ADPCM (multichannel)"},
|
||||
@ -537,8 +542,6 @@ static const coding_info coding_info_list[] = {
|
||||
{coding_RAD_IMA, "Radical 4-bit IMA ADPCM"},
|
||||
{coding_RAD_IMA_mono, "Radical 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_APPLE_IMA4, "Apple Quicktime 4-bit IMA ADPCM"},
|
||||
{coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"},
|
||||
{coding_OTNS_IMA, "Omikron: The Nomad Soul 4-bit IMA ADPCM"},
|
||||
{coding_FSB_IMA, "FSB 4-bit IMA ADPCM"},
|
||||
{coding_WWISE_IMA, "Audiokinetic Wwise 4-bit IMA ADPCM"},
|
||||
{coding_REF_IMA, "Reflections 4-bit IMA ADPCM"},
|
||||
@ -1051,6 +1054,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_XMD, "Konami XMD header"},
|
||||
{meta_CKS, "Cricket Audio CKS header"},
|
||||
{meta_CKB, "Cricket Audio CKB header"},
|
||||
{meta_WV6, "Gorilla Systems WV6 header"},
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{meta_FFmpeg, "FFmpeg supported file format"},
|
||||
|
@ -1414,6 +1414,10 @@
|
||||
RelativePath=".\meta\ws_aud.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wv6.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wvs.c"
|
||||
>
|
||||
|
@ -430,6 +430,7 @@
|
||||
<ClCompile Include="meta\wii_str.c" />
|
||||
<ClCompile Include="meta\wii_sts.c" />
|
||||
<ClCompile Include="meta\ws_aud.c" />
|
||||
<ClCompile Include="meta\wv6.c" />
|
||||
<ClCompile Include="meta\wvs.c" />
|
||||
<ClCompile Include="meta\wwise.c" />
|
||||
<ClCompile Include="meta\xau.c" />
|
||||
|
@ -865,6 +865,9 @@
|
||||
<ClCompile Include="meta\ws_aud.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\wv6.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\wvs.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -771,4 +771,6 @@ VGMSTREAM * init_vgmstream_xmd(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_cks(STREAMFILE *streamFile);
|
||||
VGMSTREAM * init_vgmstream_ckb(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_wv6(STREAMFILE *streamFile);
|
||||
|
||||
#endif /*_META_H*/
|
||||
|
55
src/meta/wv6.c
Normal file
55
src/meta/wv6.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* WV6 - Gorilla Systems PC games [Spy Kids: Mega Mission Zone (PC), Lilo & Stitch: Hawaiian Adventure (PC)] */
|
||||
VGMSTREAM * init_vgmstream_wv6(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "wv6"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x2c,streamFile) != 0x57563620 || /* "WV6 " */
|
||||
read_32bitBE(0x30,streamFile) != 0x494D415F) /* "IMA_" ("WV6 IMA_ADPCM COMPRESSED 16 BIT AUDIO") */
|
||||
goto fail;
|
||||
|
||||
/* 0x54/58/5c/60/6c: unknown (reject to catch possible stereo files, but don't seem to exist) */
|
||||
if (read_32bitLE(0x54,streamFile) != 0x01 ||
|
||||
read_32bitLE(0x58,streamFile) != 0x01 ||
|
||||
read_32bitLE(0x5c,streamFile) != 0x10 ||
|
||||
read_32bitLE(0x68,streamFile) != 0x01 ||
|
||||
read_32bitLE(0x6c,streamFile) != 0x88)
|
||||
goto fail;
|
||||
/* 0x64: PCM size (samples*channels*2) */
|
||||
|
||||
channel_count = 1;
|
||||
loop_flag = 0;
|
||||
start_offset = 0x8c;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_32bitLE(0x60, streamFile);
|
||||
vgmstream->num_samples = ima_bytes_to_samples(read_32bitLE(0x88,streamFile), channel_count);
|
||||
|
||||
vgmstream->meta_type = meta_WV6;
|
||||
vgmstream->coding_type = coding_WV6_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
read_string(vgmstream->stream_name,0x1c+1, 0x04,streamFile);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -423,6 +423,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_xmd,
|
||||
init_vgmstream_cks,
|
||||
init_vgmstream_ckb,
|
||||
init_vgmstream_wv6,
|
||||
|
||||
init_vgmstream_txth, /* should go at the end (lower priority) */
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
@ -1062,6 +1063,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_IMA_int:
|
||||
case coding_DVI_IMA_int:
|
||||
case coding_3DS_IMA:
|
||||
case coding_WV6_IMA:
|
||||
return 2;
|
||||
case coding_XBOX_IMA:
|
||||
case coding_XBOX_IMA_mch:
|
||||
@ -1225,6 +1227,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_DVI_IMA:
|
||||
case coding_DVI_IMA_int:
|
||||
case coding_3DS_IMA:
|
||||
case coding_WV6_IMA:
|
||||
return 0x01;
|
||||
case coding_MS_IMA:
|
||||
case coding_RAD_IMA:
|
||||
@ -1238,7 +1241,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
return 0x14;
|
||||
case coding_SNDS_IMA:
|
||||
case coding_OTNS_IMA:
|
||||
return 0;
|
||||
return 0; //todo: 0x01?
|
||||
case coding_UBI_IMA: /* variable (PCM then IMA) */
|
||||
return 0;
|
||||
case coding_XBOX_IMA:
|
||||
@ -1719,6 +1722,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_WV6_IMA:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_wv6_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
vgmstream->channels,vgmstream->samples_into_block,
|
||||
samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_APPLE_IMA4:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_apple_ima4(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
|
@ -124,6 +124,10 @@ typedef enum {
|
||||
coding_DVI_IMA, /* DVI IMA ADPCM (stereo or mono, high nibble first) */
|
||||
coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */
|
||||
coding_3DS_IMA, /* 3DS IMA ADPCM */
|
||||
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
||||
coding_OTNS_IMA, /* Omikron The Nomad Soul IMA ADPCM */
|
||||
coding_WV6_IMA, /* Gorilla Systems WV6 4-bit IMA ADPCM */
|
||||
|
||||
coding_MS_IMA, /* Microsoft IMA ADPCM */
|
||||
coding_XBOX_IMA, /* XBOX IMA ADPCM */
|
||||
coding_XBOX_IMA_mch, /* XBOX IMA ADPCM (multichannel) */
|
||||
@ -133,8 +137,6 @@ typedef enum {
|
||||
coding_RAD_IMA, /* Radical IMA ADPCM */
|
||||
coding_RAD_IMA_mono, /* Radical IMA ADPCM (mono/interleave) */
|
||||
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
|
||||
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
||||
coding_OTNS_IMA, /* Omikron The Nomad Soul IMA ADPCM */
|
||||
coding_FSB_IMA, /* FMOD's FSB multichannel IMA ADPCM */
|
||||
coding_WWISE_IMA, /* Audiokinetic Wwise IMA ADPCM */
|
||||
coding_REF_IMA, /* Reflections IMA ADPCM */
|
||||
@ -688,6 +690,7 @@ typedef enum {
|
||||
meta_XMD, /* Konami XMD [Silent Hill 4 (Xbox), Castlevania: Curse of Darkness (Xbox)] */
|
||||
meta_CKS, /* Cricket Audio stream [Part Time UFO (Android), Mega Man 1-6 (Android)] */
|
||||
meta_CKB, /* Cricket Audio bank [Fire Emblem Heroes (Android), Mega Man 1-6 (Android)] */
|
||||
meta_WV6, /* Gorilla Systems PC games */
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
meta_FFmpeg,
|
||||
|
Loading…
x
Reference in New Issue
Block a user