Updated VGMStream to r1050-2579-gcce259d4-72-g2ac2c0ce

This commit is contained in:
Christopher Snowhill 2019-11-23 20:33:45 -08:00
parent b6ed264b32
commit 319eb84744
9 changed files with 246 additions and 143 deletions

View file

@ -417,7 +417,6 @@
836F704418BDC2190095E648 /* ws_aud.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0818BDC2190095E648 /* ws_aud.c */; };
836F704518BDC2190095E648 /* wvs.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0918BDC2190095E648 /* wvs.c */; };
836F704618BDC2190095E648 /* x360_tra.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0A18BDC2190095E648 /* x360_tra.c */; };
836F704718BDC2190095E648 /* xbox_hlwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0B18BDC2190095E648 /* xbox_hlwav.c */; };
836F704818BDC2190095E648 /* xbox_ims.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0C18BDC2190095E648 /* xbox_ims.c */; };
836F704E18BDC2190095E648 /* xss.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1218BDC2190095E648 /* xss.c */; };
836F704F18BDC2190095E648 /* xwb.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1318BDC2190095E648 /* xwb.c */; };
@ -545,7 +544,7 @@
83C7282022BC893D00678B4A /* dcs_wav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C7280C22BC893D00678B4A /* dcs_wav.c */; };
83C7282122BC893D00678B4A /* msf_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C7280D22BC893D00678B4A /* msf_konami.c */; };
83C7282222BC893D00678B4A /* mta2_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C7280E22BC893D00678B4A /* mta2_streamfile.h */; };
83C7282722BC8C1500678B4A /* plugins.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C7282322BC8C1300678B4A /* plugins.h */; };
83C7282722BC8C1500678B4A /* plugins.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C7282322BC8C1300678B4A /* plugins.h */; settings = {ATTRIBUTES = (Public, ); }; };
83C7282822BC8C1500678B4A /* mixing.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C7282422BC8C1400678B4A /* mixing.h */; };
83C7282922BC8C1500678B4A /* mixing.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C7282522BC8C1400678B4A /* mixing.c */; };
83C7282A22BC8C1500678B4A /* plugins.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C7282622BC8C1400678B4A /* plugins.c */; };
@ -1105,7 +1104,6 @@
836F6F0818BDC2190095E648 /* ws_aud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ws_aud.c; sourceTree = "<group>"; };
836F6F0918BDC2190095E648 /* wvs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wvs.c; sourceTree = "<group>"; };
836F6F0A18BDC2190095E648 /* x360_tra.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360_tra.c; sourceTree = "<group>"; };
836F6F0B18BDC2190095E648 /* xbox_hlwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xbox_hlwav.c; sourceTree = "<group>"; };
836F6F0C18BDC2190095E648 /* xbox_ims.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xbox_ims.c; sourceTree = "<group>"; };
836F6F1218BDC2190095E648 /* xss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xss.c; sourceTree = "<group>"; };
836F6F1318BDC2190095E648 /* xwb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwb.c; sourceTree = "<group>"; };
@ -1917,7 +1915,6 @@
833A7A2D1ED11961003EC53E /* xau.c */,
837CEAEE23487F2C00E62A4A /* xavs_streamfile.h */,
837CEAE423487F2A00E62A4A /* xavs.c */,
836F6F0B18BDC2190095E648 /* xbox_hlwav.c */,
836F6F0C18BDC2190095E648 /* xbox_ims.c */,
8350C0541E071881009E0A93 /* xma.c */,
834FE0DC215C79EA000A5D3D /* xmd.c */,
@ -1987,6 +1984,7 @@
83A21F87201D8981000F04B9 /* fsb_keys.h in Headers */,
834FE0EC215C79ED000A5D3D /* kma9_streamfile.h in Headers */,
8349A90F1FE6258200E26435 /* aix_streamfile.h in Headers */,
83C7282722BC8C1500678B4A /* plugins.h in Headers */,
834FE0ED215C79ED000A5D3D /* fsb_interleave_streamfile.h in Headers */,
8351F32E2212B57000A606E4 /* ubi_bao_streamfile.h in Headers */,
8349A9111FE6258200E26435 /* bar_streamfile.h in Headers */,
@ -2020,7 +2018,6 @@
834FE0B5215C798C000A5D3D /* acm_decoder_libacm.h in Headers */,
839E21E61F2EDAF100EE54D7 /* vorbis_custom_data_wwise.h in Headers */,
834FE103215C79ED000A5D3D /* ea_schl_streamfile.h in Headers */,
83C7282722BC8C1500678B4A /* plugins.h in Headers */,
83F0AA6021E2028C004BBC04 /* vsv_streamfile.h in Headers */,
83FBD506235D31F800D35BCD /* riff_ogg_streamfile.h in Headers */,
48C2650F1A5D420800A0A3D6 /* vorbisfile.h in Headers */,
@ -2622,7 +2619,6 @@
834FE0EE215C79ED000A5D3D /* ue4opus.c in Sources */,
836F6FEA18BDC2190095E648 /* ps2_msa.c in Sources */,
836F6F3618BDC2190095E648 /* ogg_vorbis_decoder.c in Sources */,
836F704718BDC2190095E648 /* xbox_hlwav.c in Sources */,
8306B0E520984590000302D4 /* ubi_lyn.c in Sources */,
836F6F7618BDC2190095E648 /* brstm.c in Sources */,
836F700718BDC2190095E648 /* ps2_vgv.c in Sources */,

