mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-17 23:36:41 +01:00
commit
16b4cf2294
@ -32,8 +32,9 @@ void decode_wwise_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
|
||||
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 ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels);
|
||||
size_t ima_bytes_to_samples(size_t bytes, int channels);
|
||||
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels);
|
||||
size_t xbox_ima_bytes_to_samples(size_t bytes, int channels);
|
||||
size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset);
|
||||
|
||||
/* ngc_dsp_decoder */
|
||||
|
@ -403,7 +403,7 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header,
|
||||
for (i = 0; i < data->formatCtx->nb_streams; ++i) {
|
||||
stream = data->formatCtx->streams[i];
|
||||
|
||||
if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
if (stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
streamCount++;
|
||||
|
||||
/* select Nth audio stream if specified, or first one */
|
||||
|
@ -272,46 +272,126 @@ void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
|
||||
}
|
||||
|
||||
/* ************************************ */
|
||||
/* MS IMA */
|
||||
/* MS-IMA */
|
||||
/* ************************************ */
|
||||
|
||||
/* IMA with frames with header and custom sizes */
|
||||
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||
int i, sample_count;
|
||||
/* IMA with variable-sized frames, header and custom nibble layout (outputs non-aligned number of samples).
|
||||
* Officially defined in "Microsoft Multimedia Standards Update" doc (RIFFNEW.pdf). */
|
||||
void decode_ms_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, samples_read = 0, samples_done = 0, max_samples;
|
||||
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int step_index = stream->adpcm_step_index;
|
||||
int32_t hist1;// = stream->adpcm_history1_32;
|
||||
int step_index;// = stream->adpcm_step_index;
|
||||
|
||||
//internal interleave (configurable size), mixed channels (4 byte per ch)
|
||||
int block_samples = (vgmstream->interleave_block_size - 4*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
/* internal interleave (configurable size), mixed channels (4 byte per ch) */
|
||||
int block_samples = ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//normal header (per channel)
|
||||
if (first_sample == 0) {
|
||||
off_t header_offset = stream->offset + 4*channel;
|
||||
/* normal header (hist+step+reserved per channel) */
|
||||
{
|
||||
off_t header_offset = stream->offset + 0x04*channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+2,stream->streamfile);
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+0x02,stream->streamfile); /* 0x03: reserved */
|
||||
if (step_index < 0) step_index = 0;
|
||||
if (step_index > 88) step_index = 88;
|
||||
|
||||
/* write header sample */
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)hist1;
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
off_t byte_offset = stream->offset + 4*channel + 4*vgmstream->channels + i/8*4*vgmstream->channels + (i%8)/2;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
max_samples = (block_samples - samples_read);
|
||||
if (max_samples > samples_to_do + first_sample - samples_done)
|
||||
max_samples = samples_to_do + first_sample - samples_done; /* for smaller last block */
|
||||
|
||||
/* decode nibbles (layout: alternates 4*2 nibbles per channel) */
|
||||
for (i = 0; i < max_samples; i++) {
|
||||
off_t byte_offset = stream->offset + 0x04*vgmstream->channels + 0x04*channel + 0x04*vgmstream->channels*(i/8) + (i%8)/2;
|
||||
int nibble_shift = (i&1?4:0); /* low nibble first */
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)(hist1);
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
//internal interleave: increment offset on complete frame
|
||||
if (i == block_samples) stream->offset += vgmstream->interleave_block_size;
|
||||
/* internal interleave: increment offset on complete frame */
|
||||
if (first_sample + samples_done == block_samples) {
|
||||
stream->offset += vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_step_index = step_index;
|
||||
//stream->adpcm_history1_32 = hist1;
|
||||
//stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* MS IMA with fixed frame size and custom multichannel nibble layout.
|
||||
/* Reflection's MS-IMA (some layout info from XA2WAV by Deniz Oezmen) */
|
||||
void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, samples_read = 0, samples_done = 0, max_samples;
|
||||
|
||||
int32_t hist1;// = stream->adpcm_history1_32;
|
||||
int step_index;// = stream->adpcm_step_index;
|
||||
|
||||
/* internal interleave (configurable size), mixed channels (4 byte per ch) */
|
||||
int block_channel_size = (vgmstream->interleave_block_size - 0x04*vgmstream->channels) / vgmstream->channels;
|
||||
int block_samples = ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
/* normal header (hist+step+reserved per channel) */
|
||||
{
|
||||
off_t header_offset = stream->offset + 0x04*channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+0x02,stream->streamfile); /* 0x03: reserved */
|
||||
if (step_index < 0) step_index = 0;
|
||||
if (step_index > 88) step_index = 88;
|
||||
|
||||
/* write header sample */
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)hist1;
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
max_samples = (block_samples - samples_read);
|
||||
if (max_samples > samples_to_do + first_sample - samples_done)
|
||||
max_samples = samples_to_do + first_sample - samples_done; /* for smaller last block */
|
||||
|
||||
/* decode nibbles (layout: all nibbles from one channel, then other channels) */
|
||||
for (i = 0; i < max_samples; i++) {
|
||||
off_t byte_offset = stream->offset + 0x04*vgmstream->channels + block_channel_size*channel + i/2;
|
||||
int nibble_shift = (i&1?4:0); /* low nibble first */
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)(hist1);
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
/* internal interleave: increment offset on complete frame */
|
||||
if (first_sample + samples_done == block_samples) {
|
||||
stream->offset += vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
//stream->adpcm_history1_32 = hist1;
|
||||
//stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* ************************************ */
|
||||
/* XBOX-IMA */
|
||||
/* ************************************ */
|
||||
|
||||
/* MS-IMA with fixed frame size, skips last sample per channel (for aligment) and custom multichannel nibble layout.
|
||||
* For multichannel the layout is (I think) mixed stereo channels (ex. 6ch: 2ch + 2ch + 2ch) */
|
||||
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||
int i, sample_count;
|
||||
@ -351,19 +431,19 @@ void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * o
|
||||
}
|
||||
|
||||
//internal interleave: increment offset on complete frame
|
||||
if (channelspacing==1) {
|
||||
if(offset-stream->offset==32+3) // ??
|
||||
stream->offset+=36;
|
||||
if (channelspacing==1) { /* mono */
|
||||
if (offset-stream->offset == 32+3) // ??
|
||||
stream->offset += 0x24;
|
||||
} else {
|
||||
if(offset-stream->offset==64+(4*(channel%2))+3) // ??
|
||||
stream->offset+=36*channelspacing;
|
||||
if (offset-stream->offset == 64+(4*(channel%2))+3) // ??
|
||||
stream->offset += 0x24*channelspacing;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* mono XBOX ADPCM for interleave */
|
||||
/* mono XBOX-IMA ADPCM for interleave */
|
||||
void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, sample_count = 0, num_frame;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
@ -565,6 +645,7 @@ void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelsp
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* XBOX-IMA with modified data layout */
|
||||
void decode_fsb_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||
int i, sample_count;
|
||||
|
||||
@ -572,7 +653,7 @@ void decode_fsb_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * o
|
||||
int step_index = stream->adpcm_step_index;
|
||||
|
||||
//internal interleave
|
||||
int block_samples = (36 - 4) * 2; /* block size - header, 2 samples per byte */
|
||||
int block_samples = (0x24 - 4) * 2; /* block size - header, 2 samples per byte */
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//interleaved header (all hist per channel + all step_index per channel)
|
||||
@ -601,7 +682,7 @@ void decode_fsb_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * o
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
|
||||
/* XBOX-IMA with modified data layout */
|
||||
void decode_wwise_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, sample_count = 0;
|
||||
|
||||
@ -638,7 +719,6 @@ void decode_wwise_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample *
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
sample_count+=channelspacing;
|
||||
//todo atenuation: apparently from hcs's analysis Wwise IMA decodes nibbles slightly different, reducing dbs
|
||||
}
|
||||
}
|
||||
|
||||
@ -648,45 +728,23 @@ void decode_wwise_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample *
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
//todo atenuation: apparently from hcs's analysis Wwise IMA expands nibbles slightly different, reducing clipping/dbs
|
||||
/*
|
||||
From Wwise_v2015.1.6_Build5553_SDK.Linux
|
||||
<_ZN13CAkADPCMCodec12DecodeSampleEiii>:
|
||||
10: 83 e0 07 and $0x7,%eax ; sample
|
||||
13: 01 c0 add %eax,%eax ; sample*2
|
||||
15: 83 c0 01 add $0x1,%eax ; sample*2+1
|
||||
18: 0f af 45 e4 imul -0x1c(%rbp),%eax ; (sample*2+1)*scale
|
||||
1c: 8d 50 07 lea 0x7(%rax),%edx ; result+7
|
||||
1f: 85 c0 test %eax,%eax ; result negative?
|
||||
21: 0f 48 c2 cmovs %edx,%eax ; adjust if negative to fix rounding for below division
|
||||
24: c1 f8 03 sar $0x3,%eax ; (sample*2+1)*scale/8
|
||||
|
||||
/* Reflection's MS-IMA (some layout info from XA2WAV) */
|
||||
void decode_ref_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||
int i, sample_count;
|
||||
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int step_index = stream->adpcm_step_index;
|
||||
|
||||
//internal interleave (configurable size), mixed channels (4 byte per ch)
|
||||
int block_channel_size = (vgmstream->interleave_block_size - 4*vgmstream->channels) / vgmstream->channels;
|
||||
int block_samples = (vgmstream->interleave_block_size - 4*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//normal header (per channel)
|
||||
if (first_sample == 0) {
|
||||
off_t header_offset = stream->offset + 4*channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+2,stream->streamfile);
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
}
|
||||
|
||||
//layout: all nibbles from one channel, then all nibbles from other
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
off_t byte_offset = stream->offset + 4*vgmstream->channels + block_channel_size*channel + i/2;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
//internal interleave: increment offset on complete frame
|
||||
if (i == block_samples) stream->offset += vgmstream->interleave_block_size;
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
Different rounding model vs IMA's shift-and-add (also "adjust" step may be unnecessary).
|
||||
*/
|
||||
|
||||
/* MS-IMA with possibly the XBOX-IMA model of even number of samples per block (more tests are needed) */
|
||||
void decode_awc_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
@ -785,17 +843,24 @@ void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
||||
}
|
||||
|
||||
|
||||
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) {
|
||||
/* MS IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
|
||||
return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0);
|
||||
}
|
||||
|
||||
size_t ima_bytes_to_samples(size_t bytes, int channels) {
|
||||
/* 2 samples per byte (2 nibbles) in stereo or mono config */
|
||||
return bytes * 2 / channels;
|
||||
}
|
||||
|
||||
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) {
|
||||
/* MS IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
|
||||
return (bytes / block_align) * ((block_align - 0x04*channels) * 2 / channels + 1)
|
||||
+ ((bytes % block_align) ? (((bytes % block_align) - 0x04*channels) * 2 / channels + 1) : 0);
|
||||
}
|
||||
|
||||
size_t xbox_ima_bytes_to_samples(size_t bytes, int channels) {
|
||||
int block_align = 0x24 * channels;
|
||||
/* XBOX IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
|
||||
return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0); //todo probably not possible (aligned)
|
||||
}
|
||||
|
||||
size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset) {
|
||||
int version, big_endian, header_samples;
|
||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
@ -21,10 +21,6 @@ static const int ADPCMCoeffs[7][2] =
|
||||
{ 392, -232 }
|
||||
};
|
||||
|
||||
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
|
||||
return bytes/block_size*((block_size-(7-1)*channels)*2/channels);
|
||||
}
|
||||
|
||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL *ch1,*ch2;
|
||||
int i;
|
||||
@ -161,3 +157,8 @@ void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
|
||||
return (bytes / block_size) * (block_size - (7-1)*channels) * 2 / channels
|
||||
+ ((bytes % block_size) ? ((bytes % block_size) - (7-1)*channels) * 2 / channels : 0);
|
||||
}
|
||||
|
@ -470,8 +470,8 @@ static const coding_info coding_info_list[] = {
|
||||
{coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_3DS_IMA, "3DS IMA 4-bit ADPCM"},
|
||||
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
||||
{coding_XBOX, "XBOX 4-bit IMA ADPCM"},
|
||||
{coding_XBOX_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
|
||||
{coding_XBOX_IMA_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"},
|
||||
{coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"},
|
||||
{coding_RAD_IMA, "Radical 4-bit IMA ADPCM"},
|
||||
@ -564,7 +564,7 @@ static const layout_info layout_info_list[] = {
|
||||
{layout_gsb_blocked, "GSB blocked"},
|
||||
{layout_thp_blocked, "THP Movie Audio blocked"},
|
||||
{layout_filp_blocked, "FILp blocked"},
|
||||
{layout_psx_mgav_blocked, "MGAV blocked"},
|
||||
{layout_blocked_ea_swvr, "blocked (EA SWVR)"},
|
||||
{layout_ps2_adm_blocked, "ADM blocked"},
|
||||
{layout_dsp_bdsp_blocked, "DSP blocked"},
|
||||
{layout_blocked_ivaud, "blocked (IVAUD)"},
|
||||
@ -641,7 +641,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_PS2_STR, "assumed STR + STH File by .str & .sth extension"},
|
||||
{meta_PS2_ILD, "ILD header"},
|
||||
{meta_PS2_PNB, "assumed PNB (PsychoNauts Bgm File) by .pnb extension"},
|
||||
{meta_XBOX_WAVM, "assumed Xbox WAVM file by .wavm extension"},
|
||||
{meta_XBOX_WAVM, "Xbox WAVM raw header"},
|
||||
{meta_XBOX_RIFF, "Microsoft XWAV RIFF header"},
|
||||
{meta_DSP_STR, "assumed Conan Gamecube STR File by .str extension"},
|
||||
{meta_EA_SCHL, "Electronic Arts SCHl header (variable)"},
|
||||
@ -717,7 +717,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_DC_STR, "Sega Stream Asset Builder header"},
|
||||
{meta_DC_STR_V2, "variant of Sega Stream Asset Builder header"},
|
||||
{meta_XBOX_XMU, "XMU header"},
|
||||
{meta_XBOX_XVAS, "assumed TMNT file by .xvas extension"},
|
||||
{meta_XBOX_XVAS, "Konami .XVAS header"},
|
||||
{meta_PS2_XA2, "Acclaim XA2 Header"},
|
||||
{meta_DC_IDVI, "Capcom IDVI header"},
|
||||
{meta_KRAW, "Geometry Wars: Galaxies KRAW header"},
|
||||
@ -838,7 +838,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_PS2_ADSC, "ADSC Header"},
|
||||
{meta_NGC_DSP_MPDS, "MPDS DSP header"},
|
||||
{meta_DSP_STR_IG, "Infogrames dual dsp header"},
|
||||
{meta_PSX_MGAV, "Electronic Arts RVWS header"},
|
||||
{meta_EA_SWVR, "Electronic Arts SWVR header"},
|
||||
{meta_PS2_B1S, "B1S header"},
|
||||
{meta_PS2_WAD, "WAD header"},
|
||||
{meta_DSP_XIII, "XIII dsp header"},
|
||||
@ -955,6 +955,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_XWC, "Starbreeze XWC header"},
|
||||
{meta_SQEX_SAB, "Square-Enix SAB header"},
|
||||
{meta_SQEX_MAB, "Square-Enix MAB header"},
|
||||
{meta_OGG_L2SD, "Ogg Vorbis (L2SD)"},
|
||||
|
||||
#ifdef VGM_USE_MP4V2
|
||||
{meta_MP4, "AAC header"},
|
||||
|
@ -128,8 +128,8 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
||||
case layout_blocked_ivaud:
|
||||
block_update_ivaud(vgmstream->next_block_offset,vgmstream);
|
||||
break;
|
||||
case layout_psx_mgav_blocked:
|
||||
psx_mgav_block_update(vgmstream->next_block_offset,vgmstream);
|
||||
case layout_blocked_ea_swvr:
|
||||
block_update_ea_swvr(vgmstream->next_block_offset,vgmstream);
|
||||
break;
|
||||
case layout_ps2_adm_blocked:
|
||||
ps2_adm_block_update(vgmstream->next_block_offset,vgmstream);
|
||||
|
18
src/layout/blocked_ea_swvr.c
Normal file
18
src/layout/blocked_ea_swvr.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_ea_swvr(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
|
||||
int i;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = vgmstream->codec_endian ? read_32bitBE : read_32bitLE;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bit(vgmstream->current_block_offset+0x04,streamFile)-0x1C;
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size+0x1C;
|
||||
vgmstream->current_block_size/=vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x1C+(vgmstream->current_block_size*i);
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ void filp_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
void block_update_ivaud(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
void block_update_ea_swvr(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
void ps2_adm_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitLE(vgmstream->current_block_offset+0x04,vgmstream->ch[0].streamfile)-0x1C;
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size+0x1C;
|
||||
vgmstream->current_block_size/=vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x1C+(vgmstream->current_block_size*i);
|
||||
|
||||
}
|
||||
}
|
@ -795,7 +795,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_aus.c"
|
||||
RelativePath=".\meta\aus.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -1103,7 +1103,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\psx_str_mgav.c"
|
||||
RelativePath=".\meta\ea_swvr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -1771,7 +1771,7 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\psx_mgav_blocked.c"
|
||||
RelativePath=".\layout\blocked_ea_swvr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -294,7 +294,7 @@
|
||||
<ClCompile Include="meta\ps2_adsc.c" />
|
||||
<ClCompile Include="meta\ps2_ass.c" />
|
||||
<ClCompile Include="meta\ps2_ast.c" />
|
||||
<ClCompile Include="meta\ps2_aus.c" />
|
||||
<ClCompile Include="meta\aus.c" />
|
||||
<ClCompile Include="meta\ps2_b1s.c" />
|
||||
<ClCompile Include="meta\ps2_bg00.c" />
|
||||
<ClCompile Include="meta\ps2_bmdx.c" />
|
||||
@ -359,7 +359,7 @@
|
||||
<ClCompile Include="meta\psx_cdxa.c" />
|
||||
<ClCompile Include="meta\psx_fag.c" />
|
||||
<ClCompile Include="meta\psx_gms.c" />
|
||||
<ClCompile Include="meta\psx_str_mgav.c" />
|
||||
<ClCompile Include="meta\ea_swvr.c" />
|
||||
<ClCompile Include="meta\raw.c" />
|
||||
<ClCompile Include="meta\redspark.c" />
|
||||
<ClCompile Include="meta\riff.c" />
|
||||
@ -487,7 +487,7 @@
|
||||
<ClCompile Include="layout\mxch_blocked.c" />
|
||||
<ClCompile Include="layout\nolayout.c" />
|
||||
<ClCompile Include="layout\ps2_adm_blocked.c" />
|
||||
<ClCompile Include="layout\psx_mgav_blocked.c" />
|
||||
<ClCompile Include="layout\blocked_ea_swvr.c" />
|
||||
<ClCompile Include="layout\rws_blocked.c" />
|
||||
<ClCompile Include="layout\hwas_blocked.c" />
|
||||
<ClCompile Include="layout\str_snds_blocked.c" />
|
||||
|
@ -472,7 +472,7 @@
|
||||
<ClCompile Include="meta\ps2_ast.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_aus.c">
|
||||
<ClCompile Include="meta\aus.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ps2_b1s.c">
|
||||
@ -667,7 +667,7 @@
|
||||
<ClCompile Include="meta\psx_gms.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\psx_str_mgav.c">
|
||||
<ClCompile Include="meta\ea_swvr.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\raw.c">
|
||||
@ -1045,7 +1045,7 @@
|
||||
<ClCompile Include="layout\ps2_adm_blocked.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\psx_mgav_blocked.c">
|
||||
<ClCompile Include="layout\blocked_ea_swvr.c">
|
||||
<Filter>layout\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="layout\rws_blocked.c">
|
||||
|
@ -6,38 +6,33 @@
|
||||
VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
int identifer_byte;
|
||||
int loop_flag, channel_count, codec;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if (!check_extensions(streamFile,"ads")) goto fail;
|
||||
|
||||
/* check dhSS Header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x64685353)
|
||||
if (read_32bitBE(0x00,streamFile) != 0x64685353) /* "dhSS" */
|
||||
goto fail;
|
||||
|
||||
/* check dbSS Header */
|
||||
if (read_32bitBE(0x20,streamFile) != 0x64625353)
|
||||
if (read_32bitBE(0x20,streamFile) != 0x64625353) /* "dbSS" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 1;
|
||||
channel_count = read_32bitBE(0x10,streamFile);
|
||||
|
||||
if (channel_count > 0x2)
|
||||
if (channel_count > 2)
|
||||
goto fail;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
identifer_byte = read_32bitBE(0x08,streamFile);
|
||||
switch (identifer_byte) {
|
||||
vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
|
||||
|
||||
codec = read_32bitBE(0x08,streamFile);
|
||||
switch (codec) {
|
||||
case 0x00000020: /* GC */
|
||||
start_offset = 0x28 + 0x60 * channel_count;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x28,streamFile);
|
||||
if (loop_flag) {
|
||||
@ -45,9 +40,9 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
if (channel_count == 1){
|
||||
if (channel_count == 1) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
} else if (channel_count == 2){
|
||||
} else if (channel_count == 2) {
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x14,streamFile);
|
||||
}
|
||||
@ -57,10 +52,8 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
|
||||
|
||||
case 0x00000021: /* Xbox */
|
||||
start_offset = 0x28;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
|
||||
vgmstream->coding_type = coding_XBOX_int;
|
||||
vgmstream->num_samples = (read_32bitBE(0x24,streamFile) / 36 *64 / vgmstream->channels)-64; // to avoid the "pop" at the loop point
|
||||
vgmstream->coding_type = coding_XBOX_IMA_int;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitBE(0x24,streamFile), vgmstream->channels);
|
||||
vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x24;
|
||||
if (loop_flag) {
|
||||
|
@ -31,7 +31,7 @@ VGMSTREAM * init_vgmstream_aus(STREAMFILE *streamFile) {
|
||||
vgmstream->num_samples = read_32bitLE(0x08,streamFile);
|
||||
|
||||
if(read_16bitLE(0x06,streamFile)==0x02) {
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type=layout_none;
|
||||
} else {
|
||||
vgmstream->coding_type = coding_PSX;
|
@ -37,9 +37,6 @@ VGMSTREAM * init_vgmstream_awc(STREAMFILE *streamFile) {
|
||||
if (!parse_awc_header(streamFile, &awc))
|
||||
goto fail;
|
||||
|
||||
if (awc.is_encrypted)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(awc.channel_count, 0);
|
||||
@ -156,6 +153,10 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
|
||||
if (flags & 0x00080000) /* encrypted data chunk (most of GTA5 PC) */
|
||||
awc->is_encrypted = 1;
|
||||
|
||||
if (awc->is_encrypted) {
|
||||
VGM_LOG("AWC: encrypted data found\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Music when the first id is 0 (base/fake entry with info for all channels), sfx pack otherwise.
|
||||
* sfx = N single streams, music = N-1 interleaved mono channels (even for MP3/XMA).
|
||||
@ -267,7 +268,7 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
|
||||
/* If music, data is divided into blocks of block_chunk size with padding.
|
||||
* Each block has a header/seek table and interleaved data for all channels */
|
||||
if (awc->is_music && read_32bit(awc->stream_offset, streamFile) != 0) {
|
||||
VGM_LOG("AWC: music found, but block doesn't start with seek table\n");
|
||||
VGM_LOG("AWC: music found, but block doesn't start with seek table at %lx\n", awc->stream_offset);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_
|
||||
break;
|
||||
|
||||
case EA_CODEC2_XBOXADPCM: /* XBOX IMA (interleaved mono) */
|
||||
vgmstream->coding_type = coding_XBOX_int;
|
||||
vgmstream->coding_type = coding_XBOX_IMA_int;
|
||||
break;
|
||||
|
||||
case EA_CODEC2_GCADPCM: /* DSP */
|
||||
|
80
src/meta/ea_swvr.c
Normal file
80
src/meta/ea_swvr.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* SWVR - from EA games [Future Cop L.A.P.D. (PS/PC), Freekstyle (PS2/GC), EA Sports Supercross (PS)] */
|
||||
VGMSTREAM * init_vgmstream_ea_swvr(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag = 0, channel_count;
|
||||
int big_endian;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"str"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) == 0x53575652) { /* "SWVR" (GC) */
|
||||
big_endian = 1;
|
||||
read_32bit = read_32bitBE;
|
||||
}
|
||||
else if (read_32bitBE(0x00,streamFile) == 0x52565753) { /* "RVWS" (PS/PS2) */
|
||||
big_endian = 0;
|
||||
read_32bit = read_32bitLE;
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
start_offset = read_32bit(0x04,streamFile);
|
||||
loop_flag = 1;
|
||||
channel_count = 2;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = 16000;
|
||||
vgmstream->codec_endian = big_endian;
|
||||
|
||||
vgmstream->meta_type = meta_EA_SWVR;
|
||||
vgmstream->layout_type = layout_blocked_ea_swvr;
|
||||
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
|
||||
/* calculate samples */
|
||||
{
|
||||
off_t current_chunk = start_offset;
|
||||
|
||||
vgmstream->num_samples = 0;
|
||||
while ((current_chunk + start_offset) < (get_streamfile_size(streamFile))) {
|
||||
uint32_t block_id = (read_32bit(current_chunk,streamFile));
|
||||
if (block_id == 0x5641474D) { /* "VAGM" */
|
||||
block_update_ea_swvr(start_offset,vgmstream);
|
||||
vgmstream->num_samples += vgmstream->current_block_size/16*28;
|
||||
current_chunk += vgmstream->current_block_size + 0x1C;
|
||||
}
|
||||
current_chunk += 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -288,7 +288,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
|
||||
/* FSOUND_IMAADPCMSTEREO is "noninterleaved, true stereo IMA", but doesn't seem to be any different
|
||||
* (found in FSB4: Shatter, Blade Kitten (PC), Hard Corps: Uprising (PS3)) */
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
/* "interleaved header" IMA, only used with >2ch (ex. Blade Kitten 6ch)
|
||||
* or (seemingly) when flag is used (ex. Dead to Rights 2 (Xbox) 2ch in FSB3.1 */
|
||||
|
@ -237,7 +237,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
|
||||
break;
|
||||
|
||||
case 0x07: /* FMOD_SOUND_FORMAT_IMAADPCM */
|
||||
vgmstream->coding_type = (vgmstream->channels > 2) ? coding_FSB_IMA : coding_XBOX;
|
||||
vgmstream->coding_type = (vgmstream->channels > 2) ? coding_FSB_IMA : coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
|
||||
|
@ -84,7 +84,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
/* type to coding conversion */
|
||||
switch (genh.codec) {
|
||||
case PSX: coding = coding_PSX; break;
|
||||
case XBOX: coding = coding_XBOX; break;
|
||||
case XBOX: coding = coding_XBOX_IMA; break;
|
||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||
case PCM16BE: coding = coding_PCM16BE; break;
|
||||
case PCM16LE: coding = coding_PCM16LE; break;
|
||||
@ -194,7 +194,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
vgmstream->interleave_block_size = genh.interleave;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_XBOX:
|
||||
case coding_XBOX_IMA:
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_NGC_DTK:
|
||||
|
@ -490,7 +490,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_dsp_str_ig(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_psx_mgav(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_ea_swvr(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str1(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str2(STREAMFILE* streamFile);
|
||||
|
@ -18,6 +18,8 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) {
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_16bitLE(0x16,streamFile);
|
||||
if (read_32bitLE(0x18,streamFile) == 0x4800 && vgmstream->channels > 2)
|
||||
channel_count = 2; //todo add support for interleave stereo streams
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
@ -36,14 +38,12 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) {
|
||||
/* no other way to know */
|
||||
if (vgmstream->interleave_block_size == 0x4800) {
|
||||
/* interleaved stereo streams (2ch 0x4800 + 2ch 0x4800 = 4ch) */
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
|
||||
/* header values are somehow off? */
|
||||
data_size = get_streamfile_size(streamFile);
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, 0x24*vgmstream->channels, vgmstream->channels);
|
||||
|
||||
vgmstream->channels = 2; //todo add support for interleave stereo streams
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
}
|
||||
else {
|
||||
/* 0x800 interleave */
|
||||
|
@ -232,7 +232,8 @@ VGMSTREAM * init_vgmstream_ngc_mdsp_std(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave_shortblock;
|
||||
vgmstream->meta_type = meta_DSP_STD;
|
||||
vgmstream->interleave_block_size = header.block_size * 8;
|
||||
vgmstream->interleave_smallblock_size = (header.nibble_count / 2 % vgmstream->interleave_block_size + 7) / 8 * 8;
|
||||
if (vgmstream->interleave_block_size)
|
||||
vgmstream->interleave_smallblock_size = (header.nibble_count / 2 % vgmstream->interleave_block_size + 7) / 8 * 8;
|
||||
|
||||
for (i = 0; i < channel_count; i++) {
|
||||
if (read_dsp_header(&header, header_size * i, streamFile)) goto fail;
|
||||
|
@ -156,6 +156,26 @@ static void isd_ogg_decryption_callback(void *ptr, size_t size, size_t nmemb, vo
|
||||
}
|
||||
}
|
||||
|
||||
static void l2sd_ogg_decryption_callback(void *ptr, size_t size, size_t nmemb, void *datasource) {
|
||||
size_t bytes_read = size*nmemb;
|
||||
ogg_vorbis_streamfile * const ov_streamfile = datasource;
|
||||
int i;
|
||||
char *header_id = "OggS";
|
||||
|
||||
/* First "OggS" is changed */
|
||||
{
|
||||
for (i = 0; i < bytes_read; i++) {
|
||||
if (ov_streamfile->offset+i < 0x04) {
|
||||
/* replace key in the first 4 bytes with "OggS" */
|
||||
((uint8_t*)ptr)[i] = (uint8_t)header_id[(ov_streamfile->offset + i) % 4];
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Ogg Vorbis, by way of libvorbisfile; may contain loop comments */
|
||||
VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
@ -169,6 +189,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
int is_psychic = 0;
|
||||
int is_sngw = 0;
|
||||
int is_isd = 0;
|
||||
int is_l2sd = 0;
|
||||
|
||||
|
||||
/* check extension */
|
||||
@ -195,6 +216,10 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
is_psychic = 1;
|
||||
inf.decryption_callback = psychic_ogg_decryption_callback;
|
||||
}
|
||||
else if (read_32bitBE(0x00,streamFile) == 0x4C325344) { /* "L2SD" [Lineage II Chronicle 4 (PC)] */
|
||||
is_l2sd = 1;
|
||||
inf.decryption_callback = l2sd_ogg_decryption_callback;
|
||||
}
|
||||
else if (read_32bitBE(0x00,streamFile) != 0x4f676753) { /* "OggS" */
|
||||
goto fail; /* not known (ex. Wwise) */
|
||||
}
|
||||
@ -251,6 +276,8 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
inf.meta_type = meta_OGG_SNGW;
|
||||
} else if (is_isd) {
|
||||
inf.meta_type = meta_OGG_ISD;
|
||||
} else if (is_l2sd) {
|
||||
inf.meta_type = meta_OGG_L2SD;
|
||||
} else {
|
||||
inf.meta_type = meta_OGG_VORBIS;
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* STR (Future Cop L.A.P.D.) */
|
||||
VGMSTREAM * init_vgmstream_psx_mgav(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
off_t current_chunk;
|
||||
char filename[PATH_LIMIT];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int dataBuffer = 0;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("str",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x52565753) /* "RVWS" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 1;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = read_32bitLE(0x4,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 16000;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_psx_mgav_blocked;
|
||||
vgmstream->meta_type = meta_PSX_MGAV;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate samples
|
||||
current_chunk = start_offset;
|
||||
vgmstream->num_samples = 0;
|
||||
while ((current_chunk + start_offset) < (get_streamfile_size(streamFile)))
|
||||
{
|
||||
dataBuffer = (read_32bitBE(current_chunk,streamFile));
|
||||
if (dataBuffer == 0x4D474156) /* "MGAV" */
|
||||
{
|
||||
psx_mgav_block_update(start_offset,vgmstream);
|
||||
vgmstream->num_samples += vgmstream->current_block_size/16*28;
|
||||
current_chunk += vgmstream->current_block_size + 0x1C;
|
||||
}
|
||||
current_chunk += 0x10;
|
||||
}
|
||||
|
||||
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -126,18 +126,18 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk
|
||||
fmt->coding_type = coding_MSADPCM;
|
||||
break;
|
||||
|
||||
case 0x11: /* MS IMA ADPCM */
|
||||
case 0x11: /* MS IMA ADPCM [Layton Brothers: Mystery Room (iOS/Android)] */
|
||||
if (fmt->bps != 4) goto fail;
|
||||
fmt->coding_type = coding_MS_IMA;
|
||||
break;
|
||||
|
||||
case 0x69: /* MS IMA ADPCM (XBOX) - Rayman Raving Rabbids 2 (PC) */
|
||||
case 0x69: /* XBOX IMA ADPCM [Rayman Raving Rabbids 2 (PC) --maybe waa/wac/wam/wad?] */
|
||||
if (fmt->bps != 4) goto fail;
|
||||
fmt->coding_type = coding_MS_IMA;
|
||||
fmt->coding_type = coding_XBOX_IMA;
|
||||
break;
|
||||
|
||||
case 0x007A: /* MS IMA ADPCM (LA Rush, Psi Ops PC) */
|
||||
/* 0x007A is apparently "Voxware SC3" but in .MED it's just MS-IMA */
|
||||
case 0x007A: /* MS IMA ADPCM [LA Rush (PC), Psi Ops (PC)] */
|
||||
/* 0x007A is apparently "Voxware SC3" but in .MED it's just MS-IMA (0x11) */
|
||||
if (!check_extensions(streamFile,"med"))
|
||||
goto fail;
|
||||
|
||||
@ -228,8 +228,8 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
size_t file_size, riff_size, data_size = 0;
|
||||
off_t start_offset = 0;
|
||||
|
||||
int fact_sample_count = -1;
|
||||
int fact_sample_skip = -1;
|
||||
int fact_sample_count = 0;
|
||||
int fact_sample_skip = 0;
|
||||
|
||||
int loop_flag = 0;
|
||||
long loop_start_ms = -1;
|
||||
@ -246,9 +246,10 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
int at3 = 0; /* Sony ATRAC3 / ATRAC3plus */
|
||||
int at9 = 0; /* Sony ATRAC9 */
|
||||
|
||||
/* check extension, case insensitive
|
||||
* .da: The Great Battle VI (PS), .cd: Exector (PS), .med: Psi Ops (PC) */
|
||||
if ( check_extensions(streamFile, "wav,lwav,da,cd,med") ) {
|
||||
|
||||
/* check extension */
|
||||
/* .da: The Great Battle VI (PS), .cd: Exector (PS), .med: Psi Ops (PC), .snd: Layton Brothers (iOS/Android) */
|
||||
if ( check_extensions(streamFile, "wav,lwav,da,cd,med,snd") ) {
|
||||
;
|
||||
}
|
||||
else if ( check_extensions(streamFile, "mwv") ) {
|
||||
@ -355,7 +356,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
mwv_ctrl_offset = current_chunk;
|
||||
break;
|
||||
case 0x66616374: /* fact */
|
||||
if (sns && chunk_size == 0x10) {
|
||||
if (chunk_size == 0x04) { /* standard, usually found with ADPCM */
|
||||
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
|
||||
} else if (sns && chunk_size == 0x10) {
|
||||
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
|
||||
} else if ((at3 || at9) && chunk_size == 0x08) {
|
||||
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
|
||||
@ -380,13 +383,14 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
|
||||
if (!FormatChunkFound || !DataChunkFound) goto fail;
|
||||
|
||||
//todo improve detection using fmt sizes/values as Wwise's don't match the RIFF standard
|
||||
/* JUNK is an optional Wwise chunk, and Wwise hijacks the MSADPCM/MS_IMA/XBOX IMA ids (how nice).
|
||||
* To ensure their stuff is parsed in wwise.c we reject their JUNK, which they put almost always.
|
||||
* As JUNK is legal (if unusual) we only reject those codecs.
|
||||
* (ex. Cave PC games have PCM16LE + JUNK + smpl created by "Samplitude software") */
|
||||
if (JunkFound
|
||||
&& check_extensions(streamFile,"wav,lwav") /* for some .MED IMA */
|
||||
&& (fmt.coding_type==coding_MSADPCM || fmt.coding_type==coding_MS_IMA))
|
||||
&& (fmt.coding_type==coding_MSADPCM /*|| fmt.coding_type==coding_MS_IMA*/ || fmt.coding_type==coding_XBOX_IMA))
|
||||
goto fail;
|
||||
|
||||
|
||||
@ -409,9 +413,11 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
case coding_PCM16LE:
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(data_size, fmt.channel_count, 16);
|
||||
break;
|
||||
|
||||
case coding_PCM8_U_int:
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(data_size, vgmstream->channels, 8);
|
||||
break;
|
||||
|
||||
case coding_L5_555:
|
||||
if (!mwv) goto fail;
|
||||
vgmstream->num_samples = data_size / 0x12 / fmt.channel_count * 32;
|
||||
@ -437,12 +443,22 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case coding_MSADPCM:
|
||||
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
vgmstream->num_samples = fact_sample_count ? fact_sample_count :
|
||||
msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
break;
|
||||
|
||||
case coding_MS_IMA:
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
vgmstream->num_samples = fact_sample_count ? fact_sample_count :
|
||||
ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
break;
|
||||
|
||||
case coding_XBOX_IMA:
|
||||
vgmstream->num_samples = fact_sample_count ? fact_sample_count :
|
||||
xbox_ima_bytes_to_samples(data_size, fmt.channel_count);
|
||||
break;
|
||||
|
||||
case coding_NGC_DSP:
|
||||
if (!sns) goto fail;
|
||||
if (fact_sample_count <= 0) goto fail;
|
||||
@ -531,6 +547,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
switch (fmt.coding_type) {
|
||||
case coding_MSADPCM:
|
||||
case coding_MS_IMA:
|
||||
case coding_XBOX_IMA:
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case coding_FFmpeg:
|
||||
#endif
|
||||
|
138
src/meta/rsd.c
138
src/meta/rsd.c
@ -142,74 +142,44 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* RSD2XADP */
|
||||
VGMSTREAM * init_vgmstream_rsd2xadp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t data_size;
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("rsd",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x52534432) /* RSD2 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"rsd"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x52534432) /* RSD2 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x04,streamFile) != 0x58414450) /* XADP */
|
||||
goto fail;
|
||||
|
||||
start_offset = read_32bitLE(0x18,streamFile); /* not sure about this */
|
||||
data_size = get_streamfile_size(streamFile);
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x8,streamFile);
|
||||
channel_count = read_32bitLE(0x08,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = read_32bitLE(0x18,streamFile); /* not sure about this */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)*64/36/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_flag;
|
||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
|
||||
}
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_RSD2XADP;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
|
||||
if (vgmstream->coding_type == coding_XBOX) {
|
||||
vgmstream->layout_type=layout_none;
|
||||
vgmstream->ch[i].channel_start_offset=start_offset;
|
||||
} else {
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
start_offset+vgmstream->interleave_block_size*i;
|
||||
}
|
||||
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -968,72 +938,44 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* RSD6XADP */
|
||||
/* RSD6XADP - from Crash Tag Team Racing (Xbox) */
|
||||
VGMSTREAM * init_vgmstream_rsd6xadp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t data_size;
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("rsd",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"rsd"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */
|
||||
goto fail;
|
||||
|
||||
start_offset = 0x800;
|
||||
data_size = get_streamfile_size(streamFile) - start_offset;
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x8,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x800;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)*64/36/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_flag;
|
||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
|
||||
}
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_RSD6XADP;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
|
||||
if (vgmstream->coding_type == coding_XBOX) {
|
||||
vgmstream->layout_type=layout_none;
|
||||
vgmstream->ch[i].channel_start_offset=start_offset;
|
||||
} else {
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
start_offset+vgmstream->interleave_block_size*i;
|
||||
}
|
||||
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -189,13 +189,13 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
|
||||
vgmstream->num_samples = dsp_bytes_to_samples(stream_size, channel_count);
|
||||
break;
|
||||
|
||||
case 0x936538EF: /* MS-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */
|
||||
case 0x2BA22F63: /* MS-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */
|
||||
case 0x936538EF: /* XBOX-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */
|
||||
case 0x2BA22F63: /* XBOX-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */
|
||||
/* ex. Broken Sword 3 (PC), Jacked (PC/Xbox), Burnout 2 (Xbox) */
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->interleave_block_size = 0; /* uses regular XBOX/MS-IMA interleave */
|
||||
vgmstream->coding_type = coding_XBOX_IMA; /* PC and Xbox share the same data */
|
||||
vgmstream->interleave_block_size = 0;
|
||||
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24 * channel_count, channel_count);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, channel_count);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
|
||||
vgmstream->meta_type = meta_SAB;
|
||||
|
||||
switch(codec) {
|
||||
case 0x01:
|
||||
case 0x01: /* PC */
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = is_stream ? align : 0x02;
|
||||
@ -66,7 +66,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
|
||||
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
case 0x04: /* PS2 */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = is_stream ? align : 0x10;
|
||||
@ -76,14 +76,14 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
|
||||
vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, vgmstream->channels);
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
vgmstream->coding_type = is_stream ? coding_XBOX_int : coding_XBOX;
|
||||
case 0x08: /* Xbox */
|
||||
vgmstream->coding_type = is_stream ? coding_XBOX_IMA_int : coding_XBOX_IMA;
|
||||
vgmstream->layout_type = is_stream ? layout_interleave : layout_none;
|
||||
vgmstream->interleave_block_size = is_stream ? align : 0x00;
|
||||
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24*vgmstream->channels, vgmstream->channels);
|
||||
vgmstream->loop_start_sample = ms_ima_bytes_to_samples(loop_start, 0x24*vgmstream->channels, vgmstream->channels);
|
||||
vgmstream->loop_end_sample = ms_ima_bytes_to_samples(loop_end, 0x24*vgmstream->channels, vgmstream->channels);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, vgmstream->channels);
|
||||
vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_start, vgmstream->channels);
|
||||
vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(loop_end, vgmstream->channels);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* SEG (found in Eragon) */
|
||||
|
||||
/* SEG - found in Eragon */
|
||||
VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
@ -24,7 +25,7 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
|
||||
}
|
||||
else if (read_32bitBE(0x04,streamFile) == 0x78627800) /* "xbx\0" */
|
||||
{
|
||||
coding = coding_XBOX;
|
||||
coding = coding_XBOX_IMA;
|
||||
}
|
||||
else goto fail;
|
||||
|
||||
@ -60,9 +61,9 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
|
||||
vgmstream->interleave_block_size = 0x2000;
|
||||
}
|
||||
}
|
||||
else if (coding_XBOX == coding)
|
||||
else if (coding_XBOX_IMA == coding)
|
||||
{
|
||||
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile)-start_offset)/36/channel_count*64;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(0x0C,streamFile)-start_offset, channel_count);
|
||||
vgmstream->meta_type = meta_XBOX_SEG;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
||||
/* type to coding conversion */
|
||||
switch (txth.codec) {
|
||||
case PSX: coding = coding_PSX; break;
|
||||
case XBOX: coding = coding_XBOX; break;
|
||||
case XBOX: coding = coding_XBOX_IMA; break;
|
||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||
case PCM16BE: coding = coding_PCM16BE; break;
|
||||
case PCM16LE: coding = coding_PCM16LE; break;
|
||||
@ -205,7 +205,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
||||
vgmstream->interleave_block_size = txth.interleave;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_XBOX:
|
||||
case coding_XBOX_IMA:
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_NGC_DTK:
|
||||
@ -634,7 +634,7 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
|
||||
if (!txth->interleave) return 0;
|
||||
return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels);
|
||||
case XBOX:
|
||||
return ms_ima_bytes_to_samples(bytes, 0x24 * txth->channels, txth->channels);
|
||||
return xbox_ima_bytes_to_samples(bytes, txth->channels);
|
||||
case NGC_DSP:
|
||||
return dsp_bytes_to_samples(bytes, txth->channels);
|
||||
case PSX:
|
||||
|
@ -78,7 +78,8 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
switch(((uint64_t)platform << 32) | type) {
|
||||
|
||||
case 0x57696E2070636D20: /* "Win pcm " */
|
||||
case 0x4F72626970636D20: /* "Orbipcm " (Orbis = PS4)*/
|
||||
case 0x4F72626970636D20: /* "Orbipcm " (Orbis = PS4) */
|
||||
case 0x4E78202070636D20: /* "Nx pcm " (Nx = Switch) */
|
||||
/* chunks: "data" */
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
@ -162,7 +163,7 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_ATRAC9
|
||||
case 0x5649544161743920: { /*"VITAat9 "*/
|
||||
case 0x5649544161743920: { /* "VITAat9 " */
|
||||
/* chunks: "fact" (equivalent to a RIFF "fact", num_samples + skip_samples), "data" */
|
||||
atrac9_config cfg = {0};
|
||||
|
||||
@ -181,6 +182,48 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x4E7820204E782020: { /* "Nx Nx " */
|
||||
/* chunks: "MARK" (optional seek table), "STRG" (optional description) */
|
||||
uint8_t buf[0x100];
|
||||
size_t bytes, skip, opus_size;
|
||||
ffmpeg_custom_config cfg = {0};
|
||||
|
||||
/* a standard Switch Opus header */
|
||||
skip = read_32bitLE(start_offset + 0x1c, streamFile);
|
||||
opus_size = read_32bitLE(start_offset + 0x10, streamFile) + 0x08;
|
||||
start_offset += opus_size;
|
||||
data_size -= opus_size;
|
||||
|
||||
cfg.type = FFMPEG_SWITCH_OPUS;
|
||||
|
||||
bytes = ffmpeg_make_opus_header(buf,0x100, vgmstream->channels, skip, vgmstream->sample_rate);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_config(streamFile, buf,bytes, start_offset,data_size, &cfg);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
if (((ffmpeg_codec_data*)vgmstream->codec_data)->skipSamples <= 0)
|
||||
ffmpeg_set_skip_samples(vgmstream->codec_data, skip);
|
||||
|
||||
{
|
||||
off_t chunk_offset = off + 0x20 + 0xc; /* after "fmt" */
|
||||
while (chunk_offset < header_size) {
|
||||
if (read_32bitBE(chunk_offset,streamFile) == 0x4164496E) { /*"AdIn" additional info */
|
||||
off_t adin_offset = read_32bitLE(chunk_offset+0x04,streamFile);
|
||||
vgmstream->num_samples = read_32bitLE(adin_offset,streamFile);
|
||||
break;
|
||||
}
|
||||
chunk_offset += 0xc;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
VGM_LOG("RAKI: unknown platform %x and type %x\n", platform, type);
|
||||
goto fail;
|
||||
|
@ -119,6 +119,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
||||
start_offset = sb.main_size + sb.section1_size + sb.section2_size + sb.extra_size + sb.section3_size;
|
||||
start_offset += sb.stream_offset;
|
||||
}
|
||||
//;VGM_LOG("start offset=%lx, external=%i\n", start_offset, sb.is_external);
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
@ -154,9 +155,9 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
|
||||
break;
|
||||
|
||||
case RAW_XBOX:
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(sb.stream_size, 0x24*sb.channels,sb.channels);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(sb.stream_size, sb.channels);
|
||||
break;
|
||||
|
||||
case RAW_DSP:
|
||||
@ -886,5 +887,21 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Surf's Up (2007)(PC) */
|
||||
if (sb->version == 0x00190005 && is_sb0) {
|
||||
sb->section1_entry_size = 0x68;
|
||||
sb->section2_entry_size = 0x74;
|
||||
|
||||
sb->external_flag_offset = 0x28; /* maybe 0x2c */
|
||||
sb->channels_offset = 0x3c;
|
||||
sb->sample_rate_offset = 0x40;
|
||||
sb->num_samples_offset = 0x48;
|
||||
sb->stream_type_offset = 0x5c;
|
||||
sb->extra_name_offset = 0x58;
|
||||
|
||||
sb->has_extra_name_flag = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,146 +1,146 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/*
|
||||
const short wad_coef[16][2] =
|
||||
{
|
||||
{0x4002,0x2003},
|
||||
{0x2016,0xc600},
|
||||
{0xC600,0x98ab},
|
||||
{0x96bf,0x29c5},
|
||||
{0x2003,0x0081},
|
||||
{0x0e00,0x2004},
|
||||
{0x8e01,0xc500},
|
||||
{0x70bf,0x8128},
|
||||
{0x288e,0xc600},
|
||||
{0x016e,0x0e5b},
|
||||
{0xbe20,0x2003},
|
||||
{0x03c6,0xc600},
|
||||
{0x0048,0xe85a},
|
||||
{0xbe28,0x28c6},
|
||||
{0xc600,0x00F6},
|
||||
{0xbeab,0x5520}
|
||||
{0x4002,0x2003},
|
||||
{0x2016,0xc600},
|
||||
{0xC600,0x98ab},
|
||||
{0x96bf,0x29c5},
|
||||
{0x2003,0x0081},
|
||||
{0x0e00,0x2004},
|
||||
{0x8e01,0xc500},
|
||||
{0x70bf,0x8128},
|
||||
{0x288e,0xc600},
|
||||
{0x016e,0x0e5b},
|
||||
{0xbe20,0x2003},
|
||||
{0x03c6,0xc600},
|
||||
{0x0048,0xe85a},
|
||||
{0xbe28,0x28c6},
|
||||
{0xc600,0x00F6},
|
||||
{0xbeab,0x5520}
|
||||
};*/
|
||||
const short wad_coef[16] =
|
||||
{
|
||||
0x04ab, 0xfced,
|
||||
0x0789, 0xfedf,
|
||||
0x09a2, 0xfae5,
|
||||
0x0c90, 0xfac1,
|
||||
0x084d, 0xfaa4,
|
||||
0x0982, 0xfdf7,
|
||||
0x0af6, 0xfafa,
|
||||
0x0be6, 0xfbf5
|
||||
0x04ab, 0xfced,
|
||||
0x0789, 0xfedf,
|
||||
0x09a2, 0xfae5,
|
||||
0x0c90, 0xfac1,
|
||||
0x084d, 0xfaa4,
|
||||
0x0982, 0xfdf7,
|
||||
0x0af6, 0xfafa,
|
||||
0x0be6, 0xfbf5
|
||||
};
|
||||
|
||||
|
||||
/* WAC - WAD - WAM (Beyond Good & Evil GC/PS2/Xbox/Wii) */
|
||||
/* Note: A "Flat Layout" has no interleave */
|
||||
/* WAC/WAD/WAM/WAA - from Beyond Good & Evil (PS2/Xbox/GC/Wii) */
|
||||
VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
int i;
|
||||
int i;
|
||||
off_t start_offset;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
int coef1_start;
|
||||
int coef2_start;
|
||||
int second_channel_start = -1;
|
||||
int channel_count;
|
||||
int coef1_start;
|
||||
int coef2_start;
|
||||
int second_channel_start = -1;
|
||||
|
||||
// Check file extensions
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("waa",filename_extension(filename)) &&
|
||||
strcasecmp("wac",filename_extension(filename)) &&
|
||||
strcasecmp("wad",filename_extension(filename)) &&
|
||||
strcasecmp("wam",filename_extension(filename))) goto fail;
|
||||
strcasecmp("wac",filename_extension(filename)) &&
|
||||
strcasecmp("wad",filename_extension(filename)) &&
|
||||
strcasecmp("wam",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */
|
||||
read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */
|
||||
read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt\0x20" */
|
||||
read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */
|
||||
read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */
|
||||
read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt " */
|
||||
read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */
|
||||
goto fail;
|
||||
|
||||
/* files don't contain looping information,
|
||||
so the looping is not done depending on extension.
|
||||
wam and waa contain ambient sounds and music, so often they contain
|
||||
looped music. Change extension to wac or wad to make the sound non-looping.
|
||||
*/
|
||||
/* files don't contain looping information,
|
||||
so the looping is not done depending on extension.
|
||||
wam and waa contain ambient sounds and music, so often they contain
|
||||
looped music. Change extension to wac or wad to make the sound non-looping.
|
||||
*/
|
||||
loop_flag = strcasecmp("wac",filename_extension(filename)) &&
|
||||
strcasecmp("wad",filename_extension(filename));
|
||||
strcasecmp("wad",filename_extension(filename));
|
||||
channel_count = (uint16_t)read_16bitLE(0x16,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* Check what encoder is needed */
|
||||
//FIXME: //PC version uses pcm, but which encoder?
|
||||
/* Check what encoder is needed */
|
||||
//FIXME: //PC version uses pcm, but which encoder?
|
||||
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
|
||||
vgmstream->meta_type = meta_WAA_WAC_WAD_WAM;
|
||||
vgmstream->meta_type = meta_WAA_WAC_WAD_WAM;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
switch((uint16_t)read_16bitLE(0x14,streamFile)) {
|
||||
switch((uint16_t)read_16bitLE(0x14,streamFile)) {
|
||||
case 0x0069: // XBOX IMA ADPCM
|
||||
start_offset = 0x2E;
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/36/channel_count*64;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/36/channel_count*64;
|
||||
}
|
||||
start_offset = 0x2E;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile), channel_count);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile),channel_count);
|
||||
}
|
||||
break;
|
||||
case 0xFFFF: // PS2 ADPCM
|
||||
start_offset = 0x2E;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
|
||||
}
|
||||
start_offset = 0x2E;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/16*28/channel_count;
|
||||
}
|
||||
second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+start_offset;
|
||||
break;
|
||||
case 0xFFFE: // GameCube/WII DSP
|
||||
start_offset = 0x5C;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
|
||||
}
|
||||
if(read_16bitLE(0x24,streamFile)==0x00)//is a wii file with no coeff table
|
||||
{
|
||||
//FIXME: WII version of WAM/WAD/WAC need some coeff table from somewhere
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = wad_coef[i];
|
||||
if (channel_count == 2) {
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = wad_coef[i];
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+0x8A;
|
||||
/* Retrieveing the coef tables */
|
||||
coef1_start = 0x2E;
|
||||
coef2_start = (read_32bitLE(0x2A,streamFile)/2)+0x5C;
|
||||
start_offset = 0x5C;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))*14/8/channel_count;
|
||||
}
|
||||
if(read_16bitLE(0x24,streamFile)==0x00)//is a wii file with no coeff table
|
||||
{
|
||||
//FIXME: WII version of WAM/WAD/WAC need some coeff table from somewhere
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = wad_coef[i];
|
||||
if (channel_count == 2) {
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = wad_coef[i];
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+0x8A;
|
||||
/* Retrieveing the coef tables */
|
||||
coef1_start = 0x2E;
|
||||
coef2_start = (read_32bitLE(0x2A,streamFile)/2)+0x5C;
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFile);
|
||||
if (channel_count == 2) {
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFile);
|
||||
if (channel_count == 2) {
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
if (vgmstream->coding_type == coding_XBOX) {
|
||||
if (vgmstream->coding_type == coding_XBOX_IMA) {
|
||||
/* xbox interleaving is a little odd */
|
||||
vgmstream->ch[i].channel_start_offset=start_offset;
|
||||
} else {
|
||||
|
@ -1,68 +1,50 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/*
|
||||
WVS (found in Metal Arms - Glitch in the System)
|
||||
XBOX and GameCube
|
||||
*/
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* WVS - found in Metal Arms - Glitch in the System (Xbox) */
|
||||
VGMSTREAM * init_vgmstream_xbox_wvs(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t data_size;
|
||||
|
||||
int loop_flag=0;
|
||||
int channel_count;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("wvs",filename_extension(filename))) goto fail;
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"wvs"))
|
||||
goto fail;
|
||||
|
||||
if((read_16bitLE(0x0C,streamFile)!=0x69) &&
|
||||
(read_16bitLE(0x08,streamFile)!=0x4400) &&
|
||||
(read_32bitLE(0x0,streamFile)!=get_streamfile_size(streamFile)+0x20))
|
||||
goto fail;
|
||||
if (read_16bitLE(0x0C,streamFile) != 0x69 && /* codec */
|
||||
read_16bitLE(0x08,streamFile) != 0x4400)
|
||||
goto fail;
|
||||
|
||||
/* Loop seems to be set if offset(0x0A) == 0x472C */
|
||||
loop_flag = (read_16bitLE(0x0A,streamFile)==0x472C);
|
||||
start_offset = 0x20;
|
||||
data_size = read_32bitLE(0x00,streamFile);
|
||||
loop_flag = (read_16bitLE(0x0a,streamFile) == 0x472C); /* loop seems to be like this */
|
||||
channel_count = read_16bitLE(0x0e,streamFile); /* always stereo files */
|
||||
|
||||
/* Always stereo files */
|
||||
channel_count=read_16bitLE(0x0E,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
if (data_size + start_offset != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
/* allways 2 channels @ 44100 Hz */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = read_32bitLE(0,streamFile) / 36 * 64 / vgmstream->channels;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_XBOX_WVS;
|
||||
|
||||
if(loop_flag) {
|
||||
vgmstream->loop_start_sample=0;
|
||||
vgmstream->loop_end_sample=vgmstream->num_samples;
|
||||
}
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = 0x20;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -75,7 +57,7 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) {
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -94,7 +76,7 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x60;
|
||||
|
||||
if (channel_count == 1) {
|
||||
@ -103,8 +85,8 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) {
|
||||
vgmstream->sample_rate = 44100;
|
||||
}
|
||||
|
||||
vgmstream->channels = channel_count;
|
||||
|
||||
vgmstream->channels = channel_count;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)/8/channel_count*14; //(read_32bitBE(0x0C,streamFile)-start_offset)/8/channel_count*14;
|
||||
if (loop_flag) {
|
||||
|
@ -194,11 +194,12 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
break;
|
||||
|
||||
case IMA: /* common */
|
||||
/* slightly modified MS IMA with interleaved sub-blocks and LE/BE header */
|
||||
/* slightly modified XBOX-IMA with interleaved sub-blocks and LE/BE header */
|
||||
|
||||
/* Wwise uses common codecs (ex. 0x0002 MSADPCM) so this parser should go AFTER riff.c avoid misdetection */
|
||||
|
||||
if (ww.bits_per_sample != 4) goto fail;
|
||||
if (ww.block_align != 0x24 * ww.channels) goto fail;
|
||||
vgmstream->coding_type = coding_WWISE_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->interleave_block_size = ww.block_align;
|
||||
@ -207,7 +208,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
if (ww.truncated) /* enough to get real samples */
|
||||
ww.data_size = ww.file_size - ww.data_offset;
|
||||
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(ww.data_size, ww.block_align, ww.channels);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(ww.data_size, ww.channels);
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
|
@ -58,11 +58,11 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE *streamFile) {
|
||||
goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_32bitLE(0x58, streamFile);
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(read_32bitLE(start_offset-4, streamFile), read_16bitLE(0x60, streamFile), channel_count);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(start_offset-4, streamFile), channel_count);
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
|
||||
|
@ -29,8 +29,8 @@ VGMSTREAM * init_vgmstream_xbox_matx(STREAMFILE *streamFile) {
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_16bitLE(0x06,streamFile) & 0xffff;
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_matx_blocked;
|
||||
vgmstream->meta_type = meta_XBOX_MATX;
|
||||
|
||||
|
@ -1,62 +1,37 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* WAVM
|
||||
|
||||
WAVM is an headerless format which can be found on XBOX
|
||||
known extensions : WAVM
|
||||
|
||||
2008-05-23 - Fastelbja : First version ...
|
||||
*/
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* WAVM - headerless format which can be found on XBOX */
|
||||
VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset = 0;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
int loop_flag=0;
|
||||
int channel_count;
|
||||
int i;
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"wavm"))
|
||||
goto fail;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("wavm",filename_extension(filename))) goto fail;
|
||||
|
||||
/* No loop on wavm */
|
||||
loop_flag = 0;
|
||||
start_offset = 0;
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* Always stereo files */
|
||||
channel_count=2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
/* allways 2 channels @ 44100 Hz */
|
||||
vgmstream->channels = 2;
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(get_streamfile_size(streamFile), vgmstream->channels);
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) / 36 * 64 / vgmstream->channels);
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->meta_type = meta_XBOX_WAVM;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = 0;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1,65 +1,44 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* XMU
|
||||
|
||||
XMU (found in Alter Echo)
|
||||
*/
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XMU- found in Alter Echo (Xbox) */
|
||||
VGMSTREAM * init_vgmstream_xbox_xmu(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
size_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t data_size;
|
||||
|
||||
int loop_flag=0;
|
||||
int channel_count;
|
||||
int i;
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"xmu"))
|
||||
goto fail;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("xmu",filename_extension(filename))) goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x584D5520 && /* "XMU " */
|
||||
read_32bitBE(0x08,streamFile) != 0x46524D54) /* "FRMT" */
|
||||
goto fail;
|
||||
|
||||
if((read_32bitBE(0x00,streamFile)!=0x584D5520) &&
|
||||
(read_32bitBE(0x08,streamFile)!=0x46524D54))
|
||||
goto fail;
|
||||
start_offset = 0x800;
|
||||
channel_count=read_8bit(0x14,streamFile); /* always stereo files */
|
||||
loop_flag = read_8bit(0x16,streamFile); /* no Loop found atm */
|
||||
data_size = read_32bitLE(0x7FC,streamFile); /* next to "DATA" */
|
||||
|
||||
/* No Loop found atm */
|
||||
loop_flag = read_8bit(0x16,streamFile);;
|
||||
|
||||
/* Always stereo files */
|
||||
channel_count=read_8bit(0x14,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = read_32bitLE(0x7FC,streamFile) / 36 * 64 / vgmstream->channels;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_XBOX_XMU;
|
||||
|
||||
if(loop_flag) {
|
||||
vgmstream->loop_start_sample=0;
|
||||
vgmstream->loop_end_sample=vgmstream->num_samples;
|
||||
}
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = 0x800;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,72 +1,52 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* XVAS
|
||||
|
||||
XVAS (found in TMNT 2 & TMNT 3))
|
||||
*/
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XVAS - found in TMNT 2 & TMNT 3 (Xbox) */
|
||||
VGMSTREAM * init_vgmstream_xbox_xvas(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t data_size;
|
||||
|
||||
int loop_flag=0;
|
||||
int channel_count;
|
||||
int i;
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"xvas"))
|
||||
goto fail;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("xvas",filename_extension(filename))) goto fail;
|
||||
if (read_32bitLE(0x00,streamFile) != 0x69 && /* codec */
|
||||
read_32bitLE(0x08,streamFile) != 0x48) /* block size (probably 0x24 for mono) */
|
||||
goto fail;
|
||||
|
||||
if((read_32bitLE(0x00,streamFile)!=0x69) &&
|
||||
(read_32bitLE(0x08,streamFile)!=0x48))
|
||||
goto fail;
|
||||
start_offset = 0x800;
|
||||
channel_count = read_32bitLE(0x04,streamFile); /* always stereo files */
|
||||
loop_flag = (read_32bitLE(0x14,streamFile) == read_32bitLE(0x24,streamFile));
|
||||
data_size = read_32bitLE(0x24,streamFile);
|
||||
data_size -= (data_size / 0x20000) * 0x20; /* blocks of 0x20000 with padding */
|
||||
|
||||
/* No Loop found atm */
|
||||
loop_flag = (read_32bitLE(0x14,streamFile)==read_32bitLE(0x24,streamFile));
|
||||
|
||||
/* Always stereo files */
|
||||
channel_count=read_32bitLE(0x04,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x0c,streamFile);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
if(loop_flag) {
|
||||
size_t loop_size = read_32bitLE(0x10,streamFile);
|
||||
loop_size -= (loop_size / 0x20000) * 0x20;
|
||||
vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_size, vgmstream->channels);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = read_32bitLE(0x24,streamFile);
|
||||
vgmstream->num_samples -= ((vgmstream->num_samples/0x20000)*0x20);
|
||||
vgmstream->num_samples = vgmstream->num_samples / 36 * 64 / vgmstream->channels;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_xvas_blocked;
|
||||
vgmstream->meta_type = meta_XBOX_XVAS;
|
||||
|
||||
if(loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->loop_start_sample -= ((vgmstream->loop_start_sample/0x20000)*0x20);
|
||||
vgmstream->loop_start_sample = vgmstream->loop_start_sample / 36 * 64 / vgmstream->channels;
|
||||
vgmstream->loop_end_sample=vgmstream->num_samples;
|
||||
}
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = 0x800;
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
xvas_block_update(0x800,vgmstream);
|
||||
xvas_block_update(start_offset,vgmstream);
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,107 +1,91 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* XWAV
|
||||
|
||||
XWAV use the common RIFF/WAVE format with Codec ID = 0x0069
|
||||
It has been renamed to xwav to avoid vgmstream to handle all RIFF/WAV format
|
||||
known extensions : XWAV
|
||||
|
||||
2008-05-24 - Fastelbja : First version ...
|
||||
*/
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XWAV - renamed WAV with XBOX-IMA
|
||||
* (could be parsed as RIFF/.lwav but has a custom loop chunk and multichannel) */
|
||||
VGMSTREAM * init_vgmstream_xbox_xwav(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
|
||||
int loop_flag=0;
|
||||
int channel_count;
|
||||
int loop_flag, channel_count;
|
||||
off_t start_offset;
|
||||
int i,j=0;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("xwav",filename_extension(filename))) goto fail;
|
||||
/* check extension */
|
||||
if (!check_extensions(streamFile,"xwav"))
|
||||
goto fail;
|
||||
|
||||
/* Check for headers */
|
||||
if(!((read_32bitBE(0x00,streamFile)==0x52494646) &&
|
||||
(read_32bitBE(0x08,streamFile)==0x57415645) &&
|
||||
(read_32bitBE(0x0C,streamFile)==0x666D7420) &&
|
||||
(read_16bitLE(0x14,streamFile)==0x0069)))
|
||||
goto fail;
|
||||
/* check for headers */
|
||||
if(!((read_32bitBE(0x00,streamFile) == 0x52494646) && /* "RIFF" */
|
||||
(read_32bitBE(0x08,streamFile) == 0x57415645) && /* "WAVE" */
|
||||
(read_32bitBE(0x0C,streamFile) == 0x666D7420) && /* "fmt " */
|
||||
(read_16bitLE(0x14,streamFile) == 0x0069))) /* codec */
|
||||
goto fail;
|
||||
|
||||
/* No loop on wavm */
|
||||
if(read_32bitBE(0x28,streamFile)==0x77736D70)
|
||||
loop_flag = 1;
|
||||
else
|
||||
loop_flag = 0;
|
||||
|
||||
/* Always stereo files */
|
||||
channel_count=read_16bitLE(0x16,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* loop chunk found on Koei/Omega Force games [Crimson Sea, Dynasty Warriors 5] */
|
||||
loop_flag = (read_32bitBE(0x28,streamFile) == 0x77736D70); /* "wsmp" */
|
||||
channel_count = read_16bitLE(0x16,streamFile);
|
||||
|
||||
/* search for "data" */
|
||||
start_offset = 0x1C;
|
||||
do {
|
||||
if (read_32bitBE(start_offset,streamFile)==0x64617461)
|
||||
break;
|
||||
start_offset += 0x04;
|
||||
} while (start_offset < (off_t)get_streamfile_size(streamFile));
|
||||
|
||||
if (start_offset >= (off_t)get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
start_offset += 0x04;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* hack for loop wave found on Dynasty warriors */
|
||||
if(loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile);
|
||||
vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,streamFile);
|
||||
}
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(start_offset,streamFile), vgmstream->channels);
|
||||
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile);
|
||||
vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,streamFile);
|
||||
}
|
||||
|
||||
/* search for "data" */
|
||||
start_offset=0x1C;
|
||||
|
||||
do {
|
||||
if(read_32bitBE(start_offset,streamFile)==0x64617461)
|
||||
break;
|
||||
start_offset+=4;
|
||||
} while (start_offset<(off_t)get_streamfile_size(streamFile));
|
||||
|
||||
if(start_offset>=(off_t)get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
start_offset+=4;
|
||||
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->num_samples = read_32bitLE(start_offset,streamFile) / 36 * 64 / vgmstream->channels;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->meta_type = meta_XBOX_RIFF;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
//if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
// goto fail;
|
||||
|
||||
//custom init
|
||||
{
|
||||
if(channel_count>2) {
|
||||
for (i=0;i<channel_count;i++,j++) {
|
||||
if((j&2) && (i!=0)) {
|
||||
j=0;
|
||||
start_offset+=36*2;
|
||||
}
|
||||
int i, ch;
|
||||
char filename[PATH_LIMIT];
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = start_offset+4;
|
||||
if (channel_count > 2) { /* multichannel interleaved init */
|
||||
for (i=0, ch=0;i<channel_count;i++,ch++) {
|
||||
if ((ch&2) && (i!=0)) {
|
||||
ch = 0;
|
||||
start_offset += 0x24*2;
|
||||
}
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
} else {
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
|
||||
vgmstream->ch[i].offset = start_offset+4;
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24);
|
||||
vgmstream->ch[i].offset = start_offset + 0x04;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i=0; i < channel_count; i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24);
|
||||
vgmstream->ch[i].offset = start_offset + 0x04;
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
if ((read_32bitBE(0,streamFile) & 0xFFFFFF00) != 0x584E4200) /* "XNB" */
|
||||
goto fail;
|
||||
|
||||
/* 0x04: platform: ‘w’ = Windows, ‘m’ = Windows Phone 7, ‘x’ = X360, 'a' = Android, 'P': PS4 */
|
||||
/* XNA Studio platforms: 'w' = Windows, 'm' = Windows Phone 7, 'x' = X360
|
||||
* MonoGame extensions: 'i' = iOS, 'a' = Android, 'X' = MacOSX, 'P': PS4, etc */
|
||||
platform = read_8bit(0x03,streamFile);
|
||||
big_endian = (platform == 'x');
|
||||
|
||||
@ -28,8 +29,8 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
|
||||
flags = read_8bit(0x05,streamFile);
|
||||
//if (flags & 0x01) goto fail; /* "HiDef profile" content (no actual difference) */
|
||||
if (flags & 0x80) goto fail; /* compressed with XMemCompress (at 0x0a is decompressed size) */
|
||||
if (flags & 0x40) goto fail; /* custom compression? seen in Square Heroes (PS4) */
|
||||
if (flags & 0x80) goto fail; /* compressed with LZX/XMemCompress (at 0x0a is decompressed size) */
|
||||
if (flags & 0x40) goto fail; /* compressed with LZ4, MonoGame extension [ex. Square Heroes (PS4)] */
|
||||
|
||||
/* full size */
|
||||
if (read_32bitLE(0x06,streamFile) != get_streamfile_size(streamFile))
|
||||
|
@ -295,11 +295,11 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
}
|
||||
}
|
||||
else if (xwb.version <= XACT1_1_MAX && xwb.codec == XBOX_ADPCM) {
|
||||
xwb.block_align = 0x24 * xwb.channels;
|
||||
xwb.num_samples = ms_ima_bytes_to_samples(xwb.stream_size, xwb.block_align, xwb.channels);
|
||||
xwb.block_align = 0x24 * xwb.channels; /* not really needed... */
|
||||
xwb.num_samples = xbox_ima_bytes_to_samples(xwb.stream_size, xwb.channels);
|
||||
if (xwb.loop_flag) {
|
||||
xwb.loop_start_sample = ms_ima_bytes_to_samples(xwb.loop_start, xwb.block_align, xwb.channels);
|
||||
xwb.loop_end_sample = ms_ima_bytes_to_samples(xwb.loop_start + xwb.loop_end, xwb.block_align, xwb.channels);
|
||||
xwb.loop_start_sample = xbox_ima_bytes_to_samples(xwb.loop_start, xwb.channels);
|
||||
xwb.loop_end_sample = xbox_ima_bytes_to_samples(xwb.loop_start + xwb.loop_end, xwb.channels);
|
||||
}
|
||||
}
|
||||
else if (xwb.version <= XACT2_2_MAX && xwb.codec == MS_ADPCM && xwb.loop_flag) {
|
||||
@ -367,7 +367,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
break;
|
||||
|
||||
case XBOX_ADPCM: /* Silent Hill 4 (Xbox) */
|
||||
vgmstream->coding_type = coding_XBOX;
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
|
||||
|
167
src/vgmstream.c
167
src/vgmstream.c
@ -265,7 +265,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ps2_adsc,
|
||||
init_vgmstream_ngc_dsp_mpds,
|
||||
init_vgmstream_dsp_str_ig,
|
||||
init_vgmstream_psx_mgav,
|
||||
init_vgmstream_ea_swvr,
|
||||
init_vgmstream_ngc_dsp_sth_str1,
|
||||
init_vgmstream_ngc_dsp_sth_str2,
|
||||
init_vgmstream_ngc_dsp_sth_str3,
|
||||
@ -968,7 +968,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_thp_blocked:
|
||||
case layout_filp_blocked:
|
||||
case layout_blocked_ivaud:
|
||||
case layout_psx_mgav_blocked:
|
||||
case layout_blocked_ea_swvr:
|
||||
case layout_ps2_adm_blocked:
|
||||
case layout_dsp_bdsp_blocked:
|
||||
case layout_tra_blocked:
|
||||
@ -1010,11 +1010,17 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_CRI_ADX_enc_8:
|
||||
case coding_CRI_ADX_enc_9:
|
||||
return (vgmstream->interleave_block_size - 2) * 2;
|
||||
case coding_L5_555:
|
||||
return 32;
|
||||
|
||||
case coding_NGC_DSP:
|
||||
case coding_NGC_DSP_subint:
|
||||
return 14;
|
||||
case coding_NGC_AFC:
|
||||
return 16;
|
||||
case coding_NGC_DTK:
|
||||
return 28;
|
||||
case coding_G721:
|
||||
return 1;
|
||||
|
||||
case coding_PCM16LE:
|
||||
case coding_PCM16LE_XOR_int:
|
||||
case coding_PCM16BE:
|
||||
@ -1052,12 +1058,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_NWA5:
|
||||
case coding_SASSC:
|
||||
return 1;
|
||||
case coding_NDS_IMA:
|
||||
case coding_DAT4_IMA:
|
||||
return (vgmstream->interleave_block_size-4)*2;
|
||||
case coding_NGC_DTK:
|
||||
return 28;
|
||||
case coding_G721:
|
||||
|
||||
case coding_IMA:
|
||||
case coding_DVI_IMA:
|
||||
case coding_SNDS_IMA:
|
||||
@ -1067,22 +1068,36 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_IMA_int:
|
||||
case coding_DVI_IMA_int:
|
||||
case coding_3DS_IMA:
|
||||
case coding_AICA:
|
||||
return 2;
|
||||
case coding_NGC_AFC:
|
||||
return 16;
|
||||
case coding_XBOX_IMA:
|
||||
case coding_XBOX_IMA_int:
|
||||
case coding_FSB_IMA:
|
||||
return 64;
|
||||
case coding_APPLE_IMA4:
|
||||
return 64;
|
||||
case coding_MS_IMA:
|
||||
case coding_REF_IMA:
|
||||
return ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
case coding_RAD_IMA:
|
||||
case coding_WWISE_IMA:
|
||||
return (vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
case coding_NDS_IMA:
|
||||
case coding_DAT4_IMA:
|
||||
return (vgmstream->interleave_block_size - 0x04) * 2;
|
||||
case coding_AWC_IMA:
|
||||
return (0x800 - 0x04) * 2;
|
||||
case coding_RAD_IMA_mono:
|
||||
return 32;
|
||||
|
||||
case coding_XA:
|
||||
case coding_PSX:
|
||||
case coding_PSX_badflags:
|
||||
case coding_PSX_bmdx:
|
||||
case coding_HEVAG:
|
||||
case coding_XA:
|
||||
return 28;
|
||||
case coding_PSX_cfg:
|
||||
return (vgmstream->interleave_block_size - 1) * 2; /* decodes 1 byte into 2 bytes */
|
||||
case coding_XBOX:
|
||||
case coding_XBOX_int:
|
||||
case coding_FSB_IMA:
|
||||
return 64;
|
||||
|
||||
case coding_EA_XA:
|
||||
case coding_EA_XA_int:
|
||||
case coding_EA_XA_V2:
|
||||
@ -1090,24 +1105,20 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
return 28;
|
||||
case coding_EA_XAS:
|
||||
return 128;
|
||||
case coding_WS:
|
||||
/* only works if output sample size is 8 bit, which always is for WS ADPCM */
|
||||
return vgmstream->ws_output_size;
|
||||
|
||||
case coding_MSADPCM:
|
||||
return (vgmstream->interleave_block_size-(7-1)*vgmstream->channels)*2/vgmstream->channels;
|
||||
case coding_APPLE_IMA4:
|
||||
return 64;
|
||||
case coding_MS_IMA:
|
||||
case coding_RAD_IMA:
|
||||
case coding_WWISE_IMA:
|
||||
case coding_REF_IMA:
|
||||
return (vgmstream->interleave_block_size-4*vgmstream->channels)*2/vgmstream->channels;
|
||||
case coding_AWC_IMA:
|
||||
return (0x800-4)*2;
|
||||
case coding_RAD_IMA_mono:
|
||||
return 32;
|
||||
case coding_WS: /* only works if output sample size is 8 bit, which always is for WS ADPCM */
|
||||
return vgmstream->ws_output_size;
|
||||
case coding_AICA:
|
||||
return 2;
|
||||
case coding_NDS_PROCYON:
|
||||
return 30;
|
||||
case coding_L5_555:
|
||||
return 32;
|
||||
case coding_LSF:
|
||||
return 54;
|
||||
|
||||
#ifdef VGM_USE_G7221
|
||||
case coding_G7221C:
|
||||
return 32000/50;
|
||||
@ -1120,18 +1131,15 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
#endif
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case coding_FFmpeg:
|
||||
{
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||
if (data) {
|
||||
/* must know the full block size for edge loops */
|
||||
return data->sampleBufferBlock;
|
||||
if (vgmstream->codec_data) {
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data*)vgmstream->codec_data;
|
||||
return data->sampleBufferBlock; /* must know the full block size for edge loops */
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case coding_LSF:
|
||||
return 54;
|
||||
case coding_MTAF:
|
||||
return 128*2;
|
||||
case coding_MTA2:
|
||||
@ -1168,17 +1176,23 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_CRI_ADX_enc_8:
|
||||
case coding_CRI_ADX_enc_9:
|
||||
return vgmstream->interleave_block_size;
|
||||
case coding_L5_555:
|
||||
return 18;
|
||||
|
||||
case coding_NGC_DSP:
|
||||
return 0x08;
|
||||
case coding_NGC_DSP_subint:
|
||||
return 0x08 * vgmstream->channels;
|
||||
case coding_NGC_AFC:
|
||||
return 0x09;
|
||||
case coding_NGC_DTK:
|
||||
return 0x20;
|
||||
case coding_G721:
|
||||
return 0;
|
||||
|
||||
case coding_PCM16LE:
|
||||
case coding_PCM16LE_XOR_int:
|
||||
case coding_PCM16BE:
|
||||
case coding_PCM16_int:
|
||||
return 2;
|
||||
return 0x02;
|
||||
case coding_PCM8:
|
||||
case coding_PCM8_U:
|
||||
case coding_PCM8_int:
|
||||
@ -1187,9 +1201,10 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_ULAW:
|
||||
case coding_ULAW_int:
|
||||
case coding_ALAW:
|
||||
return 1;
|
||||
return 0x01;
|
||||
case coding_PCMFLOAT:
|
||||
return 4;
|
||||
return 0x04;
|
||||
|
||||
case coding_SDX2:
|
||||
case coding_SDX2_int:
|
||||
case coding_CBD2:
|
||||
@ -1200,7 +1215,14 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_NWA4:
|
||||
case coding_NWA5:
|
||||
case coding_SASSC:
|
||||
return 1;
|
||||
return 0x01;
|
||||
|
||||
case coding_IMA:
|
||||
case coding_IMA_int:
|
||||
case coding_DVI_IMA:
|
||||
case coding_DVI_IMA_int:
|
||||
case coding_3DS_IMA:
|
||||
return 0x01;
|
||||
case coding_MS_IMA:
|
||||
case coding_RAD_IMA:
|
||||
case coding_NDS_IMA:
|
||||
@ -1212,30 +1234,28 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
return 0x800;
|
||||
case coding_RAD_IMA_mono:
|
||||
return 0x14;
|
||||
case coding_NGC_DTK:
|
||||
return 32;
|
||||
case coding_G721:
|
||||
case coding_SNDS_IMA:
|
||||
case coding_OTNS_IMA:
|
||||
return 0;
|
||||
case coding_UBI_IMA: /* variable (PCM then IMA) */
|
||||
return 0;
|
||||
case coding_NGC_AFC:
|
||||
return 9;
|
||||
case coding_XBOX_IMA:
|
||||
case coding_XBOX_IMA_int:
|
||||
case coding_FSB_IMA:
|
||||
return 0x24;
|
||||
case coding_APPLE_IMA4:
|
||||
return 0x22;
|
||||
|
||||
case coding_XA:
|
||||
return 0x0e*vgmstream->channels;
|
||||
case coding_PSX:
|
||||
case coding_PSX_badflags:
|
||||
case coding_PSX_bmdx:
|
||||
case coding_HEVAG:
|
||||
case coding_NDS_PROCYON:
|
||||
return 16;
|
||||
return 0x10;
|
||||
case coding_PSX_cfg:
|
||||
return vgmstream->interleave_block_size;
|
||||
case coding_XA:
|
||||
return 14*vgmstream->channels;
|
||||
case coding_XBOX:
|
||||
case coding_XBOX_int:
|
||||
case coding_FSB_IMA:
|
||||
return 36;
|
||||
|
||||
case coding_EA_XA:
|
||||
return 0x1E;
|
||||
case coding_EA_XA_int:
|
||||
@ -1246,20 +1266,20 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
return 0; /* variable (ADPCM frames of 0x0f or PCM frames of 0x3d) */
|
||||
case coding_EA_XAS:
|
||||
return 0x4c*vgmstream->channels;
|
||||
|
||||
case coding_MSADPCM:
|
||||
return vgmstream->interleave_block_size;
|
||||
case coding_WS:
|
||||
return vgmstream->current_block_size;
|
||||
case coding_IMA:
|
||||
case coding_IMA_int:
|
||||
case coding_DVI_IMA:
|
||||
case coding_DVI_IMA_int:
|
||||
case coding_3DS_IMA:
|
||||
return 0x01;
|
||||
case coding_AICA:
|
||||
return 1;
|
||||
case coding_APPLE_IMA4:
|
||||
return 34;
|
||||
return 0x01;
|
||||
case coding_NDS_PROCYON:
|
||||
return 0x10;
|
||||
case coding_L5_555:
|
||||
return 0x12;
|
||||
case coding_LSF:
|
||||
return 28;
|
||||
return 0x1C;
|
||||
|
||||
#ifdef VGM_USE_G7221
|
||||
case coding_G7221C:
|
||||
case coding_G7221:
|
||||
@ -1273,7 +1293,6 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case coding_FFmpeg:
|
||||
#endif
|
||||
case coding_MSADPCM:
|
||||
case coding_MTAF:
|
||||
return vgmstream->interleave_block_size;
|
||||
case coding_MTA2:
|
||||
@ -1286,7 +1305,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_ATRAC9:
|
||||
return 0; /* varies with config data, usually 0x100-200 */
|
||||
#endif
|
||||
default:
|
||||
default: /* Vorbis, MPEG, ACM, etc */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1475,14 +1494,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_XBOX:
|
||||
case coding_XBOX_IMA:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_xbox_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
vgmstream->channels,vgmstream->samples_into_block,
|
||||
samples_to_do,chan);
|
||||
}
|
||||
break;
|
||||
case coding_XBOX_int:
|
||||
case coding_XBOX_IMA_int:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
vgmstream->channels,vgmstream->samples_into_block,
|
||||
|
@ -127,8 +127,8 @@ typedef enum {
|
||||
coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */
|
||||
coding_3DS_IMA, /* 3DS IMA ADPCM */
|
||||
coding_MS_IMA, /* Microsoft IMA ADPCM */
|
||||
coding_XBOX, /* XBOX IMA ADPCM */
|
||||
coding_XBOX_int, /* XBOX IMA ADPCM (interleaved) */
|
||||
coding_XBOX_IMA, /* XBOX IMA ADPCM */
|
||||
coding_XBOX_IMA_int, /* XBOX IMA ADPCM (interleaved/mono) */
|
||||
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
||||
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
|
||||
coding_RAD_IMA, /* Radical IMA ADPCM */
|
||||
@ -237,7 +237,7 @@ typedef enum {
|
||||
layout_gsb_blocked,
|
||||
layout_thp_blocked,
|
||||
layout_filp_blocked,
|
||||
layout_psx_mgav_blocked,
|
||||
layout_blocked_ea_swvr,
|
||||
layout_ps2_adm_blocked,
|
||||
layout_dsp_bdsp_blocked,
|
||||
layout_mxch_blocked,
|
||||
@ -544,7 +544,7 @@ typedef enum {
|
||||
meta_DSP_DDSP, /* Various (2 dsp files stuck together */
|
||||
meta_NGC_DSP_MPDS, /* Big Air Freestyle, Terminator 3 */
|
||||
meta_DSP_STR_IG, /* Micro Machines, Superman Superman: Shadow of Apokolis */
|
||||
meta_PSX_MGAV, /* Future Cop L.A.P.D. */
|
||||
meta_EA_SWVR, /* Future Cop L.A.P.D., Freekstyle */
|
||||
meta_NGC_DSP_STH_STR, /* SpongeBob Squarepants (NGC), Taz Wanted (NGC), Cubix (NGC), Tak (WII)*/
|
||||
meta_PS2_B1S, /* 7 Wonders of the ancient world */
|
||||
meta_PS2_WAD, /* The golden Compass */
|
||||
@ -659,6 +659,7 @@ typedef enum {
|
||||
meta_XWC, /* Starbreeze games */
|
||||
meta_SQEX_SAB, /* Square-Enix newest middleware (sound) */
|
||||
meta_SQEX_MAB, /* Square-Enix newest middleware (music) */
|
||||
meta_OGG_L2SD, /* Ogg Vorbis with obfuscation [Lineage II Chronicle 4 (PC)] */
|
||||
|
||||
#ifdef VGM_USE_MP4V2
|
||||
meta_MP4, /* AAC (iOS) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user