From 9d94fdb033a6ad438cfbc97fa5f527aa73bc55a2 Mon Sep 17 00:00:00 2001 From: Nathan Benichou Date: Sat, 1 Sep 2018 15:21:46 +0200 Subject: [PATCH] Update rfrm.c Support for LABL part in RFRM CSMP files --- src/meta/rfrm.c | 62 ++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/meta/rfrm.c b/src/meta/rfrm.c index 44327a09..dd80db47 100644 --- a/src/meta/rfrm.c +++ b/src/meta/rfrm.c @@ -1,15 +1,14 @@ #include "meta.h" #include "../coding/coding.h" - /* RFTM - Retro Studios format [Donkey Kong Country Tropical Freeze (WiiU)] */ -VGMSTREAM * init_vgmstream_rfrm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, header_offset; - size_t interleave; +VGMSTREAM *init_vgmstream_rfrm(STREAMFILE *streamFile) +{ + VGMSTREAM *vgmstream = NULL; + off_t fmta_offset = 0x20, header_offset, start_offset; + size_t stream_size, interleave; int loop_flag, channel_count; - /* checks */ if (!check_extensions(streamFile, "csmp")) goto fail; @@ -20,37 +19,46 @@ VGMSTREAM * init_vgmstream_rfrm(STREAMFILE *streamFile) { goto fail; if (read_32bitBE(0x14, streamFile) != 0x43534D50) /* "CSMP" */ goto fail; - if (read_32bitBE(0x3d, streamFile) != 0x44415441) /* "DATA" */ + + stream_size = read_32bitBE(0x08, streamFile) - 0x38; /* stream size is counted from FMTA or LABL, the fixed size FMTA part can already be removed */ + + if (read_32bitBE(fmta_offset, streamFile) == 0x4C41424C) /* "LABL" */ + { + size_t labl_size = 0x18 + read_32bitBE(0x28, streamFile); /* the size of the LABL part is variable */ + fmta_offset += labl_size; /* the FMTA part have been moved by the LABL part */ + stream_size -= labl_size; /* remove the LABL part */ + } + + header_offset = fmta_offset + 0x38; /* where the first DSP sub-file starts */ + start_offset = header_offset + 0x60; /* skip DSP header */ + + channel_count = read_32bitBE(fmta_offset + 0x15, streamFile); + loop_flag = read_16bitBE(header_offset + 0x0C, streamFile); /* read loop flag in the first DSP sub-file */ + + interleave = stream_size / channel_count; /* each DSP sub-file is a channel */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; - channel_count = read_32bitBE(0x35, streamFile); - - header_offset = 0x58; - loop_flag = read_16bitBE(header_offset+0x0c,streamFile); - - start_offset = header_offset + 0x60; - interleave = (get_streamfile_size(streamFile) - header_offset) / channel_count; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - vgmstream->meta_type = meta_RFRM; - vgmstream->sample_rate = read_32bitBE(header_offset+0x08,streamFile); - vgmstream->num_samples = read_32bitBE(header_offset+0x00,streamFile); - vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset+0x10,streamFile)); - vgmstream->loop_end_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset+0x14,streamFile))+1; + + /* read DSP header */ + vgmstream->sample_rate = read_32bitBE(header_offset + 0x08, streamFile); + vgmstream->num_samples = read_32bitBE(header_offset + 0x00, streamFile); + vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset + 0x10, streamFile)); + vgmstream->loop_end_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset + 0x14, streamFile)) + 1; if (vgmstream->loop_end_sample > vgmstream->num_samples) /* ? */ vgmstream->loop_end_sample = vgmstream->num_samples; vgmstream->coding_type = coding_NGC_DSP; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = interleave; - dsp_read_coefs_be(vgmstream, streamFile, header_offset+0x1c, interleave); - dsp_read_hist_be(vgmstream, streamFile, header_offset+0x40, interleave); + dsp_read_coefs_be(vgmstream, streamFile, header_offset + 0x1C, interleave); + dsp_read_hist_be(vgmstream, streamFile, header_offset + 0x40, interleave); - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) goto fail; return vgmstream;