From 67241ebda55131efe64bc4271a708832da2c8fe1 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 3 Oct 2021 13:48:22 +0200 Subject: [PATCH] Add LPCM .ladpcm [Melty Blood Type Lumina (Sw)] --- src/formats.c | 4 ++- src/libvgmstream.vcxproj | 3 +- src/libvgmstream.vcxproj.filters | 5 ++- src/meta/{lopu.c => lopu_fb.c} | 10 +++--- src/meta/lpcm_fb.c | 61 ++++++++++++++++++++++++++++++++ src/meta/meta.h | 4 ++- src/vgmstream.c | 3 +- src/vgmstream.h | 3 +- 8 files changed, 82 insertions(+), 11 deletions(-) rename src/meta/{lopu.c => lopu_fb.c} (88%) create mode 100644 src/meta/lpcm_fb.c diff --git a/src/formats.c b/src/formats.c index 5b07351f..ad468ca8 100644 --- a/src/formats.c +++ b/src/formats.c @@ -266,6 +266,7 @@ static const char* extension_list[] = { "l", "l00", //txth/reserved [Disney's Dinosaur (PS2)] "laac", //fake extension for .aac (tri-Ace) + "ladpcm", //not fake "laif", //fake extension for .aif (various) "laiff", //fake extension for .aiff "laifc", //fake extension for .aifc @@ -1364,7 +1365,8 @@ static const meta_info meta_info_list[] = { {meta_BNK_RELIC, "Relic BNK header"}, {meta_XSH_XSD_XSS, "Treyarch XSH+XSD/XSS header"}, {meta_PSB, "M2 PSB header"}, - {meta_LOPU, "French-Break LOPU header"}, + {meta_LOPU_FB, "French-Bread LOPU header"}, + {meta_LPCM_FB, "French-Bread LPCM header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index f25dfba9..7fceeb0a 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -215,7 +215,8 @@ - + + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 884630f0..c599c988 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1903,7 +1903,10 @@ meta\Source Files - + + meta\Source Files + + meta\Source Files diff --git a/src/meta/lopu.c b/src/meta/lopu_fb.c similarity index 88% rename from src/meta/lopu.c rename to src/meta/lopu_fb.c index 9d896a3e..f6285319 100644 --- a/src/meta/lopu.c +++ b/src/meta/lopu_fb.c @@ -2,11 +2,11 @@ #include "../coding/coding.h" -/* LOPU - French-Bread's Opus [Melty Blood: Type Lumina (Switch)] */ -VGMSTREAM* init_vgmstream_lopu(STREAMFILE* sf) { +/* LOPU - French-Bread's Opus [Melty Blood: Type Lumina (Switch)] */ +VGMSTREAM* init_vgmstream_lopu_fb(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - int loop_flag, channels, sample_rate; uint32_t start_offset, data_size; + int loop_flag, channels, sample_rate; int32_t num_samples, loop_start, loop_end, skip; /* checks */ @@ -18,7 +18,7 @@ VGMSTREAM* init_vgmstream_lopu(STREAMFILE* sf) { goto fail; start_offset = read_u32le(0x04, sf); - sample_rate = read_u32le(0x08, sf); + sample_rate = read_s32le(0x08, sf); channels = read_s16le(0x0c, sf); /* 0x10: ? (1984) */ num_samples = read_s32le(0x14, sf); @@ -37,7 +37,7 @@ VGMSTREAM* init_vgmstream_lopu(STREAMFILE* sf) { vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; - vgmstream->meta_type = meta_LOPU; + vgmstream->meta_type = meta_LOPU_FB; vgmstream->sample_rate = sample_rate; vgmstream->num_samples = num_samples; vgmstream->loop_start_sample = loop_start; diff --git a/src/meta/lpcm_fb.c b/src/meta/lpcm_fb.c new file mode 100644 index 00000000..0907c8ee --- /dev/null +++ b/src/meta/lpcm_fb.c @@ -0,0 +1,61 @@ +#include "meta.h" +#include "../coding/coding.h" + + +/* LPCM - French-Bread's DSP [Melty Blood: Type Lumina (Switch)] */ +VGMSTREAM* init_vgmstream_lpcm_fb(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + uint32_t start_offset; + int loop_flag, channels, sample_rate; + int32_t num_samples; + + /* checks */ + if (!is_id32be(0x00, sf, "LPCM")) + goto fail; + + /* .ladpcm: real extension (honest) */ + if (!check_extensions(sf, "ladpcm")) + goto fail; + + /* 0x04: dsp offset (0x20) */ + if (read_u32le(0x04, sf) != 0x20) + goto fail; + + num_samples = read_s32le(0x20, sf); + /* 0x24: nibbles? */ + sample_rate = read_s32le(0x28, sf); + /* 0x2c: 0? */ + /* 0x30: 2? */ + /* 0x34: nibbles? */ + /* 0x38: 2? */ + if (read_u32le(0x38, sf) != 2) + goto fail; + + channels = 1; + loop_flag = 0; + + start_offset = 0x78; /* could be 0x80 but this is closer to num_samples */ + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_LPCM_FB; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_none; + + dsp_read_coefs_le(vgmstream, sf, 0x3c, 0); + /* 0x5c: hist? */ + + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/meta.h b/src/meta/meta.h index 5037602d..c2e097fa 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -964,6 +964,8 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf); VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf); -VGMSTREAM* init_vgmstream_lopu(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_lopu_fb(STREAMFILE* sf); + +VGMSTREAM* init_vgmstream_lpcm_fb(STREAMFILE* sf); #endif /*_META_H*/ diff --git a/src/vgmstream.c b/src/vgmstream.c index 95bf6bd8..c42bced8 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -527,7 +527,8 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_bnk_relic, init_vgmstream_xsh_xsd_xss, init_vgmstream_psb, - init_vgmstream_lopu, + init_vgmstream_lopu_fb, + init_vgmstream_lpcm_fb, /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ diff --git a/src/vgmstream.h b/src/vgmstream.h index 3aaf9e59..19684b64 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -747,7 +747,8 @@ typedef enum { meta_BNK_RELIC, meta_XSH_XSD_XSS, meta_PSB, - meta_LOPU, + meta_LOPU_FB, + meta_LPCM_FB, } meta_t;