View file

@ -191,7 +191,6 @@ static const char* extension_list[] = {
"hdr",
"hgc1",
"his",
"hlwav",
"hps",
"hsf",
"hx2",
@ -1028,7 +1027,7 @@ static const meta_info meta_info_list[] = {
{meta_EXAKT_SC, "assumed Activision / EXAKT SC by extension"},
{meta_WII_BNS, "Nintendo BNS header"},
{meta_WII_WAS, "Sumo Digital iSWS header"},
{meta_XBOX_HLWAV, "Half Life 2 bgm header"},
{meta_XBOX_HLWAV, "Half-Life 2 .WAV header"},
{meta_MYSPD, "U-Sing .MYSPD header"},
{meta_HIS, "Her Interactive HIS header"},
{meta_PS2_AST, "KOEI AST header"},

View file

@ -561,8 +561,8 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE *streamFile, int track, int num_
int i, j;
size_t file_len, map_len;
/* if there's only one track, try opening MUS with the same name first (most common scenario) */
if (num_tracks == 1) {
/* if loading the first track, try opening MUS with the same name first (most common scenario) */
if (track == 0) {
musFile = open_streamfile_by_ext(streamFile, "mus");
if (musFile) return musFile;
}
@ -573,27 +573,40 @@ static STREAMFILE *open_mapfile_pair(STREAMFILE *streamFile, int track, int num_
for (i = 0; i < pair_count; i++) {
const char *map_name = mapfile_pairs[i][0];
const char *mus_name = mapfile_pairs[i][1];
char buf[PATH_LIMIT] = {0};
char buf[PATH_LIMIT] = { 0 };
char *pch;
int use_mask = 0;
map_len = strlen(map_name);
/* replace map_name with expected mus_name */
if (file_len < map_len)
continue;
if (strncasecmp(file_name + (file_len - map_len), map_name, map_len) != 0)
continue;
strncpy(buf, mus_name, map_len);
if (map_name[0] == '*') {
use_mask = 1;
map_name++;
map_len--;
if (strncmp(file_name + (file_len - map_len), map_name, map_len) != 0)
continue;
} else {
if (strcmp(file_name, map_name) != 0)
continue;
}
strncpy(buf, mus_name, PATH_LIMIT);
pch = strtok(buf, ","); //TODO: not thread safe in std C
for (j = 0; j < track && pch; j++) {
pch = strtok(NULL, ",");
}
if (!pch) continue; /* invalid track */
if (!pch)
continue;
if (use_mask) {
file_name[file_len - map_len] = '\0';
strcat(file_name, pch);
strncat(file_name, pch + 1, PATH_LIMIT);
} else {
strncpy(file_name, pch, PATH_LIMIT);
}
musFile = open_streamfile_by_filename(streamFile, file_name);
if (musFile) return musFile;

View file

@ -626,7 +626,8 @@ fail:
static STREAMFILE* open_mapfile_pair(STREAMFILE *streamFile, int track, int num_tracks) {
static const char *const mapfile_pairs[][2] = {
/* standard cases, replace map part with mus part (from the end to preserve prefixes) */
{"mus_ctrl.mpf", "mus_str.mus"}, /* GoldenEye - Rogue Agent */
{"MUS_CTRL.MPF", "MUS_STR.MUS"}, /* GoldenEye - Rogue Agent (PS2) */
{"mus_ctrl.mpf", "mus_str.mus"}, /* GoldenEye - Rogue Agent (others) */
{"AKA_Mus.mpf", "Track.mus"}, /* Boogie */
{"SSX4.mpf", "moments0.mus,main.mus,load_loop0.mus"}, /* SSX Blur */
{"willow.mpf", "willow.mus,willow_o.mus"}, /* Harry Potter and the Chamber of Secrets */
@ -634,16 +635,21 @@ static STREAMFILE* open_mapfile_pair(STREAMFILE *streamFile, int track, int num_
{"Peak1Amb.mpf", "Peak1_Strm.mus,Peak1_Ovr0.mus"}, /* SSX 3 */
{"Peak2Amb.mpf", "Peak2_Strm.mus,Peak2_Ovr0.mus"},
{"Peak3Amb.mpf", "Peak3_Strm.mus,Peak3_Ovr0.mus"},
{".mpf", "_main.mus"}, /* 007 - Everything or Nothing */
//TODO: improve pairs (needs better wildcard support)
//NSF2:
/* ZTRxxROK.MAP > ZTRxx.TRJ */
/* ZTRxxTEC.MAP > ZTRxx.TRM */
/* ZZSHOW.MAP and ZZSHOW2.MAP > ZZSHOW.MUS */
//NSF3:
/* ZTRxxROK.MAP > ZZZTRxxA.TRJ */
/* ZTRxxTEC.MAP > ZZZTRxxB.TRM */
/* other extra files that may need the hack below */
{"*.mpf", "*_main.mus"}, /* 007 - Everything or Nothing */
/* TODO: need better wildcard support
* NSF2:
* ZTRxxROK.MAP > ZTRxx.TRJ
* ZTRxxTEC.MAP > ZTRxx.TRM
* ZZSHOW.MAP and ZZSHOW2.MAP > ZZSHOW.MUS
* NSF3:
* ZTRxxROK.MAP > ZZZTRxxA.TRJ
* ZTRxxTEC.MAP > ZZZTRxxB.TRM
* ZTR00R0A.MAP and ZTR00R0B.MAP > ZZZTR00A.TRJ
* other extra files that may need the hack below
* SSX 3:
* *.mpf > *.mus,xxloops0.mus
* really need to think of something for this
*/
};
STREAMFILE *musFile = NULL;
char file_name[PATH_LIMIT];
@ -651,8 +657,8 @@ static STREAMFILE* open_mapfile_pair(STREAMFILE *streamFile, int track, int num_
int i, j;
size_t file_len, map_len;
/* if there's only one track, try opening MUS with the same name first (most common scenario) */
if (num_tracks == 1) {
/* if loading the first track, try opening MUS with the same name first (most common scenario) */
if (track == 0) {
musFile = open_streamfile_by_ext(streamFile, "mus");
if (musFile) return musFile;
}
@ -665,25 +671,38 @@ static STREAMFILE* open_mapfile_pair(STREAMFILE *streamFile, int track, int num_
const char *mus_name = mapfile_pairs[i][1];
char buf[PATH_LIMIT] = {0};
char *pch;
int use_mask = 0;
map_len = strlen(map_name);
/* replace map_name with expected mus_name */
if (file_len < map_len)
continue;
if (strncasecmp(file_name + (file_len - map_len), map_name, map_len) != 0)
continue;
strncpy(buf, mus_name, map_len);
if (map_name[0] == '*') {
use_mask = 1;
map_name++;
map_len--;
if (strcmp(file_name + (file_len - map_len), map_name) != 0)
continue;
} else {
if (strcmp(file_name, map_name) != 0)
continue;
}
strncpy(buf, mus_name, PATH_LIMIT);
pch = strtok(buf, ","); //TODO: not thread safe in std C
for (j = 0; j < track && pch; j++) {
pch = strtok(NULL, ",");
}
if (!pch) continue; /* invalid track */
if (!pch)
continue;
if (use_mask) {
file_name[file_len - map_len] = '\0';
strcat(file_name, pch);
strncat(file_name, pch + 1, PATH_LIMIT);
} else {
strncpy(file_name, pch, PATH_LIMIT);
}
musFile = open_streamfile_by_filename(streamFile, file_name);
if (musFile) return musFile;

View file

@ -5,8 +5,8 @@
VGMSTREAM * init_vgmstream_mib_mih(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * streamHeader = NULL;
off_t start_offset;
size_t data_size, frame_size, frame_last, frame_count;
off_t header_offset, start_offset;
size_t data_size, frame_size, frame_last, frame_count, name_size;
int channel_count, loop_flag, sample_rate;
/* check extension */
@ -16,18 +16,28 @@ VGMSTREAM * init_vgmstream_mib_mih(STREAMFILE *streamFile) {
streamHeader = open_streamfile_by_ext(streamFile,"mih");
if (!streamHeader) goto fail;
if (read_32bitBE(0x00,streamHeader) != 0x40000000) /* header size */
header_offset = 0x00;
if (read_32bitLE(0x00,streamHeader) != 0x40) { /* header size */
name_size = read_32bitLE(0x00, streamHeader);
if (read_32bitLE(0x04 + name_size, streamHeader) == 0x40 &&
read_32bitLE(0x04 + name_size + 0x04, streamHeader) == 0x40) {
/* Marc Ecko's Getting Up (PS2) has a name at the start */
header_offset = 0x04 + name_size + 0x04;
} else {
goto fail;
}
}
loop_flag = 0; /* MIB+MIH don't loop (nor use PS-ADPCM flags) per spec */
start_offset = 0x00;
/* 0x04: padding size (always 0x20, MIH header must be multiple of 0x40) */
frame_last = (uint32_t)read_32bitLE(0x05,streamHeader) & 0x00FFFFFF; /* 24b */
channel_count = read_32bitLE(0x08,streamHeader);
sample_rate = read_32bitLE(0x0c,streamHeader);
frame_size = read_32bitLE(0x10,streamHeader);
frame_count = read_32bitLE(0x14,streamHeader);
frame_last = (uint32_t)read_32bitLE(header_offset + 0x05,streamHeader) & 0x00FFFFFF; /* 24b */
channel_count = read_32bitLE(header_offset + 0x08,streamHeader);
sample_rate = read_32bitLE(header_offset + 0x0c,streamHeader);
frame_size = read_32bitLE(header_offset + 0x10,streamHeader);
frame_count = read_32bitLE(header_offset + 0x14,streamHeader);
if (frame_count == 0) { /* rarely [Gladius (PS2)] */
frame_count = get_streamfile_size(streamFile) / (frame_size * channel_count);
}

View file

@ -212,17 +212,30 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
if (!config_sb_version(&sb, streamFile))
goto fail;
if (sb.version <= 0x0000000B) {
sb.section1_num = read_32bit(0x04, streamFile);
sb.section2_num = read_32bit(0x0c, streamFile);
sb.section3_num = read_32bit(0x14, streamFile);
sb.sectionX_size = read_32bit(0x1c, streamFile);
sb.section1_offset = 0x20;
} else if (sb.version <= 0x000A0000) {
sb.section1_num = read_32bit(0x04, streamFile);
sb.section2_num = read_32bit(0x08, streamFile);
sb.section3_num = read_32bit(0x0c, streamFile);
sb.sectionX_size = read_32bit(0x10, streamFile);
sb.flag1 = read_32bit(0x14, streamFile);
if (sb.version <= 0x000A0000) {
sb.section1_offset = 0x18;
} else {
sb.section1_offset = 0x1c;
sb.section1_num = read_32bit(0x04, streamFile);
sb.section2_num = read_32bit(0x08, streamFile);
sb.section3_num = read_32bit(0x0c, streamFile);
sb.sectionX_size = read_32bit(0x10, streamFile);
sb.flag1 = read_32bit(0x14, streamFile);
sb.flag2 = read_32bit(0x18, streamFile);
sb.section1_offset = 0x1c;
}
if (sb.cfg.is_padded_section1_offset)
@ -584,7 +597,7 @@ static VGMSTREAM * init_vgmstream_ubi_sb_base(ubi_sb_header *sb, STREAMFILE *str
int block_align, encoder_delay;
block_align = 0x98 * sb->channels;
encoder_delay = 0; /* TODO: this is may be incorrect */
encoder_delay = 1024 + 69*2; /* approximate */
vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamData, start_offset,sb->stream_size, sb->num_samples,sb->channels,sb->sample_rate, block_align, encoder_delay);
if (!vgmstream->codec_data) goto fail;
@ -2351,6 +2364,21 @@ static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
return 1;
}
/* Rainbow Six 3 (2003)(PC)-bank 0x0000000B */
if (sb->version == 0x0000000B && sb->platform == UBI_PC) {
config_sb_entry(sb, 0x5c, 0x7c);
config_sb_audio_fs(sb, 0x24, 0x00, 0x28);
config_sb_audio_hs(sb, 0x46, 0x40, 0x2c, 0x34, 0x4c, 0x48);
sb->cfg.audio_has_internal_names = 1;
config_sb_sequence(sb, 0x28, 0x34);
config_sb_layer_hs(sb, 0x20, 0x60, 0x58, 0x30);
config_sb_layer_sh(sb, 0x14, 0x00, 0x06, 0x08, 0x10);
return 1;
}
/* Prince of Persia: The Sands of Time Demo (2003)(Xbox)-bank 0x0000000D */
if (sb->version == 0x0000000D && sb->platform == UBI_XBOX) {
config_sb_entry(sb, 0x5c, 0x74);
@ -2358,6 +2386,11 @@ static int config_sb_version(ubi_sb_header * sb, STREAMFILE *streamFile) {
config_sb_audio_fs(sb, 0x24, 0x00, 0x28);
config_sb_audio_hs(sb, 0x46, 0x40, 0x2c, 0x34, 0x4c, 0x48);
sb->cfg.audio_has_internal_names = 1;
config_sb_sequence(sb, 0x28, 0x34);
config_sb_layer_hs(sb, 0x20, 0x60, 0x58, 0x30);
config_sb_layer_sh(sb, 0x14, 0x00, 0x06, 0x08, 0x10);
return 1;
}

View file

@ -178,6 +178,31 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
data->block_data_start = 0x08 + data->layer_max*0x04;
break;
case 0x00000003: /* Rainbow Six 3 */
/* - layer header
* 0x04: layer count
* 0x08: stream size
* 0x0c: block header size
* 0x10: block size (fixed)
* 0x14: min layer data?
* 0x18: size of header sizes and headers
* 0x1c+(04*N): header size per layer
* - block header
* 0x00: block number
* 0x04: block offset
* 0x08+(04*N): layer size per layer
* 0xNN: layer data per layer */
data->layer_max = read_32bit(offset+0x04, streamfile);
data->header_next_start = 0x10;
data->header_sizes_start = 0x1c;
data->header_data_start = 0x1c + data->layer_max*0x04;
data->block_next_start = 0;
data->block_sizes_start = 0x08;
data->block_data_start = 0x08 + data->layer_max*0x04;
break;
case 0x00000004: /* Prince of Persia: Sands of Time, Batman: Rise of Sin Tzu */
/* - layer header
* 0x04: layer count
@ -186,7 +211,7 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
* 0x10: block header size
* 0x14: block size (fixed)
* 0x18: min layer data?
* 0x1c: size of header sizes
* 0x1c: size of header sizes and headers
* 0x20+(04*N): header size per layer
* - block header
* 0x00: block number
@ -214,7 +239,7 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
* 0x14: block header size
* 0x18: block size (fixed)
* 0x1c+(04*8): min layer data? for 8 layers (-1 after layer count)
* 0x3c: size of header sizes
* 0x3c: size of header sizes and headers
* 0x40+(04*N): header size per layer
* 0xNN: header data per layer
* - block header
@ -243,7 +268,7 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
* 0x14: block header size
* 0x18: block size (fixed)
* 0x1c+(04*11): min layer data? for 11 layers (-1 after layer count)
* 0x48: size of header sizes
* 0x48: size of header sizes and headers
* 0x4c+(04*N): header size per layer
* 0xNN: header data per layer
* - block header
@ -272,7 +297,7 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
* 0x08: layer count
* 0x0c: blocks count
* 0x10: block header size
* 0x14: size of header sizes/data
* 0x14: size of header sizes and headers/data
* 0x18: next block size
* 0x1c+(04*N): layer header size
* 0xNN: header data per layer
@ -298,7 +323,7 @@ static int ubi_sb_io_init(STREAMFILE *streamfile, ubi_sb_io_data* data) {
* 0x08: layer count
* 0x0c: blocks count
* 0x10: block header size
* 0x14: size of header sizes/data
* 0x14: size of header sizes and headers/data
* 0x18: next block size
* 0x1c+(04*10): usable size per layer
* 0x5c+(04*N): layer header size

View file

@ -1,64 +0,0 @@
#include "meta.h"
#include "../util.h"
/* HLWAV (from Half Life 2 [XBOX]) */
VGMSTREAM * init_vgmstream_xbox_hlwav(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
off_t start_offset;
int loop_flag;
int channel_count;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("hlwav",filename_extension(filename))) goto fail;
/* check header and size */
if ((read_32bitBE(0x00,streamFile) != 0x14000000)) goto fail;
if (((read_32bitLE(0x4,streamFile) + (read_32bitLE(0x8,streamFile))) != get_streamfile_size(streamFile))) goto fail;
loop_flag = (read_32bitLE(0xC,streamFile)!= 0xFFFFFFFF);
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(0x8,streamFile);
vgmstream->channels = channel_count;
vgmstream->sample_rate = 22050;
vgmstream->coding_type = coding_PCM16LE;
vgmstream->num_samples = read_32bitLE(0x4,streamFile)/2/channel_count;
if (loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x4,streamFile)/2/channel_count;
vgmstream->loop_end_sample = read_32bitLE(0xC,streamFile)/2/channel_count;
}
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x2;
vgmstream->meta_type = meta_XBOX_HLWAV;
/* 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;
}

View file

@ -1,10 +1,82 @@
#include "meta.h"
#include "../coding/coding.h"
/* .360.WAV, .PS3.WAV - from Valve games running on Source Engine */
/* .WAV - from Half-Life 2 (Xbox) */
VGMSTREAM *init_vgmstream_xbox_hlwav(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
uint32_t header_size, data_size, start_offset, sample_rate;
int32_t loop_start;
uint8_t format, freq_mode, channels;
int loop_flag;
/* checks */
if (!check_extensions(streamFile, "wav,lwav"))
goto fail;
/* check header and size */
header_size = read_u32le(0x00, streamFile);
if (header_size != 0x14)
goto fail;
data_size = read_u32le(0x04, streamFile);
start_offset = read_u32le(0x08, streamFile);
if (data_size != get_streamfile_size(streamFile) - start_offset)
goto fail;
loop_start = read_s32le(0x0c, streamFile);
format = read_u8(0x12, streamFile);
freq_mode = read_u8(0x13, streamFile) & 0x0F;
channels = (read_u8(0x13, streamFile) >> 4) & 0x0F;
switch (freq_mode) {
case 0x00: sample_rate = 11025; break;
case 0x01: sample_rate = 22050; break;
case 0x02: sample_rate = 44100; break;
default: goto fail;
}
loop_flag = (loop_start != -1);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->meta_type = meta_XBOX_HLWAV;
vgmstream->sample_rate = sample_rate;
vgmstream->loop_start_sample = loop_start;
switch (format) {
case 0x00: /* PCM */
vgmstream->coding_type = coding_PCM16LE;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x02;
vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, 16);
vgmstream->loop_end_sample = vgmstream->num_samples; /* always loops from the end */
break;
case 0x01: /* XBOX ADPCM */
vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none;
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, channels);
vgmstream->loop_end_sample = vgmstream->num_samples;
break;
default:
goto fail;
}
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}
/* .360.WAV, .PS3.WAV - from Valve games running on Source Engine, evolution of Xbox .WAV format */
/* [The Orange Box (X360), Portal 2 (PS3/X360), Counter-Strike: Global Offensive (PS3/X360)] */
VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* streamFile) {
VGMSTREAM* vgmstream = NULL;
VGMSTREAM *init_vgmstream_xmv_valve(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
int32_t loop_start;
uint32_t start_offset, data_size, sample_rate, num_samples;
uint16_t /*loop_block, loop_start_skip,*/ loop_end_skip;
@ -16,26 +88,26 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* streamFile) {
goto fail;
/* check header magic */
if (read_32bitBE(0x00, streamFile) != 0x58575620) /* "XMV " */
if (read_u32be(0x00, streamFile) != 0x58575620) /* "XMV " */
goto fail;
/* only version 4 is known */
if (read_32bitBE(0x04, streamFile) != 0x04)
if (read_u32be(0x04, streamFile) != 0x04)
goto fail;
start_offset = read_32bitBE(0x10, streamFile);
data_size = read_32bitBE(0x14, streamFile);
num_samples = read_32bitBE(0x18, streamFile);
loop_start = read_32bitBE(0x1c, streamFile);
start_offset = read_u32be(0x10, streamFile);
data_size = read_u32be(0x14, streamFile);
num_samples = read_u32be(0x18, streamFile);
loop_start = read_s32be(0x1c, streamFile);
/* XMA only */
//loop_block = read_16bitBE(0x20, streamFile);
//loop_start_skip = read_16bitBE(0x22, streamFile);
loop_end_skip = read_16bitBE(0x24, streamFile);
//loop_block = read_u16be(0x20, streamFile);
//loop_start_skip = read_u16be(0x22, streamFile);
loop_end_skip = read_u16be(0x24, streamFile);
format = read_8bit(0x28, streamFile);
freq_mode = read_8bit(0x2a, streamFile);
channels = read_8bit(0x2b, streamFile);
format = read_u8(0x28, streamFile);
freq_mode = read_u8(0x2a, streamFile);
channels = read_u8(0x2b, streamFile);
switch (freq_mode) {
case 0x00: sample_rate = 11025; break;
@ -64,7 +136,7 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* streamFile) {
break;
#ifdef VGM_USE_FFMPEG
case 0x01: { /* XMA */
ffmpeg_codec_data* ffmpeg_data;
ffmpeg_codec_data *ffmpeg_data;
uint8_t buf[0x100];
int block_count, block_size;
size_t bytes;