Updated VGMStream to r1050-532-gba4e6d1f.
parent
d2dc14a72c
commit
5df7a8f5c6
|
@ -245,7 +245,7 @@
|
||||||
836F6FF118BDC2190095E648 /* ps2_psw.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB518BDC2180095E648 /* ps2_psw.c */; };
|
836F6FF118BDC2190095E648 /* ps2_psw.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB518BDC2180095E648 /* ps2_psw.c */; };
|
||||||
836F6FF218BDC2190095E648 /* ps2_rnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB618BDC2180095E648 /* ps2_rnd.c */; };
|
836F6FF218BDC2190095E648 /* ps2_rnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB618BDC2180095E648 /* ps2_rnd.c */; };
|
||||||
836F6FF318BDC2190095E648 /* ps2_rstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB718BDC2180095E648 /* ps2_rstm.c */; };
|
836F6FF318BDC2190095E648 /* ps2_rstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB718BDC2180095E648 /* ps2_rstm.c */; };
|
||||||
836F6FF418BDC2190095E648 /* ps2_rws.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB818BDC2180095E648 /* ps2_rws.c */; };
|
836F6FF418BDC2190095E648 /* rws.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB818BDC2180095E648 /* rws.c */; };
|
||||||
836F6FF618BDC2190095E648 /* ps2_sfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBA18BDC2180095E648 /* ps2_sfs.c */; };
|
836F6FF618BDC2190095E648 /* ps2_sfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBA18BDC2180095E648 /* ps2_sfs.c */; };
|
||||||
836F6FF718BDC2190095E648 /* ps2_sl3.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBB18BDC2180095E648 /* ps2_sl3.c */; };
|
836F6FF718BDC2190095E648 /* ps2_sl3.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBB18BDC2180095E648 /* ps2_sl3.c */; };
|
||||||
836F6FF818BDC2190095E648 /* ps2_smpl.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBC18BDC2180095E648 /* ps2_smpl.c */; };
|
836F6FF818BDC2190095E648 /* ps2_smpl.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBC18BDC2180095E648 /* ps2_smpl.c */; };
|
||||||
|
@ -725,7 +725,7 @@
|
||||||
836F6EB518BDC2180095E648 /* ps2_psw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_psw.c; sourceTree = "<group>"; };
|
836F6EB518BDC2180095E648 /* ps2_psw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_psw.c; sourceTree = "<group>"; };
|
||||||
836F6EB618BDC2180095E648 /* ps2_rnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rnd.c; sourceTree = "<group>"; };
|
836F6EB618BDC2180095E648 /* ps2_rnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rnd.c; sourceTree = "<group>"; };
|
||||||
836F6EB718BDC2180095E648 /* ps2_rstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rstm.c; sourceTree = "<group>"; };
|
836F6EB718BDC2180095E648 /* ps2_rstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rstm.c; sourceTree = "<group>"; };
|
||||||
836F6EB818BDC2180095E648 /* ps2_rws.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rws.c; sourceTree = "<group>"; };
|
836F6EB818BDC2180095E648 /* rws.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rws.c; sourceTree = "<group>"; };
|
||||||
836F6EBA18BDC2180095E648 /* ps2_sfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_sfs.c; sourceTree = "<group>"; };
|
836F6EBA18BDC2180095E648 /* ps2_sfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_sfs.c; sourceTree = "<group>"; };
|
||||||
836F6EBB18BDC2180095E648 /* ps2_sl3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_sl3.c; sourceTree = "<group>"; };
|
836F6EBB18BDC2180095E648 /* ps2_sl3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_sl3.c; sourceTree = "<group>"; };
|
||||||
836F6EBC18BDC2180095E648 /* ps2_smpl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_smpl.c; sourceTree = "<group>"; };
|
836F6EBC18BDC2180095E648 /* ps2_smpl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_smpl.c; sourceTree = "<group>"; };
|
||||||
|
@ -1264,7 +1264,7 @@
|
||||||
836F6EB518BDC2180095E648 /* ps2_psw.c */,
|
836F6EB518BDC2180095E648 /* ps2_psw.c */,
|
||||||
836F6EB618BDC2180095E648 /* ps2_rnd.c */,
|
836F6EB618BDC2180095E648 /* ps2_rnd.c */,
|
||||||
836F6EB718BDC2180095E648 /* ps2_rstm.c */,
|
836F6EB718BDC2180095E648 /* ps2_rstm.c */,
|
||||||
836F6EB818BDC2180095E648 /* ps2_rws.c */,
|
836F6EB818BDC2180095E648 /* rws.c */,
|
||||||
836F6EBA18BDC2180095E648 /* ps2_sfs.c */,
|
836F6EBA18BDC2180095E648 /* ps2_sfs.c */,
|
||||||
836F6EBB18BDC2180095E648 /* ps2_sl3.c */,
|
836F6EBB18BDC2180095E648 /* ps2_sl3.c */,
|
||||||
836F6EBC18BDC2180095E648 /* ps2_smpl.c */,
|
836F6EBC18BDC2180095E648 /* ps2_smpl.c */,
|
||||||
|
@ -1811,7 +1811,7 @@
|
||||||
83709E051ECBC1A4005C03D3 /* gtd.c in Sources */,
|
83709E051ECBC1A4005C03D3 /* gtd.c in Sources */,
|
||||||
836F704A18BDC2190095E648 /* xbox_wavm.c in Sources */,
|
836F704A18BDC2190095E648 /* xbox_wavm.c in Sources */,
|
||||||
836F6F8618BDC2190095E648 /* excitebots.c in Sources */,
|
836F6F8618BDC2190095E648 /* excitebots.c in Sources */,
|
||||||
836F6FF418BDC2190095E648 /* ps2_rws.c in Sources */,
|
836F6FF418BDC2190095E648 /* rws.c in Sources */,
|
||||||
836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */,
|
836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */,
|
||||||
836F6FE818BDC2190095E648 /* ps2_mic.c in Sources */,
|
836F6FE818BDC2190095E648 /* ps2_mic.c in Sources */,
|
||||||
836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */,
|
836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */,
|
||||||
|
|
|
@ -57,6 +57,7 @@ void decode_pcm8_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac
|
||||||
void decode_pcm8_sb_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm8_sb_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_pcm8_unsigned(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm8_unsigned(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_ulaw(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample);
|
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample);
|
||||||
|
|
||||||
/* psx_decoder */
|
/* psx_decoder */
|
||||||
|
|
|
@ -97,11 +97,12 @@ static void mta2_block_update(VGMSTREAMCHANNEL * stream) {
|
||||||
void decode_mta2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
void decode_mta2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||||
int samples_done = 0, sample_count = 0, channel_block_samples, channel_first_sample, frame_size = 0;
|
int samples_done = 0, sample_count = 0, channel_block_samples, channel_first_sample, frame_size = 0;
|
||||||
int i, group, row, col;
|
int i, group, row, col;
|
||||||
int num_track = 0, channel_layout, track_channels = 0, track_channel;
|
int track_channels = 0, track_channel;
|
||||||
|
|
||||||
|
|
||||||
/* block/track skip */
|
/* block/track skip */
|
||||||
do {
|
do {
|
||||||
|
int num_track = 0, channel_layout;
|
||||||
/* autodetect and skip macroblock header */
|
/* autodetect and skip macroblock header */
|
||||||
mta2_block_update(stream);
|
mta2_block_update(stream);
|
||||||
|
|
||||||
|
@ -112,8 +113,13 @@ void decode_mta2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||||
frame_size = read_16bitBE(stream->offset+0x06,stream->streamfile); /* not including this header */
|
frame_size = read_16bitBE(stream->offset+0x06,stream->streamfile); /* not including this header */
|
||||||
/* 0x08(8): null */
|
/* 0x08(8): null */
|
||||||
|
|
||||||
if (num_track < 0)
|
/* EOF: 0-fill buffer (or, as track_channels = 0 > divs by 0) */
|
||||||
break; /* EOF: whatever */
|
if (num_track < 0) {
|
||||||
|
for (i = 0; i < samples_to_do; i++)
|
||||||
|
outbuf[i * channelspacing] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
track_channels = 0;
|
track_channels = 0;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
|
|
|
@ -86,6 +86,38 @@ void decode_pcm16LE_XOR_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int chan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* decodes u-law (ITU G.711 non-linear PCM) */
|
||||||
|
void decode_ulaw(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
|
int i;
|
||||||
|
int32_t sample_count;
|
||||||
|
int sign, segment, quantization, sample;
|
||||||
|
const int bias = 0x84;
|
||||||
|
|
||||||
|
|
||||||
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
|
uint8_t ulawbyte = read_8bit(stream->offset+i,stream->streamfile);
|
||||||
|
|
||||||
|
ulawbyte = ~ulawbyte; /* stored in complement */
|
||||||
|
sign = (ulawbyte & 0x80);
|
||||||
|
segment = (ulawbyte & 0x70) >> 4; /* exponent */
|
||||||
|
quantization = ulawbyte & 0x0F; /* mantissa */
|
||||||
|
|
||||||
|
sample = (quantization << 3) + bias; /* add bias */
|
||||||
|
sample <<= segment;
|
||||||
|
sample = (sign) ? (bias - sample) : (sample - bias); /* remove bias */
|
||||||
|
|
||||||
|
#if 0 // the above follows Sun's implementation, but this works too
|
||||||
|
{
|
||||||
|
static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764}; /* precalcs from bias */
|
||||||
|
sample = exp_lut[segment] + (quantization << (segment + 3));
|
||||||
|
if (sign != 0) sample = -sample;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outbuf[sample_count] = sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample) {
|
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample) {
|
||||||
return bytes / channels / (bits_per_sample/8);
|
return bytes / channels / (bits_per_sample/8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,6 +283,7 @@ static const char* extension_list[] = {
|
||||||
"tun",
|
"tun",
|
||||||
"tydsp",
|
"tydsp",
|
||||||
|
|
||||||
|
"ulw",
|
||||||
"um3",
|
"um3",
|
||||||
|
|
||||||
"vag",
|
"vag",
|
||||||
|
@ -394,6 +395,7 @@ static const coding_info coding_info_list[] = {
|
||||||
{coding_PCM8_U_int, "8-bit unsigned PCM with 1 byte interleave"},
|
{coding_PCM8_U_int, "8-bit unsigned PCM with 1 byte interleave"},
|
||||||
{coding_PCM8_int, "8-bit PCM with 1 byte interleave"},
|
{coding_PCM8_int, "8-bit PCM with 1 byte interleave"},
|
||||||
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave"},
|
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave"},
|
||||||
|
{coding_ULAW, "8-bit u-Law"},
|
||||||
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
|
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
|
||||||
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM with exponential scale"},
|
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM with exponential scale"},
|
||||||
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM with fixed coefficients"},
|
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM with fixed coefficients"},
|
||||||
|
@ -515,6 +517,7 @@ static const layout_info layout_info_list[] = {
|
||||||
{layout_ivaud_blocked, "GTA IV blocked"},
|
{layout_ivaud_blocked, "GTA IV blocked"},
|
||||||
{layout_ps2_iab_blocked, "IAB blocked"},
|
{layout_ps2_iab_blocked, "IAB blocked"},
|
||||||
{layout_ps2_strlr_blocked, "The Bouncer STR blocked"},
|
{layout_ps2_strlr_blocked, "The Bouncer STR blocked"},
|
||||||
|
{layout_rws_blocked, "RWS blocked"},
|
||||||
{layout_tra_blocked, "TRA blocked"},
|
{layout_tra_blocked, "TRA blocked"},
|
||||||
{layout_acm, "ACM blocked"},
|
{layout_acm, "ACM blocked"},
|
||||||
{layout_mus_acm, "multiple ACM files, ACM blocked"},
|
{layout_mus_acm, "multiple ACM files, ACM blocked"},
|
||||||
|
@ -614,7 +617,7 @@ static const meta_info meta_info_list[] = {
|
||||||
{meta_XSS, "Dino Crisis 3 XSS File"},
|
{meta_XSS, "Dino Crisis 3 XSS File"},
|
||||||
{meta_HGC1, "Knights of the Temple 2 hgC1 Header"},
|
{meta_HGC1, "Knights of the Temple 2 hgC1 Header"},
|
||||||
{meta_AUS, "Capcom AUS Header"},
|
{meta_AUS, "Capcom AUS Header"},
|
||||||
{meta_RWS, "RWS Header"},
|
{meta_RWS, "RenderWare RWS header"},
|
||||||
{meta_EACS_PC, "EACS Header (PC)"},
|
{meta_EACS_PC, "EACS Header (PC)"},
|
||||||
{meta_EACS_PSX, "EACS Header (PSX)"},
|
{meta_EACS_PSX, "EACS Header (PSX)"},
|
||||||
{meta_EACS_SAT, "EACS Header (SATURN)"},
|
{meta_EACS_SAT, "EACS Header (SATURN)"},
|
||||||
|
@ -866,6 +869,7 @@ static const meta_info meta_info_list[] = {
|
||||||
{meta_TA_AAC_X360, "tri-Ace AAC (X360) header"},
|
{meta_TA_AAC_X360, "tri-Ace AAC (X360) header"},
|
||||||
{meta_TA_AAC_PS3, "tri-Ace AAC (PS3) header"},
|
{meta_TA_AAC_PS3, "tri-Ace AAC (PS3) header"},
|
||||||
{meta_PS3_MTA2, "Konami MTA2 header"},
|
{meta_PS3_MTA2, "Konami MTA2 header"},
|
||||||
|
{meta_NGC_ULW, "Criterion ULW raw header"},
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
||||||
|
|
|
@ -127,9 +127,12 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
||||||
case layout_ps2_iab_blocked:
|
case layout_ps2_iab_blocked:
|
||||||
ps2_iab_block_update(vgmstream->next_block_offset,vgmstream);
|
ps2_iab_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
break;
|
break;
|
||||||
case layout_ps2_strlr_blocked:
|
case layout_ps2_strlr_blocked:
|
||||||
ps2_strlr_block_update(vgmstream->next_block_offset,vgmstream);
|
ps2_strlr_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
break;
|
break;
|
||||||
|
case layout_rws_blocked:
|
||||||
|
rws_block_update(vgmstream->next_block_offset,vgmstream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ void ps2_iab_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void ps2_strlr_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
void ps2_strlr_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void rws_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
/* other layouts */
|
/* other layouts */
|
||||||
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "layout.h"
|
||||||
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
/* a simple headerless block with padding; configured in the main header */
|
||||||
|
void rws_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||||
|
int i;
|
||||||
|
size_t block_size;
|
||||||
|
size_t interleave;
|
||||||
|
|
||||||
|
/* no header; size is configured in the main header */
|
||||||
|
block_size = vgmstream->full_block_size;
|
||||||
|
interleave = vgmstream->interleave_block_size;
|
||||||
|
|
||||||
|
vgmstream->current_block_offset = block_offset;
|
||||||
|
vgmstream->next_block_offset = block_offset
|
||||||
|
+ block_size;
|
||||||
|
|
||||||
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
|
vgmstream->ch[i].offset = block_offset + interleave*i;
|
||||||
|
}
|
||||||
|
}
|
|
@ -672,4 +672,6 @@ VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps3_mta2(STREAMFILE *streamFile);
|
VGMSTREAM * init_vgmstream_ps3_mta2(STREAMFILE *streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ngc_ulw(STREAMFILE * streamFile);
|
||||||
|
|
||||||
#endif /*_META_H*/
|
#endif /*_META_H*/
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
|
/* ULW - headerless U-law, found in Burnout (GC) */
|
||||||
|
VGMSTREAM * init_vgmstream_ngc_ulw(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset;
|
||||||
|
int loop_flag = 0, channel_count;
|
||||||
|
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
if ( !check_extensions(streamFile,"ulw"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* raw data, the info is in the filename (really!) */
|
||||||
|
{
|
||||||
|
char* path;
|
||||||
|
char basename[PATH_LIMIT];
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
|
/* get base name */
|
||||||
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
|
path = strrchr(filename,DIR_SEPARATOR);
|
||||||
|
if (path!=NULL)
|
||||||
|
path = path+1;
|
||||||
|
else
|
||||||
|
path = filename;
|
||||||
|
strcpy(basename,path);
|
||||||
|
|
||||||
|
/* first letter gives the channels */
|
||||||
|
if (basename[0]=='M') /* Mono */
|
||||||
|
channel_count = 1;
|
||||||
|
else if (basename[0]=='S' || basename[0]=='D') /* Stereo/Dolby */
|
||||||
|
channel_count = 2;
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* not very robust but meh (other tracks don't loop) */
|
||||||
|
if (strcmp(basename,"MMenu.ulw")==0 || strcmp(basename,"DMenu.ulw")==0) {
|
||||||
|
loop_flag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->sample_rate = 32000;
|
||||||
|
vgmstream->coding_type = coding_ULAW;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = 0x01;
|
||||||
|
vgmstream->meta_type = meta_NGC_ULW;
|
||||||
|
vgmstream->num_samples = pcm_bytes_to_samples(get_streamfile_size(streamFile), channel_count, 8);
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = 0;
|
||||||
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_offset = 0;
|
||||||
|
|
||||||
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -1,103 +0,0 @@
|
||||||
#include "meta.h"
|
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* RWS (Silent Hill Origins, Ghost Rider, Max Payne 2) */
|
|
||||||
VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
int loop_flag = 0;
|
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("rws",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x0D080000)
|
|
||||||
goto fail;
|
|
||||||
#if 0
|
|
||||||
/* check if is used as container file */
|
|
||||||
if (read_32bitBE(0x38,streamFile) != 0x01000000)
|
|
||||||
goto fail;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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(0x50,streamFile);
|
|
||||||
vgmstream->channels = channel_count;
|
|
||||||
|
|
||||||
|
|
||||||
switch (read_32bitLE(0x38,streamFile)) {
|
|
||||||
case 0x01:
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0xE4,streamFile);
|
|
||||||
vgmstream->num_samples = read_32bitLE(0x98,streamFile)/16*28/vgmstream->channels;
|
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = 0;
|
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x98,streamFile)/16*28/vgmstream->channels;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
if (start_offset < 0x800) // Max Payne 2
|
|
||||||
{
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x178,streamFile);
|
|
||||||
vgmstream->num_samples = read_32bitLE(0x150,streamFile)/16*28/vgmstream->channels;
|
|
||||||
if (loop_flag)
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample = 0;
|
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x150,streamFile)/16*28/vgmstream->channels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Nana (2005)(Konami)
|
|
||||||
{
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x128,streamFile);
|
|
||||||
vgmstream->num_samples = read_32bitLE(0x7F8,streamFile)/16*28/vgmstream->channels;
|
|
||||||
if (loop_flag)
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample = 0;
|
|
||||||
vgmstream->loop_end_sample = read_32bitLE(0x7F8,streamFile)/16*28/vgmstream->channels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_PSX;
|
|
||||||
|
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
|
||||||
vgmstream->interleave_block_size = read_32bitLE(0x4C,streamFile)/2;
|
|
||||||
vgmstream->meta_type = meta_RWS;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
vgmstream->ch[i].channel_start_offset=
|
|
||||||
vgmstream->ch[i].offset=start_offset+
|
|
||||||
vgmstream->interleave_block_size*i;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -253,7 +253,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
else if (!strcasecmp("sns",filename_extension(filename)))
|
else if (!strcasecmp("sns",filename_extension(filename)))
|
||||||
sns = 1;
|
sns = 1;
|
||||||
#if defined(VGM_USE_MAIATRAC3PLUS) || defined(VGM_USE_FFMPEG)
|
#if defined(VGM_USE_MAIATRAC3PLUS) || defined(VGM_USE_FFMPEG)
|
||||||
else if (!strcasecmp("at3",filename_extension(filename)))
|
else if ( check_extensions(streamFile, "at3,rws") ) /* Renamed .RWS AT3 found in Climax games (Silent Hill Origins PSP, Oblivion PSP) */
|
||||||
at3 = 1;
|
at3 = 1;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
#include "../layout/layout.h"
|
||||||
|
|
||||||
|
|
||||||
|
static off_t get_rws_string_size(off_t off, STREAMFILE *streamFile);
|
||||||
|
|
||||||
|
|
||||||
|
/* RWS - RenderWare Stream (from games using RenderWare Audio middleware) */
|
||||||
|
VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset, off, coefs_offset = 0, stream_offset = 0;
|
||||||
|
int loop_flag = 0, channel_count, codec;
|
||||||
|
size_t file_size, header_size, data_size, stream_size = 0, info_size;
|
||||||
|
int block_size_max = 0, block_size = 0, sample_rate;
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||||
|
int i, total_segments, total_streams, target_stream = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (!check_extensions(streamFile,"rws"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* check chunks (always LE) */
|
||||||
|
/* Made of a file chunk with header and data chunks (other chunks exist for non-audio .RWS).
|
||||||
|
* A chunk is: id, size, RW version (no real diffs), data of size (version is repeated but same for all chunks).
|
||||||
|
* Version: 16b main + 16b build (can vary between files) ex: 0c02, 1003, 1400 = 3.5, 1803 = 3.6, 1C02 = 3.7. */
|
||||||
|
if (read_32bitLE(0x00,streamFile) != 0x0000080d) /* audio file chunk id */
|
||||||
|
goto fail;
|
||||||
|
file_size = read_32bitLE(0x04,streamFile); /* audio file chunk size */
|
||||||
|
if (file_size + 0x0c != get_streamfile_size(streamFile)) goto fail;
|
||||||
|
|
||||||
|
if (read_32bitLE(0x0c,streamFile) != 0x0000080e) /* header chunk id */
|
||||||
|
goto fail;
|
||||||
|
header_size = read_32bitLE(0x10,streamFile); /* header chunk size */
|
||||||
|
|
||||||
|
off = 0x0c + 0x0c + header_size;
|
||||||
|
if (read_32bitLE(off+0x00,streamFile) != 0x0000080f) /* data chunk id */
|
||||||
|
goto fail;
|
||||||
|
data_size = read_32bitLE(off+0x04,streamFile); /* data chunk size */
|
||||||
|
if (data_size+0x0c + off != get_streamfile_size(streamFile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* inside header chunk (many unknown fields are probably IDs/config, as two same-sized files vary a lot) */
|
||||||
|
off = 0x0c + 0x0c;
|
||||||
|
|
||||||
|
/* 0x00: actual header size (less than chunk size), useful to check endianness (Wii/X360 = BE) */
|
||||||
|
read_32bit = (read_32bitLE(off+0x00,streamFile) > header_size) ? read_32bitBE : read_32bitLE;
|
||||||
|
|
||||||
|
/* 0x04-14: sizes of various sections?, others: ? */
|
||||||
|
total_segments = read_32bit(off+0x20,streamFile);
|
||||||
|
total_streams = read_32bit(off+0x28,streamFile);
|
||||||
|
/* 0x2c: unk, 0x30: 0x800?, 0x34: max block size?, 0x38: data offset, 0x3c: 0?, 0x40-50: file uuid? */
|
||||||
|
off += 0x50 + get_rws_string_size(off+0x50, streamFile); /* skip audio file name */
|
||||||
|
|
||||||
|
/* check streams/segments */
|
||||||
|
/* Data can be divided into segments (cues/divisions within data, ex. intro+main, voice1+2+..N) or
|
||||||
|
* tracks/streams in interleaved blocks that can contain padding and don't need to match between tracks
|
||||||
|
* (ex 0x1800 data + 0 pad of stream_0 2ch, 0x1800 data + 0x200 pad of stream1 2ch, etc). */
|
||||||
|
if (target_stream == 0) target_stream = 1;
|
||||||
|
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail;
|
||||||
|
|
||||||
|
/* skip segment stuff and get stream size (from sizes for all segments, repeated per track) */
|
||||||
|
off += 0x20 * total_segments; /* segment data (mostly unknown except @ 0x18: full data size, 0x1c: offset) */
|
||||||
|
for (i = 0; i < total_segments; i++) { /* sum usable segment sizes (no padding) */
|
||||||
|
stream_size += read_32bit(off + 0x04 * i + total_segments*(target_stream-1),streamFile);
|
||||||
|
}
|
||||||
|
off += 0x04 * (total_segments * total_streams);
|
||||||
|
off += 0x10 * total_segments; /* segment uuids? */
|
||||||
|
for (i = 0; i < total_segments; i++) { /* skip segments names */
|
||||||
|
off += get_rws_string_size(off, streamFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get stream layout: 0xc: samples per frame (ex. 28 in VAG), 0x24: offset within data chunk, others: ? */
|
||||||
|
/* get block_size for our target stream and from all streams, to skip their blocks during decode */
|
||||||
|
for (i = 0; i < total_streams; i++) { /* get block_sizes */
|
||||||
|
block_size_max += read_32bit(off+0x10 + 0x28*i,streamFile); /* includes padding and can be different per stream */
|
||||||
|
if (target_stream-1 == i) {
|
||||||
|
block_size = read_32bit(off+0x20 + 0x28*i,streamFile); /* actual size */
|
||||||
|
stream_offset = read_32bit(off+0x24 + 0x28*i,streamFile); /* within data */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off += 0x28 * total_streams;
|
||||||
|
|
||||||
|
/* get stream config: 0x0c(1): bits per sample, others: ? */
|
||||||
|
info_size = total_streams > 1 ? 0x30 : 0x2c; //todo this doesn't look right
|
||||||
|
sample_rate = read_32bit(off+0x00 + info_size*(target_stream-1),streamFile);
|
||||||
|
//unk_size = read_32bit(off+0x08 + info_size*(target_stream-1),streamFile); /* segment size? loop-related? */
|
||||||
|
channel_count = read_8bit(off+0x0d + info_size*(target_stream-1),streamFile);
|
||||||
|
codec = read_32bitBE(off+0x1c + info_size*(target_stream-1),streamFile); /* uuid of 128b but the first is enough */
|
||||||
|
off += info_size * total_streams;
|
||||||
|
|
||||||
|
|
||||||
|
/* if codec is DSP there is an extra field */
|
||||||
|
if (codec == 0xF86215B0) {
|
||||||
|
/* 0x00: approx num samples? 0x04: approx size? */
|
||||||
|
coefs_offset = off + 0x1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* next is 0x14 * streams = ?(4) + uuid? (header ends), rest is garbage/padding until chunk end (may contain strings and weird stuff) */
|
||||||
|
|
||||||
|
start_offset = 0x0c + 0x0c + header_size + 0x0c + stream_offset; /* usually 0x800 but not always */
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_RWS;
|
||||||
|
vgmstream->sample_rate = sample_rate;
|
||||||
|
vgmstream->num_streams = total_streams;
|
||||||
|
|
||||||
|
vgmstream->layout_type = layout_rws_blocked;
|
||||||
|
vgmstream->current_block_size = block_size / vgmstream->channels;
|
||||||
|
vgmstream->full_block_size = block_size_max;
|
||||||
|
|
||||||
|
switch(codec) {
|
||||||
|
case 0xD01BD217: /* PCM X360 (D01BD217 35874EED B9D9B8E8 6EA9B995) */
|
||||||
|
/* The Legend of Spyro (X360) */
|
||||||
|
vgmstream->coding_type = coding_PCM16BE;
|
||||||
|
//vgmstream->interleave_block_size = block_size / 2; //0x2; //todo 2ch PCM not working correctly (interleaved PCM not ok?)
|
||||||
|
|
||||||
|
vgmstream->num_samples = pcm_bytes_to_samples(stream_size, channel_count, 16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x9897EAD9: /* PS-ADPCM PS2 (9897EAD9 BCBB7B44 96B26547 59102E16) */
|
||||||
|
/* ex. Silent Hill Origins (PS2), Ghost Rider (PS2), Max Payne 2 (PS2), Nana (PS2) */
|
||||||
|
vgmstream->coding_type = coding_PSX;
|
||||||
|
vgmstream->interleave_block_size = block_size / 2;
|
||||||
|
|
||||||
|
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channel_count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xF86215B0: /* DSP Wii (F86215B0 31D54C29 BD37CDBF 9BD10C53) */
|
||||||
|
/* ex. Alice in Wonderland (Wii) */
|
||||||
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
|
vgmstream->interleave_block_size = block_size / 2;
|
||||||
|
|
||||||
|
/* get coefs (all channels share them so 0 spacing; also seem fixed for all RWS) */
|
||||||
|
dsp_read_coefs_be(vgmstream,streamFile,coefs_offset, 0);
|
||||||
|
|
||||||
|
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) */
|
||||||
|
/* 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->num_samples = ms_ima_bytes_to_samples(stream_size, 0x48, channel_count);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
VGM_LOG("RSW: unknown codec 0x%08x\n", codec);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
rws_block_update(start_offset, vgmstream); /* block init */
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* rws-strings are null-terminated then padded to 0x10 (weirdly the padding contains garbage) */
|
||||||
|
static off_t get_rws_string_size(off_t off, STREAMFILE *streamFile) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 0x800; i++) { /* 0x800=arbitrary max */
|
||||||
|
if (read_8bit(off+i,streamFile) == 0) { /* null terminator */
|
||||||
|
return i + (0x10 - (i % 0x10)); /* size is padded */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE *streamFile) {
|
||||||
/* miniheader over a common header with some tweaks, so we'll simplify parsing */
|
/* miniheader over a common header with some tweaks, so we'll simplify parsing */
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 0x50533200: /* "PS2\0" */
|
case 0x50533200: /* "PS2\0" */
|
||||||
if (read_32bitBE(0x40,streamFile) != 0x56414770) goto fail; /* "VAGp" */
|
if (read_32bitBE(0x40,streamFile) != 0x56414770) goto fail; /* mutant "VAGp" (long header size) */
|
||||||
|
|
||||||
start_offset = 0x800;
|
start_offset = 0x800;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x50, streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x50, streamFile);
|
||||||
|
@ -48,22 +48,24 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE *streamFile) {
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x8000;
|
vgmstream->interleave_block_size = 0x8000;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x58420000: /* "XB\0\0" */
|
|
||||||
if (read_32bitBE(0x40,streamFile) != 0x52494646) goto fail; /* "RIFF" */
|
|
||||||
|
|
||||||
start_offset = 0x70;
|
case 0x58420000: /* "XB\0\0" */
|
||||||
|
if (read_32bitBE(0x40,streamFile) != 0x52494646) goto fail; /* mutant "RIFF" (sometimes wrong RIFF size) */
|
||||||
|
|
||||||
|
/* start offset: find "data" chunk, as sometimes there is a "smpl" chunk at the start or the end (same as loop_start/end) */
|
||||||
|
if (!find_chunk_le(streamFile, 0x64617461, 0x4c, 0, &start_offset, NULL) )
|
||||||
|
goto fail;
|
||||||
|
|
||||||
vgmstream->sample_rate = read_32bitLE(0x58, streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x58, streamFile);
|
||||||
vgmstream->num_samples = ms_ima_bytes_to_samples(read_32bitLE(0x6c, streamFile), read_16bitLE(0x60, streamFile), channel_count);
|
vgmstream->num_samples = ms_ima_bytes_to_samples(read_32bitLE(start_offset-4, streamFile), read_16bitLE(0x60, streamFile), channel_count);
|
||||||
vgmstream->loop_start_sample = loop_start;
|
vgmstream->loop_start_sample = loop_start;
|
||||||
vgmstream->loop_end_sample = loop_end;
|
vgmstream->loop_end_sample = loop_end;
|
||||||
/* there is also a "smpl" chunk at the end, same as loop_start/end */
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_XBOX;
|
vgmstream->coding_type = coding_XBOX;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,8 @@ int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) {
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
const char * ext = NULL;
|
const char * ext = NULL;
|
||||||
const char * cmp_ext = NULL;
|
const char * cmp_ext = NULL;
|
||||||
int ext_len, cmp_len;
|
const char * ststr_res = NULL;
|
||||||
|
size_t ext_len, cmp_len;
|
||||||
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
ext = filename_extension(filename);
|
ext = filename_extension(filename);
|
||||||
|
@ -493,14 +494,15 @@ int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) {
|
||||||
|
|
||||||
cmp_ext = cmp_exts;
|
cmp_ext = cmp_exts;
|
||||||
do {
|
do {
|
||||||
cmp_len = strstr(cmp_ext, ",") - cmp_ext; /* find next ext; becomes negative if not found */
|
ststr_res = strstr(cmp_ext, ",");
|
||||||
if (cmp_len < 0)
|
cmp_len = ststr_res == NULL
|
||||||
cmp_len = strlen(cmp_ext); /* total length if more not found */
|
? strlen(cmp_ext) /* total length if more not found */
|
||||||
|
: (intptr_t)ststr_res - (intptr_t)cmp_ext; /* find next ext; ststr_res should always be greater than cmp_ext, resulting in a positive cmp_len */
|
||||||
|
|
||||||
if (strncasecmp(ext,cmp_ext, ext_len) == 0 && ext_len == cmp_len)
|
if (ext_len == cmp_len && strncasecmp(ext,cmp_ext, ext_len) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
cmp_ext = strstr(cmp_ext, ",");
|
cmp_ext = ststr_res;
|
||||||
if (cmp_ext != NULL)
|
if (cmp_ext != NULL)
|
||||||
cmp_ext = cmp_ext + 1; /* skip comma */
|
cmp_ext = cmp_ext + 1; /* skip comma */
|
||||||
|
|
||||||
|
|
|
@ -361,6 +361,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||||
init_vgmstream_ta_aac_x360,
|
init_vgmstream_ta_aac_x360,
|
||||||
init_vgmstream_ta_aac_ps3,
|
init_vgmstream_ta_aac_ps3,
|
||||||
init_vgmstream_ps3_mta2,
|
init_vgmstream_ps3_mta2,
|
||||||
|
init_vgmstream_ngc_ulw,
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
init_vgmstream_mp4_aac_ffmpeg,
|
init_vgmstream_mp4_aac_ffmpeg,
|
||||||
|
@ -935,7 +936,8 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||||
case layout_dsp_bdsp_blocked:
|
case layout_dsp_bdsp_blocked:
|
||||||
case layout_tra_blocked:
|
case layout_tra_blocked:
|
||||||
case layout_ps2_iab_blocked:
|
case layout_ps2_iab_blocked:
|
||||||
case layout_ps2_strlr_blocked:
|
case layout_ps2_strlr_blocked:
|
||||||
|
case layout_rws_blocked:
|
||||||
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
||||||
break;
|
break;
|
||||||
case layout_interleave_byte:
|
case layout_interleave_byte:
|
||||||
|
@ -979,6 +981,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||||
case coding_PCM8_int:
|
case coding_PCM8_int:
|
||||||
case coding_PCM8_SB_int:
|
case coding_PCM8_SB_int:
|
||||||
case coding_PCM8_U_int:
|
case coding_PCM8_U_int:
|
||||||
|
case coding_ULAW:
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
case coding_ogg_vorbis:
|
case coding_ogg_vorbis:
|
||||||
case coding_fsb_vorbis:
|
case coding_fsb_vorbis:
|
||||||
|
@ -1136,6 +1139,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||||
case coding_PCM8_int:
|
case coding_PCM8_int:
|
||||||
case coding_PCM8_SB_int:
|
case coding_PCM8_SB_int:
|
||||||
case coding_PCM8_U_int:
|
case coding_PCM8_U_int:
|
||||||
|
case coding_ULAW:
|
||||||
case coding_SDX2:
|
case coding_SDX2:
|
||||||
case coding_SDX2_int:
|
case coding_SDX2_int:
|
||||||
case coding_CBD2:
|
case coding_CBD2:
|
||||||
|
@ -1356,6 +1360,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||||
samples_to_do);
|
samples_to_do);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case coding_ULAW:
|
||||||
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
|
decode_ulaw(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||||
|
vgmstream->channels,vgmstream->samples_into_block,
|
||||||
|
samples_to_do);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case coding_NDS_IMA:
|
case coding_NDS_IMA:
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
decode_nds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
decode_nds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||||
|
|
|
@ -91,6 +91,7 @@ typedef enum {
|
||||||
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
||||||
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0) with sample-level interleave */
|
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0) with sample-level interleave */
|
||||||
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement) with sample-level interleave */
|
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement) with sample-level interleave */
|
||||||
|
coding_ULAW, /* 8-bit u-Law (non-linear PCM) */
|
||||||
|
|
||||||
/* 4-bit ADPCM */
|
/* 4-bit ADPCM */
|
||||||
coding_CRI_ADX, /* CRI ADX */
|
coding_CRI_ADX, /* CRI ADX */
|
||||||
|
@ -242,6 +243,7 @@ typedef enum {
|
||||||
layout_tra_blocked, /* DefJam Rapstar .tra blocks */
|
layout_tra_blocked, /* DefJam Rapstar .tra blocks */
|
||||||
layout_ps2_iab_blocked,
|
layout_ps2_iab_blocked,
|
||||||
layout_ps2_strlr_blocked,
|
layout_ps2_strlr_blocked,
|
||||||
|
layout_rws_blocked,
|
||||||
|
|
||||||
/* otherwise odd */
|
/* otherwise odd */
|
||||||
layout_acm, /* libacm layout */
|
layout_acm, /* libacm layout */
|
||||||
|
@ -347,7 +349,7 @@ typedef enum {
|
||||||
meta_SL3, /* Test Drive Unlimited */
|
meta_SL3, /* Test Drive Unlimited */
|
||||||
meta_HGC1, /* Knights of the Temple 2 */
|
meta_HGC1, /* Knights of the Temple 2 */
|
||||||
meta_AUS, /* Various Capcom games */
|
meta_AUS, /* Various Capcom games */
|
||||||
meta_RWS, /* Various Konami games */
|
meta_RWS, /* RenderWare games (only when using RW Audio middleware) */
|
||||||
meta_FSB1, /* FMOD Sample Bank, version 1 */
|
meta_FSB1, /* FMOD Sample Bank, version 1 */
|
||||||
meta_FSB2, /* FMOD Sample Bank, version 2 */
|
meta_FSB2, /* FMOD Sample Bank, version 2 */
|
||||||
meta_FSB3, /* FMOD Sample Bank, version 3.0/3.1 */
|
meta_FSB3, /* FMOD Sample Bank, version 3.0/3.1 */
|
||||||
|
@ -625,6 +627,7 @@ typedef enum {
|
||||||
meta_TA_AAC_X360, /* tri-ace AAC (Star Ocean 4, End of Eternity, Infinite Undiscovery) */
|
meta_TA_AAC_X360, /* tri-ace AAC (Star Ocean 4, End of Eternity, Infinite Undiscovery) */
|
||||||
meta_TA_AAC_PS3, /* tri-ace AAC (Star Ocean International, Resonance of Fate) */
|
meta_TA_AAC_PS3, /* tri-ace AAC (Star Ocean International, Resonance of Fate) */
|
||||||
meta_PS3_MTA2, /* Metal Gear Solid 4 MTA2 */
|
meta_PS3_MTA2, /* Metal Gear Solid 4 MTA2 */
|
||||||
|
meta_NGC_ULW, /* Burnout 1 (GC only) */
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
meta_OGG_VORBIS, /* Ogg Vorbis */
|
meta_OGG_VORBIS, /* Ogg Vorbis */
|
||||||
|
@ -732,9 +735,11 @@ typedef struct {
|
||||||
size_t interleave_smallblock_size; /* smaller interleave for last block */
|
size_t interleave_smallblock_size; /* smaller interleave for last block */
|
||||||
/* headered blocks */
|
/* headered blocks */
|
||||||
off_t current_block_offset; /* start of this block (offset of block header) */
|
off_t current_block_offset; /* start of this block (offset of block header) */
|
||||||
size_t current_block_size; /* size of the block we're in now */
|
size_t current_block_size; /* size of the block we're in now (usable data) */
|
||||||
|
size_t full_block_size; /* size including padding and other unusable data */
|
||||||
off_t next_block_offset; /* offset of header of the next block */
|
off_t next_block_offset; /* offset of header of the next block */
|
||||||
int block_count; /* count of "semi" block in total block */
|
int block_count; /* count of "semi" block in total block */
|
||||||
|
|
||||||
|
|
||||||
/* loop layout (saved values) */
|
/* loop layout (saved values) */
|
||||||
int32_t loop_sample; /* saved from current_sample, should be loop_start_sample... */
|
int32_t loop_sample; /* saved from current_sample, should be loop_start_sample... */
|
||||||
|
|
Loading…
Reference in New Issue