From 27bcba48a9b3fed3d0f84f61e276b48209e7bd53 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 16 Jul 2020 21:43:01 +0200 Subject: [PATCH] Codec internal cleanup and moved out of vgmstream.h --- src/coding/acm_decoder.c | 32 +- src/coding/at3plus_decoder.c | 8 + src/coding/coding.h | 552 ++++++++++++++++++----------- src/coding/ffmpeg_decoder.c | 76 ++-- src/coding/g719_decoder.c | 20 +- src/coding/hca_decoder.c | 52 ++- src/coding/vorbis_custom_decoder.h | 52 ++- src/meta/hca.c | 58 +-- src/vgmstream.c | 9 +- src/vgmstream.h | 202 +---------- 10 files changed, 548 insertions(+), 513 deletions(-) diff --git a/src/coding/acm_decoder.c b/src/coding/acm_decoder.c index 9814752a..cd701d41 100644 --- a/src/coding/acm_decoder.c +++ b/src/coding/acm_decoder.c @@ -5,15 +5,16 @@ /* libacm 1.2 (despite what libacm.h says) from: https://github.com/markokr/libacm */ typedef struct { - STREAMFILE *streamfile; + STREAMFILE* streamfile; /* reference */ int offset; } acm_io_config; -static int acm_read_streamfile(void *ptr, int size, int n, void *arg); -static int acm_seek_streamfile(void *arg, int offset, int whence); -static int acm_get_length_streamfile(void *arg); -acm_codec_data *init_acm(STREAMFILE *streamFile, int force_channel_number) { +static int acm_read_streamfile(void* ptr, int size, int n, void* arg); +static int acm_seek_streamfile(void* arg, int offset, int whence); +static int acm_get_length_streamfile(void* arg); + +acm_codec_data* init_acm(STREAMFILE* sf, int force_channel_number) { acm_codec_data* data = NULL; char filename[PATH_LIMIT]; @@ -24,15 +25,15 @@ acm_codec_data *init_acm(STREAMFILE *streamFile, int force_channel_number) { data->io_config = calloc(1,sizeof(acm_io_config)); if (!data->io_config) goto fail; - streamFile->get_name(streamFile,filename,sizeof(filename)); - data->streamfile = open_streamfile(streamFile,filename); + get_streamfile_name(sf, filename, sizeof(filename)); + data->streamfile = open_streamfile(sf,filename); if (!data->streamfile) goto fail; /* Setup libacm decoder, needs read callbacks and a parameter for said callbacks */ { - ACMStream *handle = NULL; + ACMStream* handle = NULL; int res; - acm_io_config *io_config = data->io_config; + acm_io_config* io_config = data->io_config; acm_io_callbacks io_callbacks = {0}; io_config->offset = 0; @@ -60,8 +61,8 @@ fail: return NULL; } -void decode_acm(acm_codec_data *data, sample * outbuf, int32_t samples_to_do, int channelspacing) { - ACMStream * acm = data->handle; +void decode_acm(acm_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channelspacing) { + ACMStream* acm = data->handle; int32_t samples_read = 0; while (samples_read < samples_to_do) { @@ -79,14 +80,14 @@ void decode_acm(acm_codec_data *data, sample * outbuf, int32_t samples_to_do, in } } -void reset_acm(acm_codec_data *data) { +void reset_acm(acm_codec_data* data) { if (!data || !data->handle) return; acm_seek_pcm(data->handle, 0); } -void free_acm(acm_codec_data *data) { +void free_acm(acm_codec_data* data) { if (!data) return; @@ -96,6 +97,11 @@ void free_acm(acm_codec_data *data) { free(data); } +STREAMFILE* acm_get_streamfile(acm_codec_data* data) { + if (!data) return NULL; + return data->streamfile; +} + /* ******************************* */ static int acm_read_streamfile(void *ptr, int size, int n, void *arg) { diff --git a/src/coding/at3plus_decoder.c b/src/coding/at3plus_decoder.c index ff00f8bb..9347d8a7 100644 --- a/src/coding/at3plus_decoder.c +++ b/src/coding/at3plus_decoder.c @@ -4,6 +4,14 @@ #ifdef VGM_USE_MAIATRAC3PLUS #include "maiatrac3plus.h" +struct maiatrac3plus_codec_data { + sample_t* buffer; + int channels; + int samples_discard; + void* handle; +}; + + maiatrac3plus_codec_data *init_at3plus() { maiatrac3plus_codec_data *data = malloc(sizeof(maiatrac3plus_codec_data)); diff --git a/src/coding/coding.h b/src/coding/coding.h index 41b90965..2854c03a 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -4,39 +4,41 @@ #include "../vgmstream.h" /* adx_decoder */ -void decode_adx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes, coding_t coding_type); -void adx_next_key(VGMSTREAMCHANNEL * stream); +void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes, coding_t coding_type); +void adx_next_key(VGMSTREAMCHANNEL* stream); + /* g721_decoder */ -void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void g72x_init_state(struct g72x_state *state_ptr); +void decode_g721(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void g72x_init_state(struct g72x_state* state_ptr); + /* ima_decoder */ -void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first); -void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_wv6_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_alp_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_blitz_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_mtf_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); +void decode_standard_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo, int is_high_first); +void decode_3ds_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_snds_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_otns_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_wv6_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_alp_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ffta2_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_blitz_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_mtf_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); -void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); -void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); +void decode_ms_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); +void decode_ref_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); -void decode_xbox_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); -void decode_xbox_ima_mch(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); -void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_fsb_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_wwise_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_awc_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int codec_config); -void decode_h4m_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, uint16_t frame_format); +void decode_xbox_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); +void decode_xbox_ima_mch(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_nds_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_dat4_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_rad_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); +void decode_rad_ima_mono(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_apple_ima4(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_fsb_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_wwise_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_awc_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ubi_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int codec_config); +void decode_h4m_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, uint16_t frame_format); void decode_cd_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); size_t ima_bytes_to_samples(size_t bytes, int channels); size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels); @@ -44,149 +46,181 @@ size_t xbox_ima_bytes_to_samples(size_t bytes, int channels); size_t dat4_ima_bytes_to_samples(size_t bytes, int channels); size_t apple_ima4_bytes_to_samples(size_t bytes, int channels); + /* ngc_dsp_decoder */ -void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_ngc_dsp_subint(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave); +void decode_ngc_dsp(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ngc_dsp_subint(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave); size_t dsp_bytes_to_samples(size_t bytes, int channels); int32_t dsp_nibbles_to_samples(int32_t nibbles); -void dsp_read_coefs_be(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing); -void dsp_read_coefs_le(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing); -void dsp_read_coefs(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing, int be); -void dsp_read_hist_be(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing); -void dsp_read_hist_le(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing); -void dsp_read_hist(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing, int be); +void dsp_read_coefs_be(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing); +void dsp_read_coefs_le(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing); +void dsp_read_coefs(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing, int be); +void dsp_read_hist_be(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing); +void dsp_read_hist_le(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing); +void dsp_read_hist(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, off_t spacing, int be); + /* ngc_dtk_decoder */ -void decode_ngc_dtk(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ngc_dtk(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); + /* ngc_afc_decoder */ -void decode_ngc_afc(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ngc_afc(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* vadpcm_decoder */ -void decode_vadpcm(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int order); +void decode_vadpcm(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int order); //int32_t vadpcm_bytes_to_samples(size_t bytes, int channels); void vadpcm_read_coefs_be(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset, int order, int entries, int ch); + /* pcm_decoder */ -void decode_pcm16le(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm16be(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm16_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); -void decode_pcm8(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm8_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm8_unsigned(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm8_sb(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcm4(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_pcm4_unsigned(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_ulaw(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_ulaw_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_alaw(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_pcmfloat(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); +void decode_pcm16le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm16be(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm16_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); +void decode_pcm8(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm8_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm8_unsigned(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm8_sb(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm4(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_pcm4_unsigned(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ulaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcmfloat(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample); + /* psx_decoder */ void decode_psx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags, int config); void decode_psx_configurable(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size, int config); -void decode_psx_pivotal(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size); -int ps_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t * out_loop_start, int32_t * out_loop_end); -int ps_find_loop_offsets_full(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t * out_loop_start, int32_t * out_loop_end); -size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int discard_empty); +void decode_psx_pivotal(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size); +int ps_find_loop_offsets(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t* out_loop_start, int32_t* out_loop_end); +int ps_find_loop_offsets_full(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t* out_loop_start, int32_t* out_loop_end); +size_t ps_find_padding(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, size_t interleave, int discard_empty); size_t ps_bytes_to_samples(size_t bytes, int channels); size_t ps_cfg_bytes_to_samples(size_t bytes, size_t frame_size, int channels); -int ps_check_format(STREAMFILE *streamFile, off_t offset, size_t max); +int ps_check_format(STREAMFILE* sf, off_t offset, size_t max); + /* psv_decoder */ -void decode_hevag(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_hevag(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* xa_decoder */ -void decode_xa(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_xa(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); size_t xa_bytes_to_samples(size_t bytes, int channels, int is_blocked, int is_form2); + /* ea_xa_decoder */ -void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_ea_xa_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_ea_xa_v2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); -void decode_maxis_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ea_xa(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ea_xa_int(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ea_xa_v2(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); +void decode_maxis_xa(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); int32_t ea_xa_bytes_to_samples(size_t bytes, int channels); + /* ea_xas_decoder */ -void decode_ea_xas_v0(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_ea_xas_v1(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ea_xas_v0(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_ea_xas_v1(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); + /* sdx2_decoder */ -void decode_sdx2(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_sdx2_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_cbd2(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_cbd2_int(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_sdx2(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_sdx2_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_cbd2(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_cbd2_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* ws_decoder */ -void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_ws(VGMSTREAM* vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* acm_decoder */ -acm_codec_data *init_acm(STREAMFILE *streamFile, int force_channel_number); -void decode_acm(acm_codec_data *data, sample * outbuf, int32_t samples_to_do, int channelspacing); -void reset_acm(acm_codec_data *data); -void free_acm(acm_codec_data *data); +acm_codec_data* init_acm(STREAMFILE* sf, int force_channel_number); +void decode_acm(acm_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channelspacing); +void reset_acm(acm_codec_data* data); +void free_acm(acm_codec_data* data); +STREAMFILE* acm_get_streamfile(acm_codec_data* data); + /* nwa_decoder */ -void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do); +void decode_nwa(NWAData* nwa, sample *outbuf, int32_t samples_to_do); + /* msadpcm_decoder */ -void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do); -void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_msadpcm_stereo(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t first_sample, int32_t samples_to_do); +void decode_msadpcm_mono(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_msadpcm_ck(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); long msadpcm_bytes_to_samples(long bytes, int block_size, int channels); -int msadpcm_check_coefs(STREAMFILE *sf, off_t offset); +int msadpcm_check_coefs(STREAMFILE* sf, off_t offset); + /* yamaha_decoder */ -void decode_aica(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); -void decode_aska(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_nxap(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_aica(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); +void decode_aska(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_nxap(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); size_t yamaha_bytes_to_samples(size_t bytes, int channels); size_t aska_bytes_to_samples(size_t bytes, int channels); + /* tgcadpcm_decoder */ -void decode_tgc(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do); +void decode_tgc(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int32_t first_sample, int32_t samples_to_do); + /* nds_procyon_decoder */ -void decode_nds_procyon(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_nds_procyon(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* l5_555_decoder */ -void decode_l5_555(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_l5_555(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* sassc_decoder */ -void decode_sassc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_sassc(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* lsf_decode */ -void decode_lsf(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_lsf(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* mtaf_decoder */ -void decode_mtaf(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_mtaf(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); + /* mta2_decoder */ -void decode_mta2(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_mta2(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); + /* mc3_decoder */ -void decode_mc3(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_mc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); + /* fadpcm_decoder */ -void decode_fadpcm(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_fadpcm(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* asf_decoder */ -void decode_asf(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_asf(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); int32_t asf_bytes_to_samples(size_t bytes, int channels); + /* dsa_decoder */ -void decode_dsa(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_dsa(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* xmd_decoder */ -void decode_xmd(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, size_t frame_size); +void decode_xmd(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, size_t frame_size); + /* derf_decoder */ -void decode_derf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_derf(VGMSTREAMCHANNEL* stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* circus_decoder */ typedef struct circus_codec_data circus_codec_data; + circus_codec_data* init_circus_vq(STREAMFILE* sf, off_t start, uint8_t codec, uint8_t flags); void decode_circus_vq(circus_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels); void reset_circus_vq(circus_codec_data* data); @@ -194,93 +228,167 @@ void seek_circus_vq(circus_codec_data* data, int32_t num_sample); void free_circus_vq(circus_codec_data* data); void decode_circus_adpcm(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); + /* oki_decoder */ -void decode_pcfx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode); -void decode_oki16(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); -void decode_oki4s(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_pcfx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode); +void decode_oki16(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +void decode_oki4s(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); size_t oki_bytes_to_samples(size_t bytes, int channels); + /* ptadpcm_decoder */ -void decode_ptadpcm(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, size_t frame_size); +void decode_ptadpcm(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, size_t frame_size); size_t ptadpcm_bytes_to_samples(size_t bytes, int channels, size_t frame_size); + /* ubi_adpcm_decoder */ -ubi_adpcm_codec_data *init_ubi_adpcm(STREAMFILE *streamFile, off_t offset, int channels); -void decode_ubi_adpcm(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t samples_to_do); -void reset_ubi_adpcm(ubi_adpcm_codec_data *data); -void seek_ubi_adpcm(ubi_adpcm_codec_data *data, int32_t num_sample); -void free_ubi_adpcm(ubi_adpcm_codec_data *data); -int ubi_adpcm_get_samples(ubi_adpcm_codec_data *data); +typedef struct ubi_adpcm_codec_data ubi_adpcm_codec_data; + +ubi_adpcm_codec_data* init_ubi_adpcm(STREAMFILE* sf, off_t offset, int channels); +void decode_ubi_adpcm(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do); +void reset_ubi_adpcm(ubi_adpcm_codec_data* data); +void seek_ubi_adpcm(ubi_adpcm_codec_data* data, int32_t num_sample); +void free_ubi_adpcm(ubi_adpcm_codec_data* data); +int ubi_adpcm_get_samples(ubi_adpcm_codec_data* data); + /* imuse_decoder */ typedef struct imuse_codec_data imuse_codec_data; -imuse_codec_data *init_imuse(STREAMFILE* sf, int channels); + +imuse_codec_data* init_imuse(STREAMFILE* sf, int channels); void decode_imuse(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do); void reset_imuse(imuse_codec_data* data); void seek_imuse(imuse_codec_data* data, int32_t num_sample); void free_imuse(imuse_codec_data* data); + /* ea_mt_decoder*/ -ea_mt_codec_data *init_ea_mt(int channels, int type); -ea_mt_codec_data *init_ea_mt_loops(int channels, int pcm_blocks, int loop_sample, off_t *loop_offsets); -void decode_ea_mt(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); -void reset_ea_mt(VGMSTREAM * vgmstream); -void flush_ea_mt(VGMSTREAM *vgmstream); -void seek_ea_mt(VGMSTREAM * vgmstream, int32_t num_sample); -void free_ea_mt(ea_mt_codec_data *data, int channels); +typedef struct ea_mt_codec_data ea_mt_codec_data; + +ea_mt_codec_data* init_ea_mt(int channels, int type); +ea_mt_codec_data* init_ea_mt_loops(int channels, int pcm_blocks, int loop_sample, off_t* loop_offsets); +void decode_ea_mt(VGMSTREAM* vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); +void reset_ea_mt(VGMSTREAM* vgmstream); +void flush_ea_mt(VGMSTREAM* vgmstream); +void seek_ea_mt(VGMSTREAM* vgmstream, int32_t num_sample); +void free_ea_mt(ea_mt_codec_data* data, int channels); + /* relic_decoder */ +typedef struct relic_codec_data relic_codec_data; + relic_codec_data* init_relic(int channels, int bitrate, int codec_rate); void decode_relic(VGMSTREAMCHANNEL* stream, relic_codec_data* data, sample_t* outbuf, int32_t samples_to_do); void reset_relic(relic_codec_data* data); void seek_relic(relic_codec_data* data, int32_t num_sample); void free_relic(relic_codec_data* data); + /* hca_decoder */ -hca_codec_data *init_hca(STREAMFILE *streamFile); -void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do); -void reset_hca(hca_codec_data * data); -void loop_hca(hca_codec_data * data, int32_t num_sample); -void free_hca(hca_codec_data * data); -int test_hca_key(hca_codec_data * data, unsigned long long keycode); +typedef struct hca_codec_data hca_codec_data; + +hca_codec_data* init_hca(STREAMFILE* sf); +void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do); +void reset_hca(hca_codec_data* data); +void loop_hca(hca_codec_data* data, int32_t num_sample); +void free_hca(hca_codec_data* data); +int test_hca_key(hca_codec_data* data, unsigned long long keycode); +void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode); +clHCA_stInfo* hca_get_info(hca_codec_data* data); +STREAMFILE* hca_get_streamfile(hca_codec_data* data); + #ifdef VGM_USE_VORBIS /* ogg_vorbis_decoder */ -ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE *sf, off_t start, off_t size, ogg_vorbis_io *io); -void decode_ogg_vorbis(ogg_vorbis_codec_data *data, sample_t *outbuf, int32_t samples_to_do, int channels); -void reset_ogg_vorbis(VGMSTREAM *vgmstream); -void seek_ogg_vorbis(VGMSTREAM *vgmstream, int32_t num_sample); -void free_ogg_vorbis(ogg_vorbis_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 */ + + /* decryption setup */ + 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; +} ogg_vorbis_io; + +ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE* sf, off_t start, off_t size, ogg_vorbis_io* io); +void decode_ogg_vorbis(ogg_vorbis_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels); +void reset_ogg_vorbis(VGMSTREAM* vgmstream); +void seek_ogg_vorbis(VGMSTREAM* vgmstream, int32_t num_sample); +void free_ogg_vorbis(ogg_vorbis_codec_data* data); + +int ogg_vorbis_get_comment(ogg_vorbis_codec_data* data, const char** comment); +void ogg_vorbis_get_info(ogg_vorbis_codec_data* data, int* p_channels, int* p_sample_rate); +void ogg_vorbis_get_samples(ogg_vorbis_codec_data* data, int* p_samples); +void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data* data, int set); +STREAMFILE* ogg_vorbis_get_streamfile(ogg_vorbis_codec_data* data); -int ogg_vorbis_get_comment(ogg_vorbis_codec_data *data, const char **comment); -void ogg_vorbis_get_info(ogg_vorbis_codec_data *data, int *p_channels, int *p_sample_rate); -void ogg_vorbis_get_samples(ogg_vorbis_codec_data *data, int *p_samples); -void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data *data, int set); -STREAMFILE* ogg_vorbis_get_streamfile(ogg_vorbis_codec_data *data); /* vorbis_custom_decoder */ -vorbis_custom_codec_data *init_vorbis_custom(STREAMFILE *streamfile, off_t start_offset, vorbis_custom_t type, vorbis_custom_config * config); -void decode_vorbis_custom(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t samples_to_do, int channels); -void reset_vorbis_custom(VGMSTREAM *vgmstream); -void seek_vorbis_custom(VGMSTREAM *vgmstream, int32_t num_sample); -void free_vorbis_custom(vorbis_custom_codec_data *data); +typedef struct vorbis_custom_codec_data vorbis_custom_codec_data; + +typedef enum { + VORBIS_FSB, /* FMOD FSB: simplified/external setup packets, custom packet headers */ + VORBIS_WWISE, /* Wwise WEM: many variations (custom setup, headers and data) */ + VORBIS_OGL, /* Shin'en OGL: custom packet headers */ + VORBIS_SK, /* Silicon Knights AUD: "OggS" replaced by "SK" */ + VORBIS_VID1, /* Neversoft VID1: custom packet blocks/headers */ +} vorbis_custom_t; + +/* config for Wwise Vorbis (3 types for flexibility though not all combinations exist) */ +typedef enum { WWV_HEADER_TRIAD, WWV_FULL_SETUP, WWV_INLINE_CODEBOOKS, WWV_EXTERNAL_CODEBOOKS, WWV_AOTUV603_CODEBOOKS } wwise_setup_t; +typedef enum { WWV_TYPE_8, WWV_TYPE_6, WWV_TYPE_2 } wwise_header_t; +typedef enum { WWV_STANDARD, WWV_MODIFIED } wwise_packet_t; + +typedef struct { + /* to reconstruct init packets */ + int channels; + int sample_rate; + int blocksize_0_exp; + int blocksize_1_exp; + + uint32_t setup_id; /* external setup */ + int big_endian; /* flag */ + + /* Wwise Vorbis config */ + wwise_setup_t setup_type; + wwise_header_t header_type; + wwise_packet_t packet_type; + + /* output (kinda ugly here but to simplify) */ + off_t data_start_offset; + +} vorbis_custom_config; + +vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset, vorbis_custom_t type, vorbis_custom_config* config); +void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels); +void reset_vorbis_custom(VGMSTREAM* vgmstream); +void seek_vorbis_custom(VGMSTREAM* vgmstream, int32_t num_sample); +void free_vorbis_custom(vorbis_custom_codec_data* data); #endif + #ifdef VGM_USE_MPEG /* mpeg_decoder */ -mpeg_codec_data *init_mpeg(STREAMFILE *streamfile, off_t start_offset, coding_t *coding_type, int channels); -mpeg_codec_data *init_mpeg_custom(STREAMFILE *streamFile, off_t start_offset, coding_t *coding_type, int channels, mpeg_custom_t custom_type, mpeg_custom_config *config); -void decode_mpeg(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t samples_to_do, int channels); -void reset_mpeg(VGMSTREAM *vgmstream); -void seek_mpeg(VGMSTREAM *vgmstream, int32_t num_sample); -void free_mpeg(mpeg_codec_data *data); -void flush_mpeg(mpeg_codec_data * data); +mpeg_codec_data* init_mpeg(STREAMFILE* sf, off_t start_offset, coding_t *coding_type, int channels); +mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* coding_type, int channels, mpeg_custom_t custom_type, mpeg_custom_config* config); +void decode_mpeg(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels); +void reset_mpeg(VGMSTREAM* vgmstream); +void seek_mpeg(VGMSTREAM* vgmstream, int32_t num_sample); +void free_mpeg(mpeg_codec_data* data); +void flush_mpeg(mpeg_codec_data* data); -long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data *data); +long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data); #endif + #ifdef VGM_USE_G7221 /* g7221_decoder */ +typedef struct g7221_codec_data g7221_codec_data; + g7221_codec_data* init_g7221(int channel_count, int frame_size); void decode_g7221(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t samples_to_do, int channel); void reset_g7221(g7221_codec_data* data); @@ -289,73 +397,93 @@ void set_key_g7221(g7221_codec_data* data, const uint8_t* key); int test_key_g7221(g7221_codec_data* data, off_t start, STREAMFILE* sf); #endif + #ifdef VGM_USE_G719 /* g719_decoder */ -g719_codec_data *init_g719(int channel_count, int frame_size); -void decode_g719(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); -void reset_g719(g719_codec_data * data, int channels); -void free_g719(g719_codec_data * data, int channels); +typedef struct g719_codec_data g719_codec_data; + +g719_codec_data* init_g719(int channel_count, int frame_size); +void decode_g719(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t samples_to_do, int channel); +void reset_g719(g719_codec_data* data, int channels); +void free_g719(g719_codec_data* data, int channels); #endif + #if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC) /* mp4_aac_decoder */ -void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels); -void reset_mp4_aac(VGMSTREAM *vgmstream); -void seek_mp4_aac(VGMSTREAM *vgmstream, int32_t num_sample); -void free_mp4_aac(mp4_aac_codec_data * data); +void decode_mp4_aac(mp4_aac_codec_data* data, sample * outbuf, int32_t samples_to_do, int channels); +void reset_mp4_aac(VGMSTREAM* vgmstream); +void seek_mp4_aac(VGMSTREAM* vgmstream, int32_t num_sample); +void free_mp4_aac(mp4_aac_codec_data* data); #endif + #ifdef VGM_USE_MAIATRAC3PLUS /* at3plus_decoder */ -maiatrac3plus_codec_data *init_at3plus(); -void decode_at3plus(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); -void reset_at3plus(VGMSTREAM *vgmstream); -void seek_at3plus(VGMSTREAM *vgmstream, int32_t num_sample); -void free_at3plus(maiatrac3plus_codec_data *data); +typedef struct maiatrac3plus_codec_data maiatrac3plus_codec_data; + +maiatrac3plus_codec_data* init_at3plus(); +void decode_at3plus(VGMSTREAM* vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); +void reset_at3plus(VGMSTREAM* vgmstream); +void seek_at3plus(VGMSTREAM* vgmstream, int32_t num_sample); +void free_at3plus(maiatrac3plus_codec_data* data); #endif + #ifdef VGM_USE_ATRAC9 /* atrac9_decoder */ -atrac9_codec_data *init_atrac9(atrac9_config *cfg); -void decode_atrac9(VGMSTREAM *vgmstream, sample_t * outbuf, int32_t samples_to_do, int channels); -void reset_atrac9(VGMSTREAM *vgmstream); -void seek_atrac9(VGMSTREAM *vgmstream, int32_t num_sample); -void free_atrac9(atrac9_codec_data *data); -size_t atrac9_bytes_to_samples(size_t bytes, atrac9_codec_data *data); +typedef struct { + int channels; /* to detect weird multichannel */ + uint32_t config_data; /* ATRAC9 config header */ + int encoder_delay; /* initial samples to discard */ +} atrac9_config; +typedef struct atrac9_codec_data atrac9_codec_data; + +atrac9_codec_data* init_atrac9(atrac9_config* cfg); +void decode_atrac9(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels); +void reset_atrac9(VGMSTREAM* vgmstream); +void seek_atrac9(VGMSTREAM* vgmstream, int32_t num_sample); +void free_atrac9(atrac9_codec_data* data); +size_t atrac9_bytes_to_samples(size_t bytes, atrac9_codec_data* data); size_t atrac9_bytes_to_samples_cfg(size_t bytes, uint32_t atrac9_config); #endif + #ifdef VGM_USE_CELT /* celt_fsb_decoder */ -celt_codec_data *init_celt_fsb(int channels, celt_lib_t version); -void decode_celt_fsb(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do, int channels); -void reset_celt_fsb(VGMSTREAM *vgmstream); -void seek_celt_fsb(VGMSTREAM *vgmstream, int32_t num_sample); -void free_celt_fsb(celt_codec_data *data); +typedef enum { CELT_0_06_1,CELT_0_11_0} celt_lib_t; +typedef struct celt_codec_data celt_codec_data; + +celt_codec_data* init_celt_fsb(int channels, celt_lib_t version); +void decode_celt_fsb(VGMSTREAM* vgmstream, sample * outbuf, int32_t samples_to_do, int channels); +void reset_celt_fsb(VGMSTREAM* vgmstream); +void seek_celt_fsb(VGMSTREAM* vgmstream, int32_t num_sample); +void free_celt_fsb(celt_codec_data* data); #endif + #ifdef VGM_USE_FFMPEG /* ffmpeg_decoder */ -ffmpeg_codec_data *init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size); -ffmpeg_codec_data *init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size); -ffmpeg_codec_data *init_ffmpeg_header_offset_subsong(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size, int target_subsong); +ffmpeg_codec_data* init_ffmpeg_offset(STREAMFILE* sf, uint64_t start, uint64_t size); +ffmpeg_codec_data* init_ffmpeg_header_offset(STREAMFILE* sf, uint8_t* header, uint64_t header_size, uint64_t start, uint64_t size); +ffmpeg_codec_data* init_ffmpeg_header_offset_subsong(STREAMFILE* sf, uint8_t* header, uint64_t header_size, uint64_t start, uint64_t size, int target_subsong); -void decode_ffmpeg(VGMSTREAM *stream, sample_t * outbuf, int32_t samples_to_do, int channels); -void reset_ffmpeg(VGMSTREAM *vgmstream); -void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample); -void free_ffmpeg(ffmpeg_codec_data *data); +void decode_ffmpeg(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels); +void reset_ffmpeg(VGMSTREAM* vgmstream); +void seek_ffmpeg(VGMSTREAM* vgmstream, int32_t num_sample); +void free_ffmpeg(ffmpeg_codec_data* data); -void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples); -uint32_t ffmpeg_get_channel_layout(ffmpeg_codec_data * data); -void ffmpeg_set_channel_remapping(ffmpeg_codec_data * data, int *channels_remap); -const char* ffmpeg_get_codec_name(ffmpeg_codec_data * data); -void ffmpeg_set_force_seek(ffmpeg_codec_data * data); +void ffmpeg_set_skip_samples(ffmpeg_codec_data* data, int skip_samples); +uint32_t ffmpeg_get_channel_layout(ffmpeg_codec_data* data); +void ffmpeg_set_channel_remapping(ffmpeg_codec_data* data, int* channels_remap); +const char* ffmpeg_get_codec_name(ffmpeg_codec_data* data); +void ffmpeg_set_force_seek(ffmpeg_codec_data* data); const char* ffmpeg_get_metadata_value(ffmpeg_codec_data* data, const char* key); - +STREAMFILE* ffmpeg_get_streamfile(ffmpeg_codec_data* data); /* ffmpeg_decoder_utils.c (helper-things) */ -ffmpeg_codec_data * init_ffmpeg_atrac3_raw(STREAMFILE *sf, off_t offset, size_t data_size, int sample_count, int channels, int sample_rate, int block_align, int encoder_delay); -ffmpeg_codec_data * init_ffmpeg_atrac3_riff(STREAMFILE *sf, off_t offset, int* out_samples); +ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t data_size, int sample_count, int channels, int sample_rate, int block_align, int encoder_delay); +ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* out_samples); /* ffmpeg_decoder_custom_opus.c (helper-things) */ @@ -369,28 +497,28 @@ typedef struct { int channel_mapping[8]; } opus_config; -ffmpeg_codec_data * init_ffmpeg_switch_opus_config(STREAMFILE *streamFile, off_t start_offset, size_t data_size, opus_config* cfg); -ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); -ffmpeg_codec_data * init_ffmpeg_ue4_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); -ffmpeg_codec_data * init_ffmpeg_ea_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); -ffmpeg_codec_data * init_ffmpeg_x_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); +ffmpeg_codec_data* init_ffmpeg_switch_opus_config(STREAMFILE* sf, off_t start_offset, size_t data_size, opus_config* cfg); +ffmpeg_codec_data* init_ffmpeg_switch_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); +ffmpeg_codec_data* init_ffmpeg_ue4_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); +ffmpeg_codec_data* init_ffmpeg_ea_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); +ffmpeg_codec_data* init_ffmpeg_x_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); -size_t switch_opus_get_samples(off_t offset, size_t stream_size, STREAMFILE *streamFile); +size_t switch_opus_get_samples(off_t offset, size_t stream_size, STREAMFILE* sf); -size_t switch_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile); -size_t ue4_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile); -size_t ea_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile); +size_t switch_opus_get_encoder_delay(off_t offset, STREAMFILE* sf); +size_t ue4_opus_get_encoder_delay(off_t offset, STREAMFILE* sf); +size_t ea_opus_get_encoder_delay(off_t offset, STREAMFILE* sf); #endif /* coding_utils */ -int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, size_t chunk_size, uint16_t codec); -int ffmpeg_make_riff_atrac3plus(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay); -int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode); -int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size); -int ffmpeg_make_riff_xma_from_fmt_chunk(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian); -int ffmpeg_make_riff_xma2_from_xma2_chunk(uint8_t * buf, size_t buf_size, off_t xma2_offset, size_t xma2_size, size_t data_size, STREAMFILE *streamFile); -int ffmpeg_make_riff_xwma(uint8_t * buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align); +int ffmpeg_fmt_chunk_swap_endian(uint8_t* chunk, size_t chunk_size, uint16_t codec); +int ffmpeg_make_riff_atrac3plus(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay); +int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode); +int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size); +int ffmpeg_make_riff_xma_from_fmt_chunk(uint8_t* buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE* sf, int big_endian); +int ffmpeg_make_riff_xma2_from_xma2_chunk(uint8_t* buf, size_t buf_size, off_t xma2_offset, size_t xma2_size, size_t data_size, STREAMFILE* sf); +int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align); /* MS audio format's sample info (struct to avoid passing so much stuff, separate for reusing) */ typedef struct { @@ -414,39 +542,39 @@ typedef struct { int32_t loop_start_sample; int32_t loop_end_sample; } ms_sample_data; -void xma_get_samples(ms_sample_data * msd, STREAMFILE *streamFile); -void wmapro_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, int block_align, int sample_rate, uint32_t decode_flags); -void wma_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, int block_align, int sample_rate, uint32_t decode_flags); +void xma_get_samples(ms_sample_data* msd, STREAMFILE* sf); +void wmapro_get_samples(ms_sample_data* msd, STREAMFILE* sf, int block_align, int sample_rate, uint32_t decode_flags); +void wma_get_samples(ms_sample_data* msd, STREAMFILE* sf, int block_align, int sample_rate, uint32_t decode_flags); -void xma1_parse_fmt_chunk(STREAMFILE *streamFile, off_t chunk_offset, int * channels, int * sample_rate, int * loop_flag, int32_t * loop_start_b, int32_t * loop_end_b, int32_t * loop_subframe, int be); -void xma2_parse_fmt_chunk_extra(STREAMFILE *streamFile, off_t chunk_offset, int * loop_flag, int32_t * out_num_samples, int32_t * out_loop_start_sample, int32_t * out_loop_end_sample, int be); -void xma2_parse_xma2_chunk(STREAMFILE *streamFile, off_t chunk_offset, int * channels, int * sample_rate, int * loop_flag, int32_t * num_samples, int32_t * loop_start_sample, int32_t * loop_end_sample); +void xma1_parse_fmt_chunk(STREAMFILE* sf, off_t chunk_offset, int* channels, int* sample_rate, int* loop_flag, int32_t* loop_start_b, int32_t* loop_end_b, int32_t* loop_subframe, int be); +void xma2_parse_fmt_chunk_extra(STREAMFILE* sf, off_t chunk_offset, int* loop_flag, int32_t* out_num_samples, int32_t* out_loop_start_sample, int32_t* out_loop_end_sample, int be); +void xma2_parse_xma2_chunk(STREAMFILE* sf, off_t chunk_offset, int* channels, int* sample_rate, int* loop_flag, int32_t* num_samples, int32_t* loop_start_sample, int32_t* loop_end_sample); -void xma_fix_raw_samples(VGMSTREAM *vgmstream, STREAMFILE*streamFile, off_t stream_offset, size_t stream_size, off_t chunk_offset, int fix_num_samples, int fix_loop_samples); -void xma_fix_raw_samples_hb(VGMSTREAM *vgmstream, STREAMFILE *headerFile, STREAMFILE *bodyFile, off_t stream_offset, size_t stream_size, off_t chunk_offset, int fix_num_samples, int fix_loop_samples); -void xma_fix_raw_samples_ch(VGMSTREAM *vgmstream, STREAMFILE*streamFile, off_t stream_offset, size_t stream_size, int channel_per_stream, int fix_num_samples, int fix_loop_samples); +void xma_fix_raw_samples(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t stream_offset, size_t stream_size, off_t chunk_offset, int fix_num_samples, int fix_loop_samples); +void xma_fix_raw_samples_hb(VGMSTREAM* vgmstream, STREAMFILE* sf_head, STREAMFILE* sf_body, off_t stream_offset, size_t stream_size, off_t chunk_offset, int fix_num_samples, int fix_loop_samples); +void xma_fix_raw_samples_ch(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t stream_offset, size_t stream_size, int channel_per_stream, int fix_num_samples, int fix_loop_samples); size_t atrac3_bytes_to_samples(size_t bytes, int full_block_align); size_t atrac3plus_bytes_to_samples(size_t bytes, int full_block_align); size_t ac3_bytes_to_samples(size_t bytes, int full_block_align, int channels); -size_t aac_get_samples(STREAMFILE *streamFile, off_t start_offset, size_t bytes); -size_t mpeg_get_samples(STREAMFILE *streamFile, off_t start_offset, size_t bytes); +size_t aac_get_samples(STREAMFILE* sf, off_t start_offset, size_t bytes); +size_t mpeg_get_samples(STREAMFILE* sf, off_t start_offset, size_t bytes); /* An internal struct to pass around and simulate a bitstream. */ typedef enum { BITSTREAM_MSF, BITSTREAM_VORBIS } vgm_bitstream_t; typedef struct { - uint8_t * buf; /* buffer to read/write*/ + uint8_t* buf; /* buffer to read/write*/ size_t bufsize; /* max size of the buffer */ off_t b_off; /* current offset in bits inside the buffer */ vgm_bitstream_t mode; /* read/write modes */ } vgm_bitstream; -int r_bits(vgm_bitstream * ib, int num_bits, uint32_t * value); -int w_bits(vgm_bitstream * ob, int num_bits, uint32_t value); +int r_bits(vgm_bitstream* ib, int num_bits, uint32_t* value); +int w_bits(vgm_bitstream* ob, int num_bits, uint32_t value); /* helper to pass a wrapped, clamped, fake extension-ed, SF to another meta */ -STREAMFILE* setup_subfile_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* extension); +STREAMFILE* setup_subfile_streamfile(STREAMFILE* sf, off_t subfile_offset, size_t subfile_size, const char* extension); #endif /*_CODING_H*/ diff --git a/src/coding/ffmpeg_decoder.c b/src/coding/ffmpeg_decoder.c index 1070921f..12d8d1ce 100644 --- a/src/coding/ffmpeg_decoder.c +++ b/src/coding/ffmpeg_decoder.c @@ -8,11 +8,11 @@ static volatile int g_ffmpeg_initialized = 0; -static void free_ffmpeg_config(ffmpeg_codec_data *data); -static int init_ffmpeg_config(ffmpeg_codec_data * data, int target_subsong, int reset); +static void free_ffmpeg_config(ffmpeg_codec_data* data); +static int init_ffmpeg_config(ffmpeg_codec_data* data, int target_subsong, int reset); -static void reset_ffmpeg_internal(ffmpeg_codec_data *data); -static void seek_ffmpeg_internal(ffmpeg_codec_data *data, int32_t num_sample); +static void reset_ffmpeg_internal(ffmpeg_codec_data* data); +static void seek_ffmpeg_internal(ffmpeg_codec_data* data, int32_t num_sample); /* ******************************************** */ /* INTERNAL UTILS */ @@ -34,7 +34,7 @@ static void g_init_ffmpeg() { } } -static void remap_audio(sample_t *outbuf, int sample_count, int channels, int *channel_mappings) { +static void remap_audio(sample_t* outbuf, int sample_count, int channels, int* channel_mappings) { int ch_from,ch_to,s; sample_t temp; for (s = 0; s < sample_count; s++) { @@ -65,7 +65,7 @@ static void remap_audio(sample_t *outbuf, int sample_count, int channels, int *c * first frame/packet and sets up index to timestamp 0. This ensures faulty demuxers will seek to 0 correctly. * Some formats may not seek to 0 even with this, though. */ -static int init_seek(ffmpeg_codec_data * data) { +static int init_seek(ffmpeg_codec_data* data) { int ret, ts_index, packet_count = 0; int64_t ts = 0; /* seek timestamp */ int64_t pos = 0; /* data offset */ @@ -161,8 +161,8 @@ fail: /* ******************************************** */ /* AVIO callback: read stream, handling custom data */ -static int ffmpeg_read(void *opaque, uint8_t *buf, int read_size) { - ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque; +static int ffmpeg_read(void* opaque, uint8_t* buf, int read_size) { + ffmpeg_codec_data* data = opaque; int bytes = 0; int max_to_copy = 0; @@ -196,8 +196,8 @@ static int ffmpeg_read(void *opaque, uint8_t *buf, int read_size) { } /* AVIO callback: seek stream, handling custom data */ -static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) { - ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque; +static int64_t ffmpeg_seek(void* opaque, int64_t offset, int whence) { + ffmpeg_codec_data* data = opaque; int ret = 0; /* get cache'd size */ @@ -243,12 +243,12 @@ static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) { /* MAIN INIT/DECODER */ /* ******************************************** */ -ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) { - return init_ffmpeg_header_offset(streamFile, NULL,0, start,size); +ffmpeg_codec_data* init_ffmpeg_offset(STREAMFILE* sf, uint64_t start, uint64_t size) { + return init_ffmpeg_header_offset(sf, NULL,0, start,size); } -ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size) { - return init_ffmpeg_header_offset_subsong(streamFile, header, header_size, start, size, 0); +ffmpeg_codec_data* init_ffmpeg_header_offset(STREAMFILE* sf, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size) { + return init_ffmpeg_header_offset_subsong(sf, header, header_size, start, size, 0); } @@ -261,8 +261,8 @@ ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * * NULL header can used given if the stream has internal data recognized by FFmpeg at offset. * Stream index can be passed if the file has multiple audio streams that FFmpeg can demux (1=first). */ -ffmpeg_codec_data * init_ffmpeg_header_offset_subsong(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size, int target_subsong) { - ffmpeg_codec_data * data = NULL; +ffmpeg_codec_data* init_ffmpeg_header_offset_subsong(STREAMFILE* sf, uint8_t* header, uint64_t header_size, uint64_t start, uint64_t size, int target_subsong) { + ffmpeg_codec_data* data = NULL; int errcode; @@ -270,9 +270,9 @@ ffmpeg_codec_data * init_ffmpeg_header_offset_subsong(STREAMFILE *streamFile, ui if ((header && !header_size) || (!header && header_size)) goto fail; - if (size == 0 || start + size > get_streamfile_size(streamFile)) { - VGM_LOG("FFMPEG: wrong start+size found: %x + %x > %x \n", (uint32_t)start, (uint32_t)size, get_streamfile_size(streamFile)); - size = get_streamfile_size(streamFile) - start; + if (size == 0 || start + size > get_streamfile_size(sf)) { + VGM_LOG("FFMPEG: wrong start+size found: %x + %x > %x \n", (uint32_t)start, (uint32_t)size, get_streamfile_size(sf)); + size = get_streamfile_size(sf) - start; } @@ -284,7 +284,7 @@ ffmpeg_codec_data * init_ffmpeg_header_offset_subsong(STREAMFILE *streamFile, ui data = calloc(1, sizeof(ffmpeg_codec_data)); if (!data) return NULL; - data->streamfile = reopen_streamfile(streamFile, 0); + data->streamfile = reopen_streamfile(sf, 0); if (!data->streamfile) goto fail; /* fake header to trick FFmpeg into demuxing/decoding the stream */ @@ -366,7 +366,7 @@ fail: return NULL; } -static int init_ffmpeg_config(ffmpeg_codec_data * data, int target_subsong, int reset) { +static int init_ffmpeg_config(ffmpeg_codec_data* data, int target_subsong, int reset) { int errcode = 0; /* basic IO/format setup */ @@ -455,7 +455,7 @@ fail: } /* decodes a new frame to internal data */ -static int decode_ffmpeg_frame(ffmpeg_codec_data *data) { +static int decode_ffmpeg_frame(ffmpeg_codec_data* data) { int errcode; int frame_error = 0; @@ -672,7 +672,7 @@ static void samples_dblp_to_s16(sample_t* obuf, double** inbuf, int ichs, int sa } } -static void copy_samples(ffmpeg_codec_data *data, sample_t *outbuf, int samples_to_do) { +static void copy_samples(ffmpeg_codec_data* data, sample_t* outbuf, int samples_to_do) { int channels = data->codecCtx->channels; int is_planar = av_sample_fmt_is_planar(data->codecCtx->sample_fmt) && (channels > 1); void* ibuf; @@ -709,8 +709,8 @@ static void copy_samples(ffmpeg_codec_data *data, sample_t *outbuf, int samples_ } /* decode samples of any kind of FFmpeg format */ -void decode_ffmpeg(VGMSTREAM *vgmstream, sample_t * outbuf, int32_t samples_to_do, int channels) { - ffmpeg_codec_data *data = vgmstream->codec_data; +void decode_ffmpeg(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels) { + ffmpeg_codec_data* data = vgmstream->codec_data; while (samples_to_do > 0) { @@ -757,14 +757,14 @@ decode_fail: /* UTILS */ /* ******************************************** */ -void reset_ffmpeg_internal(ffmpeg_codec_data *data) { +void reset_ffmpeg_internal(ffmpeg_codec_data* data) { seek_ffmpeg_internal(data, 0); } -void reset_ffmpeg(VGMSTREAM *vgmstream) { +void reset_ffmpeg(VGMSTREAM* vgmstream) { reset_ffmpeg_internal(vgmstream->codec_data); } -void seek_ffmpeg_internal(ffmpeg_codec_data *data, int32_t num_sample) { +void seek_ffmpeg_internal(ffmpeg_codec_data* data, int32_t num_sample) { if (!data) return; /* Start from 0 and discard samples until sample (slower but not too noticeable). @@ -813,12 +813,12 @@ fail: data->bad_init = 1; /* internals were probably free'd */ } -void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) { +void seek_ffmpeg(VGMSTREAM* vgmstream, int32_t num_sample) { seek_ffmpeg_internal(vgmstream->codec_data, num_sample); } -static void free_ffmpeg_config(ffmpeg_codec_data *data) { +static void free_ffmpeg_config(ffmpeg_codec_data* data) { if (data == NULL) return; @@ -858,7 +858,7 @@ static void free_ffmpeg_config(ffmpeg_codec_data *data) { //todo avformat_find_stream_info may cause some Win Handle leaks? related to certain option } -void free_ffmpeg(ffmpeg_codec_data *data) { +void free_ffmpeg(ffmpeg_codec_data* data) { if (data == NULL) return; @@ -883,7 +883,7 @@ void free_ffmpeg(ffmpeg_codec_data *data) { * This could be added per format in FFmpeg directly, but it's here for flexibility and due to bugs * (FFmpeg's stream->(start_)skip_samples causes glitches in XMA). */ -void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples) { +void ffmpeg_set_skip_samples(ffmpeg_codec_data* data, int skip_samples) { AVStream *stream = NULL; if (!data || !data->formatCtx) return; @@ -902,7 +902,7 @@ void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples) { } /* returns channel layout if set */ -uint32_t ffmpeg_get_channel_layout(ffmpeg_codec_data * data) { +uint32_t ffmpeg_get_channel_layout(ffmpeg_codec_data* data) { if (!data || !data->codecCtx) return 0; return (uint32_t)data->codecCtx->channel_layout; /* uint64 but there ain't so many speaker mappings */ } @@ -910,7 +910,7 @@ uint32_t ffmpeg_get_channel_layout(ffmpeg_codec_data * data) { /* yet another hack to fix codecs that encode channels in different order and reorder on decoder * but FFmpeg doesn't do it automatically * (maybe should be done via mixing, but could clash with other stuff?) */ -void ffmpeg_set_channel_remapping(ffmpeg_codec_data * data, int *channel_remap) { +void ffmpeg_set_channel_remapping(ffmpeg_codec_data* data, int *channel_remap) { int i; if (data->channels > 32) @@ -922,7 +922,7 @@ void ffmpeg_set_channel_remapping(ffmpeg_codec_data * data, int *channel_remap) data->channel_remap_set = 1; } -const char* ffmpeg_get_codec_name(ffmpeg_codec_data * data) { +const char* ffmpeg_get_codec_name(ffmpeg_codec_data* data) { if (!data || !data->codec) return NULL; if (data->codec->long_name) @@ -932,7 +932,7 @@ const char* ffmpeg_get_codec_name(ffmpeg_codec_data * data) { return NULL; } -void ffmpeg_set_force_seek(ffmpeg_codec_data * data) { +void ffmpeg_set_force_seek(ffmpeg_codec_data* data) { /* some formats like Smacker are so buggy that any seeking is impossible (even on video players), * or MPC with an incorrectly parsed seek table (using as 0 some non-0 seek offset). * whatever, we'll just kill and reconstruct FFmpeg's config every time */ @@ -959,4 +959,8 @@ const char* ffmpeg_get_metadata_value(ffmpeg_codec_data* data, const char* key) return avde->value; } +STREAMFILE* ffmpeg_get_streamfile(ffmpeg_codec_data* data) { + if (!data) return NULL; + return data->streamfile; +} #endif diff --git a/src/coding/g719_decoder.c b/src/coding/g719_decoder.c index ab676ac6..66852f4c 100644 --- a/src/coding/g719_decoder.c +++ b/src/coding/g719_decoder.c @@ -4,10 +4,14 @@ #ifdef VGM_USE_G719 #define G719_MAX_CODES ((1280/8)) /* in int16, so max frame size is (value/8)*2 (0xF0=common, 0x140=decoder max 2560b, rare) */ +struct g719_codec_data { + sample_t buffer[960]; + void *handle; +}; -g719_codec_data *init_g719(int channel_count, int frame_size) { +g719_codec_data* init_g719(int channel_count, int frame_size) { int i; - g719_codec_data *data = NULL; + g719_codec_data* data = NULL; if (frame_size / sizeof(int16_t) > G719_MAX_CODES) goto fail; @@ -34,10 +38,10 @@ fail: } -void decode_g719(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel) { - VGMSTREAMCHANNEL *ch = &vgmstream->ch[channel]; - g719_codec_data *data = vgmstream->codec_data; - g719_codec_data *ch_data = &data[channel]; +void decode_g719(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t samples_to_do, int channel) { + VGMSTREAMCHANNEL* ch = &vgmstream->ch[channel]; + g719_codec_data* data = vgmstream->codec_data; + g719_codec_data* ch_data = &data[channel]; int i; if (0 == vgmstream->samples_into_block) { @@ -53,7 +57,7 @@ void decode_g719(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int } -void reset_g719(g719_codec_data * data, int channels) { +void reset_g719(g719_codec_data* data, int channels) { int i; if (!data) return; @@ -62,7 +66,7 @@ void reset_g719(g719_codec_data * data, int channels) { } } -void free_g719(g719_codec_data * data, int channels) { +void free_g719(g719_codec_data* data, int channels) { int i; if (!data) return; diff --git a/src/coding/hca_decoder.c b/src/coding/hca_decoder.c index 64b6cd47..c94f8003 100644 --- a/src/coding/hca_decoder.c +++ b/src/coding/hca_decoder.c @@ -1,21 +1,37 @@ #include "coding.h" +struct hca_codec_data { + STREAMFILE* streamfile; + clHCA_stInfo info; + + signed short* sample_buffer; + size_t samples_filled; + size_t samples_consumed; + size_t samples_to_discard; + + void* data_buffer; + + unsigned int current_block; + + void* handle; +}; + /* init a HCA stream; STREAMFILE will be duplicated for internal use. */ -hca_codec_data * init_hca(STREAMFILE *streamFile) { +hca_codec_data* init_hca(STREAMFILE* sf) { char filename[PATH_LIMIT]; uint8_t header_buffer[0x2000]; /* hca header buffer data (probable max ~0x400) */ - hca_codec_data * data = NULL; /* vgmstream HCA context */ + hca_codec_data* data = NULL; /* vgmstream HCA context */ int header_size; int status; /* test header */ - if (read_streamfile(header_buffer, 0x00, 0x08, streamFile) != 0x08) + if (read_streamfile(header_buffer, 0x00, 0x08, sf) != 0x08) goto fail; header_size = clHCA_isOurFile(header_buffer, 0x08); if (header_size < 0 || header_size > 0x1000) goto fail; - if (read_streamfile(header_buffer, 0x00, header_size, streamFile) != header_size) + if (read_streamfile(header_buffer, 0x00, header_size, sf) != header_size) goto fail; /* init vgmstream context */ @@ -39,8 +55,8 @@ hca_codec_data * init_hca(STREAMFILE *streamFile) { if (!data->sample_buffer) goto fail; /* load streamfile for reads */ - get_streamfile_name(streamFile,filename, sizeof(filename)); - data->streamfile = open_streamfile(streamFile,filename); + get_streamfile_name(sf,filename, sizeof(filename)); + data->streamfile = open_streamfile(sf,filename); if (!data->streamfile) goto fail; /* set initial values */ @@ -53,7 +69,7 @@ fail: return NULL; } -void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do) { +void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do) { int samples_done = 0; const unsigned int channels = data->info.channelCount; const unsigned int blockSize = data->info.blockSize; @@ -120,7 +136,7 @@ void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do) { } } -void reset_hca(hca_codec_data * data) { +void reset_hca(hca_codec_data* data) { if (!data) return; clHCA_DecodeReset(data->handle); @@ -130,7 +146,7 @@ void reset_hca(hca_codec_data * data) { data->samples_to_discard = data->info.encoderDelay; } -void loop_hca(hca_codec_data * data, int32_t num_sample) { +void loop_hca(hca_codec_data* data, int32_t num_sample) { if (!data) return; /* manually calc loop values if not set (should only happen with installed/forced looping, @@ -149,7 +165,7 @@ void loop_hca(hca_codec_data * data, int32_t num_sample) { data->samples_to_discard = data->info.loopStartDelay; } -void free_hca(hca_codec_data * data) { +void free_hca(hca_codec_data* data) { if (!data) return; close_streamfile(data->streamfile); @@ -175,7 +191,7 @@ void free_hca(hca_codec_data * data) { /* Test a number of frames if key decrypts correctly. * Returns score: <0: error/wrong, 0: unknown/silent file, >0: good (the closest to 1 the better). */ -int test_hca_key(hca_codec_data * data, unsigned long long keycode) { +int test_hca_key(hca_codec_data* data, unsigned long long keycode) { size_t test_frames = 0, current_frame = 0, blank_frames = 0; int total_score = 0, found_regular_frame = 0; const unsigned int blockSize = data->info.blockSize; @@ -242,3 +258,17 @@ int test_hca_key(hca_codec_data * data, unsigned long long keycode) { clHCA_DecodeReset(data->handle); return total_score; } + +void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode) { + VGM_LOG("k=%x%x", (uint32_t)((keycode >> 32) & 0xFFFFFFFF), (uint32_t)(keycode & 0xFFFFFFFF)); + clHCA_SetKey(data->handle, (unsigned long long)keycode); +} + +clHCA_stInfo* hca_get_info(hca_codec_data* data) { + return &data->info; +} + +STREAMFILE* hca_get_streamfile(hca_codec_data* data) { + if (!data) return NULL; + return data->streamfile; +} diff --git a/src/coding/vorbis_custom_decoder.h b/src/coding/vorbis_custom_decoder.h index 0801d91c..4e51f391 100644 --- a/src/coding/vorbis_custom_decoder.h +++ b/src/coding/vorbis_custom_decoder.h @@ -6,17 +6,49 @@ /* used by vorbis_custom_decoder.c, but scattered in other .c files */ #ifdef VGM_USE_VORBIS -int vorbis_custom_setup_init_fsb(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data); -int vorbis_custom_setup_init_wwise(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data); -int vorbis_custom_setup_init_ogl(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data); -int vorbis_custom_setup_init_sk(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data); -int vorbis_custom_setup_init_vid1(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data); -int vorbis_custom_parse_packet_fsb(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data); -int vorbis_custom_parse_packet_wwise(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data); -int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data); -int vorbis_custom_parse_packet_sk(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data); -int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data); +/* custom Vorbis without Ogg layer */ +struct vorbis_custom_codec_data { + vorbis_info vi; /* stream settings */ + vorbis_comment vc; /* stream comments */ + vorbis_dsp_state vd; /* decoder global state */ + vorbis_block vb; /* decoder local state */ + ogg_packet op; /* fake packet for internal use */ + + uint8_t * buffer; /* internal raw data buffer */ + size_t buffer_size; + + size_t samples_to_discard; /* for looping purposes */ + int samples_full; /* flag, samples available in vorbis buffers */ + + vorbis_custom_t type; /* Vorbis subtype */ + vorbis_custom_config config; /* config depending on the mode */ + + /* Wwise Vorbis: saved data to reconstruct modified packets */ + uint8_t mode_blockflag[64+1]; /* max 6b+1; flags 'n stuff */ + int mode_bits; /* bits to store mode_number */ + uint8_t prev_blockflag; /* blockflag in the last decoded packet */ + /* Ogg-style Vorbis: packet within a page */ + int current_packet; + /* reference for page/blocks */ + off_t block_offset; + size_t block_size; + + int prev_block_samples; /* count for optimization */ +}; + + +int vorbis_custom_setup_init_fsb(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data); +int vorbis_custom_setup_init_wwise(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data); +int vorbis_custom_setup_init_ogl(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data); +int vorbis_custom_setup_init_sk(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data); +int vorbis_custom_setup_init_vid1(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data); + +int vorbis_custom_parse_packet_fsb(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data* data); +int vorbis_custom_parse_packet_wwise(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data* data); +int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data* data); +int vorbis_custom_parse_packet_sk(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data* data); +int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data* data); #endif/* VGM_USE_VORBIS */ #endif/*_VORBIS_CUSTOM_DECODER_H_ */ diff --git a/src/meta/hca.c b/src/meta/hca.c index d4d03243..3d510982 100644 --- a/src/meta/hca.c +++ b/src/meta/hca.c @@ -10,69 +10,73 @@ static void find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t /* CRI HCA - streamed audio from CRI ADX2/Atom middleware */ -VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) { - return init_vgmstream_hca_subkey(streamFile, 0x0000); +VGMSTREAM * init_vgmstream_hca(STREAMFILE* sf) { + return init_vgmstream_hca_subkey(sf, 0x0000); } -VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) { +VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) { VGMSTREAM * vgmstream = NULL; - hca_codec_data * hca_data = NULL; + hca_codec_data* hca_data = NULL; + clHCA_stInfo* hca_info; /* checks */ - if ( !check_extensions(streamFile, "hca")) + if (!check_extensions(sf, "hca")) return NULL; - if (((uint32_t)read_32bitBE(0x00,streamFile) & 0x7f7f7f7f) != 0x48434100) /* "HCA\0", possibly masked */ + + if ((read_u32be(0x00,sf) & 0x7F7F7F7F) != 0x48434100) /* "HCA\0", possibly masked */ goto fail; /* init vgmstream and library's context, will validate the HCA */ - hca_data = init_hca(streamFile); + hca_data = init_hca(sf); if (!hca_data) goto fail; + hca_info = hca_get_info(hca_data); + /* find decryption key in external file or preloaded list */ - if (hca_data->info.encryptionEnabled) { + if (hca_info->encryptionEnabled) { uint64_t keycode = 0; uint8_t keybuf[0x08+0x02]; size_t keysize; - keysize = read_key_file(keybuf, 0x08+0x04, streamFile); + keysize = read_key_file(keybuf, 0x08+0x04, sf); if (keysize == 0x08) { /* standard */ - keycode = (uint64_t)get_64bitBE(keybuf+0x00); + keycode = get_u64be(keybuf+0x00); if (subkey) { keycode = keycode * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) ); } } else if (keysize == 0x08+0x02) { /* seed key + AWB subkey */ - uint64_t file_key = (uint64_t)get_64bitBE(keybuf+0x00); - uint16_t file_sub = (uint16_t)get_16bitBE(keybuf+0x08); + uint64_t file_key = get_u64be(keybuf+0x00); + uint16_t file_sub = get_u16be(keybuf+0x08); keycode = file_key * ( ((uint64_t)file_sub << 16u) | ((uint16_t)~file_sub + 2u) ); } #ifdef HCA_BRUTEFORCE else if (1) { - bruteforce_hca_key(streamFile, hca_data, &keycode, subkey); + bruteforce_hca_key(sf, hca_data, &keycode, subkey); } #endif else { find_hca_key(hca_data, &keycode, subkey); } - clHCA_SetKey(hca_data->handle, (unsigned long long)keycode); //maybe should be done through hca_decoder.c? + hca_set_encryption_key(hca_data, keycode); } /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(hca_data->info.channelCount, hca_data->info.loopEnabled); + vgmstream = allocate_vgmstream(hca_info->channelCount, hca_info->loopEnabled); if (!vgmstream) goto fail; vgmstream->meta_type = meta_HCA; - vgmstream->sample_rate = hca_data->info.samplingRate; + vgmstream->sample_rate = hca_info->samplingRate; - vgmstream->num_samples = hca_data->info.blockCount * hca_data->info.samplesPerBlock - - hca_data->info.encoderDelay - hca_data->info.encoderPadding; - vgmstream->loop_start_sample = hca_data->info.loopStartBlock * hca_data->info.samplesPerBlock - - hca_data->info.encoderDelay + hca_data->info.loopStartDelay; - vgmstream->loop_end_sample = hca_data->info.loopEndBlock * hca_data->info.samplesPerBlock - - hca_data->info.encoderDelay + (hca_data->info.samplesPerBlock - hca_data->info.loopEndPadding); + vgmstream->num_samples = hca_info->blockCount * hca_info->samplesPerBlock - + hca_info->encoderDelay - hca_info->encoderPadding; + vgmstream->loop_start_sample = hca_info->loopStartBlock * hca_info->samplesPerBlock - + hca_info->encoderDelay + hca_info->loopStartDelay; + vgmstream->loop_end_sample = hca_info->loopEndBlock * hca_info->samplesPerBlock - + hca_info->encoderDelay + (hca_info->samplesPerBlock - hca_info->loopEndPadding); /* After loop end CRI's encoder removes the rest of the original samples and puts some * garbage in the last frame that should be ignored. Optionally it can encode fully preserving * the file too, but it isn't detectable, so we'll allow the whole thing just in case */ @@ -80,10 +84,10 @@ VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) { // vgmstream->num_samples = vgmstream->loop_end_sample; /* this can happen in preloading HCA from memory AWB */ - if (hca_data->info.blockCount * hca_data->info.blockSize > get_streamfile_size(streamFile)) { - unsigned int max_block = get_streamfile_size(streamFile) / hca_data->info.blockSize; - vgmstream->num_samples = max_block * hca_data->info.samplesPerBlock - - hca_data->info.encoderDelay - hca_data->info.encoderPadding; + if (hca_info->blockCount * hca_info->blockSize > get_streamfile_size(sf)) { + unsigned int max_block = get_streamfile_size(sf) / hca_info->blockSize; + vgmstream->num_samples = max_block * hca_info->samplesPerBlock - + hca_info->encoderDelay - hca_info->encoderPadding; } vgmstream->coding_type = coding_CRI_HCA; @@ -115,7 +119,7 @@ fail: } -static inline void test_key(hca_codec_data * hca_data, uint64_t key, uint16_t subkey, int *best_score, uint64_t *best_keycode) { +static inline void test_key(hca_codec_data* hca_data, uint64_t key, uint16_t subkey, int* best_score, uint64_t* best_keycode) { int score; if (subkey) { diff --git a/src/vgmstream.c b/src/vgmstream.c index 308e1a42..144c0218 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -2748,8 +2748,7 @@ static STREAMFILE * get_vgmstream_average_bitrate_channel_streamfile(VGMSTREAM * } if (vgmstream->coding_type == coding_ACM) { - acm_codec_data *data = vgmstream->codec_data; - return (data && data->handle) ? data->streamfile : NULL; + return acm_get_streamfile(vgmstream->codec_data); } #ifdef VGM_USE_VORBIS @@ -2758,13 +2757,11 @@ static STREAMFILE * get_vgmstream_average_bitrate_channel_streamfile(VGMSTREAM * } #endif if (vgmstream->coding_type == coding_CRI_HCA) { - hca_codec_data *data = vgmstream->codec_data; - return data ? data->streamfile : NULL; + return hca_get_streamfile(vgmstream->codec_data); } #ifdef VGM_USE_FFMPEG if (vgmstream->coding_type == coding_FFmpeg) { - ffmpeg_codec_data *data = vgmstream->codec_data; - return data ? data->streamfile : NULL; + return ffmpeg_get_streamfile(vgmstream->codec_data); } #endif #if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC) diff --git a/src/vgmstream.h b/src/vgmstream.h index b93cd001..1dfc095c 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -908,108 +908,23 @@ typedef struct { /* main state */ - VGMSTREAMCHANNEL * ch; /* array of channels */ - VGMSTREAMCHANNEL * start_ch; /* shallow copy of channels as they were at the beginning of the stream (for resets) */ - VGMSTREAMCHANNEL * loop_ch; /* shallow copy of channels as they were at the loop point (for loops) */ + VGMSTREAMCHANNEL* ch; /* array of channels */ + VGMSTREAMCHANNEL* start_ch; /* shallow copy of channels as they were at the beginning of the stream (for resets) */ + VGMSTREAMCHANNEL* loop_ch; /* shallow copy of channels as they were at the loop point (for loops) */ void* start_vgmstream; /* shallow copy of the VGMSTREAM as it was at the beginning of the stream (for resets) */ - void * mixing_data; /* state for mixing effects */ + void* mixing_data; /* state for mixing effects */ /* Optional data the codec needs for the whole stream. This is for codecs too * different from vgmstream's structure to be reasonably shoehorned. * Note also that support must be added for resetting, looping and * closing for every codec that uses this, as it will not be handled. */ - void * codec_data; + void* codec_data; /* Same, for special layouts. layout_data + codec_data may exist at the same time. */ - void * layout_data; + void* layout_data; } VGMSTREAM; -#ifdef VGM_USE_VORBIS - -/* standard Ogg Vorbis */ -typedef struct { - 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 */ - - /* decryption setup */ - 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; - -} ogg_vorbis_io; - -typedef struct ogg_vorbis_codec_data ogg_vorbis_codec_data; - - -/* custom Vorbis modes */ -typedef enum { - VORBIS_FSB, /* FMOD FSB: simplified/external setup packets, custom packet headers */ - VORBIS_WWISE, /* Wwise WEM: many variations (custom setup, headers and data) */ - VORBIS_OGL, /* Shin'en OGL: custom packet headers */ - VORBIS_SK, /* Silicon Knights AUD: "OggS" replaced by "SK" */ - VORBIS_VID1, /* Neversoft VID1: custom packet blocks/headers */ -} vorbis_custom_t; - -/* config for Wwise Vorbis (3 types for flexibility though not all combinations exist) */ -typedef enum { WWV_HEADER_TRIAD, WWV_FULL_SETUP, WWV_INLINE_CODEBOOKS, WWV_EXTERNAL_CODEBOOKS, WWV_AOTUV603_CODEBOOKS } wwise_setup_t; -typedef enum { WWV_TYPE_8, WWV_TYPE_6, WWV_TYPE_2 } wwise_header_t; -typedef enum { WWV_STANDARD, WWV_MODIFIED } wwise_packet_t; - -typedef struct { - /* to reconstruct init packets */ - int channels; - int sample_rate; - int blocksize_0_exp; - int blocksize_1_exp; - - uint32_t setup_id; /* external setup */ - int big_endian; /* flag */ - - /* Wwise Vorbis config */ - wwise_setup_t setup_type; - wwise_header_t header_type; - wwise_packet_t packet_type; - - /* output (kinda ugly here but to simplify) */ - off_t data_start_offset; - -} vorbis_custom_config; - -/* custom Vorbis without Ogg layer */ -typedef struct { - vorbis_info vi; /* stream settings */ - vorbis_comment vc; /* stream comments */ - vorbis_dsp_state vd; /* decoder global state */ - vorbis_block vb; /* decoder local state */ - ogg_packet op; /* fake packet for internal use */ - - uint8_t * buffer; /* internal raw data buffer */ - size_t buffer_size; - - size_t samples_to_discard; /* for looping purposes */ - int samples_full; /* flag, samples available in vorbis buffers */ - - vorbis_custom_t type; /* Vorbis subtype */ - vorbis_custom_config config; /* config depending on the mode */ - - /* Wwise Vorbis: saved data to reconstruct modified packets */ - uint8_t mode_blockflag[64+1]; /* max 6b+1; flags 'n stuff */ - int mode_bits; /* bits to store mode_number */ - uint8_t prev_blockflag; /* blockflag in the last decoded packet */ - /* Ogg-style Vorbis: packet within a page */ - int current_packet; - /* reference for page/blocks */ - off_t block_offset; - size_t block_size; - - int prev_block_samples; /* count for optimization */ - -} vorbis_custom_codec_data; -#endif #ifdef VGM_USE_MPEG @@ -1102,48 +1017,14 @@ typedef struct { } mpeg_codec_data; #endif -#ifdef VGM_USE_G7221 -typedef struct g7221_codec_data g7221_codec_data; -#endif - -#ifdef VGM_USE_G719 -typedef struct { - sample_t buffer[960]; - void *handle; -} g719_codec_data; -#endif - -#ifdef VGM_USE_MAIATRAC3PLUS -typedef struct { - sample_t *buffer; - int channels; - int samples_discard; - void *handle; -} maiatrac3plus_codec_data; -#endif - -#ifdef VGM_USE_ATRAC9 -/* ATRAC9 config */ -typedef struct { - int channels; /* to detect weird multichannel */ - uint32_t config_data; /* ATRAC9 config header */ - int encoder_delay; /* initial samples to discard */ -} atrac9_config; -typedef struct atrac9_codec_data atrac9_codec_data; -#endif - -#ifdef VGM_USE_CELT -typedef enum { CELT_0_06_1,CELT_0_11_0} celt_lib_t; -typedef struct celt_codec_data celt_codec_data; -#endif - /* libacm interface */ typedef struct { - STREAMFILE *streamfile; - void *handle; - void *io_config; + STREAMFILE* streamfile; + void* handle; + void* io_config; } acm_codec_data; + /* for files made of "continuous" segments, one per section of a song (using a complete sub-VGMSTREAM) */ typedef struct { int segment_count; @@ -1163,28 +1044,12 @@ typedef struct { int output_channels; /* resulting channels (after mixing, if applied) */ } layered_layout_data; + /* for compressed NWA */ typedef struct { NWAData *nwa; } nwa_codec_data; -typedef struct relic_codec_data relic_codec_data; - -typedef struct { - STREAMFILE *streamfile; - clHCA_stInfo info; - - signed short *sample_buffer; - size_t samples_filled; - size_t samples_consumed; - size_t samples_to_discard; - - void* data_buffer; - - unsigned int current_block; - - void* handle; -} hca_codec_data; #ifdef VGM_USE_FFMPEG typedef struct { @@ -1263,51 +1128,8 @@ typedef struct { INT_PCM sample_buffer[( (6) * (2048)*4 )]; } mp4_aac_codec_data; #endif -#endif +#endif //VGM_USE_MP4V2 -typedef struct ubi_adpcm_codec_data ubi_adpcm_codec_data; - -typedef struct ea_mt_codec_data ea_mt_codec_data; - - -#if 0 -//possible future public/opaque API - -/* define standard C param call and name mangling (to avoid __stdcall / .defs) */ -#define VGMSTREAM_CALL __cdecl //needed? - -/* define external function types (during compilation) */ -#if defined(VGMSTREAM_EXPORT) - #define VGMSTREAM_API __declspec(dllexport) /* when exporting/creating vgmstream DLL */ -#elif defined(VGMSTREAM_IMPORT) - #define VGMSTREAM_API __declspec(dllimport) /* when importing/linking vgmstream DLL */ -#else - #define VGMSTREAM_API /* nothing, internal/default */ -#endif - -//VGMSTREAM_API void VGMSTREAM_CALL vgmstream_function(void); - -//info for opaque VGMSTREAM -typedef struct { - const int channels; - const int sample_rate; - const int num_samples; - const int loop_start_sample; - const int loop_end_sample; - const int loop_flag; - const int num_streams; - const int current_sample; - const int average_bitrate; -} VGMSTREAM_INFO; -void vgmstream_get_info(VGMSTREAM* vgmstream, VGMSTREAM_INFO *vgmstream_info); - -//or maybe -enum vgmstream_value_t { VGMSTREAM_CHANNELS, VGMSTREAM_CURRENT_SAMPLE, ... }; -int vgmstream_get_info(VGMSTREAM* vgmstream, vgmstream_value_t type); -// or -int vgmstream_get_current_sample(VGMSTREAM* vgmstream); - -#endif /* -------------------------------------------------------------------------*/ /* vgmstream "public" API */