From 396bfd630a5c80daf2dc18338a58af0dfa1b8995 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 16 Jul 2020 23:16:52 +0200 Subject: [PATCH] Minor cleanup --- src/meta/akb.c | 16 +-- src/meta/gsp_gsb.c | 296 +++++++++++++++++++-------------------- src/meta/naac.c | 127 ++++++++--------- src/meta/sgxd.c | 80 +++++------ src/meta/strm_abylight.c | 136 +++++++++--------- src/meta/ubi_sb.c | 12 +- src/meta/vawx.c | 212 ++++++++++++++-------------- src/meta/x360_cxs.c | 129 +++++++++-------- src/meta/xmv_valve.c | 7 +- 9 files changed, 488 insertions(+), 527 deletions(-) diff --git a/src/meta/akb.c b/src/meta/akb.c index 422a5676..15a12ea8 100644 --- a/src/meta/akb.c +++ b/src/meta/akb.c @@ -128,12 +128,8 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { /* Alt decoding without libvorbis (minor number of beginning samples difference). * Otherwise same output with (inaudible) +-1 lower byte differences due to rounding. */ case 0x05: { /* Ogg Vorbis [Final Fantasy VI (iOS), Dragon Quest II-VI (iOS)] */ - ffmpeg_codec_data *ffmpeg_data; - - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,stream_size); - if ( !ffmpeg_data ) goto fail; - - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,stream_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; /* These oggs have loop info in the comments, too */ @@ -149,12 +145,8 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 0x06: { /* M4A with AAC [The World Ends with You (iPad)] */ /* init_vgmstream_akb_mp4 above has priority, but this works fine too */ - ffmpeg_codec_data *ffmpeg_data; - - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,stream_size-start_offset); - if ( !ffmpeg_data ) goto fail; - - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,stream_size-start_offset); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/gsp_gsb.c b/src/meta/gsp_gsb.c index 71f5bbf1..b04fdf0a 100644 --- a/src/meta/gsp_gsb.c +++ b/src/meta/gsp_gsb.c @@ -1,149 +1,147 @@ -#include "meta.h" -#include "../layout/layout.h" -#include "../coding/coding.h" - -/* GSP+GSB - from Tecmo's Super Swing Golf 1 & 2 (Wii), Quantum Theory (PS3/X360) */ -VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - STREAMFILE * streamHeader = NULL; - int loop_flag, channel_count, sample_rate, num_samples, loop_start, loop_end; - off_t start_offset, chunk_offset, first_offset; - size_t data_size; - int codec; - - - /* checks */ - if (!check_extensions(streamFile,"gsb")) - goto fail; - - streamHeader = open_streamfile_by_ext(streamFile, "gsp"); - if (!streamHeader) goto fail; - - if (read_32bitBE(0x00,streamHeader) != 0x47534E44) /* "GSND" */ - goto fail; - /* 0x04: version? */ - /* 0x08: 1? */ - /* 0x0c: 0? */ - first_offset = read_32bitBE(0x10,streamHeader); /* usually 0x14 */ - - if (!find_chunk_be(streamHeader, 0x48454144,first_offset,1, &chunk_offset,NULL)) /* "HEAD" */ - goto fail; - /* 0x00: header size */ - /* 0x04: num_chunks */ - - if (!find_chunk_be(streamHeader, 0x44415441,first_offset,1, &chunk_offset,NULL)) /* "DATA" */ - goto fail; - data_size = read_32bitBE(chunk_offset + 0x00,streamHeader); - codec = read_32bitBE(chunk_offset + 0x04,streamHeader); - sample_rate = read_32bitBE(chunk_offset + 0x08,streamHeader); - /* 0x0c: always 16? */ - channel_count = read_16bitBE(chunk_offset + 0x0e,streamHeader); - /* 0x10: always 0? */ - num_samples = read_32bitBE(chunk_offset + 0x14,streamHeader); - /* 0x18: always 0? */ - /* 0x1c: unk (varies with codec_id) */ - - if (!find_chunk_be(streamHeader, 0x42534943,first_offset,1, &chunk_offset,NULL)) /* "BSIC" */ - goto fail; - /* 0x00/0x04: probably volume/pan/etc floats (1.0) */ - /* 0x08: null? */ - loop_flag = read_8bit(chunk_offset+0x0c,streamHeader); - loop_start = read_32bitBE(chunk_offset+0x10,streamHeader); - loop_end = read_32bitBE(chunk_offset+0x14,streamHeader); - - //if (!find_chunk_be(streamHeader, 0x4E414D45,first_offset,1, &chunk_offset,NULL)) /* "NAME" */ - // goto fail; - /* 0x00: name_size */ - /* 0x04+: name (same as filename) */ - - - start_offset = 0x00; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_GSP_GSB; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - - switch (codec) { - case 0x04: { /* DSP [Super Swing Golf (Wii)] */ - size_t block_header_size; - size_t num_blocks; - - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_blocked_gsb; - - if (!find_chunk_be(streamHeader, 0x47434558,first_offset,1, &chunk_offset,NULL)) /* "GCEX" */ - goto fail; - - //vgmstream->current_block_size = read_32bitBE(chunk_offset+0x00,streamHeader); - block_header_size = read_32bitBE(chunk_offset+0x04,streamHeader); - num_blocks = read_32bitBE(chunk_offset+0x08,streamHeader); - vgmstream->num_samples = (data_size - block_header_size * num_blocks) / 8 / vgmstream->channels * 14; - /* 0x0c+: unk */ - - dsp_read_coefs_be(vgmstream, streamHeader, chunk_offset+0x18, 0x30); - break; - } -#ifdef VGM_USE_FFMPEG - case 0x08: { /* ATRAC3 [Quantum Theory (PS3)] */ - int block_align, encoder_delay; - - block_align = 0x98 * vgmstream->channels; - encoder_delay = 1024 + 69*2; /* observed default, matches XMA (needed as many files start with garbage) */ - vgmstream->num_samples = atrac3_bytes_to_samples(data_size, block_align) - encoder_delay; - /* fix num_samples as header samples seem to be modified to match altered (49999/48001) sample rates somehow */ - - vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamFile, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* set offset samples (offset 0 jumps to sample 0 > pre-applied delay, and offset end loops after sample end > adjusted delay) */ - vgmstream->loop_start_sample = atrac3_bytes_to_samples(loop_start, block_align); //- encoder_delay - vgmstream->loop_end_sample = atrac3_bytes_to_samples(loop_end, block_align) - encoder_delay; - break; - } - - case 0x09: { /* XMA2 [Quantum Theory (PS3)] */ - ffmpeg_codec_data *ffmpeg_data = NULL; - uint8_t buf[200]; - int32_t bytes; - - if (!find_chunk_be(streamHeader, 0x584D4558,first_offset,1, &chunk_offset,NULL)) /* "XMEX" */ - goto fail; - /* 0x00: fmt0x166 header (BE) */ - /* 0x34: seek table */ - - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, chunk_offset,0x34, data_size, streamHeader, 1); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); - if ( !ffmpeg_data ) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */ - break; - } -#endif - default: - goto fail; - } - - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - close_streamfile(streamHeader); - return vgmstream; - -fail: - close_streamfile(streamHeader); - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../layout/layout.h" +#include "../coding/coding.h" + +/* GSP+GSB - from Tecmo's Super Swing Golf 1 & 2 (Wii), Quantum Theory (PS3/X360) */ +VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + STREAMFILE * streamHeader = NULL; + int loop_flag, channel_count, sample_rate, num_samples, loop_start, loop_end; + off_t start_offset, chunk_offset, first_offset; + size_t data_size; + int codec; + + + /* checks */ + if (!check_extensions(streamFile,"gsb")) + goto fail; + + streamHeader = open_streamfile_by_ext(streamFile, "gsp"); + if (!streamHeader) goto fail; + + if (read_32bitBE(0x00,streamHeader) != 0x47534E44) /* "GSND" */ + goto fail; + /* 0x04: version? */ + /* 0x08: 1? */ + /* 0x0c: 0? */ + first_offset = read_32bitBE(0x10,streamHeader); /* usually 0x14 */ + + if (!find_chunk_be(streamHeader, 0x48454144,first_offset,1, &chunk_offset,NULL)) /* "HEAD" */ + goto fail; + /* 0x00: header size */ + /* 0x04: num_chunks */ + + if (!find_chunk_be(streamHeader, 0x44415441,first_offset,1, &chunk_offset,NULL)) /* "DATA" */ + goto fail; + data_size = read_32bitBE(chunk_offset + 0x00,streamHeader); + codec = read_32bitBE(chunk_offset + 0x04,streamHeader); + sample_rate = read_32bitBE(chunk_offset + 0x08,streamHeader); + /* 0x0c: always 16? */ + channel_count = read_16bitBE(chunk_offset + 0x0e,streamHeader); + /* 0x10: always 0? */ + num_samples = read_32bitBE(chunk_offset + 0x14,streamHeader); + /* 0x18: always 0? */ + /* 0x1c: unk (varies with codec_id) */ + + if (!find_chunk_be(streamHeader, 0x42534943,first_offset,1, &chunk_offset,NULL)) /* "BSIC" */ + goto fail; + /* 0x00/0x04: probably volume/pan/etc floats (1.0) */ + /* 0x08: null? */ + loop_flag = read_8bit(chunk_offset+0x0c,streamHeader); + loop_start = read_32bitBE(chunk_offset+0x10,streamHeader); + loop_end = read_32bitBE(chunk_offset+0x14,streamHeader); + + //if (!find_chunk_be(streamHeader, 0x4E414D45,first_offset,1, &chunk_offset,NULL)) /* "NAME" */ + // goto fail; + /* 0x00: name_size */ + /* 0x04+: name (same as filename) */ + + + start_offset = 0x00; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_GSP_GSB; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + switch (codec) { + case 0x04: { /* DSP [Super Swing Golf (Wii)] */ + size_t block_header_size; + size_t num_blocks; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_blocked_gsb; + + if (!find_chunk_be(streamHeader, 0x47434558,first_offset,1, &chunk_offset,NULL)) /* "GCEX" */ + goto fail; + + //vgmstream->current_block_size = read_32bitBE(chunk_offset+0x00,streamHeader); + block_header_size = read_32bitBE(chunk_offset+0x04,streamHeader); + num_blocks = read_32bitBE(chunk_offset+0x08,streamHeader); + vgmstream->num_samples = (data_size - block_header_size * num_blocks) / 8 / vgmstream->channels * 14; + /* 0x0c+: unk */ + + dsp_read_coefs_be(vgmstream, streamHeader, chunk_offset+0x18, 0x30); + break; + } +#ifdef VGM_USE_FFMPEG + case 0x08: { /* ATRAC3 [Quantum Theory (PS3)] */ + int block_align, encoder_delay; + + block_align = 0x98 * vgmstream->channels; + encoder_delay = 1024 + 69*2; /* observed default, matches XMA (needed as many files start with garbage) */ + vgmstream->num_samples = atrac3_bytes_to_samples(data_size, block_align) - encoder_delay; + /* fix num_samples as header samples seem to be modified to match altered (49999/48001) sample rates somehow */ + + vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamFile, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + /* set offset samples (offset 0 jumps to sample 0 > pre-applied delay, and offset end loops after sample end > adjusted delay) */ + vgmstream->loop_start_sample = atrac3_bytes_to_samples(loop_start, block_align); //- encoder_delay + vgmstream->loop_end_sample = atrac3_bytes_to_samples(loop_end, block_align) - encoder_delay; + break; + } + + case 0x09: { /* XMA2 [Quantum Theory (PS3)] */ + uint8_t buf[0x100]; + int32_t bytes; + + if (!find_chunk_be(streamHeader, 0x584D4558,first_offset,1, &chunk_offset,NULL)) /* "XMEX" */ + goto fail; + /* 0x00: fmt0x166 header (BE) */ + /* 0x34: seek table */ + + bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, chunk_offset,0x34, data_size, streamHeader, 1); + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */ + break; + } +#endif + default: + goto fail; + } + + + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + goto fail; + close_streamfile(streamHeader); + return vgmstream; + +fail: + close_streamfile(streamHeader); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/naac.c b/src/meta/naac.c index b657e598..9f649cf4 100644 --- a/src/meta/naac.c +++ b/src/meta/naac.c @@ -1,66 +1,61 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* .NAAC - from Namco 3DS games (Ace Combat - Assault Horizon Legacy, Taiko no Tatsujin Don to Katsu no Jikuu Daibouken) */ -VGMSTREAM * init_vgmstream_naac(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - size_t data_size; - - /* check extension */ - if ( !check_extensions(streamFile,"naac") ) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x41414320) /* "AAC " */ - goto fail; - if (read_32bitLE(0x04,streamFile) != 0x01) /* version? */ - goto fail; - - start_offset = 0x1000; - loop_flag = (read_32bitLE(0x18,streamFile) != 0); - channel_count = read_32bitLE(0x08,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = read_32bitLE(0x0c,streamFile); - vgmstream->num_samples = read_32bitLE(0x10,streamFile); /* without skip_samples */ - vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile); /* with skip_samples */ - vgmstream->loop_end_sample = read_32bitLE(0x18,streamFile); - /* 0x1c: loop start offset, 0x20: loop end offset (within data) */ - data_size = read_32bitLE(0x24,streamFile); - /* 0x28: unknown; 0x2c: table start offset?; 0x30: seek table (always 0xFD0, padded) */ - - vgmstream->meta_type = meta_NAAC; - -#ifdef VGM_USE_FFMPEG - { - ffmpeg_codec_data *ffmpeg_data = NULL; - - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,data_size); - if (!ffmpeg_data) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* observed default, some files start without silence though seems correct when loop_start=0 */ - if (!ffmpeg_data->skipSamples) /* FFmpeg doesn't seem to use not report it */ - ffmpeg_set_skip_samples(ffmpeg_data, 1024); - vgmstream->num_samples -= 1024; - } -#else - goto fail; -#endif - - /* 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 "../coding/coding.h" + +/* .NAAC - from Namco 3DS games (Ace Combat - Assault Horizon Legacy, Taiko no Tatsujin Don to Katsu no Jikuu Daibouken) */ +VGMSTREAM* init_vgmstream_naac(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + size_t data_size; + + /* check extension */ + if ( !check_extensions(sf,"naac") ) + goto fail; + + /* check header */ + if (read_32bitBE(0x00,sf) != 0x41414320) /* "AAC " */ + goto fail; + if (read_32bitLE(0x04,sf) != 0x01) /* version? */ + goto fail; + + start_offset = 0x1000; + loop_flag = (read_32bitLE(0x18,sf) != 0); + channel_count = read_32bitLE(0x08,sf); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_32bitLE(0x0c,sf); + vgmstream->num_samples = read_32bitLE(0x10,sf); /* without skip_samples */ + vgmstream->loop_start_sample = read_32bitLE(0x14,sf); /* with skip_samples */ + vgmstream->loop_end_sample = read_32bitLE(0x18,sf); + /* 0x1c: loop start offset, 0x20: loop end offset (within data) */ + data_size = read_32bitLE(0x24,sf); + /* 0x28: unknown; 0x2c: table start offset?; 0x30: seek table (always 0xFD0, padded) */ + + vgmstream->meta_type = meta_NAAC; + +#ifdef VGM_USE_FFMPEG + { + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset,data_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + /* observed default, some files start without silence though seems correct when loop_start=0 */ + ffmpeg_set_skip_samples(vgmstream->codec_data, 1024); /* raw AAC doesn't set this */ + vgmstream->num_samples -= 1024; + } +#else + goto fail; +#endif + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/sgxd.c b/src/meta/sgxd.c index b107b22b..91af9aec 100644 --- a/src/meta/sgxd.c +++ b/src/meta/sgxd.c @@ -3,36 +3,36 @@ /* SGXD - Sony/SCEI's format (SGB+SGH / SGD / SGX) */ -VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - STREAMFILE * streamHeader = NULL; +VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* sf_head = NULL; off_t start_offset, data_offset, chunk_offset, name_offset = 0; size_t stream_size; int is_sgx, is_sgb = 0; int loop_flag, channels, codec; int sample_rate, num_samples, loop_start_sample, loop_end_sample; - int total_subsongs, target_subsong = streamFile->stream_index; + int total_subsongs, target_subsong = sf->stream_index; /* check extension, case insensitive */ /* .sgx: header+data (Genji), .sgd: header+data, .sgh/sgd: header/data */ - if (!check_extensions(streamFile,"sgx,sgd,sgb")) + if (!check_extensions(sf,"sgx,sgd,sgb")) goto fail; - is_sgx = check_extensions(streamFile,"sgx"); - is_sgb = check_extensions(streamFile,"sgb"); + is_sgx = check_extensions(sf,"sgx"); + is_sgb = check_extensions(sf,"sgb"); /* SGB+SGH: use SGH as header; otherwise use the current file as header */ if (is_sgb) { - streamHeader = open_streamfile_by_ext(streamFile, "sgh"); - if (!streamHeader) goto fail; + sf_head = open_streamfile_by_ext(sf, "sgh"); + if (!sf_head) goto fail; } else { - streamHeader = streamFile; + sf_head = sf; } /* SGXD base (size 0x10) */ - if (read_32bitBE(0x00,streamHeader) != 0x53475844) /* "SGXD" */ + if (read_32bitBE(0x00,sf_head) != 0x53475844) /* "SGXD" */ goto fail; /* 0x04 SGX: full header_size; SGD/SGH: unknown header_size (counting from 0x0/0x8/0x10, varies) */ /* 0x08 SGX: first chunk offset? (0x10); SGD/SGH: full header_size */ @@ -40,24 +40,24 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { if (is_sgb) { data_offset = 0x00; } else if ( is_sgx ) { - data_offset = read_32bitLE(0x04,streamHeader); + data_offset = read_32bitLE(0x04,sf_head); } else { - data_offset = read_32bitLE(0x08,streamHeader); + data_offset = read_32bitLE(0x08,sf_head); } /* typical chunks: WAVE, RGND, NAME (strings for WAVE or RGND), SEQD (related to SFX), WSUR, WMKR, BUSS */ /* WAVE chunk (size 0x10 + files * 0x38 + optional padding) */ if (is_sgx) { /* position after chunk+size */ - if (read_32bitBE(0x10,streamHeader) != 0x57415645) goto fail; /* "WAVE" */ + if (read_32bitBE(0x10,sf_head) != 0x57415645) goto fail; /* "WAVE" */ chunk_offset = 0x18; } else { - if (!find_chunk_le(streamHeader, 0x57415645,0x10,0, &chunk_offset,NULL)) goto fail; /* "WAVE" */ + if (!find_chunk_le(sf_head, 0x57415645,0x10,0, &chunk_offset,NULL)) goto fail; /* "WAVE" */ } /* 0x04 SGX: unknown; SGD/SGH: chunk length, 0x08 null */ /* check multi-streams (usually only SE containers; Puppeteer) */ - total_subsongs = read_32bitLE(chunk_offset+0x04,streamHeader); + total_subsongs = read_32bitLE(chunk_offset+0x04,sf_head); if (target_subsong == 0) target_subsong = 1; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; @@ -68,11 +68,11 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { /* 0x00 ? (00/01/02) */ if (!is_sgx) /* meaning unknown in .sgx; offset 0 = not a stream (a RGND sample) */ - name_offset = read_32bitLE(chunk_offset+0x04,streamHeader); - codec = read_8bit(chunk_offset+0x08,streamHeader); - channels = read_8bit(chunk_offset+0x09,streamHeader); + name_offset = read_32bitLE(chunk_offset+0x04,sf_head); + codec = read_8bit(chunk_offset+0x08,sf_head); + channels = read_8bit(chunk_offset+0x09,sf_head); /* 0x0a null */ - sample_rate = read_32bitLE(chunk_offset+0x0c,streamHeader); + sample_rate = read_32bitLE(chunk_offset+0x0c,sf_head); /* 0x10 info_type: meaning of the next value * (00=null, 30/40=data size without padding (ADPCM, ATRAC3plus), 80/A0=block size (AC3) */ @@ -80,15 +80,15 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { /* 0x18 unknown (ex. 0x0008/0010/3307/CC02/etc)x2 */ /* 0x1c null */ - num_samples = read_32bitLE(chunk_offset+0x20,streamHeader); - loop_start_sample = read_32bitLE(chunk_offset+0x24,streamHeader); - loop_end_sample = read_32bitLE(chunk_offset+0x28,streamHeader); - stream_size = read_32bitLE(chunk_offset+0x2c,streamHeader); /* stream size (without padding) / interleave (for type3) */ + num_samples = read_32bitLE(chunk_offset+0x20,sf_head); + loop_start_sample = read_32bitLE(chunk_offset+0x24,sf_head); + loop_end_sample = read_32bitLE(chunk_offset+0x28,sf_head); + stream_size = read_32bitLE(chunk_offset+0x2c,sf_head); /* stream size (without padding) / interleave (for type3) */ if (is_sgx) { stream_offset = 0x0; } else{ - stream_offset = read_32bitLE(chunk_offset+0x30,streamHeader); + stream_offset = read_32bitLE(chunk_offset+0x30,sf_head); } /* 0x34 SGX: unknown; SGD/SGH: stream size (with padding) / interleave */ @@ -109,7 +109,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { vgmstream->stream_size = stream_size; vgmstream->meta_type = meta_SGXD; if (name_offset) - read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader); + read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,sf_head); switch (codec) { @@ -121,7 +121,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { #ifdef VGM_USE_VORBIS case 0x02: /* Ogg Vorbis [Ni no Kuni: Wrath of the White Witch Remastered (PC)] (codec hijack?) */ - vgmstream->codec_data = init_ogg_vorbis(streamFile, start_offset, stream_size, NULL); + vgmstream->codec_data = init_ogg_vorbis(sf, start_offset, stream_size, NULL); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_OGG_VORBIS; vgmstream->layout_type = layout_none; @@ -143,7 +143,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 0x04: { /* ATRAC3plus [Kurohyo 1/2 (PSP), BraveStory (PSP)] */ - vgmstream->codec_data = init_ffmpeg_atrac3_riff(streamFile, start_offset, NULL); + vgmstream->codec_data = init_ffmpeg_atrac3_riff(sf, start_offset, NULL); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -163,20 +163,15 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 0x06: { /* AC3 [Tokyo Jungle (PS3), Afrika (PS3)] */ - ffmpeg_codec_data *ffmpeg_data; - - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset, stream_size); - if ( !ffmpeg_data ) goto fail; - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset, stream_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - /* manually set skip_samples if FFmpeg didn't do it */ - if (ffmpeg_data->skipSamples <= 0) { - /* PS3 AC3 consistently has 256 encoder delay samples, and there are ~1000-2000 samples after num_samples. - * Skipping them marginally improves full loops in some Tokyo Jungle tracks (ex. a_1.sgd). */ - ffmpeg_set_skip_samples(ffmpeg_data, 256); - } + /* PS3 AC3 consistently has 256 encoder delay samples, and there are ~1000-2000 samples after num_samples. + * Skipping them marginally improves full loops in some Tokyo Jungle tracks (ex. a_1.sgd). */ + ffmpeg_set_skip_samples(vgmstream->codec_data, 256); + /* SGXD loop/sample values are relative (without skip samples), no need to adjust */ break; @@ -188,15 +183,14 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { goto fail; } - /* open the file for reading */ - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; - if (is_sgb && streamHeader) close_streamfile(streamHeader); + if (is_sgb && sf_head) close_streamfile(sf_head); return vgmstream; fail: - if (is_sgb && streamHeader) close_streamfile(streamHeader); + if (is_sgb && sf_head) close_streamfile(sf_head); close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/strm_abylight.c b/src/meta/strm_abylight.c index c5f884da..4b619d65 100644 --- a/src/meta/strm_abylight.c +++ b/src/meta/strm_abylight.c @@ -1,71 +1,65 @@ -#include "meta.h" -#include "../coding/coding.h" - - -/* .STRM - from Abylight 3DS games [Cursed Castilla (3DS)] */ -VGMSTREAM * init_vgmstream_strm_abylight(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count, sample_rate; - size_t data_size; - - - /* check extension */ - if ( !check_extensions(streamFile,"strm") ) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x5354524D) /* "STRM" */ - goto fail; - if (read_32bitLE(0x04,streamFile) != 0x03E8) /* version 1000? */ - goto fail; - - loop_flag = 0; - channel_count = 2; /* there are various possible fields but all files are stereo */ - sample_rate = read_32bitLE(0x08,streamFile); - - start_offset = 0x1e; - data_size = read_32bitLE(0x10,streamFile); - if (data_size != get_streamfile_size(streamFile) - start_offset) - goto fail; - if (data_size != read_32bitLE(0x18,streamFile)) - goto fail; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = aac_get_samples(streamFile, start_offset, data_size); - - vgmstream->meta_type = meta_STRM_ABYLIGHT; - -#ifdef VGM_USE_FFMPEG - { - ffmpeg_codec_data *ffmpeg_data = NULL; - - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,data_size); - if (!ffmpeg_data) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* apparently none, or maybe ~600 */ - //if (!ffmpeg_data->skipSamples) - // ffmpeg_set_skip_samples(ffmpeg_data, 1024); - //vgmstream->num_samples -= 1024; - } -#else - goto fail; -#endif - - /* 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 "../coding/coding.h" + + +/* .STRM - from Abylight 3DS games [Cursed Castilla (3DS)] */ +VGMSTREAM* init_vgmstream_strm_abylight(STREAMFILE* sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count, sample_rate; + size_t data_size; + + + /* checks */ + if ( !check_extensions(sf,"strm") ) + goto fail; + + if (read_32bitBE(0x00,sf) != 0x5354524D) /* "STRM" */ + goto fail; + if (read_32bitLE(0x04,sf) != 0x03E8) /* version 1000? */ + goto fail; + + loop_flag = 0; + channel_count = 2; /* there are various possible fields but all files are stereo */ + sample_rate = read_32bitLE(0x08,sf); + + start_offset = 0x1e; + data_size = read_32bitLE(0x10,sf); + if (data_size != get_streamfile_size(sf) - start_offset) + goto fail; + if (data_size != read_32bitLE(0x18,sf)) + goto fail; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = aac_get_samples(sf, start_offset, data_size); + + vgmstream->meta_type = meta_STRM_ABYLIGHT; + +#ifdef VGM_USE_FFMPEG + { + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset, data_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + /* apparently none, or maybe ~600 */ + //ffmpeg_set_skip_samples(ffmpeg_data, 1024); + //vgmstream->num_samples -= 1024; + } +#else + goto fail; +#endif + + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ubi_sb.c b/src/meta/ubi_sb.c index c6a0e067..14b9e809 100644 --- a/src/meta/ubi_sb.c +++ b/src/meta/ubi_sb.c @@ -1116,7 +1116,6 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h // Probably a beta/custom encoder that creates some buggy frames, that a real X360 handles ok, but trips FFmpeg // xmaencode decodes correctly if counters are fixed (otherwise has clicks on every frame). case FMT_XMA1: { - ffmpeg_codec_data *ffmpeg_data; uint8_t buf[0x100]; uint32_t sec1_num, sec2_num, sec3_num, bits_per_frame; uint8_t flag; @@ -1147,9 +1146,8 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, header_offset, chunk_size, data_size, sf_data, 1); - ffmpeg_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, data_size); - if (!ffmpeg_data) goto fail; - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, data_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -1158,7 +1156,6 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h } case RAW_XMA1: { - ffmpeg_codec_data *ffmpeg_data; uint8_t buf[0x100]; size_t bytes, chunk_size; off_t header_offset; @@ -1173,9 +1170,8 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, header_offset, chunk_size, sb->stream_size, sf_head, 1); - ffmpeg_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, sb->stream_size); - if (!ffmpeg_data) goto fail; - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, sb->stream_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/vawx.c b/src/meta/vawx.c index fceddac1..ef40a980 100644 --- a/src/meta/vawx.c +++ b/src/meta/vawx.c @@ -1,107 +1,105 @@ -#include "meta.h" -#include "../layout/layout.h" -#include "../coding/coding.h" - - -/* VAWX - found in feelplus games [No More Heroes: Heroes Paradise (PS3/X360), Moon Diver (PS3/X360)] */ -VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, data_size; - int loop_flag = 0, channel_count, codec; - - - /* checks */ - /* .xwv: actual extension [Moon Diver (PS3/X360)] - * .vawx: header id */ - if ( !check_extensions(streamFile, "xwv,vawx") ) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x56415758) /* "VAWX" */ - goto fail; - - loop_flag = read_8bit(0x37,streamFile); - channel_count = read_8bit(0x39,streamFile); - start_offset = 0x800; /* ? read_32bitLE(0x0c,streamFile); */ - codec = read_8bit(0x36,streamFile); /* could be at 0x38 too */ - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* 0x04: filesize */ - /* 0x16: file id */ - vgmstream->num_samples = read_32bitBE(0x3c,streamFile); - vgmstream->sample_rate = read_32bitBE(0x40,streamFile); - - vgmstream->meta_type = meta_VAWX; - - switch(codec) { - case 2: /* PS-ADPCM */ - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = channel_count == 6 ? layout_blocked_vawx : layout_interleave; - vgmstream->interleave_block_size = 0x10; - - vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile); - vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile); - - break; - -#ifdef VGM_USE_FFMPEG - case 1: { /* XMA2 */ - ffmpeg_codec_data *ffmpeg_data = NULL; - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; - - data_size = get_streamfile_size(streamFile)-start_offset; - block_size = 0x10000; /* VAWX default */ - block_count = (uint16_t)read_16bitBE(0x3A, streamFile); /* also at 0x56 */ - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); - if ( !ffmpeg_data ) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile); - vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile); - - //todo fix loops/samples vs ATRAC3 - /* may be only applying end_skip to num_samples? */ - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); - break; - } - - case 7: { /* ATRAC3 */ - int block_align, encoder_delay; - - data_size = read_32bitBE(0x54,streamFile); - block_align = 0x98 * vgmstream->channels; - encoder_delay = 1024 + 69*2; /* observed default, matches XMA (needed as many files start with garbage) */ - vgmstream->num_samples = atrac3_bytes_to_samples(data_size, block_align) - encoder_delay; /* original samples break looping in some files otherwise */ - - vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamFile, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* set offset samples (offset 0 jumps to sample 0 > pre-applied delay, and offset end loops after sample end > adjusted delay) */ - vgmstream->loop_start_sample = atrac3_bytes_to_samples(read_32bitBE(0x44,streamFile), block_align); //- encoder_delay - vgmstream->loop_end_sample = atrac3_bytes_to_samples(read_32bitBE(0x48,streamFile), block_align) - encoder_delay; - break; - } -#endif - default: - goto fail; - - } - - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../layout/layout.h" +#include "../coding/coding.h" + + +/* VAWX - found in feelplus games [No More Heroes: Heroes Paradise (PS3/X360), Moon Diver (PS3/X360)] */ +VGMSTREAM* init_vgmstream_vawx(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset, data_size; + int loop_flag = 0, channel_count, codec; + + + /* checks */ + /* .xwv: actual extension [Moon Diver (PS3/X360)] + * .vawx: header id */ + if ( !check_extensions(sf, "xwv,vawx") ) + goto fail; + if (read_32bitBE(0x00,sf) != 0x56415758) /* "VAWX" */ + goto fail; + + loop_flag = read_8bit(0x37,sf); + channel_count = read_8bit(0x39,sf); + start_offset = 0x800; /* ? read_32bitLE(0x0c,sf); */ + codec = read_8bit(0x36,sf); /* could be at 0x38 too */ + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* 0x04: filesize */ + /* 0x16: file id */ + vgmstream->num_samples = read_32bitBE(0x3c,sf); + vgmstream->sample_rate = read_32bitBE(0x40,sf); + + vgmstream->meta_type = meta_VAWX; + + switch(codec) { + case 2: /* PS-ADPCM */ + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = channel_count == 6 ? layout_blocked_vawx : layout_interleave; + vgmstream->interleave_block_size = 0x10; + + vgmstream->loop_start_sample = read_32bitBE(0x44,sf); + vgmstream->loop_end_sample = read_32bitBE(0x48,sf); + + break; + +#ifdef VGM_USE_FFMPEG + case 1: { /* XMA2 */ + uint8_t buf[0x100]; + int32_t bytes, block_size, block_count; + + data_size = get_streamfile_size(sf)-start_offset; + block_size = 0x10000; /* VAWX default */ + block_count = (uint16_t)read_16bitBE(0x3A, sf); /* also at 0x56 */ + + bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); + vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + vgmstream->loop_start_sample = read_32bitBE(0x44,sf); + vgmstream->loop_end_sample = read_32bitBE(0x48,sf); + + //todo fix loops/samples vs ATRAC3 + /* may be only applying end_skip to num_samples? */ + xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); + break; + } + + case 7: { /* ATRAC3 */ + int block_align, encoder_delay; + + data_size = read_32bitBE(0x54,sf); + block_align = 0x98 * vgmstream->channels; + encoder_delay = 1024 + 69*2; /* observed default, matches XMA (needed as many files start with garbage) */ + vgmstream->num_samples = atrac3_bytes_to_samples(data_size, block_align) - encoder_delay; /* original samples break looping in some files otherwise */ + + vgmstream->codec_data = init_ffmpeg_atrac3_raw(sf, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + /* set offset samples (offset 0 jumps to sample 0 > pre-applied delay, and offset end loops after sample end > adjusted delay) */ + vgmstream->loop_start_sample = atrac3_bytes_to_samples(read_32bitBE(0x44,sf), block_align); //- encoder_delay + vgmstream->loop_end_sample = atrac3_bytes_to_samples(read_32bitBE(0x48,sf), block_align) - encoder_delay; + break; + } +#endif + default: + goto fail; + + } + + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/x360_cxs.c b/src/meta/x360_cxs.c index 5e5df728..eb080a4a 100644 --- a/src/meta/x360_cxs.c +++ b/src/meta/x360_cxs.c @@ -1,66 +1,63 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* CXS - found in Eternal Sonata (X360) */ -VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - /* checks */ - if ( !check_extensions(streamFile,"cxs")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x43585320) /* "CXS " */ - goto fail; - - loop_flag = read_32bitBE(0x18,streamFile) > 0; - channel_count = read_32bitBE(0x0c,streamFile); - start_offset = read_32bitBE(0x04,streamFile) + read_32bitBE(0x28,streamFile); /* assumed, seek table always at 0x800 */ - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* 0x04: data start? */ - vgmstream->sample_rate = read_32bitBE(0x08,streamFile); - vgmstream->num_samples = read_32bitBE(0x10,streamFile); - vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile); - vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile); - /* 0x1c: below */ - - vgmstream->meta_type = meta_X360_CXS; - -#ifdef VGM_USE_FFMPEG - { - ffmpeg_codec_data *ffmpeg_data = NULL; - uint8_t buf[100]; - size_t bytes, datasize, block_size, block_count; - - block_count = read_32bitBE(0x1c,streamFile); - block_size = read_32bitBE(0x20,streamFile); - datasize = read_32bitBE(0x24,streamFile); - - bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - if (bytes <= 0) goto fail; - - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize); - if ( !ffmpeg_data ) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset,datasize, 0, 0,1); /* num samples are ok */ - } -#else - goto fail; -#endif - - /* 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 "../coding/coding.h" + +/* CXS - found in Eternal Sonata (X360) */ +VGMSTREAM* init_vgmstream_x360_cxs(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + + /* checks */ + if ( !check_extensions(sf,"cxs")) + goto fail; + if (read_32bitBE(0x00,sf) != 0x43585320) /* "CXS " */ + goto fail; + + loop_flag = read_32bitBE(0x18,sf) > 0; + channel_count = read_32bitBE(0x0c,sf); + start_offset = read_32bitBE(0x04,sf) + read_32bitBE(0x28,sf); /* assumed, seek table always at 0x800 */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* 0x04: data start? */ + vgmstream->sample_rate = read_32bitBE(0x08,sf); + vgmstream->num_samples = read_32bitBE(0x10,sf); + vgmstream->loop_start_sample = read_32bitBE(0x14,sf); + vgmstream->loop_end_sample = read_32bitBE(0x18,sf); + /* 0x1c: below */ + + vgmstream->meta_type = meta_X360_CXS; + +#ifdef VGM_USE_FFMPEG + { + uint8_t buf[0x100]; + size_t bytes, datasize, block_size, block_count; + + block_count = read_32bitBE(0x1c,sf); + block_size = read_32bitBE(0x20,sf); + datasize = read_32bitBE(0x24,sf); + + bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); + if (bytes <= 0) goto fail; + + vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,datasize); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + xma_fix_raw_samples(vgmstream, sf, start_offset,datasize, 0, 0,1); /* num samples are ok */ + } +#else + goto fail; +#endif + + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/xmv_valve.c b/src/meta/xmv_valve.c index 9573b612..966287a0 100644 --- a/src/meta/xmv_valve.c +++ b/src/meta/xmv_valve.c @@ -142,7 +142,6 @@ VGMSTREAM *init_vgmstream_xmv_valve(STREAMFILE *streamFile) { break; #ifdef VGM_USE_FFMPEG case 0x01: { /* XMA */ - ffmpeg_codec_data *ffmpeg_data; uint8_t buf[0x100]; int block_count, block_size; size_t bytes; @@ -152,10 +151,8 @@ VGMSTREAM *init_vgmstream_xmv_valve(STREAMFILE *streamFile) { bytes = ffmpeg_make_riff_xma2(buf, 0x100, num_samples, data_size, channels, sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size); - if (!ffmpeg_data) goto fail; - - vgmstream->codec_data = ffmpeg_data; + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; vgmstream->loop_end_sample -= loop_end_skip;