From 4ea05e512ad1199c9dc44e4406f2e9a3f88d5f25 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 29 Jul 2021 23:20:43 +0200 Subject: [PATCH] cleanup: simplify ogg vorbis meta call --- src/coding/coding.h | 8 +- src/coding/vorbis_custom_decoder.c | 1 - src/coding/vorbis_custom_decoder.h | 1 + src/meta/akb.c | 116 ++++---- src/meta/ao.c | 2 +- src/meta/his.c | 36 +-- src/meta/ikm.c | 2 +- src/meta/meta.h | 4 +- src/meta/mogg.c | 8 +- src/meta/nwav.c | 114 ++++---- src/meta/ogg_vorbis.c | 18 +- src/meta/ogv_3rdeye.c | 2 +- src/meta/rsd.c | 2 +- src/meta/sqex_scd.c | 2 +- src/meta/sqex_sead.c | 2 +- src/meta/wave_segmented.c | 440 ++++++++++++++--------------- src/vgmstream.h | 4 - 17 files changed, 380 insertions(+), 382 deletions(-) diff --git a/src/coding/coding.h b/src/coding/coding.h index 41dd086f..2c40a2f3 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -341,12 +341,12 @@ void free_tac(tac_codec_data* data); typedef struct ogg_vorbis_codec_data ogg_vorbis_codec_data; typedef struct { //todo simplify STREAMFILE *streamfile; - ogg_int64_t start; /* file offset where the Ogg starts */ - ogg_int64_t offset; /* virtual offset, from 0 to size */ - ogg_int64_t size; /* virtual size of the Ogg */ + int64_t start; /* file offset where the Ogg starts */ + int64_t offset; /* virtual offset, from 0 to size */ + int64_t size; /* virtual size of the Ogg */ /* decryption setup */ - void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource); + void (*decryption_callback)(void* ptr, size_t size, size_t nmemb, void* datasource); uint8_t scd_xor; off_t scd_xor_length; uint32_t xor_value; diff --git a/src/coding/vorbis_custom_decoder.c b/src/coding/vorbis_custom_decoder.c index 4dbcd825..bf09b662 100644 --- a/src/coding/vorbis_custom_decoder.c +++ b/src/coding/vorbis_custom_decoder.c @@ -3,7 +3,6 @@ #include "vorbis_custom_decoder.h" #ifdef VGM_USE_VORBIS -#include #define VORBIS_DEFAULT_BUFFER_SIZE 0x8000 /* should be at least the size of the setup header, ~0x2000 */ diff --git a/src/coding/vorbis_custom_decoder.h b/src/coding/vorbis_custom_decoder.h index b3fa05ae..c913d8bf 100644 --- a/src/coding/vorbis_custom_decoder.h +++ b/src/coding/vorbis_custom_decoder.h @@ -6,6 +6,7 @@ /* used by vorbis_custom_decoder.c, but scattered in other .c files */ #ifdef VGM_USE_VORBIS +#include /* custom Vorbis without Ogg layer */ struct vorbis_custom_codec_data { diff --git a/src/meta/akb.c b/src/meta/akb.c index 15a12ea8..e4647142 100644 --- a/src/meta/akb.c +++ b/src/meta/akb.c @@ -3,20 +3,20 @@ #if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC) /* AKB (AAC only) - found in SQEX iOS games */ -VGMSTREAM * init_vgmstream_akb_mp4(STREAMFILE *streamFile) { +VGMSTREAM * init_vgmstream_akb_mp4(STREAMFILE *sf) { VGMSTREAM * vgmstream = NULL; size_t filesize; uint32_t loop_start, loop_end; - if ((uint32_t)read_32bitBE(0, streamFile) != 0x414b4220) goto fail; + if ((uint32_t)read_32bitBE(0, sf) != 0x414b4220) goto fail; - loop_start = read_32bitLE(0x14, streamFile); - loop_end = read_32bitLE(0x18, streamFile); + loop_start = read_32bitLE(0x14, sf); + loop_end = read_32bitLE(0x18, sf); - filesize = get_streamfile_size( streamFile ); + filesize = get_streamfile_size( sf ); - vgmstream = init_vgmstream_mp4_aac_offset( streamFile, 0x20, filesize - 0x20 ); + vgmstream = init_vgmstream_mp4_aac_offset( sf, 0x20, filesize - 0x20 ); if ( !vgmstream ) goto fail; if ( loop_start || loop_end ) { @@ -34,7 +34,7 @@ fail: /* AKB - found in SQEX iOS games */ -VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { +VGMSTREAM * init_vgmstream_akb(STREAMFILE *sf) { VGMSTREAM * vgmstream = NULL; off_t start_offset, extradata_offset = 0; size_t stream_size, header_size, subheader_size = 0, extradata_size = 0; @@ -44,28 +44,28 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { /* checks */ /* .akb.bytes is the usual extension in later games */ - if ( !check_extensions(streamFile, "akb,bytes") ) + if ( !check_extensions(sf, "akb,bytes") ) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x414B4220) /* "AKB " */ + if (read_32bitBE(0x00,sf) != 0x414B4220) /* "AKB " */ goto fail; - if (read_32bitLE(0x08,streamFile) != get_streamfile_size(streamFile)) + if (read_32bitLE(0x08,sf) != get_streamfile_size(sf)) goto fail; /* 0x04(1): version */ - header_size = read_16bitLE(0x06,streamFile); + header_size = read_16bitLE(0x06,sf); - codec = read_8bit(0x0c,streamFile); - channel_count = read_8bit(0x0d,streamFile); - sample_rate = (uint16_t)read_16bitLE(0x0e,streamFile); - num_samples = read_32bitLE(0x10,streamFile); - loop_start = read_32bitLE(0x14,streamFile); - loop_end = read_32bitLE(0x18,streamFile); + codec = read_8bit(0x0c,sf); + channel_count = read_8bit(0x0d,sf); + sample_rate = (uint16_t)read_16bitLE(0x0e,sf); + num_samples = read_32bitLE(0x10,sf); + loop_start = read_32bitLE(0x14,sf); + loop_end = read_32bitLE(0x18,sf); /* possibly more complex, see AKB2 */ if (header_size >= 0x44) { /* v2+ */ - extradata_size = read_16bitLE(0x1c,streamFile); + extradata_size = read_16bitLE(0x1c,sf); /* 0x20+: config? (pan, volume) */ - subheader_size = read_16bitLE(0x28,streamFile); + subheader_size = read_16bitLE(0x28,sf); /* 0x24: file_id? */ /* 0x2b: encryption bitflag if version > 2? */ extradata_offset = header_size + subheader_size; @@ -75,7 +75,7 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { start_offset = header_size; } - stream_size = get_streamfile_size(streamFile) - start_offset; + stream_size = get_streamfile_size(sf) - start_offset; loop_flag = (loop_end > loop_start); @@ -91,14 +91,14 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { case 0x02: { /* MSADPCM [Dragon Quest II (iOS) sfx] */ vgmstream->coding_type = coding_MSADPCM; vgmstream->layout_type = layout_none; - vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02,streamFile); + vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02,sf); /* adjusted samples; bigger or smaller than base samples, akb lib uses these fields instead * (base samples may have more than possible and read over file size otherwise, very strange) * loop_end seems to exist even with loop disabled */ - vgmstream->num_samples = read_32bitLE(extradata_offset + 0x04, streamFile); - vgmstream->loop_start_sample = read_32bitLE(extradata_offset + 0x08, streamFile); - vgmstream->loop_end_sample = read_32bitLE(extradata_offset + 0x0c, streamFile); + vgmstream->num_samples = read_32bitLE(extradata_offset + 0x04, sf); + vgmstream->loop_start_sample = read_32bitLE(extradata_offset + 0x08, sf); + vgmstream->loop_end_sample = read_32bitLE(extradata_offset + 0x0c, sf); break; } @@ -112,7 +112,7 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { /* extradata + 0x04: Ogg loop start offset */ /* oggs have loop info in the comments */ - ogg_vgmstream = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); + ogg_vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); if (ogg_vgmstream) { close_vgmstream(vgmstream); return ogg_vgmstream; @@ -128,7 +128,7 @@ 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)] */ - vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,stream_size); + 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; @@ -145,7 +145,7 @@ 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 */ - vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,stream_size-start_offset); + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset,stream_size-start_offset); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -168,7 +168,7 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) { } /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) goto fail; return vgmstream; @@ -180,22 +180,22 @@ fail: /* AKB2 - found in later SQEX iOS games */ -VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { +VGMSTREAM * init_vgmstream_akb2(STREAMFILE *sf) { VGMSTREAM * vgmstream = NULL; off_t start_offset, material_offset, extradata_offset; size_t material_size, extradata_size, stream_size; int loop_flag = 0, channel_count, encryption_flag, codec, sample_rate, num_samples, loop_start, loop_end; - int total_subsongs, target_subsong = streamFile->stream_index; + int total_subsongs, target_subsong = sf->stream_index; /* check extensions */ /* .akb.bytes is the usual extension in later games */ - if ( !check_extensions(streamFile, "akb,bytes") ) + if ( !check_extensions(sf, "akb,bytes") ) goto fail; /* checks */ - if (read_32bitBE(0x00,streamFile) != 0x414B4232) /* "AKB2" */ + if (read_32bitBE(0x00,sf) != 0x414B4232) /* "AKB2" */ goto fail; - if (read_32bitLE(0x08,streamFile) != get_streamfile_size(streamFile)) + if (read_32bitLE(0x08,sf) != get_streamfile_size(sf)) goto fail; /* 0x04: version */ @@ -203,37 +203,37 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { { off_t table_offset; size_t table_size, entry_size; - off_t akb_header_size = read_16bitLE(0x06, streamFile); - int table_count = read_8bit(0x0c, streamFile); + off_t akb_header_size = read_16bitLE(0x06, sf); + int table_count = read_8bit(0x0c, sf); /* probably each table has its type somewhere, but only seen last table = sound table */ if (table_count > 2) /* 2 only seen in some Mobius FF sound banks */ goto fail; entry_size = 0x10; /* technically every entry/table has its own size but to simplify... */ - table_offset = read_32bitLE(akb_header_size + (table_count-1)*entry_size + 0x04, streamFile); - table_size = read_16bitLE(table_offset + 0x02, streamFile); + table_offset = read_32bitLE(akb_header_size + (table_count-1)*entry_size + 0x04, sf); + table_size = read_16bitLE(table_offset + 0x02, sf); - total_subsongs = read_8bit(table_offset + 0x0f, streamFile); /* can contain 0 entries too */ + total_subsongs = read_8bit(table_offset + 0x0f, sf); /* can contain 0 entries too */ if (target_subsong == 0) target_subsong = 1; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; - material_offset = table_offset + read_32bitLE(table_offset + table_size + (target_subsong-1)*entry_size + 0x04, streamFile); + material_offset = table_offset + read_32bitLE(table_offset + table_size + (target_subsong-1)*entry_size + 0x04, sf); } /** stream header (material) **/ /* 0x00: 0? */ - codec = read_8bit(material_offset+0x01,streamFile); - channel_count = read_8bit(material_offset+0x02,streamFile); - encryption_flag = read_8bit(material_offset+0x03,streamFile); - material_size = read_16bitLE(material_offset+0x04,streamFile); - sample_rate = (uint16_t)read_16bitLE(material_offset+0x06,streamFile); - stream_size = read_32bitLE(material_offset+0x08,streamFile); - num_samples = read_32bitLE(material_offset+0x0c,streamFile); + codec = read_8bit(material_offset+0x01,sf); + channel_count = read_8bit(material_offset+0x02,sf); + encryption_flag = read_8bit(material_offset+0x03,sf); + material_size = read_16bitLE(material_offset+0x04,sf); + sample_rate = (uint16_t)read_16bitLE(material_offset+0x06,sf); + stream_size = read_32bitLE(material_offset+0x08,sf); + num_samples = read_32bitLE(material_offset+0x0c,sf); - loop_start = read_32bitLE(material_offset+0x10,streamFile); - loop_end = read_32bitLE(material_offset+0x14,streamFile); - extradata_size = read_32bitLE(material_offset+0x18,streamFile); + loop_start = read_32bitLE(material_offset+0x10,sf); + loop_end = read_32bitLE(material_offset+0x14,sf); + extradata_size = read_32bitLE(material_offset+0x18,sf); /* rest: ? (empty or 0x3f80) */ loop_flag = (loop_end > loop_start); @@ -269,14 +269,14 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { case 0x02: { /* MSADPCM [The Irregular at Magic High School Lost Zero (Android)] */ vgmstream->coding_type = coding_MSADPCM; vgmstream->layout_type = layout_none; - vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02, streamFile); + vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02, sf); /* adjusted samples; bigger or smaller than base samples, akb lib uses these fields instead * (base samples may have more than possible and read over file size otherwise, very strange) * loop_end seems to exist even with loop disabled */ - vgmstream->num_samples = read_32bitLE(extradata_offset + 0x04, streamFile); - vgmstream->loop_start_sample = read_32bitLE(extradata_offset + 0x08, streamFile); - vgmstream->loop_end_sample = read_32bitLE(extradata_offset + 0x0c, streamFile); + vgmstream->num_samples = read_32bitLE(extradata_offset + 0x04, sf); + vgmstream->loop_start_sample = read_32bitLE(extradata_offset + 0x08, sf); + vgmstream->loop_end_sample = read_32bitLE(extradata_offset + 0x0c, sf); break; } @@ -289,7 +289,7 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { ovmi.total_subsongs = total_subsongs; ovmi.stream_size = stream_size; - ogg_vgmstream = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); + ogg_vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); if (ogg_vgmstream) { ogg_vgmstream->num_streams = vgmstream->num_streams; ogg_vgmstream->stream_size = vgmstream->stream_size; @@ -310,7 +310,7 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { case 0x05: { /* Ogg Vorbis [The World Ends with You (iOS / latest update)] */ ffmpeg_codec_data *ffmpeg_data; - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,stream_size); + ffmpeg_data = init_ffmpeg_offset(sf, start_offset,stream_size); if ( !ffmpeg_data ) goto fail; vgmstream->codec_data = ffmpeg_data; @@ -319,8 +319,8 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { /* When loop_flag num_samples may be much larger than real num_samples (it's fine when looping is off) * Actual num_samples would be loop_end_sample+1, but more testing is needed */ - vgmstream->num_samples = read_32bitLE(material_offset+0x0c,streamFile);//num_samples; - vgmstream->loop_start_sample = read_32bitLE(material_offset+0x10,streamFile);//loop_start; + vgmstream->num_samples = read_32bitLE(material_offset+0x0c,sf);//num_samples; + vgmstream->loop_start_sample = read_32bitLE(material_offset+0x10,sf);//loop_start; vgmstream->loop_end_sample = loop_end; break; } @@ -331,7 +331,7 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) { } /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/ao.c b/src/meta/ao.c index c8af91d3..5c151ff9 100644 --- a/src/meta/ao.c +++ b/src/meta/ao.c @@ -27,7 +27,7 @@ VGMSTREAM* init_vgmstream_ao(STREAMFILE *sf) { /* AlphaOgg defines up to 16 loop points for some reason */ start_offset = 0xc8; - vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, start_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); } #else goto fail; diff --git a/src/meta/his.c b/src/meta/his.c index 121141e9..e9b9fdcd 100644 --- a/src/meta/his.c +++ b/src/meta/his.c @@ -3,49 +3,49 @@ /* HIS - Her Interactive games [Nancy Drew series (PC)] */ -VGMSTREAM * init_vgmstream_his(STREAMFILE *streamFile) { +VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { VGMSTREAM * vgmstream = NULL; int channel_count, loop_flag = 0, bps, sample_rate, num_samples, version; off_t start_offset; /* checks */ - if (!check_extensions(streamFile, "his")) + if (!check_extensions(sf, "his")) goto fail; - if (read_32bitBE(0x00,streamFile) == 0x48657220) { /* "Her Interactive Sound\x1a" */ + if (read_32bitBE(0x00,sf) == 0x48657220) { /* "Her Interactive Sound\x1a" */ /* Nancy Drew: Secrets Can Kill (PC) */ version = 0; - channel_count = read_16bitLE(0x16,streamFile); - sample_rate = read_32bitLE(0x18,streamFile); + channel_count = read_16bitLE(0x16,sf); + sample_rate = read_32bitLE(0x18,sf); /* 0x1c: bitrate */ /* 0x20: block size */ - bps = read_16bitLE(0x22,streamFile); + bps = read_16bitLE(0x22,sf); - if (read_32bitBE(0x24,streamFile) != 0x64617461) /* "data" */ + if (read_32bitBE(0x24,sf) != 0x64617461) /* "data" */ goto fail; - num_samples = pcm_bytes_to_samples(read_32bitLE(0x28,streamFile), channel_count, bps); + num_samples = pcm_bytes_to_samples(read_32bitLE(0x28,sf), channel_count, bps); start_offset = 0x2c; } - else if (read_32bitBE(0x00,streamFile) == 0x48495300) { /* HIS\0 */ + else if (read_32bitBE(0x00,sf) == 0x48495300) { /* HIS\0 */ /* most(?) others */ - version = read_32bitLE(0x04,streamFile); + version = read_32bitLE(0x04,sf); /* 0x08: codec */ - channel_count = read_16bitLE(0x0a,streamFile); - sample_rate = read_32bitLE(0x0c,streamFile); + channel_count = read_16bitLE(0x0a,sf); + sample_rate = read_32bitLE(0x0c,sf); /* 0x10: bitrate */ /* 0x14: block size */ - bps = read_16bitLE(0x16,streamFile); + bps = read_16bitLE(0x16,sf); - num_samples = pcm_bytes_to_samples(read_32bitLE(0x18,streamFile), channel_count, bps); /* true even for Ogg */ + num_samples = pcm_bytes_to_samples(read_32bitLE(0x18,sf), channel_count, bps); /* true even for Ogg */ /* later games use "OggS" */ if (version == 1) start_offset = 0x1c; /* Nancy Drew: The Final Scene (PC) */ - else if (version == 2 && read_32bitBE(0x1e,streamFile) == 0x4F676753) + else if (version == 2 && read_32bitBE(0x1e,sf) == 0x4F676753) start_offset = 0x1e; /* Nancy Drew: The Haunted Carousel (PC) */ - else if (version == 2 && read_32bitBE(0x20,streamFile) == 0x4F676753) + else if (version == 2 && read_32bitBE(0x20,sf) == 0x4F676753) start_offset = 0x20; /* Nancy Drew: The Silent Spy (PC) */ else goto fail; @@ -60,7 +60,7 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *streamFile) { ogg_vorbis_meta_info_t ovmi = {0}; ovmi.meta_type = meta_HIS; - return init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); + return init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); #else goto fail; #endif @@ -89,7 +89,7 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *streamFile) { goto fail; } - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; diff --git a/src/meta/ikm.c b/src/meta/ikm.c index 7c2456eb..57962d15 100644 --- a/src/meta/ikm.c +++ b/src/meta/ikm.c @@ -80,7 +80,7 @@ VGMSTREAM* init_vgmstream_ikm_pc(STREAMFILE* sf) { ovmi.loop_flag = ovmi.loop_end > 0; ovmi.stream_size = read_s32le(0x24, sf); - vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, start_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); } #else goto fail; diff --git a/src/meta/meta.h b/src/meta/meta.h index 957037f5..6f086522 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -137,9 +137,11 @@ typedef struct { off_t scd_xor_length; uint32_t xor_value; + //ov_callbacks *callbacks + } ogg_vorbis_meta_info_t; -VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, ov_callbacks *callbacks, off_t start, const ogg_vorbis_meta_info_t *ovmi); +VGMSTREAM* init_vgmstream_ogg_vorbis_config(STREAMFILE *sf, off_t start, const ogg_vorbis_meta_info_t* ovmi); #endif VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile); diff --git a/src/meta/mogg.c b/src/meta/mogg.c index 9054d235..40be9d99 100644 --- a/src/meta/mogg.c +++ b/src/meta/mogg.c @@ -10,12 +10,12 @@ #include "../coding/coding.h" /* MOGG - Harmonix Music Systems (Guitar Hero)[Unencrypted Type] */ -VGMSTREAM * init_vgmstream_mogg(STREAMFILE *streamFile) { +VGMSTREAM* init_vgmstream_mogg(STREAMFILE *sf) { #ifdef VGM_USE_VORBIS off_t start_offset; /* checks */ - if (!check_extensions(streamFile, "mogg")) + if (!check_extensions(sf, "mogg")) goto fail; { @@ -24,8 +24,8 @@ VGMSTREAM * init_vgmstream_mogg(STREAMFILE *streamFile) { ovmi.meta_type = meta_MOGG; - start_offset = read_32bitLE(0x04, streamFile); - result = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); + start_offset = read_32bitLE(0x04, sf); + result = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); if (result != NULL) { return result; diff --git a/src/meta/nwav.c b/src/meta/nwav.c index 3d2309e2..a9557722 100644 --- a/src/meta/nwav.c +++ b/src/meta/nwav.c @@ -1,57 +1,57 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* NWAV - from Chunsoft games [Fuurai no Shiren Gaiden: Onnakenshi Asuka Kenzan! (PC)] */ -VGMSTREAM * init_vgmstream_nwav(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - - - /* checks */ - /* .nwav: header id (no filenames in bigfiles) */ - if ( !check_extensions(streamFile,"nwav") ) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x4E574156) /* "NWAV" */ - goto fail; - - -#ifdef VGM_USE_VORBIS - { - ogg_vorbis_meta_info_t ovmi = {0}; - int channels; - - /* 0x04: version? */ - /* 0x08: crc? */ - ovmi.stream_size = read_32bitLE(0x0c, streamFile); - ovmi.loop_end = read_32bitLE(0x10, streamFile); /* num_samples, actually */ - /* 0x14: sample rate */ - /* 0x18: bps? (16) */ - channels = read_8bit(0x19, streamFile); - start_offset = read_16bitLE(0x1a, streamFile); - - ovmi.loop_flag = read_16bitLE(0x1c, streamFile) != 0; /* loop count? -1 = loops */ - /* 0x1e: always 2? */ - /* 0x20: always 1? */ - ovmi.loop_start = read_32bitLE(0x24, streamFile); - /* 0x28: always 1? */ - /* 0x2a: always 1? */ - /* 0x2c: always null? */ - - ovmi.meta_type = meta_NWAV; - - /* values are in resulting bytes */ - ovmi.loop_start = ovmi.loop_start / sizeof(int16_t) / channels; - ovmi.loop_end = ovmi.loop_end / sizeof(int16_t) / channels; - - vgmstream = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, start_offset, &ovmi); - } -#else - goto fail; -#endif - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* NWAV - from Chunsoft games [Fuurai no Shiren Gaiden: Onnakenshi Asuka Kenzan! (PC)] */ +VGMSTREAM * init_vgmstream_nwav(STREAMFILE *sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + + + /* checks */ + /* .nwav: header id (no filenames in bigfiles) */ + if ( !check_extensions(sf,"nwav") ) + goto fail; + if (read_32bitBE(0x00,sf) != 0x4E574156) /* "NWAV" */ + goto fail; + + +#ifdef VGM_USE_VORBIS + { + ogg_vorbis_meta_info_t ovmi = {0}; + int channels; + + /* 0x04: version? */ + /* 0x08: crc? */ + ovmi.stream_size = read_32bitLE(0x0c, sf); + ovmi.loop_end = read_32bitLE(0x10, sf); /* num_samples, actually */ + /* 0x14: sample rate */ + /* 0x18: bps? (16) */ + channels = read_8bit(0x19, sf); + start_offset = read_16bitLE(0x1a, sf); + + ovmi.loop_flag = read_16bitLE(0x1c, sf) != 0; /* loop count? -1 = loops */ + /* 0x1e: always 2? */ + /* 0x20: always 1? */ + ovmi.loop_start = read_32bitLE(0x24, sf); + /* 0x28: always 1? */ + /* 0x2a: always 1? */ + /* 0x2c: always null? */ + + ovmi.meta_type = meta_NWAV; + + /* values are in resulting bytes */ + ovmi.loop_start = ovmi.loop_start / sizeof(int16_t) / channels; + ovmi.loop_end = ovmi.loop_end / sizeof(int16_t) / channels; + + vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); + } +#else + goto fail; +#endif + + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ogg_vorbis.c b/src/meta/ogg_vorbis.c index 63c12133..beb13415 100644 --- a/src/meta/ogg_vorbis.c +++ b/src/meta/ogg_vorbis.c @@ -286,21 +286,21 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { * 0x0c(2): PCM block size, 0x0e(2): PCM bps, 0x10: null, 0x18: samples (in PCM bytes) * - .isl: looping table (encrypted like the files) */ if (isl_name) { - STREAMFILE* islFile = NULL; + STREAMFILE* sf_isl = NULL; - islFile = open_streamfile_by_filename(sf, isl_name); + sf_isl = open_streamfile_by_filename(sf, isl_name); - if (!islFile) { + if (!sf_isl) { /* try in ../(file) too since that's how the .isl is stored on disc */ char isl_path[PATH_LIMIT]; snprintf(isl_path, sizeof(isl_path), "../%s", isl_name); - islFile = open_streamfile_by_filename(sf, isl_path); + sf_isl = open_streamfile_by_filename(sf, isl_path); } - if (islFile) { + if (sf_isl) { STREAMFILE* dec_sf = NULL; - dec_sf = setup_ogg_vorbis_streamfile(islFile, cfg); + dec_sf = setup_ogg_vorbis_streamfile(sf_isl, cfg); if (dec_sf) { off_t loop_offset; char basename[PATH_LIMIT]; @@ -327,7 +327,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { close_streamfile(dec_sf); } - close_streamfile(islFile); + close_streamfile(sf_isl); } } } @@ -416,7 +416,7 @@ VGMSTREAM* init_vgmstream_ogg_vorbis(STREAMFILE* sf) { ovmi.meta_type = meta_OGG_VORBIS; } - vgmstream = init_vgmstream_ogg_vorbis_callbacks(temp_sf != NULL ? temp_sf : sf, NULL, start_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_config(temp_sf != NULL ? temp_sf : sf, start_offset, &ovmi); close_streamfile(temp_sf); return vgmstream; @@ -426,7 +426,7 @@ fail: return NULL; } -VGMSTREAM* init_vgmstream_ogg_vorbis_callbacks(STREAMFILE* sf, ov_callbacks* callbacks, off_t start, const ogg_vorbis_meta_info_t *ovmi) { +VGMSTREAM* init_vgmstream_ogg_vorbis_config(STREAMFILE* sf, off_t start, const ogg_vorbis_meta_info_t* ovmi) { VGMSTREAM* vgmstream = NULL; ogg_vorbis_codec_data* data = NULL; ogg_vorbis_io io = {0}; diff --git a/src/meta/ogv_3rdeye.c b/src/meta/ogv_3rdeye.c index 9a930e58..553d5109 100644 --- a/src/meta/ogv_3rdeye.c +++ b/src/meta/ogv_3rdeye.c @@ -27,7 +27,7 @@ VGMSTREAM* init_vgmstream_ogv_3rdeye(STREAMFILE* sf) { ovmi.meta_type = meta_OGV_3RDEYE; ovmi.stream_size = subfile_size; - vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, subfile_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_config(sf, subfile_offset, &ovmi); } #else goto fail; diff --git a/src/meta/rsd.c b/src/meta/rsd.c index e7253425..cb47075f 100644 --- a/src/meta/rsd.c +++ b/src/meta/rsd.c @@ -134,7 +134,7 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { ovmi.meta_type = meta_RSD; close_vgmstream(vgmstream); - vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, start_offset, &ovmi); + vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); if (!vgmstream) goto fail; break; } diff --git a/src/meta/sqex_scd.c b/src/meta/sqex_scd.c index cb53d60f..acc012fd 100644 --- a/src/meta/sqex_scd.c +++ b/src/meta/sqex_scd.c @@ -192,7 +192,7 @@ VGMSTREAM* init_vgmstream_sqex_scd(STREAMFILE* sf) { } /* actual Ogg init */ - ogg_vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, start_offset, &ovmi); + ogg_vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); if (ogg_vgmstream && name_offset) read_string(ogg_vgmstream->stream_name, PATH_LIMIT, name_offset, sf); return ogg_vgmstream; diff --git a/src/meta/sqex_sead.c b/src/meta/sqex_sead.c index 43de6e8f..6a4a75c8 100644 --- a/src/meta/sqex_sead.c +++ b/src/meta/sqex_sead.c @@ -172,7 +172,7 @@ VGMSTREAM* init_vgmstream_sqex_sead(STREAMFILE* sf) { /* 0x18: reserved x2 */ /* 0x20: seek table */ - ogg_vgmstream = init_vgmstream_ogg_vorbis_callbacks(sf, NULL, subfile_offset, &ovmi); + ogg_vgmstream = init_vgmstream_ogg_vorbis_config(sf, subfile_offset, &ovmi); if (ogg_vgmstream) { ogg_vgmstream->num_streams = vgmstream->num_streams; ogg_vgmstream->stream_size = vgmstream->stream_size; diff --git a/src/meta/wave_segmented.c b/src/meta/wave_segmented.c index 51fb0aee..8891cdf2 100644 --- a/src/meta/wave_segmented.c +++ b/src/meta/wave_segmented.c @@ -1,220 +1,220 @@ -#include "meta.h" -#include "../coding/coding.h" -#include "../layout/layout.h" - -#define MAX_SEGMENTS 4 - -/* .WAVE - "EngineBlack" games, segmented [Shantae and the Pirate's Curse (PC/3DS), TMNT: Danger of the Ooze (PS3/3DS)] */ -VGMSTREAM * init_vgmstream_wave_segmented(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t segments_offset; - int loop_flag = 0, channel_count, sample_rate; - int32_t num_samples, loop_start_sample = 0, loop_end_sample = 0; - - segmented_layout_data *data = NULL; - int segment_count, loop_start_segment = 0, loop_end_segment = 0; - - int big_endian; - int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; - int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; - - - /* checks */ - if (!check_extensions(streamFile, "wave")) - goto fail; - - if (read_32bitLE(0x00,streamFile) != 0x4DF72D4A && /* header id */ - read_32bitBE(0x00,streamFile) != 0x4DF72D4A) - goto fail; - if (read_8bit(0x04,streamFile) != 0x01) /* version? */ - goto fail; - - /* PS3/X360 games */ - big_endian = read_32bitBE(0x00,streamFile) == 0x4DF72D4A; - if (big_endian) { - read_32bit = read_32bitBE; - read_16bit = read_16bitBE; - } else { - read_32bit = read_32bitLE; - read_16bit = read_16bitLE; - } - - channel_count = read_8bit(0x05,streamFile); - segment_count = read_16bit(0x06,streamFile); - if (segment_count > MAX_SEGMENTS || segment_count <= 0) goto fail; - - loop_start_segment = read_16bit(0x08, streamFile); - loop_end_segment = read_16bit(0x0a, streamFile); - segments_offset = read_32bit(0x0c, streamFile); - - sample_rate = read_32bit(0x10, streamFile); - num_samples = read_32bit(0x14, streamFile); - /* 0x18: unknown (usually 0, maybe some count) */ - - - /* init layout */ - data = init_layout_segmented(segment_count); - if (!data) goto fail; - - /* parse segments (usually: preload + intro + loop + ending, intro/ending may be skipped) - * Often first segment is ADPCM and rest Ogg; may only have one segment. */ - { - off_t extradata_offset, table_offset, segment_offset; - size_t segment_size; - int32_t segment_samples; - int codec; - int i, ch; - - /* open each segment subfile */ - for (i = 0; i < segment_count; i++) { - codec = read_8bit(segments_offset+0x10*i+0x00, streamFile); - /* 0x01(1): unknown (flag? usually 0x00/0x01/0x02) */ - if (read_8bit(segments_offset+0x10*i+0x02, streamFile) != 0x01) goto fail; /* unknown */ - if (read_8bit(segments_offset+0x10*i+0x03, streamFile) != 0x00) goto fail; /* unknown */ - - segment_samples = read_32bit(segments_offset+0x10*i+0x04, streamFile); - extradata_offset = read_32bit(segments_offset+0x10*i+0x08, streamFile); - table_offset = read_32bit(segments_offset+0x10*i+0x0c, streamFile); - - /* create a sub-VGMSTREAM per segment - * (we'll reopen this streamFile as needed, so each sub-VGMSTREAM is fully independent) */ - switch(codec) { - case 0x02: { /* "adpcm" */ - data->segments[i] = allocate_vgmstream(channel_count, 0); - if (!data->segments[i]) goto fail; - - data->segments[i]->sample_rate = sample_rate; - data->segments[i]->meta_type = meta_WAVE; - data->segments[i]->coding_type = coding_IMA_int; - data->segments[i]->layout_type = layout_none; - data->segments[i]->num_samples = segment_samples; - - if (!vgmstream_open_stream(data->segments[i],streamFile,0x00)) - goto fail; - - /* bizarrely enough channel data isn't sequential (segment0 ch1+ may go after all other segments) */ - for (ch = 0; ch < channel_count; ch++) { - segment_offset = read_32bit(table_offset + 0x04*ch, streamFile); - data->segments[i]->ch[ch].channel_start_offset = - data->segments[i]->ch[ch].offset = segment_offset; - - /* ADPCM setup */ - data->segments[i]->ch[ch].adpcm_history1_32 = read_16bit(extradata_offset+0x04*ch+0x00, streamFile); - data->segments[i]->ch[ch].adpcm_step_index = read_8bit(extradata_offset+0x04*ch+0x02, streamFile); - /* 0x03: reserved */ - } - - break; - } - - case 0x03: { /* "dsp-adpcm" */ - data->segments[i] = allocate_vgmstream(channel_count, 0); - if (!data->segments[i]) goto fail; - - data->segments[i]->sample_rate = sample_rate; - data->segments[i]->meta_type = meta_WAVE; - data->segments[i]->coding_type = coding_NGC_DSP; - data->segments[i]->layout_type = layout_none; - data->segments[i]->num_samples = segment_samples; - - if (!vgmstream_open_stream(data->segments[i],streamFile,0x00)) - goto fail; - - /* bizarrely enough channel data isn't sequential (segment0 ch1+ may go after all other segments) */ - for (ch = 0; ch < channel_count; ch++) { - segment_offset = read_32bit(table_offset + 0x04*ch, streamFile); - data->segments[i]->ch[ch].channel_start_offset = - data->segments[i]->ch[ch].offset = segment_offset; - } - - /* ADPCM setup: 0x06 initial ps/hist1/hist2 (per channel) + 0x20 coefs (per channel) */ - dsp_read_hist(data->segments[i], streamFile, extradata_offset+0x02, 0x06, big_endian); - dsp_read_coefs(data->segments[i], streamFile, extradata_offset+0x06*channel_count+0x00, 0x20, big_endian); - - break; - } - -#ifdef VGM_USE_VORBIS - case 0x04: { /* "vorbis" */ - ogg_vorbis_meta_info_t ovmi = {0}; - - segment_offset = read_32bit(table_offset, streamFile); - segment_size = read_32bitBE(segment_offset, streamFile); /* always BE */ - - ovmi.meta_type = meta_WAVE; - ovmi.stream_size = segment_size; - - data->segments[i] = init_vgmstream_ogg_vorbis_callbacks(streamFile, NULL, segment_offset+0x04, &ovmi); - if (!data->segments[i]) goto fail; - - if (data->segments[i]->num_samples != segment_samples) { - VGM_LOG("WAVE: segment %i samples != num_samples\n", i); - goto fail; - } - - break; - } -#endif - - default: /* others: s16be/s16le/mp3 as referenced in the exe? */ - VGM_LOG("WAVE: unknown codec\n"); - goto fail; - } - } - } - - /* setup segmented VGMSTREAMs */ - if (!setup_layout_segmented(data)) - goto fail; - - - /* parse samples */ - { - int32_t sample_count = 0; - int i; - - loop_flag = (loop_start_segment > 0); - - for (i = 0; i < segment_count; i++) { - if (loop_flag && loop_start_segment == i) { - loop_start_sample = sample_count; - } - - sample_count += data->segments[i]->num_samples; - - if (loop_flag && loop_end_segment-1 == i) { - loop_end_sample = sample_count; - } - } - - if (sample_count != num_samples) { - VGM_LOG("WAVE: total segments samples %i != num_samples %i\n", sample_count, num_samples); - goto fail; - } - } - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = loop_end_sample; - - vgmstream->meta_type = meta_WAVE_segmented; - vgmstream->stream_size = get_streamfile_size(streamFile); /* wrong kbps otherwise */ - - /* .wave can mix codecs, usually first segment is a small ADPCM section) */ - vgmstream->coding_type = (segment_count == 1 ? data->segments[0]->coding_type : data->segments[1]->coding_type); - vgmstream->layout_type = layout_segmented; - vgmstream->layout_data = data; - - return vgmstream; - -fail: - free_layout_segmented(data); - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" +#include "../layout/layout.h" + +#define MAX_SEGMENTS 4 + +/* .WAVE - "EngineBlack" games, segmented [Shantae and the Pirate's Curse (PC/3DS), TMNT: Danger of the Ooze (PS3/3DS)] */ +VGMSTREAM * init_vgmstream_wave_segmented(STREAMFILE *sf) { + VGMSTREAM * vgmstream = NULL; + off_t segments_offset; + int loop_flag = 0, channel_count, sample_rate; + int32_t num_samples, loop_start_sample = 0, loop_end_sample = 0; + + segmented_layout_data *data = NULL; + int segment_count, loop_start_segment = 0, loop_end_segment = 0; + + int big_endian; + int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; + int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; + + + /* checks */ + if (!check_extensions(sf, "wave")) + goto fail; + + if (read_32bitLE(0x00,sf) != 0x4DF72D4A && /* header id */ + read_32bitBE(0x00,sf) != 0x4DF72D4A) + goto fail; + if (read_8bit(0x04,sf) != 0x01) /* version? */ + goto fail; + + /* PS3/X360 games */ + big_endian = read_32bitBE(0x00,sf) == 0x4DF72D4A; + if (big_endian) { + read_32bit = read_32bitBE; + read_16bit = read_16bitBE; + } else { + read_32bit = read_32bitLE; + read_16bit = read_16bitLE; + } + + channel_count = read_8bit(0x05,sf); + segment_count = read_16bit(0x06,sf); + if (segment_count > MAX_SEGMENTS || segment_count <= 0) goto fail; + + loop_start_segment = read_16bit(0x08, sf); + loop_end_segment = read_16bit(0x0a, sf); + segments_offset = read_32bit(0x0c, sf); + + sample_rate = read_32bit(0x10, sf); + num_samples = read_32bit(0x14, sf); + /* 0x18: unknown (usually 0, maybe some count) */ + + + /* init layout */ + data = init_layout_segmented(segment_count); + if (!data) goto fail; + + /* parse segments (usually: preload + intro + loop + ending, intro/ending may be skipped) + * Often first segment is ADPCM and rest Ogg; may only have one segment. */ + { + off_t extradata_offset, table_offset, segment_offset; + size_t segment_size; + int32_t segment_samples; + int codec; + int i, ch; + + /* open each segment subfile */ + for (i = 0; i < segment_count; i++) { + codec = read_8bit(segments_offset+0x10*i+0x00, sf); + /* 0x01(1): unknown (flag? usually 0x00/0x01/0x02) */ + if (read_8bit(segments_offset+0x10*i+0x02, sf) != 0x01) goto fail; /* unknown */ + if (read_8bit(segments_offset+0x10*i+0x03, sf) != 0x00) goto fail; /* unknown */ + + segment_samples = read_32bit(segments_offset+0x10*i+0x04, sf); + extradata_offset = read_32bit(segments_offset+0x10*i+0x08, sf); + table_offset = read_32bit(segments_offset+0x10*i+0x0c, sf); + + /* create a sub-VGMSTREAM per segment + * (we'll reopen this sf as needed, so each sub-VGMSTREAM is fully independent) */ + switch(codec) { + case 0x02: { /* "adpcm" */ + data->segments[i] = allocate_vgmstream(channel_count, 0); + if (!data->segments[i]) goto fail; + + data->segments[i]->sample_rate = sample_rate; + data->segments[i]->meta_type = meta_WAVE; + data->segments[i]->coding_type = coding_IMA_int; + data->segments[i]->layout_type = layout_none; + data->segments[i]->num_samples = segment_samples; + + if (!vgmstream_open_stream(data->segments[i],sf,0x00)) + goto fail; + + /* bizarrely enough channel data isn't sequential (segment0 ch1+ may go after all other segments) */ + for (ch = 0; ch < channel_count; ch++) { + segment_offset = read_32bit(table_offset + 0x04*ch, sf); + data->segments[i]->ch[ch].channel_start_offset = + data->segments[i]->ch[ch].offset = segment_offset; + + /* ADPCM setup */ + data->segments[i]->ch[ch].adpcm_history1_32 = read_16bit(extradata_offset+0x04*ch+0x00, sf); + data->segments[i]->ch[ch].adpcm_step_index = read_8bit(extradata_offset+0x04*ch+0x02, sf); + /* 0x03: reserved */ + } + + break; + } + + case 0x03: { /* "dsp-adpcm" */ + data->segments[i] = allocate_vgmstream(channel_count, 0); + if (!data->segments[i]) goto fail; + + data->segments[i]->sample_rate = sample_rate; + data->segments[i]->meta_type = meta_WAVE; + data->segments[i]->coding_type = coding_NGC_DSP; + data->segments[i]->layout_type = layout_none; + data->segments[i]->num_samples = segment_samples; + + if (!vgmstream_open_stream(data->segments[i],sf,0x00)) + goto fail; + + /* bizarrely enough channel data isn't sequential (segment0 ch1+ may go after all other segments) */ + for (ch = 0; ch < channel_count; ch++) { + segment_offset = read_32bit(table_offset + 0x04*ch, sf); + data->segments[i]->ch[ch].channel_start_offset = + data->segments[i]->ch[ch].offset = segment_offset; + } + + /* ADPCM setup: 0x06 initial ps/hist1/hist2 (per channel) + 0x20 coefs (per channel) */ + dsp_read_hist(data->segments[i], sf, extradata_offset+0x02, 0x06, big_endian); + dsp_read_coefs(data->segments[i], sf, extradata_offset+0x06*channel_count+0x00, 0x20, big_endian); + + break; + } + +#ifdef VGM_USE_VORBIS + case 0x04: { /* "vorbis" */ + ogg_vorbis_meta_info_t ovmi = {0}; + + segment_offset = read_32bit(table_offset, sf); + segment_size = read_32bitBE(segment_offset, sf); /* always BE */ + + ovmi.meta_type = meta_WAVE; + ovmi.stream_size = segment_size; + + data->segments[i] = init_vgmstream_ogg_vorbis_config(sf, segment_offset+0x04, &ovmi); + if (!data->segments[i]) goto fail; + + if (data->segments[i]->num_samples != segment_samples) { + VGM_LOG("WAVE: segment %i samples != num_samples\n", i); + goto fail; + } + + break; + } +#endif + + default: /* others: s16be/s16le/mp3 as referenced in the exe? */ + VGM_LOG("WAVE: unknown codec\n"); + goto fail; + } + } + } + + /* setup segmented VGMSTREAMs */ + if (!setup_layout_segmented(data)) + goto fail; + + + /* parse samples */ + { + int32_t sample_count = 0; + int i; + + loop_flag = (loop_start_segment > 0); + + for (i = 0; i < segment_count; i++) { + if (loop_flag && loop_start_segment == i) { + loop_start_sample = sample_count; + } + + sample_count += data->segments[i]->num_samples; + + if (loop_flag && loop_end_segment-1 == i) { + loop_end_sample = sample_count; + } + } + + if (sample_count != num_samples) { + VGM_LOG("WAVE: total segments samples %i != num_samples %i\n", sample_count, num_samples); + goto fail; + } + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + + vgmstream->meta_type = meta_WAVE_segmented; + vgmstream->stream_size = get_streamfile_size(sf); /* wrong kbps otherwise */ + + /* .wave can mix codecs, usually first segment is a small ADPCM section) */ + vgmstream->coding_type = (segment_count == 1 ? data->segments[0]->coding_type : data->segments[1]->coding_type); + vgmstream->layout_type = layout_segmented; + vgmstream->layout_data = data; + + return vgmstream; + +fail: + free_layout_segmented(data); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.h b/src/vgmstream.h index 8383c636..871e41ed 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -31,10 +31,6 @@ enum { VGMSTREAM_MAX_NUM_SAMPLES = 1000000000 }; /* no ~5h vgm hopefully */ //#define VGM_USE_SPEEX -#ifdef VGM_USE_VORBIS -#include -#endif - #ifdef VGM_USE_MP4V2 #define MP4V2_NO_STDINT_DEFS #include