diff --git a/doc/FORMATS.md b/doc/FORMATS.md index 369b6b87..3ef348f2 100644 --- a/doc/FORMATS.md +++ b/doc/FORMATS.md @@ -1791,6 +1791,10 @@ different internally (encrypted, different versions, etc) and not always can be - **snds.c** - Sony SNDS header [*SNDS*] - Codecs: ATRAC9 +- **nxof.c** + - Nihon Falcom FDK Opus Header [*NXOF*] + - *nxof*: `.nxopus` + - Codecs: Opus - **scd_pcm.c** - Lunar: Eternal Blue .PCM header [*SCD_PCM*] - *scd_pcm*: `.pcm` diff --git a/src/formats.c b/src/formats.c index 93afc56f..4f789bad 100644 --- a/src/formats.c +++ b/src/formats.c @@ -392,6 +392,7 @@ static const char* extension_list[] = { "nwa", "nwav", "nxa", + "nxopus", //"ogg", //common "ogg_", @@ -1416,6 +1417,7 @@ static const meta_info meta_info_list[] = { {meta_SQUEAKSTREAM, "Torus SqueakStream header"}, {meta_SQUEAKSAMPLE, "Torus SqueakSample header"}, {meta_SNDS, "Sony SNDS header"}, + {meta_NXOF, "Nihon Falcom FDK Opus 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 99a85c6a..252291b0 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -535,6 +535,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index bb2f940c..e1d5a370 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1426,6 +1426,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/meta.h b/src/meta/meta.h index f11b389c..d40f7f47 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -982,4 +982,6 @@ VGMSTREAM* init_vgmstream_squeaksample(STREAMFILE* sf); VGMSTREAM* init_vgmstream_snds(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_nxof(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/meta/nxof.c b/src/meta/nxof.c new file mode 100644 index 00000000..73409b34 --- /dev/null +++ b/src/meta/nxof.c @@ -0,0 +1,53 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* Nihon Falcom FDK NXOpus [Ys X -NORDICS- (Switch)] */ +VGMSTREAM* init_vgmstream_nxof(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels, sample_rate; + size_t data_size, skip = 0; + int32_t num_samples, loop_start, loop_end; + + /* checks */ + if (!is_id32le(0x00, sf, "nxof")) + goto fail; + if (!check_extensions(sf,"nxopus")) + goto fail; + + channels = read_u8(0x05, sf); + sample_rate = read_u32le(0x08, sf); + start_offset = read_u32le(0x18, sf); + data_size = read_u32le(0x1C, sf); + num_samples = read_u32le(0x20, sf); + loop_start = read_u32le(0x30, sf); + loop_end = read_u32le(0x34, sf); + + loop_flag = (loop_end > 0); + + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_NXOF; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + +#ifdef VGM_USE_FFMPEG + skip = switch_opus_get_encoder_delay(start_offset, sf); + vgmstream->codec_data = init_ffmpeg_switch_opus(sf, start_offset, data_size, vgmstream->channels, skip, vgmstream->sample_rate); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; +#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/vgmstream.c b/src/vgmstream.c index 1dcf641c..fc2f9515 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -521,6 +521,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_squeaksample, init_vgmstream_snds, init_vgmstream_adm2, + init_vgmstream_nxof, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_scd_pcm, diff --git a/src/vgmstream_types.h b/src/vgmstream_types.h index 15217c33..600874ad 100644 --- a/src/vgmstream_types.h +++ b/src/vgmstream_types.h @@ -702,6 +702,7 @@ typedef enum { meta_SQUEAKSTREAM, meta_SQUEAKSAMPLE, meta_SNDS, + meta_NXOF, } meta_t;