From 3a00376590ea8999d6e48bc695f9b6677f4d7af1 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 18 Nov 2021 00:17:17 +0100 Subject: [PATCH] meta: fix some validations and cleanup --- src/meta/dsf.c | 100 +++++++++--------- src/meta/g1l.c | 83 +++++++-------- src/meta/h4m.c | 217 +++++++++++++++++++-------------------- src/meta/mus_vc.c | 8 +- src/meta/ogg_opus.c | 69 +++++++------ src/meta/ogg_vorbis.c | 5 +- src/meta/ogl.c | 150 ++++++++++++++------------- src/meta/omu.c | 90 ++++++++-------- src/meta/sat_baka.c | 80 ++++++--------- src/meta/sthd.c | 134 ++++++++++++------------ src/meta/str_asr.c | 122 ++++++++-------------- src/meta/strm_abylight.c | 5 +- src/meta/xmu.c | 91 ++++++++-------- 13 files changed, 556 insertions(+), 598 deletions(-) diff --git a/src/meta/dsf.c b/src/meta/dsf.c index 342ff10b..54b1a25b 100644 --- a/src/meta/dsf.c +++ b/src/meta/dsf.c @@ -1,51 +1,49 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* .DSF - from Ocean game(s?) [Last Rites (PC)] */ -VGMSTREAM * init_vgmstream_dsf(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count, sample_rate; - size_t data_size; - - - /* checks */ - if (!check_extensions(streamFile, "dsf")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x4F434541 && /* "OCEA" */ - read_32bitBE(0x00,streamFile) != 0x4E204453 && /* "N DS" */ - read_32bitBE(0x00,streamFile) != 0x41000000) /* "A\0\0\0" */ - goto fail; - - /* 0x10(2): always 1? */ - /* 0x12(4): total nibbles / 0x10? */ - /* 0x16(4): always 0? */ - start_offset = read_32bitLE(0x1a,streamFile); - sample_rate = read_32bitLE(0x1e,streamFile); - channel_count = read_32bitLE(0x22,streamFile) + 1; - data_size = get_streamfile_size(streamFile) - start_offset; - loop_flag = 0; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_DSF; - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = ((data_size / 0x08 / channel_count) * 14); /* bytes-to-samples */ - vgmstream->coding_type = coding_DSA; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x08; - - read_string(vgmstream->stream_name,0x20+1, 0x26,streamFile); - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* .DSF - from Ocean game(s?) [Last Rites (PC)] */ +VGMSTREAM* init_vgmstream_dsf(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels, sample_rate; + size_t data_size; + + + /* checks */ + if (!is_id32be(0x00,sf, "OCEA") || !is_id64be(0x04,sf, "N DSA\0\0\0")) + goto fail; + + if (!check_extensions(sf, "dsf")) + goto fail; + + /* 0x10(2): always 1? */ + /* 0x12(4): total nibbles / 0x10? */ + /* 0x16(4): always 0? */ + start_offset = read_u32le(0x1a,sf); + sample_rate = read_s32le(0x1e,sf); + channels = read_s32le(0x22,sf) + 1; + data_size = get_streamfile_size(sf) - start_offset; + loop_flag = 0; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_DSF; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = ((data_size / 0x08 / channels) * 14); /* bytes-to-samples */ + vgmstream->coding_type = coding_DSA; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x08; + + read_string(vgmstream->stream_name,0x20+1, 0x26,sf); + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/g1l.c b/src/meta/g1l.c index 7c6e43d8..a5258ad9 100644 --- a/src/meta/g1l.c +++ b/src/meta/g1l.c @@ -2,45 +2,48 @@ #include "../util.h" #include "../coding/coding.h" -static VGMSTREAM * init_vgmstream_kt_wiibgm_offset(STREAMFILE *streamFile, off_t offset); +static VGMSTREAM* init_vgmstream_kt_wiibgm_offset(STREAMFILE* sf, off_t offset); /* Koei Tecmo G1L - container format, sometimes containing a single stream. * It probably makes more sense to extract it externally, it's here mainly for Hyrule Warriors */ -VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - int type; - int total_streams, target_stream = streamFile->stream_index; - off_t stream_offset; +VGMSTREAM* init_vgmstream_kt_g1l(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int type; + int total_streams, target_stream = sf->stream_index; + off_t stream_offset; int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; - if (!check_extensions(streamFile,"g1l")) - goto fail; - /* check header */ - if ((read_32bitBE(0x0, streamFile) != 0x47314C5F /* "G1L_" (BE) */ - || read_32bitBE(0x0, streamFile) != 0x5F4C3147) /* "_L1G" (LE) */ - && read_32bitBE(0x4, streamFile) != 0x30303030) /* "0000" (version?) */ - goto fail; + /* checks */ + if (!is_id32be(0x00, sf, "G1L_") && /* BE */ + !is_id32le(0x00, sf, "G1L_")) /* LE */ + goto fail; - if (read_32bitBE(0x0, streamFile) == 0x47314C5F) { - read_32bit = read_32bitBE; - } else { + if (!check_extensions(sf,"g1l")) + goto fail; + + if (!is_id32be(0x04, sf, "0000")) /* version? */ + goto fail; + + if (is_id32be(0x00, sf, "G1L_")) { + read_32bit = read_32bitBE; + } else { read_32bit = read_32bitLE; - } + } /* 0x08: filesize, 0x0c: header size */ - type = read_32bit(0x10,streamFile); - total_streams = read_32bit(0x14,streamFile); + type = read_32bit(0x10,sf); + total_streams = read_32bit(0x14,sf); if (target_stream==0) target_stream = 1; - if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; + if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; - stream_offset = read_32bit(0x18 + 0x4*(target_stream-1),streamFile); + stream_offset = read_32bit(0x18 + 0x4*(target_stream-1),sf); //stream_size = stream_offset - stream_next_offset;//not ok, sometimes entries are unordered/repeats */ switch(type) { /* type may not be correct */ case 0x09: /* DSP (WiiBGM) from Hyrule Warriors (Wii U) */ - vgmstream = init_vgmstream_kt_wiibgm_offset(streamFile, stream_offset); + vgmstream = init_vgmstream_kt_wiibgm_offset(sf, stream_offset); break; case 0x06: /* ATRAC9 (RIFF) from One Piece Pirate Warriors 3 (Vita) */ case 0x01: /* ATRAC3plus (RIFF) from One Piece Pirate Warriors 2 (PS3) */ @@ -51,41 +54,41 @@ VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE *streamFile) { } - return vgmstream; + return vgmstream; fail: - close_vgmstream(vgmstream); - return NULL; + close_vgmstream(vgmstream); + return NULL; } /* Koei Tecmo "WiiBGM" DSP format - found in Hyrule Warriors, Romance of the Three Kingdoms 12 */ -VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE *streamFile) { - return init_vgmstream_kt_wiibgm_offset(streamFile, 0x0); +VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE *sf) { + return init_vgmstream_kt_wiibgm_offset(sf, 0x0); } -static VGMSTREAM * init_vgmstream_kt_wiibgm_offset(STREAMFILE *streamFile, off_t offset) { - VGMSTREAM * vgmstream = NULL; +static VGMSTREAM* init_vgmstream_kt_wiibgm_offset(STREAMFILE* sf, off_t offset) { + VGMSTREAM* vgmstream = NULL; int loop_flag, channel_count; off_t start_offset; - if (!check_extensions(streamFile,"g1l,dsp")) + /* check */ + if (!is_id64be(offset+0x0, sf, "WiiBGM\0\0") && + read_32bitBE(offset+0x4, sf) != 0x474D0000) goto fail; - if (read_32bitBE(offset+0x0, streamFile) != 0x57696942 && /* "WiiB" */ - read_32bitBE(offset+0x4, streamFile) != 0x474D0000) /* "GM\0\0" */ + if (!check_extensions(sf,"g1l,dsp")) goto fail; /* check type details */ - loop_flag = read_32bitBE(offset+0x14, streamFile) > 0; - channel_count = read_8bit(offset+0x23, streamFile); + loop_flag = read_32bitBE(offset+0x14, sf) > 0; + channel_count = read_u8(offset+0x23, sf); /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count, loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->num_samples = read_32bitBE(offset+0x10, streamFile); - vgmstream->sample_rate = (uint16_t)read_16bitBE(offset+0x26, streamFile); - vgmstream->loop_start_sample = read_32bitBE(offset+0x14, streamFile); + vgmstream->num_samples = read_32bitBE(offset+0x10, sf); + vgmstream->sample_rate = (uint16_t)read_16bitBE(offset+0x26, sf); + vgmstream->loop_start_sample = read_32bitBE(offset+0x14, sf); vgmstream->loop_end_sample = vgmstream->num_samples; vgmstream->coding_type = coding_NGC_DSP_subint; @@ -93,10 +96,10 @@ static VGMSTREAM * init_vgmstream_kt_wiibgm_offset(STREAMFILE *streamFile, off_t vgmstream->interleave_block_size = 0x1; vgmstream->meta_type = meta_KT_WIIBGM; - dsp_read_coefs_be(vgmstream,streamFile, offset+0x5C, 0x60); + dsp_read_coefs_be(vgmstream,sf, offset+0x5C, 0x60); start_offset = offset+0x800; - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; diff --git a/src/meta/h4m.c b/src/meta/h4m.c index 80540977..3383ef94 100644 --- a/src/meta/h4m.c +++ b/src/meta/h4m.c @@ -1,109 +1,108 @@ -#include "meta.h" -#include "../layout/layout.h" -#include "../coding/coding.h" - -/* H4M - from Hudson HVQM4 videos [Resident Evil 0 (GC), Tales of Symphonia (GC)] - * (info from hcs/Nisto's h4m_audio_decode) */ -VGMSTREAM * init_vgmstream_h4m(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - int format, extra_tracks, sample_rate; - int total_subsongs, target_subsong = streamFile->stream_index; - - - /* checks */ - if (!check_extensions(streamFile, "h4m")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x4856514D && /* "HVQM" */ - read_32bitBE(0x04,streamFile) != 0x3420312E) /* "4 1." */ - goto fail; - if (read_32bitBE(0x08,streamFile) != 0x33000000 && /* "3\0\0\0" */ - read_32bitBE(0x08,streamFile) != 0x35000000) /* "5\0\0\0" */ - goto fail; - - /* header */ - start_offset = read_32bitBE(0x10, streamFile); /* header_size */ - if (start_offset != 0x44) /* known size */ - goto fail; - if (read_32bitBE(0x14, streamFile) != get_streamfile_size(streamFile) - start_offset) /* body_size */ - goto fail; - if (read_32bitBE(0x18, streamFile) == 0) /* blocks */ - goto fail; - /* 0x1c: video_frames */ - if (read_32bitBE(0x20, streamFile) == 0) /* audio_frames */ - goto fail; - /* 0x24: frame interval */ - /* 0x28: max_video_frame_size */ - /* 0x2c: unk2C (0) */ - if (read_32bitBE(0x30, streamFile) == 0) /* max_audio_frame_size */ - goto fail; - /* 0x34: hres */ - /* 0x36: vres */ - /* 0x38: h_srate */ - /* 0x39: v_srate */ - /* 0x3a: unk3A (0 or 0x12) */ - /* 0x3b: unk3B (0) */ - channel_count = read_8bit(0x3c,streamFile); - if (read_8bit(0x3d,streamFile) != 16) /* bitdepth */ - goto fail; //todo Pikmin (GC) is using some kind of variable blocks - format = (uint8_t)read_8bit(0x3e,streamFile); /* flags? */ - extra_tracks = read_8bit(0x3f,streamFile); - sample_rate = read_32bitBE(0x40,streamFile); - - loop_flag = 0; - - /* tracks for languages [Pokemon Channel], or sometimes used to fake multichannel [Tales of Symphonia] */ - total_subsongs = extra_tracks + 1; - if (target_subsong == 0) target_subsong = 1; - if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_streams = total_subsongs; - vgmstream->stream_size = get_streamfile_size(streamFile) / total_subsongs; /* approx... */ - vgmstream->codec_config = format; /* for blocks */ - vgmstream->meta_type = meta_H4M; - vgmstream->layout_type = layout_blocked_h4m; - - switch(format & 0x7F) { - case 0x00: - vgmstream->coding_type = coding_H4M_IMA; - break; - - /* no games known to use these, h4m_audio_decode may decode them */ - case 0x01: /* Uncompressed PCM */ - case 0x04: /* 8-bit (A)DPCM */ - default: - VGM_LOG("H4M: unknown codec %x\n", format); - goto fail; - } - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - - /* calc num_samples manually */ - { - vgmstream->stream_index = target_subsong; /* extra setup for H4M */ - vgmstream->full_block_size = 0; /* extra setup for H4M */ - vgmstream->next_block_offset = start_offset; - do { - block_update(vgmstream->next_block_offset,vgmstream); - vgmstream->num_samples += vgmstream->current_block_samples; - } - while (vgmstream->next_block_offset < get_streamfile_size(streamFile)); - vgmstream->full_block_size = 0; /* extra cleanup for H4M */ - block_update(start_offset, vgmstream); - } - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../layout/layout.h" +#include "../coding/coding.h" + +/* H4M - from Hudson HVQM4 videos [Resident Evil 0 (GC), Tales of Symphonia (GC)] + * (info from hcs/Nisto's h4m_audio_decode) */ +VGMSTREAM* init_vgmstream_h4m(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + int format, extra_tracks, sample_rate; + int total_subsongs, target_subsong = sf->stream_index; + + + /* checks */ + if (!is_id64be(0x00,sf, "HVQM4 1.")) + goto fail; + if (!is_id32be(0x08,sf, "3\0\0\0") && + !is_id32be(0x08,sf, "5\0\0\0")) + goto fail; + + if (!check_extensions(sf, "h4m")) + goto fail; + + /* header */ + start_offset = read_u32be(0x10, sf); /* header_size */ + if (start_offset != 0x44) /* known size */ + goto fail; + if (read_u32be(0x14, sf) != get_streamfile_size(sf) - start_offset) /* body_size */ + goto fail; + if (read_u32be(0x18, sf) == 0) /* blocks */ + goto fail; + /* 0x1c: video_frames */ + if (read_u32be(0x20, sf) == 0) /* audio_frames */ + goto fail; + /* 0x24: frame interval */ + /* 0x28: max_video_frame_size */ + /* 0x2c: unk2C (0) */ + if (read_u32be(0x30, sf) == 0) /* max_audio_frame_size */ + goto fail; + /* 0x34: hres */ + /* 0x36: vres */ + /* 0x38: h_srate */ + /* 0x39: v_srate */ + /* 0x3a: unk3A (0 or 0x12) */ + /* 0x3b: unk3B (0) */ + channel_count = read_u8(0x3c,sf); + if (read_u8(0x3d,sf) != 16) /* bitdepth */ + goto fail; //todo Pikmin (GC) is using some kind of variable blocks + format = read_u8(0x3e,sf); /* flags? */ + extra_tracks = read_u8(0x3f,sf); + sample_rate = read_s32be(0x40,sf); + + loop_flag = 0; + + /* tracks for languages [Pokemon Channel], or sometimes used to fake multichannel [Tales of Symphonia] */ + total_subsongs = extra_tracks + 1; + if (target_subsong == 0) target_subsong = 1; + if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_streams = total_subsongs; + vgmstream->stream_size = get_streamfile_size(sf) / total_subsongs; /* approx... */ + vgmstream->codec_config = format; /* for blocks */ + vgmstream->meta_type = meta_H4M; + vgmstream->layout_type = layout_blocked_h4m; + + switch(format & 0x7F) { + case 0x00: + vgmstream->coding_type = coding_H4M_IMA; + break; + + /* no games known to use these, h4m_audio_decode may decode them */ + case 0x01: /* Uncompressed PCM */ + case 0x04: /* 8-bit (A)DPCM */ + default: + VGM_LOG("H4M: unknown codec %x\n", format); + goto fail; + } + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + + /* calc num_samples manually */ + { + vgmstream->stream_index = target_subsong; /* extra setup for H4M */ + vgmstream->full_block_size = 0; /* extra setup for H4M */ + vgmstream->next_block_offset = start_offset; + do { + block_update(vgmstream->next_block_offset,vgmstream); + vgmstream->num_samples += vgmstream->current_block_samples; + } + while (vgmstream->next_block_offset < get_streamfile_size(sf)); + vgmstream->full_block_size = 0; /* extra cleanup for H4M */ + block_update(start_offset, vgmstream); + } + + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/mus_vc.c b/src/meta/mus_vc.c index f992f533..3076def8 100644 --- a/src/meta/mus_vc.c +++ b/src/meta/mus_vc.c @@ -11,11 +11,15 @@ VGMSTREAM* init_vgmstream_mus_vc(STREAMFILE* sf) { /* checks */ + if (read_u32be(0x00,sf) != 0xFBBFFBBF && /* BE */ + read_u32le(0x00,sf) != 0xFBBFFBBF) /* LE */ + goto fail; + if (!check_extensions(sf, "mus")) goto fail; - if (read_u32be(0x08,sf) != 0xBBBBBBBB && - read_u32be(0x14,sf) != 0xBBBBBBBB && + if (read_u32be(0x08,sf) != 0xBBBBBBBB || + read_u32be(0x14,sf) != 0xBBBBBBBB || read_u32be(0x2c,sf) != 0xBEBEBEBE) goto fail; diff --git a/src/meta/ogg_opus.c b/src/meta/ogg_opus.c index e3c5fb68..5d6bd1a3 100644 --- a/src/meta/ogg_opus.c +++ b/src/meta/ogg_opus.c @@ -2,12 +2,12 @@ #include "../coding/coding.h" -static int get_ogg_page_size(STREAMFILE *streamFile, off_t page_offset, off_t *out_data_offset, size_t *out_page_size); -static int ogg_get_num_samples(STREAMFILE *streamFile, off_t start_offset); +static int get_ogg_page_size(STREAMFILE* sf, off_t page_offset, off_t *out_data_offset, size_t *out_page_size); +static int ogg_get_num_samples(STREAMFILE* sf, off_t start_offset); /* Ogg Opus - standard Opus with optional looping comments [The Pillars of Earth (PC), Monster Boy and the Cursed Kingdom (Switch)] */ -VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_ogg_opus(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset, data_offset = 0; size_t page_size = 0; int loop_flag, channel_count, original_rate; @@ -15,35 +15,36 @@ VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE *streamFile) { /* checks */ + if (!is_id32be(0x00,sf, "OggS")) + goto fail; + /* .opus: standard, .lopus: fake extension for plugins * .ogg: less common, .logg: same * .bgm: Utawarerumono: Mask of Truth (PC) */ - if (!check_extensions(streamFile, "opus,lopus,ogg,logg,bgm")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x4F676753) /* "OggS" */ + if (!check_extensions(sf, "opus,lopus,ogg,logg,bgm")) goto fail; /* see: https://tools.ietf.org/html/rfc7845.html */ start_offset = 0x00; /* parse 1st page: opus head */ - if (!get_ogg_page_size(streamFile, start_offset, &data_offset, &page_size)) + if (!get_ogg_page_size(sf, start_offset, &data_offset, &page_size)) goto fail; - if (read_32bitBE(data_offset+0x00,streamFile) != 0x4F707573 && /* "Opus" */ - read_32bitBE(data_offset+0x04,streamFile) != 0x48656164) /* "Head" */ + if (!is_id32be(data_offset+0x00,sf, "Opus") || + !is_id32be(data_offset+0x04,sf, "Head")) goto fail; /* 0x01: version 1, fixed */ - channel_count = read_8bit(data_offset+0x09,streamFile); + channel_count = read_u8(data_offset+0x09,sf); /* 0x0A: skip samples */ - original_rate = read_32bitLE(data_offset+0x0c,streamFile); + original_rate = read_s32le(data_offset+0x0c,sf); /* 0x10: gain */ /* 0x12: mapping family */ /* parse 2nd page: opus tags (also mandatory) */ - if (!get_ogg_page_size(streamFile, start_offset+page_size, &data_offset, &page_size)) + if (!get_ogg_page_size(sf, start_offset+page_size, &data_offset, &page_size)) goto fail; - if (read_32bitBE(data_offset+0x00,streamFile) != 0x4F707573 && /* "Opus" */ - read_32bitBE(data_offset+0x04,streamFile) != 0x54616773) /* "Tags" */ + if (!is_id32be(data_offset+0x00,sf, "Opus") || + !is_id32be(data_offset+0x04,sf, "Tags")) goto fail; loop_flag = 0; @@ -54,15 +55,15 @@ VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE *streamFile) { int i; int has_encoder_options = 0, has_title = 0; - vendor_size = read_32bitLE(data_offset+0x08,streamFile); - comment_count = read_32bitLE(data_offset+0x0c+vendor_size,streamFile); + vendor_size = read_s32le(data_offset+0x08,sf); + comment_count = read_s32le(data_offset+0x0c+vendor_size,sf); /* parse comments */ offset = data_offset + 0x0c + vendor_size + 0x04; for (i = 0; i < comment_count; i++) { - user_comment_size = read_32bitLE(offset+0x00,streamFile); + user_comment_size = read_s32le(offset+0x00,sf); user_comment_max = user_comment_size > 1024 ? 1024 : user_comment_size; - read_string(user_comment,user_comment_max+1, offset+0x04,streamFile); + read_string(user_comment,user_comment_max+1, offset+0x04,sf); /* parse loop strings */ @@ -112,13 +113,13 @@ VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE *streamFile) { vgmstream->meta_type = meta_OGG_OPUS; vgmstream->sample_rate = 48000; /* Opus always resamples to this */ - vgmstream->num_samples = ogg_get_num_samples(streamFile, 0x00); + vgmstream->num_samples = ogg_get_num_samples(sf, 0x00); vgmstream->loop_start_sample = loop_start; vgmstream->loop_end_sample = loop_end; #ifdef VGM_USE_FFMPEG { - vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset, get_streamfile_size(streamFile)); + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset, get_streamfile_size(sf)); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -129,7 +130,7 @@ VGMSTREAM * init_vgmstream_ogg_opus(STREAMFILE *streamFile) { goto fail; #endif - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; @@ -140,23 +141,23 @@ fail: /* parse OggS's bizarre segment table */ -static int get_ogg_page_size(STREAMFILE *streamFile, off_t page_offset, off_t *out_data_offset, size_t *out_page_size) { +static int get_ogg_page_size(STREAMFILE* sf, off_t page_offset, off_t* p_data_offset, size_t* p_page_size) { uint8_t segments; size_t page_size = 0; int i; - if (read_32bitBE(page_offset+0x00,streamFile) != 0x4F676753) /* "OggS" */ + if (!is_id32be(page_offset+0x00,sf, "OggS")) goto fail; /* read all segment sizes */ - segments = (uint8_t)read_8bit(page_offset+0x1a, streamFile); + segments = read_u8(page_offset+0x1a, sf); for (i = 0; i < segments; i++) { - page_size += (uint8_t)read_8bit(page_offset + 0x1b + i, streamFile); + page_size += read_u8(page_offset + 0x1b + i, sf); } page_size += 0x1b + segments; - if (out_data_offset) *out_data_offset = page_offset + 0x1b + segments; - if (out_page_size) *out_page_size = page_size; + if (p_data_offset) *p_data_offset = page_offset + 0x1b + segments; + if (p_page_size) *p_page_size = page_size; return 1; fail: return 0; @@ -164,18 +165,18 @@ fail: /* Ogg doesn't have num_samples info, must manually seek+read last granule * (Xiph is insistent this is the One True Way). */ -static int ogg_get_num_samples(STREAMFILE *streamFile, off_t start_offset) { - uint32_t expected_id = 0x4F676753; - off_t offset = get_streamfile_size(streamFile) - 0x04-0x01-0x01-0x08-0x04-0x04-0x04; +static int ogg_get_num_samples(STREAMFILE *sf, off_t start_offset) { + uint32_t expected_id = get_id32be("OggS"); + off_t offset = get_streamfile_size(sf) - 0x04-0x01-0x01-0x08-0x04-0x04-0x04; //todo better buffer reads (Ogg page max is 0xFFFF) //lame way to force buffer, assuming it's around that - read_32bitBE(offset - 0x4000, streamFile); + read_u32be(offset - 0x4000, sf); while (offset >= start_offset) { - uint32_t current_id = read_32bitBE(offset, streamFile); + uint32_t current_id = read_u32be(offset, sf); if (current_id == expected_id) { /* if more checks are needed last page starts with 0x0004 */ - return read_32bitLE(offset+0x04+0x01+0x01, streamFile); /* get last granule = total samples (64b but whatevs) */ + return read_s32le(offset+0x04+0x01+0x01, sf); /* get last granule = total samples (64b but whatevs) */ } offset--; diff --git a/src/meta/ogg_vorbis.c b/src/meta/ogg_vorbis.c index f587967c..42ae010a 100644 --- a/src/meta/ogg_vorbis.c +++ b/src/meta/ogg_vorbis.c @@ -380,10 +380,9 @@ static VGMSTREAM* _init_vgmstream_ogg_vorbis_common(STREAMFILE* sf) { } if (is_rpgmvo) { /* [RPG Maker MV (PC), RPG Maker MZ (PC)] */ - if (read_32bitBE(0x00,sf) != 0x5250474D && /* "RPGM" */ - read_32bitBE(0x00,sf) != 0x56000000) { /* "V\0\0\0" */ + if (!is_id64be(0x00,sf, "RPGMV\0\0\0")) goto fail; - } + ovmi.decryption_callback = rpgmvo_ogg_decryption_callback; cfg.start = 0x10; diff --git a/src/meta/ogl.c b/src/meta/ogl.c index f7a2a26e..11bb5134 100644 --- a/src/meta/ogl.c +++ b/src/meta/ogl.c @@ -1,72 +1,78 @@ -#include "meta.h" -#include "../util.h" -#include "../coding/coding.h" - - -/* OGL - Shin'en custom Vorbis [Jett Rocket (Wii), FAST Racing NEO (WiiU)] */ -VGMSTREAM * init_vgmstream_ogl(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - size_t partial_file_size; - int loop_flag, channel_count, sample_rate; - uint32_t num_samples, loop_start_sample, loop_end_sample; - - /* check extension, case insensitive */ - if (!check_extensions(streamFile,"ogl")) - goto fail; - - /* OGL headers are very basic with no ID but libvorbis should reject garbage data anyway */ - loop_flag = read_32bitLE(0x00,streamFile) > 0; /* absolute loop offset */ - loop_start_sample = read_32bitLE(0x04,streamFile); - //loop_start_block = read_32bitLE(0x08,streamFile); - num_samples = read_32bitLE(0x0c,streamFile); - partial_file_size = read_32bitLE(0x10,streamFile); /* header + data not counting end padding */ - if (partial_file_size > get_streamfile_size(streamFile)) goto fail; - loop_end_sample = num_samples; /* there is no data after num_samples (ie.- it's really num_samples) */ - - /* actually peeking into the Vorbis id packet */ - channel_count = read_8bit (0x21,streamFile); - sample_rate = read_32bitLE(0x22,streamFile); - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = loop_end_sample; - vgmstream->meta_type = meta_OGL; - -#ifdef VGM_USE_VORBIS - { - vorbis_custom_config cfg = {0}; - - vgmstream->layout_type = layout_none; - vgmstream->coding_type = coding_VORBIS_custom; - vgmstream->codec_data = init_vorbis_custom(streamFile, 0x14, VORBIS_OGL, &cfg); - if (!vgmstream->codec_data) goto fail; - - start_offset = cfg.data_start_offset; - } -#else - goto fail; -#endif - - /* non-looping files do this */ - if (!num_samples) { - uint32_t avg_bitrate = read_32bitLE(0x2a,streamFile); /* inside id packet */ - /* approximate as we don't know the sizes of all packet headers */ //todo this is wrong... but somehow works? - vgmstream->num_samples = (partial_file_size - start_offset) * ((sample_rate*10/avg_bitrate)+1); - } - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../util.h" +#include "../coding/coding.h" + + +/* OGL - Shin'en custom Vorbis [Jett Rocket (Wii), FAST Racing NEO (WiiU)] */ +VGMSTREAM* init_vgmstream_ogl(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + size_t partial_file_size; + int loop_flag, channels, sample_rate; + uint32_t num_samples, loop_start_sample, loop_end_sample; + + /* checks */ + if (read_u32le(0x00, sf) > 0x10000000) /* limit loop samples (should catch fourccs) */ + goto fail; + if (!is_id32be(0x17, sf, "vorb")) /* Vorbis id packet */ + goto fail; + + if (!check_extensions(sf,"ogl")) + goto fail; + + /* OGL headers are very basic with no ID but libvorbis should reject garbage data anyway */ + loop_flag = read_s32le(0x00,sf) > 0; /* absolute loop offset */ + loop_start_sample = read_s32le(0x04,sf); + //loop_start_block = read_s32le(0x08,streamFile); + num_samples = read_s32le(0x0c,sf); + partial_file_size = read_s32le(0x10,sf); /* header + data not counting end padding */ + if (partial_file_size > get_streamfile_size(sf)) + goto fail; + loop_end_sample = num_samples; /* there is no data after num_samples (ie.- it's really num_samples) */ + + /* actually peeking into the Vorbis id packet */ + channels = read_u8 (0x21,sf); + sample_rate = read_s32le(0x22,sf); + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + vgmstream->meta_type = meta_OGL; + +#ifdef VGM_USE_VORBIS + { + vorbis_custom_config cfg = {0}; + + vgmstream->layout_type = layout_none; + vgmstream->coding_type = coding_VORBIS_custom; + vgmstream->codec_data = init_vorbis_custom(sf, 0x14, VORBIS_OGL, &cfg); + if (!vgmstream->codec_data) goto fail; + + start_offset = cfg.data_start_offset; + } +#else + goto fail; +#endif + + /* non-looping files do this */ + if (!num_samples) { + uint32_t avg_bitrate = read_u32le(0x2a,sf); /* inside id packet */ + /* approximate as we don't know the sizes of all packet headers */ //todo this is wrong... but somehow works? + vgmstream->num_samples = (partial_file_size - start_offset) * ((sample_rate*10/avg_bitrate)+1); + } + + /* open the file for reading */ + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/omu.c b/src/meta/omu.c index c45a0020..38711410 100644 --- a/src/meta/omu.c +++ b/src/meta/omu.c @@ -1,45 +1,45 @@ -#include "meta.h" - -/* IMU - found in Alter Echo (PS2) */ -VGMSTREAM * init_vgmstream_ps2_omu(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - - /* check extension */ - if ( !check_extensions(streamFile,"omu") ) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x4F4D5520 && /* "OMU " */ - read_32bitBE(0x08,streamFile) != 0x46524D54) /* "FRMT" */ - goto fail; - - loop_flag = 1; - channel_count = (int)read_8bit(0x14,streamFile); - start_offset = 0x40; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->num_samples = (int32_t)(read_32bitLE(0x3C,streamFile)/(vgmstream->channels*2)); - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = vgmstream->num_samples; - - vgmstream->coding_type = coding_PCM16LE; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x200; - vgmstream->meta_type = meta_PS2_OMU; - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" + +/* IMU - found in Alter Echo (PS2) */ +VGMSTREAM* init_vgmstream_ps2_omu(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + + /* checks */ + if (!is_id32be(0x00,sf, "OMU ")) + goto fail; + + if (!check_extensions(sf,"omu")) + goto fail; + + if (!is_id32be(0x08,sf, "FRMT")) + goto fail; + + loop_flag = 1; + channels = read_u8(0x14,sf); + start_offset = 0x40; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_s32le(0x10,sf); + vgmstream->num_samples = (read_u32le(0x3C,sf) / (vgmstream->channels*2)); + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->coding_type = coding_PCM16LE; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x200; + vgmstream->meta_type = meta_PS2_OMU; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/sat_baka.c b/src/meta/sat_baka.c index 8deb4613..bf007270 100644 --- a/src/meta/sat_baka.c +++ b/src/meta/sat_baka.c @@ -1,72 +1,50 @@ #include "meta.h" #include "../util.h" -/* manakoAT 28.01.2009 : - BAKA - found in "Crypt Killer (Saturn)... - looks like some developers were really bored, every file starts with - the word "BAKA" which is the japanese word for "IDIOT" :o) - Files containing "begloop" markers at EOF... - some files should loop, but i don't know how to get the loopstart here!*/ -VGMSTREAM * init_vgmstream_sat_baka(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; +/* BAKA - from KCET games [Crypt Killer (Saturn)] */ +VGMSTREAM* init_vgmstream_sat_baka(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; - int loop_flag = 0; - int channel_count; + int loop_flag, channels; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("baka",filename_extension(filename))) goto fail; + /* checks */ + if (!is_id32be(0x00,sf, "BAKA")) + goto fail; + + /* (extensionless): original + * .baka: header id */ + if (!check_extensions(sf, ",baka")) + goto fail; + + /* RIFF style chunks */ + if (!is_id32be(0x08,sf, " AHO") || + !is_id32be(0x0C,sf, "PAPA") || + !is_id32be(0x26,sf, "MAMA")) + goto fail; + + //todo begloop markers at EOF + loop_flag = 0; + channels = 2; + start_offset = 0x2E; - /* check header */ - if ((read_32bitBE(0x00,streamFile) != 0x42414B41 && /* "BAKA" */ - read_32bitBE(0x08,streamFile) != 0x2041484F && /* " AHO" */ - read_32bitBE(0x0C,streamFile) != 0x50415041 && /* "PAPA" */ - read_32bitBE(0x26,streamFile) != 0x4D414D41)) /* "MAMA" */ - goto fail; - - channel_count = 2; - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x2E; - vgmstream->channels = channel_count; vgmstream->sample_rate = 44100; - vgmstream->coding_type = coding_PCM16BE; - vgmstream->num_samples = read_32bitBE(0x16,streamFile); - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = read_32bitBE(0x16,streamFile); - } + vgmstream->num_samples = read_u32be(0x16,sf); + vgmstream->coding_type = coding_PCM16BE; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x2; vgmstream->meta_type = meta_SAT_BAKA; - /* 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;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/sthd.c b/src/meta/sthd.c index 5c025df6..e7be64c1 100644 --- a/src/meta/sthd.c +++ b/src/meta/sthd.c @@ -1,67 +1,67 @@ -#include "meta.h" -#include "../coding/coding.h" -#include "../layout/layout.h" - -/* STHD - Dream Factory .stx [Kakuto Chojin (Xbox)] */ -VGMSTREAM * init_vgmstream_sthd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - - /* checks */ - if (!check_extensions(streamFile, "stx")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x53544844) /* "STHD" */ - goto fail; - /* first block has special values */ - if (read_32bitLE(0x04,streamFile) != 0x0800 && - read_32bitLE(0x0c,streamFile) != 0x0001 && - read_32bitLE(0x14,streamFile) != 0x0000) - goto fail; - - channel_count = read_16bitLE(0x06,streamFile); - loop_flag = read_16bitLE(0x18,streamFile) != -1; - start_offset = 0x800; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_STHD; - vgmstream->sample_rate = read_32bitLE(0x20, streamFile); /* repeated ~8 times? */ - - vgmstream->coding_type = coding_XBOX_IMA_int; - vgmstream->layout_type = layout_blocked_sthd; - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - - /* calc num_samples manually (blocks data varies in size) */ - { - /* loop values may change to +1 in first actual block, but this works ok enough */ - int loop_start_block = (uint16_t)read_16bitLE(0x1a,streamFile); - int loop_end_block = (uint16_t)read_16bitLE(0x1c,streamFile); - int block_count = 1; /* header block = 0 */ - - vgmstream->next_block_offset = start_offset; - do { - block_update(vgmstream->next_block_offset,vgmstream); - if (block_count == loop_start_block) - vgmstream->loop_start_sample = vgmstream->num_samples; - if (block_count == loop_end_block) - vgmstream->loop_end_sample = vgmstream->num_samples; - - vgmstream->num_samples += xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1); - block_count++; - } - while (vgmstream->next_block_offset < get_streamfile_size(streamFile)); - block_update(start_offset, vgmstream); - } - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" +#include "../layout/layout.h" + +/* STHD - Dream Factory .stx [Kakuto Chojin (Xbox)] */ +VGMSTREAM * init_vgmstream_sthd(STREAMFILE *sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + + + /* checks */ + if (!is_id32be(0x00,sf, "STHD")) + goto fail; + if (!check_extensions(sf, "stx")) + goto fail; + /* first block has special values */ + if (read_u16le(0x04,sf) != 0x0800 || + read_u32le(0x0c,sf) != 0x0001 || + read_u32le(0x14,sf) != 0x0000) + goto fail; + + channel_count = read_s16le(0x06,sf); + loop_flag = read_s16le(0x18,sf) != -1; + start_offset = read_u16le(0x04,sf); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_STHD; + vgmstream->sample_rate = read_s32le(0x20, sf); /* repeated ~8 times? */ + + vgmstream->coding_type = coding_XBOX_IMA_int; + vgmstream->layout_type = layout_blocked_sthd; + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + + /* calc num_samples manually (blocks data varies in size) */ + { + /* loop values may change to +1 in first actual block, but this works ok enough */ + int loop_start_block = (uint16_t)read_16bitLE(0x1a,sf); + int loop_end_block = (uint16_t)read_16bitLE(0x1c,sf); + int block_count = 1; /* header block = 0 */ + + vgmstream->next_block_offset = start_offset; + do { + block_update(vgmstream->next_block_offset,vgmstream); + if (block_count == loop_start_block) + vgmstream->loop_start_sample = vgmstream->num_samples; + if (block_count == loop_end_block) + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->num_samples += xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1); + block_count++; + } + while (vgmstream->next_block_offset < get_streamfile_size(sf)); + block_update(start_offset, vgmstream); + } + + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/str_asr.c b/src/meta/str_asr.c index f1184e41..9a78476e 100644 --- a/src/meta/str_asr.c +++ b/src/meta/str_asr.c @@ -1,97 +1,63 @@ #include "meta.h" -#include "../util.h" +#include "../coding/coding.h" -/* STR -ASR (from Donkey Kong Jet Race) */ -VGMSTREAM * init_vgmstream_str_asr(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; + +/* KNON - from Donkey Kong: Barrel Blast (Wii) */ +VGMSTREAM* init_vgmstream_str_asr(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; + int loop_flag, channels; - int loop_flag = 0; - int channel_count; + /* checks*/ + if (!is_id32be(0x00,sf, "KNON")) + goto fail; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("str",filename_extension(filename)) && /* PCM Files */ - strcasecmp("asr",filename_extension(filename))) /* DSP Files */ - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x4B4E4F4E && /* "KNON" */ - read_32bitBE(0x04,streamFile) != 0x00000000 && /* "0x0" */ - read_32bitBE(0x08,streamFile) != 0x57494920) goto fail; /* "WII\0x20" */ + /* .str: PCM files + * .asr: DSP files */ + if (!check_extensions(sf, "str,asr")) + goto fail; + + if (!is_id32be(0x08,sf, "WII ")) + goto fail; + + loop_flag = (read_32bitBE(0x44,sf) != 0); + channels = 2; + start_offset = 0x800; - loop_flag = (read_32bitBE(0x44,streamFile)!=0); - channel_count = 2; - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x40,streamFile); + vgmstream->sample_rate = read_32bitBE(0x40,sf); - switch (read_32bitBE(0x20,streamFile)) { - case 0x4B415354: /* KAST - DSP encoding */ - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = (read_32bitBE(0x3C,streamFile))*14/8/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitBE(0x44,streamFile))*14/8/channel_count; - vgmstream->loop_end_sample = (read_32bitBE(0x48,streamFile))*14/8/channel_count; - } - vgmstream->interleave_block_size = 0x10; - break; - case 0x4B505354: /* KPST - PCM encoding */ - vgmstream->coding_type = coding_PCM16BE; - vgmstream->num_samples = (read_32bitBE(0x3C,streamFile))/2/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitBE(0x44,streamFile))/2/channel_count; - vgmstream->loop_end_sample = (read_32bitBE(0x48,streamFile))/2/channel_count; + switch (read_32bitBE(0x20,sf)) { + case 0x4B415354: /* "KAST" */ + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = (read_32bitBE(0x3C,sf))*14/8/channels; + vgmstream->loop_start_sample = (read_32bitBE(0x44,sf))*14/8/channels; + vgmstream->loop_end_sample = (read_32bitBE(0x48,sf))*14/8/channels; + vgmstream->interleave_block_size = 0x10; + dsp_read_coefs_be(vgmstream, sf, 0x8c, 0x60); + break; + case 0x4B505354: /* "KPST" */ + vgmstream->coding_type = coding_PCM16BE; + vgmstream->num_samples = (read_32bitBE(0x3C,sf))/2/channels; + vgmstream->loop_start_sample = (read_32bitBE(0x44,sf))/2/channels; + vgmstream->loop_end_sample = (read_32bitBE(0x48,sf))/2/channels; + vgmstream->interleave_block_size = 0x10; + break; + default: + goto fail; } - vgmstream->interleave_block_size = 0x10; - break; - default: - goto fail; - } - /* Interleave and Layout settings */ vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_STR_ASR; - if (vgmstream->coding_type == coding_NGC_DSP) { - int i; - for (i=0;i<16;i++) { - vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x8C+i*2,streamFile); - } - if (vgmstream->channels) { - for (i=0;i<16;i++) { - vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0xEC+i*2,streamFile); - } - } - } - - /* 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;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; return vgmstream; - - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/strm_abylight.c b/src/meta/strm_abylight.c index cfdda7f3..dc87cd34 100644 --- a/src/meta/strm_abylight.c +++ b/src/meta/strm_abylight.c @@ -11,11 +11,12 @@ VGMSTREAM* init_vgmstream_strm_abylight(STREAMFILE* sf) { /* checks */ - if ( !check_extensions(sf,"strm") ) + if (!is_id32be(0x00,sf, "STRM")) goto fail; - if (read_32bitBE(0x00,sf) != 0x5354524D) /* "STRM" */ + if (!check_extensions(sf,"strm")) goto fail; + if (read_32bitLE(0x04,sf) != 0x03E8) /* version 1000? */ goto fail; diff --git a/src/meta/xmu.c b/src/meta/xmu.c index 690416c9..47a3f7ec 100644 --- a/src/meta/xmu.c +++ b/src/meta/xmu.c @@ -1,44 +1,47 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* XMU - found in Alter Echo (Xbox) */ -VGMSTREAM * init_vgmstream_xmu(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - size_t start_offset; - int loop_flag, channel_count; - size_t data_size; - - /* check extension */ - if (!check_extensions(streamFile,"xmu")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x584D5520 && /* "XMU " */ - read_32bitBE(0x08,streamFile) != 0x46524D54) /* "FRMT" */ - 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" */ - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_XMU; - 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_IMA; - vgmstream->layout_type = layout_none; - - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* XMU - found in Alter Echo (Xbox) */ +VGMSTREAM* init_vgmstream_xmu(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + size_t start_offset; + int loop_flag, channel_count; + size_t data_size; + + /* checks */ + if (!is_id32be(0x00,sf, "XMU ")) + goto fail; + + if (!check_extensions(sf,"xmu")) + goto fail; + + if (!is_id32be(0x08,sf, "FRMT")) + goto fail; + + + start_offset = 0x800; + channel_count = read_u8(0x14,sf); /* always stereo files */ + loop_flag = read_u8(0x16,sf); /* no Loop found atm */ + data_size = read_u32le(0x7FC,sf); /* next to "DATA" */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_XMU; + vgmstream->sample_rate = read_s32le(0x10,sf); + 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_IMA; + vgmstream->layout_type = layout_none; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +}