From fcc728c8b15ec88be82fc169f7af3a0310b6ae8e Mon Sep 17 00:00:00 2001 From: bxaimc Date: Wed, 1 Aug 2018 01:24:26 -0400 Subject: [PATCH] Add Entergram NXA Opus --- src/formats.c | 1 + src/meta/meta.h | 1 + src/meta/opus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/vgmstream.c | 1 + 4 files changed, 75 insertions(+) diff --git a/src/formats.c b/src/formats.c index 75dfc06e..8ca57a37 100644 --- a/src/formats.c +++ b/src/formats.c @@ -244,6 +244,7 @@ static const char* extension_list[] = { "npsf", //fake extension/header id for .nps (to be removed) "nus3bank", "nwa", + "nxa", //"ogg", //common "ogl", diff --git a/src/meta/meta.h b/src/meta/meta.h index 3fc10128..b7863854 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -679,6 +679,7 @@ VGMSTREAM * init_vgmstream_opus_nop(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_opus_shinen(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_opus_nus3(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_opus_nlsd(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_opus_nxa(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_pc_al2(STREAMFILE * streamFile); diff --git a/src/meta/opus.c b/src/meta/opus.c index 5d010bfd..75e69290 100644 --- a/src/meta/opus.c +++ b/src/meta/opus.c @@ -332,3 +332,75 @@ VGMSTREAM * init_vgmstream_opus_nlsd(STREAMFILE *streamFile) { fail: return NULL; } + +/* Entergram NXA Opus [Higurashi no Naku Koro ni Hou (Switch)] */ +VGMSTREAM * init_vgmstream_opus_nxa(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag = 0, channel_count; + size_t data_size, skip = 0; + + /* checks */ + if (!check_extensions(streamFile, "nxa")) + goto fail; + if (read_32bitBE(0x00, streamFile) != 0x4E584131) /* "NXA1" */ + goto fail; + + channel_count = read_16bitLE(0x10, streamFile); + skip = read_16bitLE(0x16, streamFile); + data_size = read_32bitLE(0x08, streamFile)-0x30; + start_offset = 0x30; + + /* TODO: Determine if loop points are stored externally. No visible loop points in header */ + loop_flag = 0; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->num_samples = read_32bitLE(0x20, streamFile); + vgmstream->sample_rate = read_32bitLE(0x0C, streamFile); + vgmstream->meta_type = meta_OPUS; + +#ifdef VGM_USE_FFMPEG + { + uint8_t buf[0x100]; + size_t bytes; + ffmpeg_custom_config cfg = { 0 }; + ffmpeg_codec_data *ffmpeg_data; + + bytes = ffmpeg_make_opus_header(buf, 0x100, vgmstream->channels, skip, vgmstream->sample_rate); + if (bytes <= 0) goto fail; + + cfg.type = FFMPEG_SWITCH_OPUS; + + ffmpeg_data = init_ffmpeg_config(streamFile, buf, bytes, start_offset, data_size, &cfg); + if (!ffmpeg_data) goto fail; + + vgmstream->codec_data = ffmpeg_data; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + if (ffmpeg_data->skipSamples <= 0) { + ffmpeg_set_skip_samples(ffmpeg_data, skip); + } + + if (vgmstream->num_samples == 0) { + vgmstream->num_samples = switch_opus_get_samples(start_offset, data_size, + vgmstream->sample_rate, streamFile) - skip; + } + } +#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; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index 357466c0..a1867898 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -373,6 +373,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { init_vgmstream_opus_shinen, init_vgmstream_opus_nus3, init_vgmstream_opus_nlsd, + init_vgmstream_opus_nxa, init_vgmstream_pc_al2, init_vgmstream_pc_ast, init_vgmstream_naac,