From 637273bcd901c99d6f27b2bbc3ac2166f06d9e7d Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 22:35:38 +0200 Subject: [PATCH 01/17] cleanup: move defs around --- src/base/info.c | 1 + src/base/mixing.c | 1 + src/base/mixing_macros.c | 1 + src/base/plugins.h | 8 ++ src/coding/ws_decoder.c | 167 +++++++++++++++++++++------------------ src/formats.c | 3 +- src/layout/layout.h | 70 ++++++++++------ src/vgmstream.h | 91 ++++++++------------- xmplay/xmp_vgmstream.c | 5 +- 9 files changed, 188 insertions(+), 159 deletions(-) diff --git a/src/base/info.c b/src/base/info.c index eb24828d4..df3cea816 100644 --- a/src/base/info.c +++ b/src/base/info.c @@ -1,6 +1,7 @@ #include #include "../vgmstream.h" #include "../coding/coding.h" +#include "../layout/layout.h" #include "mixing.h" #include "../util/channel_mappings.h" #include "../util/sf_utils.h" diff --git a/src/base/mixing.c b/src/base/mixing.c index 6ed4f2753..afd4313e5 100644 --- a/src/base/mixing.c +++ b/src/base/mixing.c @@ -4,6 +4,7 @@ #include "mixer.h" #include "mixer_priv.h" #include "sbuf.h" +#include "../layout/layout.h" #include #include diff --git a/src/base/mixing_macros.c b/src/base/mixing_macros.c index a9a6eb7e6..fa3ce258a 100644 --- a/src/base/mixing_macros.c +++ b/src/base/mixing_macros.c @@ -1,5 +1,6 @@ #include "../vgmstream.h" #include "../util/channel_mappings.h" +#include "../layout/layout.h" #include "mixing.h" #include "mixer_priv.h" #include diff --git a/src/base/plugins.h b/src/base/plugins.h index dbc25c79c..f937f7b90 100644 --- a/src/base/plugins.h +++ b/src/base/plugins.h @@ -8,6 +8,14 @@ #include "../vgmstream.h" +/* List supported formats and return elements in the list, for plugins that need to know. + * The list disables some common formats that may conflict (.wav, .ogg, etc). */ +const char** vgmstream_get_formats(size_t* size); + +/* same, but for common-but-disabled formats in the above list. */ +const char** vgmstream_get_common_formats(size_t* size); + + /* ****************************************** */ /* CONTEXT: simplifies plugin code */ /* ****************************************** */ diff --git a/src/coding/ws_decoder.c b/src/coding/ws_decoder.c index ea0a36edd..9057986c6 100644 --- a/src/coding/ws_decoder.c +++ b/src/coding/ws_decoder.c @@ -3,135 +3,148 @@ #include "../util.h" /* Westwood Studios ADPCM */ - /* Based on Valery V. Anisimovsky's WS-AUD.txt */ -static char WSTable2bit[4] = { -2,-1,0,1 }; -static char WSTable4bit[16] = { -9,-8,-6,-5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5 ,6, 8 }; +static char WSTable2bit[4] = { -2, -1, 0, 1 }; +static char WSTable4bit[16] = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 }; -/* We pass in the VGMSTREAM here, unlike in other codings, because - the decoder has to know about the block structure. */ -void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, - int32_t samples_to_do) { - VGMSTREAMCHANNEL * stream = &(vgmstream->ch[channel]); +/* We pass in the VGMSTREAM here, unlike in other codings, because the decoder has to know about the block structure. */ +void decode_ws(VGMSTREAM* vgmstream, int channel, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { + VGMSTREAMCHANNEL* stream = &(vgmstream->ch[channel]); + STREAMFILE* sf = stream->streamfile; int16_t hist = stream->adpcm_history1_16; off_t offset = stream->offset; - int samples_left_in_frame = stream->samples_left_in_frame; - off_t header_off = stream->frame_header_offset; + int samples_left_in_frame = stream->ws_samples_left_in_frame; + off_t header_offset = stream->ws_frame_header_offset; - int i; - int32_t sample_count; + //int i; + int32_t sample_count = 0; if (vgmstream->ws_output_size == vgmstream->current_block_size) { - /* uncompressed, we just need to convert to 16-bit */ - for (i=first_sample,sample_count=0; istreamfile)-0x80)*0x100; + /* uncompressed pcm8 to pcm16 */ + for (int i = first_sample; i < first_sample + samples_to_do; i++) { + outbuf[sample_count] = (read_u8(offset,sf) - 0x80) * 0x100; + sample_count += channelspacing; + offset++; } - } else { + } + else { if (first_sample == 0) { hist = 0x80; samples_left_in_frame = 0; } - /* actually decompress */ - for (i=first_sample,sample_count=0; istreamfile); - count = header & 0x3f; - switch (header>>6) { /* code */ + uint8_t header = read_u8(header_offset, sf); + uint8_t count = header & 0x3f; + uint8_t code = header >> 6; + switch (code) { /* code */ case 0: /* 2-bit ADPCM */ - if (samples_left_in_frame == 0) { - samples_left_in_frame = (count + 1)*4; - } - for (;samples_left_in_frame>0 && /* read this frame */ - istreamfile); - sample = (sample >> (twobit*2)) & 0x3; + if (samples_left_in_frame == 0) + samples_left_in_frame = (count + 1) * 4; + + /* read this frame up to samples_to_do */ + for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) { + + int twobit = ((count + 1) * 4 - samples_left_in_frame) % 4; + uint8_t sample = read_u8(offset,sf); + sample = (sample >> (twobit * 2)) & 0x3; hist += WSTable2bit[sample]; + if (hist < 0) hist = 0; - if (hist > 0xff) hist = 0xff; - outbuf[sample_count]=(hist-0x80)*0x100; + else if (hist > 0xff) hist = 0xff; + + outbuf[sample_count] = (hist - 0x80) * 0x100; + sample_count += channelspacing; + samples_left_in_frame--; if (twobit == 3) offset++; /* done with that byte */ } break; + case 1: /* 4-bit ADPCM */ - if (samples_left_in_frame == 0) { - samples_left_in_frame = (count + 1)*2; - } - for (;samples_left_in_frame>0 && /* read this frame */ - istreamfile); + if (samples_left_in_frame == 0) + samples_left_in_frame = (count + 1) * 2; + + /* read this frame up to samples_to_do */ + for ( ; samples_left_in_frame>0 && i < first_sample + samples_to_do; i++) { + + int nibble = ((count + 1) * 4 - samples_left_in_frame) % 2; + uint8_t sample = read_u8(offset, sf); if (nibble == 0) sample &= 0xf; else sample >>= 4; hist += WSTable4bit[sample]; + if (hist < 0) hist = 0; - if (hist > 0xff) hist = 0xff; - outbuf[sample_count]=(hist-0x80)*0x100; + else if (hist > 0xff) hist = 0xff; + + outbuf[sample_count] = (hist - 0x80) * 0x100; + sample_count += channelspacing; + samples_left_in_frame--; if (nibble == 1) offset++; /* done with that byte */ } break; + case 2: /* no compression */ - if (count & 0x20) { /* delta */ - /* Note no checks against samples_to_do here, - at the top of the for loop we can always do at - least one sample */ + if (count & 0x20) { /* new delta */ + /* Note no checks against samples_to_do here, at the top of the for loop + * we can always do at least one sample */ + /* low 5 bits are a signed delta */ if (count & 0x10) { - hist -= ((count & 0xf)^0xf) + 1; + hist -= ((count & 0x0f) ^ 0x0f) + 1; } else { - hist += count & 0xf; + hist += count & 0x0f; } - /* Valery doesn't specify this, but I will assume */ + /* Valery doesn't specify this, but clamp just in case */ if (hist < 0) hist = 0; - if (hist > 0xff) hist = 0xff; + else if (hist > 0xff) hist = 0xff; - outbuf[sample_count]=(hist-0x80)*0x100; - sample_count+=channelspacing; i++; - /* just one, and we got it */ - samples_left_in_frame = 0; - } else { /* copy bytes verbatim */ + outbuf[sample_count] = (hist - 0x80) * 0x100; + sample_count += channelspacing; + samples_left_in_frame = 0; /* just one */ + } + else { + /* copy bytes verbatim */ if (samples_left_in_frame == 0) - samples_left_in_frame=count+1; - for (;samples_left_in_frame>0 && /* read this frame */ - istreamfile))-0x80)*0x100; + samples_left_in_frame = (count + 1); + + /* read this frame up to samples_to_do */ + for ( ; samples_left_in_frame > 0 && i < first_sample + samples_to_do; i++) { + hist = read_u8(offset,sf); + offset++; + + outbuf[sample_count] = (hist - 0x80) * 0x100; + sample_count += channelspacing; + samples_left_in_frame--; } } break; + case 3: /* RLE */ if (samples_left_in_frame == 0) - samples_left_in_frame=count+1; - for (;samples_left_in_frame>0 && /* read this frame */ - i 0 && i < first_sample + samples_to_do; i++) { + outbuf[sample_count] = (hist - 0x80) * 0x100; + sample_count += channelspacing; + samples_left_in_frame--; } default: break; @@ -141,6 +154,6 @@ void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channels stream->offset = offset; stream->adpcm_history1_16 = hist; - stream->samples_left_in_frame = samples_left_in_frame; - stream->frame_header_offset = header_off; + stream->ws_samples_left_in_frame = samples_left_in_frame; + stream->ws_frame_header_offset = header_offset; } diff --git a/src/formats.c b/src/formats.c index e06f5c054..27ab3b7fd 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1,5 +1,6 @@ #include "vgmstream.h" #include "coding/coding.h" +#include "layout/layout.h" /* Defines the list of accepted extensions. vgmstream doesn't use it internally so it's here @@ -1237,7 +1238,7 @@ static const meta_info meta_info_list[] = { {meta_EB_SF0, "assumed Excitebots .sf0 by extension"}, {meta_MTAF, "Konami MTAF header"}, {meta_ALP, "High Voltage ALP header"}, - {meta_WPD, "WPD 'DPW' header"}, + {meta_WPD, "Navel WPD header"}, {meta_MN_STR, "Mini Ninjas 'STR' header"}, {meta_MSS, "Guerilla MCSS header"}, {meta_PS2_HSF, "Lowrider 'HSF' header"}, diff --git a/src/layout/layout.h b/src/layout/layout.h index 3423e2d8c..6b4d15e51 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -6,6 +6,53 @@ #include "../util/reader_sf.h" #include "../util/log.h" +/* basic layouts */ +void render_vgmstream_flat(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); + +void render_vgmstream_interleave(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); + +/* segmented layout */ +/* for files made of "continuous" segments, one per section of a song (using a complete sub-VGMSTREAM) */ +typedef struct { + int segment_count; + VGMSTREAM** segments; + int current_segment; + sample_t* buffer; + int input_channels; /* internal buffer channels */ + int output_channels; /* resulting channels (after mixing, if applied) */ + int mixed_channels; /* segments have different number of channels */ +} segmented_layout_data; + +void render_vgmstream_segmented(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); +segmented_layout_data* init_layout_segmented(int segment_count); +int setup_layout_segmented(segmented_layout_data* data); +void free_layout_segmented(segmented_layout_data* data); +void reset_layout_segmented(segmented_layout_data* data); +void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample); +void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample); +VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment); + +/* layered layout */ +/* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */ +typedef struct { + int layer_count; + VGMSTREAM** layers; + sample_t* buffer; + int input_channels; /* internal buffer channels */ + int output_channels; /* resulting channels (after mixing, if applied) */ + int external_looping; /* don't loop using per-layer loops, but layout's own looping */ + int curr_layer; /* helper */ +} layered_layout_data; + +void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); +layered_layout_data* init_layout_layered(int layer_count); +int setup_layout_layered(layered_layout_data* data); +void free_layout_layered(layered_layout_data* data); +void reset_layout_layered(layered_layout_data* data); +void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample); +void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample); +VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data); + /* blocked layouts */ void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); void block_update(off_t block_offset, VGMSTREAM* vgmstream); @@ -51,27 +98,4 @@ void block_update_ubi_sce(off_t block_offset, VGMSTREAM* vgmstream); void block_update_tt_ad(off_t block_offset, VGMSTREAM* vgmstream); void block_update_vas(off_t block_offset, VGMSTREAM* vgmstream); -/* other layouts */ -void render_vgmstream_interleave(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); - -void render_vgmstream_flat(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); - -void render_vgmstream_segmented(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); -segmented_layout_data* init_layout_segmented(int segment_count); -int setup_layout_segmented(segmented_layout_data* data); -void free_layout_segmented(segmented_layout_data* data); -void reset_layout_segmented(segmented_layout_data* data); -void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample); -void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample); -VGMSTREAM *allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment); - -void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); -layered_layout_data* init_layout_layered(int layer_count); -int setup_layout_layered(layered_layout_data* data); -void free_layout_layered(layered_layout_data* data); -void reset_layout_layered(layered_layout_data* data); -void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample); -void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample); -VGMSTREAM *allocate_layered_vgmstream(layered_layout_data* data); - #endif diff --git a/src/vgmstream.h b/src/vgmstream.h index 69f7575e7..d7030a676 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -94,27 +94,28 @@ typedef struct { } play_state_t; -/* info for a single vgmstream channel */ +/* info for a single vgmstream 'channel' (or rather, mono stream) */ typedef struct { STREAMFILE* streamfile; /* file used by this channel */ off_t channel_start_offset; /* where data for this channel begins */ off_t offset; /* current location in the file */ - off_t frame_header_offset; /* offset of the current frame header (for WS) */ - int samples_left_in_frame; /* for WS */ + /* format and channel specific */ - /* format specific */ + /* ADPCM with built or variable decode coefficients */ + union { + int16_t adpcm_coef[16]; /* DSP, some ADX (in rare cases may change per block) */ + int16_t vadpcm_coefs[8*2*8]; /* VADPCM: max 8 groups * max 2 order * fixed 8 subframe = 128 coefs */ + int32_t adpcm_coef_3by32[96]; /* Level-5 0x555 */ + }; - /* adpcm */ - int16_t adpcm_coef[16]; /* formats with decode coefficients built in (DSP, some ADX) */ - int32_t adpcm_coef_3by32[0x60]; /* Level-5 0x555 */ - int16_t vadpcm_coefs[8*2*8]; /* VADPCM: max 8 groups * max 2 order * fixed 8 subframe coefs */ + /* previous ADPCM samples */ union { - int16_t adpcm_history1_16; /* previous sample */ + int16_t adpcm_history1_16; int32_t adpcm_history1_32; }; union { - int16_t adpcm_history2_16; /* previous previous sample */ + int16_t adpcm_history2_16; int32_t adpcm_history2_32; }; union { @@ -129,14 +130,20 @@ typedef struct { //double adpcm_history1_double; //double adpcm_history2_double; - int adpcm_step_index; /* for IMA */ - int adpcm_scale; /* for MS ADPCM */ + /* for ADPCM decoders that store steps (IMA) or scales (MSADPCM) */ + union { + int adpcm_step_index; + int adpcm_scale; + }; + + /* Westwood Studios decoder */ + off_t ws_frame_header_offset; /* offset of the current frame header */ + int ws_samples_left_in_frame; /* last decoded info */ /* state for G.721 decoder, sort of big but we might as well keep it around */ struct g72x_state g72x_state; /* ADX encryption */ - int adx_channels; uint16_t adx_xor; uint16_t adx_mult; uint16_t adx_add; @@ -147,9 +154,9 @@ typedef struct { /* main vgmstream info */ typedef struct { /* basic config */ - int32_t num_samples; /* the actual max number of samples */ + int channels; /* number of channels for the current stream */ int32_t sample_rate; /* sample rate in Hz */ - int channels; /* number of channels */ + int32_t num_samples; /* the actual max number of samples */ coding_t coding_type; /* type of encoding */ layout_t layout_type; /* type of layout */ meta_t meta_type; /* type of metadata */ @@ -180,13 +187,13 @@ typedef struct { int format_id; /* internal format ID */ /* layout/block state */ - size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */ int32_t current_sample; /* sample point within the file (for loop detection) */ int32_t samples_into_block; /* number of samples into the current block/interleave/segment/etc */ off_t current_block_offset; /* start of this block (offset of block header) */ size_t current_block_size; /* size in usable bytes of the block we're in now (used to calculate num_samples per block) */ int32_t current_block_samples; /* size in samples of the block we're in now (used over current_block_size if possible) */ off_t next_block_offset; /* offset of header of the next block */ + size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */ /* loop state (saved when loop is hit to restore later) */ int32_t loop_current_sample; /* saved from current_sample (same as loop_start_sample, but more state-like) */ @@ -228,35 +235,13 @@ typedef struct { play_state_t pstate; /* player state (applied over decoding) */ int loop_count; /* counter of complete loops (1=looped once) */ int loop_target; /* max loops before continuing with the stream end (loops forever if not set) */ + sample_t* tmpbuf; /* garbage buffer used for seeking/trimming */ size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels) */ } VGMSTREAM; -/* for files made of "continuous" segments, one per section of a song (using a complete sub-VGMSTREAM) */ -typedef struct { - int segment_count; - VGMSTREAM** segments; - int current_segment; - sample_t* buffer; - int input_channels; /* internal buffer channels */ - int output_channels; /* resulting channels (after mixing, if applied) */ - int mixed_channels; /* segments have different number of channels */ -} segmented_layout_data; - -/* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */ -typedef struct { - int layer_count; - VGMSTREAM** layers; - sample_t* buffer; - int input_channels; /* internal buffer channels */ - int output_channels; /* resulting channels (after mixing, if applied) */ - int external_looping; /* don't loop using per-layer loops, but layout's own looping */ - int curr_layer; /* helper */ -} layered_layout_data; - - // VGMStream description in structure format typedef struct { int sample_rate; @@ -304,9 +289,6 @@ void reset_vgmstream(VGMSTREAM* vgmstream); /* close an open vgmstream */ void close_vgmstream(VGMSTREAM* vgmstream); -/* calculate the number of samples to be played based on looping parameters */ -int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream); - /* Decode data into sample buffer. Returns < sample_count on stream end */ int render_vgmstream(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); @@ -321,20 +303,6 @@ void describe_vgmstream_info(VGMSTREAM* vgmstream, vgmstream_info* desc); /* Return the average bitrate in bps of all unique files contained within this stream. */ int get_vgmstream_average_bitrate(VGMSTREAM* vgmstream); -/* List supported formats and return elements in the list, for plugins that need to know. - * The list disables some common formats that may conflict (.wav, .ogg, etc). */ -const char** vgmstream_get_formats(size_t* size); - -/* same, but for common-but-disabled formats in the above list. */ -const char** vgmstream_get_common_formats(size_t* size); - -/* Force enable/disable internal looping. Should be done before playing anything (or after reset), - * and not all codecs support arbitrary loop values ATM. */ -void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample); - -/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */ -void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target); - /* Return 1 if vgmstream detects from the filename that said file can be used even if doesn't physically exist */ int vgmstream_is_virtual_filename(const char* filename); @@ -358,5 +326,16 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size); void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size); +/* calculate the number of samples to be played based on looping parameters */ +int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream); + void setup_state_vgmstream(VGMSTREAM* vgmstream); + +/* Force enable/disable internal looping. Should be done before playing anything (or after reset), + * and not all codecs support arbitrary loop values ATM. */ +void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample); + +/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */ +void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target); + #endif diff --git a/xmplay/xmp_vgmstream.c b/xmplay/xmp_vgmstream.c index 2c52066ef..94666d7cd 100644 --- a/xmplay/xmp_vgmstream.c +++ b/xmplay/xmp_vgmstream.c @@ -237,8 +237,9 @@ void WINAPI xmplay_GetInfoText(char* format, char* length) { rate = vgmstream->sample_rate; samples = vgmstream->num_samples; bps = get_vgmstream_average_bitrate(vgmstream) / 1000; - get_vgmstream_coding_description(vgmstream, fmt, sizeof(fmt)); - if (strcmp(fmt, "FFmpeg") == 0) + + //get_vgmstream_coding_description(vgmstream, fmt, sizeof(fmt)); + //if (strcmp(fmt, "FFmpeg") == 0) { char buffer[1024]; buffer[0] = '\0'; From 21b3067a7cec5d4020b42b25f7da4d59f582cc3e Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 22:36:14 +0200 Subject: [PATCH 02/17] cleanup: wpd, ws_aud --- src/meta/wpd.c | 92 +++++++++++++++-------------------------- src/meta/ws_aud.c | 103 +++++++++++++++++++--------------------------- 2 files changed, 76 insertions(+), 119 deletions(-) diff --git a/src/meta/wpd.c b/src/meta/wpd.c index 21d81ceec..0631a89ed 100644 --- a/src/meta/wpd.c +++ b/src/meta/wpd.c @@ -1,59 +1,33 @@ -#include "meta.h" -#include "../util.h" - -/* WPD (from Shuffle! (PC)) */ -VGMSTREAM * init_vgmstream_wpd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - int channel_count; - int loop_flag; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("wpd",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x20445057) /* " DPW" */ - goto fail; - - channel_count = read_32bitLE(0x4,streamFile); - loop_flag = 0; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x30; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->coding_type = coding_PCM16LE; - vgmstream->num_samples = (read_32bitLE(0x14,streamFile))/2/channel_count; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 2; - vgmstream->meta_type = meta_WPD; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../util/meta_utils.h" + +/* WPD - from Shuffle! (PC) */ +VGMSTREAM* init_vgmstream_wpd(STREAMFILE* sf) { + + /* checks */ + if (!is_id32be(0x00,sf, " DPW")) + return NULL; + if (!check_extensions(sf, "wpd")) + return NULL; + + meta_header_t h = {0}; + h.meta = meta_WPD; + h.channels = read_u32le(0x04,sf); /* always 2? */ + // 08: always 2? + // 0c: bits per sample (16) + h.sample_rate = read_s32le(0x10,sf); /* big endian? */ + h.data_size = read_u32le(0x14,sf); + // 18: PCM fmt (codec 0001, channels, srate, bitrate...) + + h.stream_offset = 0x30; + h.num_samples = pcm16_bytes_to_samples(h.data_size, h.channels); + + h.coding = coding_PCM16LE; + h.layout = layout_interleave; + h.interleave = 0x02; + + h.sf = sf; + h.open_stream = true; + + return alloc_metastream(&h); +} diff --git a/src/meta/ws_aud.c b/src/meta/ws_aud.c index cd468007c..f9ae1c03e 100644 --- a/src/meta/ws_aud.c +++ b/src/meta/ws_aud.c @@ -2,15 +2,11 @@ #include "../layout/layout.h" #include "../util.h" -/* Westwood Studios .aud (WS-AUD) */ - +/* .AUD - from Westwood Studios games [Command & Conquer (PC), ] */ VGMSTREAM* init_vgmstream_ws_aud(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - coding_t coding_type = -1; off_t format_offset; - int channels; bool new_type = false; - int bytes_per_sample = 0; /* checks **/ @@ -31,82 +27,69 @@ VGMSTREAM* init_vgmstream_ws_aud(STREAMFILE* sf) { } /* blocked format with a mini-header */ + int sample_rate = read_u16le(0x00,sf); + uint8_t channel_flags = read_u8(format_offset + 0x00, sf); + uint8_t format_flags = read_u8(format_offset + 0x01, sf); - if (read_u8(format_offset + 0x00, sf) & 1) - channels = 2; - else - channels = 1; - + int channels = channel_flags & 1 ? 2 : 1; if (channels == 2) - goto fail; /* not seen */ - - if (read_u8(format_offset + 0x01,sf) & 2) - bytes_per_sample = 2; - else - bytes_per_sample = 1; - - /* check codec type */ - switch (read_u8(format_offset + 0x01,sf)) { - case 1: /* Westwood custom */ - coding_type = coding_WS; - if (bytes_per_sample != 1) goto fail; /* shouldn't happen? */ - break; - case 99: /* IMA ADPCM */ - coding_type = coding_IMA_int; - break; - default: - goto fail; - } - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels, 0); - if (!vgmstream) goto fail; + return NULL; /* not seen */ + int bytes_per_sample = (channel_flags & 2) ? 2 : 1; + uint32_t data_size; if (new_type) { - vgmstream->num_samples = read_32bitLE(0x06,sf)/bytes_per_sample/channels; + data_size = read_u32le(0x06,sf); } else { - /* Doh, no output size in old type files. We have to read through the - * file looking at chunk headers! Crap! */ - int32_t out_size = 0; - off_t current_offset = 0x8; + /* to read through the file looking at chunk headers */ + off_t offset = 0x08; off_t file_size = get_streamfile_size(sf); - while (current_offset < file_size) { - int16_t chunk_size; - chunk_size = read_16bitLE(current_offset,sf); - out_size += read_16bitLE(current_offset+2,sf); + data_size = 0; + while (offset < file_size) { + uint16_t chunk_size = read_u16le(offset + 0x00,sf); + data_size += read_u16le(offset + 0x02,sf); /* while we're here might as well check for valid chunks */ - if (read_32bitLE(current_offset+4,sf) != 0x0000DEAF) goto fail; - current_offset+=8+chunk_size; + if (read_u32le(offset + 0x04, sf) != 0x0000DEAF) + goto fail; + offset += 0x08 + chunk_size; } - - vgmstream->num_samples = out_size/bytes_per_sample/channels; } - + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, 0); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_WS_AUD; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = data_size / bytes_per_sample / channels; /* they tend to not actually have data for the last odd sample */ - if (vgmstream->num_samples & 1) vgmstream->num_samples--; - vgmstream->sample_rate = (uint16_t)read_16bitLE(0x00,sf); + if (vgmstream->num_samples & 1) + vgmstream->num_samples--; + + switch (format_flags) { + case 0x01: /* Westwood ADPCM [The Legend of Kyrandia - Book 3 (PC)] */ + vgmstream->coding_type = coding_WS; + if (bytes_per_sample != 1) /* shouldn't happen? */ + goto fail; + break; - vgmstream->coding_type = coding_type; - if (new_type) { - vgmstream->meta_type = meta_WS_AUD; + case 0x63: /* IMA ADPCM [Blade Runner (PC)] */ + vgmstream->coding_type = coding_IMA_int; + break; + default: + goto fail; } vgmstream->layout_type = layout_blocked_ws_aud; if (!vgmstream_open_stream(vgmstream, sf, 0x00) ) goto fail; - - if (new_type) { - block_update(0x0c, vgmstream); - } else { - block_update(0x08, vgmstream); - } + block_update(new_type ? 0x0c : 0x08, vgmstream); return vgmstream; - fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } From 8515d2beee1c4c3789f5009272081063a902a97d Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 22:36:35 +0200 Subject: [PATCH 03/17] cleanup: fix util --- src/util/endianness.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/endianness.h b/src/util/endianness.h index 0c1d2de48..c4e3d7cf8 100644 --- a/src/util/endianness.h +++ b/src/util/endianness.h @@ -33,7 +33,7 @@ static inline int guess_endian32(off_t offset, STREAMFILE* sf) { } static inline read_u32_t guess_read_u32(off_t offset, STREAMFILE* sf) { - return guess_endian32(0x08,sf) ? read_u32be : read_u32le; + return guess_endian32(offset,sf) ? read_u32be : read_u32le; } #endif From 4e19ecb051ce1b08ec27cfb24640981a42b8fa13 Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 22:40:36 +0200 Subject: [PATCH 04/17] cleanup: adx validations --- src/meta/adx.c | 96 ++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/src/meta/adx.c b/src/meta/adx.c index 014a81c35..ade96e2cc 100644 --- a/src/meta/adx.c +++ b/src/meta/adx.c @@ -31,55 +31,51 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { int32_t num_samples, loop_start_sample = 0, loop_end_sample = 0; uint16_t cutoff; uint16_t version; - uint8_t encoding_type, frame_size; int16_t coef1, coef2; uint16_t xor_start = 0, xor_mult = 0, xor_add = 0; - meta_t header_type; coding_t coding_type; /* checks*/ if (read_u16be(0x00,sf) != 0x8000) - goto fail; + return NULL; /* .adx: standard * .adp: Headhunter (DC) */ if (!check_extensions(sf,"adx,adp")) - goto fail; + return NULL; - /* CRI checks both 0x8000 and memcmps this */ start_offset = read_u16be(0x02,sf) + 0x04; - if (read_u16be(start_offset - 0x06,sf) != 0x2863 || /* "(c" */ - read_u32be(start_offset - 0x04,sf) != 0x29435249) /* ")CRI" */ - goto fail; - - encoding_type = read_u8(0x04, sf); + uint8_t encoding_type = read_u8(0x04, sf); switch (encoding_type) { case 0x02: - coding_type = coding_CRI_ADX_fixed; + coding_type = coding_CRI_ADX_fixed; /* unused/encoder only */ break; case 0x03: coding_type = coding_CRI_ADX; break; case 0x04: - coding_type = coding_CRI_ADX_exp; + coding_type = coding_CRI_ADX_exp; /* unused/encoder only */ break; default: /* 0x10 is AHX for DC, 0x11 is AHX */ - goto fail; + return NULL; } /* ADX encoders can't set this value, but is honored by ADXPlay if changed and multiple of 0x12, * though output is unusual and may not be fully supported (works in mono so not an interleave) - * Later versions of the decode just use constant 0x12 ignoring it, though. */ - frame_size = read_u8(0x05, sf); - - if (read_u8(0x06,sf) != 4) /* bits per sample */ - goto fail; - - /* older ADX (adxencd) up to 2ch, newer ADX (criatomencd) up to 8 */ - channels = read_u8(0x07,sf); + * Later versions of the decoder just use constant 0x12 ignoring it, though. */ + uint8_t frame_size = read_u8(0x05, sf); + if (frame_size != 0x12) + return NULL; + uint8_t bits_per_sample = read_u8(0x06,sf); + if (bits_per_sample != 4) + return NULL; + + channels = read_u8(0x07,sf); /* older ADX (adxencd) up to 2ch, newer ADX (criatomencd) up to 8 */ + if (channels > 8) + return NULL; sample_rate = read_s32be(0x08,sf); num_samples = read_s32be(0x0c,sf); cutoff = read_u16be(0x10,sf); /* high-pass cutoff frequency, always 500 */ @@ -132,8 +128,9 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { hist_size = (channels > 1 ? 0x04 * channels : 0x04 + 0x04); /* min is 0x8, even in 1ch files */ ainf_offset = base_size + hist_size + 0x04; /* not seen with >2ch though */ - if (is_id32be(ainf_offset+0x00,sf, "AINF")) + if (is_id32be(ainf_offset+0x00,sf, "AINF")) { ainf_size = read_u32be(ainf_offset+0x04,sf); + } if (start_offset - ainf_size - 0x06 >= hist_offset + hist_size + loops_size) { /* enough space for loop info? */ off_t loops_offset = base_size + hist_size; @@ -169,10 +166,18 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { header_type = meta_ADX_05; } else { /* not a known/supported version signature */ - goto fail; + return NULL; } + /* CRI mainly checks value 0x8000 at 0x00, and memcmps this, but offset is right before data start + * usually aligned to 0x100/0x800/0x1000, so do other checks first to avoid seeking back and forth */ + uint8_t cri_str[0x06] = {0}; + read_streamfile(cri_str, start_offset - 0x06, sizeof(cri_str), sf); + if (memcmp(cri_str, "(c)CRI", sizeof(cri_str)) != 0) + return NULL; + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; @@ -191,9 +196,8 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { /* calculate filter coefficients */ if (coding_type == coding_CRI_ADX_fixed) { - int i; - /* standard XA coefs * (2<<11) */ - for (i = 0; i < channels; i++) { + /* standard XA coefs * (2 << 11) */ + for (int i = 0; i < channels; i++) { vgmstream->ch[i].adpcm_coef[0] = 0x0000; vgmstream->ch[i].adpcm_coef[1] = 0x0000; vgmstream->ch[i].adpcm_coef[2] = 0x0F00; @@ -206,7 +210,6 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { } else { /* coefs from cutoff frequency (some info from decomps, uses floats but no diffs if using doubles due to rounding) */ - int i; float x, y, z, a, b, c; x = cutoff; @@ -220,34 +223,28 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { coef1 = (short)(c * 8192); coef2 = (short)(c * c * -4096); - for (i = 0; i < channels; i++) { + for (int i = 0; i < channels; i++) { vgmstream->ch[i].adpcm_coef[0] = coef1; vgmstream->ch[i].adpcm_coef[1] = coef2; } } /* init decoder */ - { - int i; - - for (i = 0; i < channels; i++) { - /* 2 hist shorts per ch, corresponding to the very first original sample repeated (verified with CRI's encoders). - * Not vital as their effect is small, after a few samples they don't matter, and most songs start in silence. */ - if (hist_offset) { - vgmstream->ch[i].adpcm_history1_32 = read_s16be(hist_offset + i*4 + 0x00,sf); - vgmstream->ch[i].adpcm_history2_32 = read_s16be(hist_offset + i*4 + 0x02,sf); - } + for (int i = 0; i < channels; i++) { + /* 2 hist shorts per ch, corresponding to the very first original sample repeated (verified with CRI's encoders). + * Not vital as their effect is small, after a few samples they don't matter, and most songs start in silence. */ + if (hist_offset) { + vgmstream->ch[i].adpcm_history1_32 = read_s16be(hist_offset + i*4 + 0x00,sf); + vgmstream->ch[i].adpcm_history2_32 = read_s16be(hist_offset + i*4 + 0x02,sf); + } - if (coding_type == coding_CRI_ADX_enc_8 || coding_type == coding_CRI_ADX_enc_9) { - int j; - vgmstream->ch[i].adx_channels = channels; - vgmstream->ch[i].adx_xor = xor_start; - vgmstream->ch[i].adx_mult = xor_mult; - vgmstream->ch[i].adx_add = xor_add; + if (coding_type == coding_CRI_ADX_enc_8 || coding_type == coding_CRI_ADX_enc_9) { + vgmstream->ch[i].adx_xor = xor_start; + vgmstream->ch[i].adx_mult = xor_mult; + vgmstream->ch[i].adx_add = xor_add; - for (j = 0; j < i; j++) - adx_next_key(&vgmstream->ch[i]); - } + for (int j = 0; j < i; j++) + adx_next_key(&vgmstream->ch[i]); } } @@ -255,7 +252,6 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; @@ -387,13 +383,13 @@ static bool find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint /* read the prescales */ for (i = 0; i < bruteframe_start; i++) { - prescales[i] = read_16bitBE(start_offset + i*frame_size, sf); + prescales[i] = read_u16be(start_offset + i * frame_size, sf); } } /* read in the scales */ for (i = 0; i < bruteframe_count; i++) { - scales[i] = read_16bitBE(start_offset + (bruteframe_start + i)*frame_size, sf); + scales[i] = read_u16be(start_offset + (bruteframe_start + i) * frame_size, sf); } } From 9b485ac735b7969f5ec9653b43bbafe5a3dd5f63 Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 23:07:24 +0200 Subject: [PATCH 05/17] cleanup: rename possibly reserved var --- src/coding/libs/compresswave_lib.c | 600 ++++++++++++++--------------- src/coding/libs/compresswave_lib.h | 32 +- 2 files changed, 316 insertions(+), 316 deletions(-) diff --git a/src/coding/libs/compresswave_lib.c b/src/coding/libs/compresswave_lib.c index 1e87106a2..ac6f1b295 100644 --- a/src/coding/libs/compresswave_lib.c +++ b/src/coding/libs/compresswave_lib.c @@ -36,11 +36,11 @@ typedef struct { int64_t Size; } TStream; -static void TStream_Read_Uint32(TStream* this, uint32_t* value) { +static void TStream_Read_Uint32(TStream* self, uint32_t* value) { uint8_t buf[0x4] = {0}; - read_streamfile(buf, this->Position, sizeof(buf), this->File); - this->Position += 0x4; + read_streamfile(buf, self->Position, sizeof(buf), self->File); + self->Position += 0x4; *value = get_u32le(buf); } @@ -118,83 +118,83 @@ typedef struct { //related to huffman encoding -static void THuff_InitHuffTree(THuff* this); //initializes tree -static int THuff_InsertHuffNode(THuff* this, int v, int w, TNodeState s, int b1, int b2); //add node to tree -static void THuff_MakeHuffTree(THuff* this); +static void THuff_InitHuffTree(THuff* self); //initializes tree +static int THuff_InsertHuffNode(THuff* self, int v, int w, TNodeState s, int b1, int b2); //add node to tree +static void THuff_MakeHuffTree(THuff* self); //related to single bit IO -static void THuff_BeginBitIO(THuff* this); -static void THuff_EndBitIO(THuff* this); -static int THuff_ReadBit(THuff* this); +static void THuff_BeginBitIO(THuff* self); +static void THuff_EndBitIO(THuff* self); +static int THuff_ReadBit(THuff* self); static uint32_t THuff__ROR(uint32_t src, uint32_t shift); static THuff* THuff_Create(TStream* buf); // creation -static void THuff_Free(THuff* this); // release the power -static void THuff_SetCipherCode(THuff* this, uint32_t msk); // encryption mask bits +static void THuff_Free(THuff* self); // release the power +static void THuff_SetCipherCode(THuff* self, uint32_t msk); // encryption mask bits //functions for reading -static void THuff_BeginRead(THuff* this); -static int THuff_Read(THuff* this); +static void THuff_BeginRead(THuff* self); +static int THuff_Read(THuff* self); #if 0 -static int64_t THuff_GetFileSize(THuff* this); // get file size before encoding -static int THuff_GetEOF(THuff* this); // EOF detection +static int64_t THuff_GetFileSize(THuff* self); // get file size before encoding +static int THuff_GetEOF(THuff* self); // EOF detection #endif -static void THuff_MoveBeginPosition(THuff* this); // return to initial state -static void THuff_GetPositionData(THuff* this, THuffPositionData* s); // secret -static void THuff_SetPositionData(THuff* this, THuffPositionData* s); +static void THuff_MoveBeginPosition(THuff* self); // return to initial state +static void THuff_GetPositionData(THuff* self, THuffPositionData* s); // secret +static void THuff_SetPositionData(THuff* self, THuffPositionData* s); //------------------------------------------------------------------------------ //create static THuff* THuff_Create(TStream* buf) { - THuff* this = malloc(sizeof(THuff)); - if (!this) return NULL; + THuff* self = malloc(sizeof(THuff)); + if (!self) return NULL; //define stream - this->Buff = *buf; + self->Buff = *buf; //initialization - THuff_InitHuffTree(this); - memcpy(this->Hed.HedChar, "HUF\0", 0x4); - this->Hed.Version = 1; - this->Hed.FileSize = 0; + THuff_InitHuffTree(self); + memcpy(self->Hed.HedChar, "HUF\0", 0x4); + self->Hed.Version = 1; + self->Hed.FileSize = 0; //set cipher bits - this->CipherBuf = 0; - THuff_SetCipherCode(this, 0x0); + self->CipherBuf = 0; + THuff_SetCipherCode(self, 0x0); //mode - this->Mode = 0; + self->Mode = 0; - return this; + return self; } //------------------------------------------------------------------------------ //free -static void THuff_Free(THuff* this) { - if (this == NULL) return; - if (this->Mode == 2) - THuff_EndBitIO(this); - free(this); +static void THuff_Free(THuff* self) { + if (self == NULL) return; + if (self->Mode == 2) + THuff_EndBitIO(self); + free(self); } //------------------------------------------------------------------------------ //init tree structure (unused state) -static void THuff_InitHuffTree(THuff* this) { +static void THuff_InitHuffTree(THuff* self) { int i; for (i = 0; i < 512; i++) { - this->Node[i].State = nsEmpty; + self->Node[i].State = nsEmpty; } } //------------------------------------------------------------------------------ //add node to huffman tree -static int THuff_InsertHuffNode(THuff* this, int v, int w, TNodeState s, int b1, int b2) { +static int THuff_InsertHuffNode(THuff* self, int v, int w, TNodeState s, int b1, int b2) { int result = 0; int i; i = 0; - while ((this->Node[i].State != nsEmpty) && (i < 512)) { + while ((self->Node[i].State != nsEmpty) && (i < 512)) { i++; } @@ -203,15 +203,15 @@ static int THuff_InsertHuffNode(THuff* this, int v, int w, TNodeState s, int b1, return result; //exit; } - this->Node[i].Value = v & 0xFF; //BYTE(v); - this->Node[i].Weight = w; - this->Node[i].State = s; - this->Node[i].Link[0] = b1; - if (this->Node[i].Link[0] > 511) { + self->Node[i].Value = v & 0xFF; //BYTE(v); + self->Node[i].Weight = w; + self->Node[i].State = s; + self->Node[i].Link[0] = b1; + if (self->Node[i].Link[0] > 511) { return -1;//? //halt; } - this->Node[i].Link[1] = b2; - if (this->Node[i].Link[1] > 511) { + self->Node[i].Link[1] = b2; + if (self->Node[i].Link[1] > 511) { return -1;//? //halt; } //return entry number @@ -221,31 +221,31 @@ static int THuff_InsertHuffNode(THuff* this, int v, int w, TNodeState s, int b1, //------------------------------------------------------------------------------ //reads and expands huffman-encoded data -static int THuff_Read(THuff* this) { +static int THuff_Read(THuff* self) { int i; - i = this->Root; - while (this->Node[i].State != nsLeaf) { - i = this->Node[i].Link[THuff_ReadBit(this)]; + i = self->Root; + while (self->Node[i].State != nsLeaf) { + i = self->Node[i].Link[THuff_ReadBit(self)]; } - return this->Node[i].Value; + return self->Node[i].Value; } //------------------------------------------------------------------------------ //creates fork code from tree //finds node of lowest weight -static int THuff_MakeHuffTree_SerchMinNode(THuff* this, int* tNode) { +static int THuff_MakeHuffTree_SerchMinNode(THuff* self, int* tNode) { int ii, aaa1, aaa2; aaa1 = 0xFFFFFFF; aaa2 = 0; for (ii = 0 ; ii < 256; ii++) { if (tNode[ii] != -1) { - if (this->Node[tNode[ii]].Weight < aaa1) { + if (self->Node[tNode[ii]].Weight < aaa1) { aaa2 = ii; - aaa1 = this->Node[tNode[ii]].Weight; + aaa1 = self->Node[tNode[ii]].Weight; } } } @@ -253,43 +253,43 @@ static int THuff_MakeHuffTree_SerchMinNode(THuff* this, int* tNode) { } //finds closest node -static int THuff_MakeHuffTree_SerchNearNode(THuff* this, int* tNode, int pos) { +static int THuff_MakeHuffTree_SerchNearNode(THuff* self, int* tNode, int pos) { int ii, aaa1, aaa2; aaa1 = 0xFFFFFFF; aaa2 = 0; for (ii = 0 ; ii < 256; ii++) { if (tNode[ii] != -1) { - if ((abs(this->Node[tNode[ii]].Weight - this->Node[tNode[pos]].Weight) < aaa1) && (pos != ii)) { + if ((abs(self->Node[tNode[ii]].Weight - self->Node[tNode[pos]].Weight) < aaa1) && (pos != ii)) { aaa2 = ii; - aaa1 = this->Node[tNode[ii]].Weight; + aaa1 = self->Node[tNode[ii]].Weight; } } } return aaa2; } -static void THuff_MakeHuffTree_MakeHuffCodeFromTree(THuff* this, uint8_t* tCode1, int* tCodePos, int pos) { +static void THuff_MakeHuffTree_MakeHuffCodeFromTree(THuff* self, uint8_t* tCode1, int* tCodePos, int pos) { int ii, aaa1; - if (this->Node[pos].State == nsLeaf) { //found + if (self->Node[pos].State == nsLeaf) { //found tCode1[*tCodePos] = 0xFF; - aaa1 = this->Node[pos].Value; + aaa1 = self->Node[pos].Value; for (ii = 0; ii < 256; ii++) { - this->Code[aaa1][ii] = tCode1[ii]; + self->Code[aaa1][ii] = tCode1[ii]; } } else { //not - if (this->Node[pos].Link[0] != -1) { + if (self->Node[pos].Link[0] != -1) { tCode1[*tCodePos] = 0; (*tCodePos)++; - THuff_MakeHuffTree_MakeHuffCodeFromTree(this, tCode1, tCodePos, this->Node[pos].Link[0]); + THuff_MakeHuffTree_MakeHuffCodeFromTree(self, tCode1, tCodePos, self->Node[pos].Link[0]); } - if (this->Node[pos].Link[1] != -1) { + if (self->Node[pos].Link[1] != -1) { tCode1[*tCodePos] = 1; (*tCodePos)++; - THuff_MakeHuffTree_MakeHuffCodeFromTree(this, tCode1, tCodePos, this->Node[pos].Link[1]); + THuff_MakeHuffTree_MakeHuffCodeFromTree(self, tCode1, tCodePos, self->Node[pos].Link[1]); } } @@ -297,7 +297,7 @@ static void THuff_MakeHuffTree_MakeHuffCodeFromTree(THuff* this, uint8_t* tCode1 } // creates huffman tree/codes from apparance rate (0..255) -static void THuff_MakeHuffTree(THuff* this) { +static void THuff_MakeHuffTree(THuff* self) { int i, aa1, aa2, aa3; int tCodePos; uint8_t tCode1[257]; @@ -307,7 +307,7 @@ static void THuff_MakeHuffTree(THuff* this) { int tNode[257]; //initializes huffman tree - THuff_InitHuffTree(this); + THuff_InitHuffTree(self); for (i = 0; i < 256; i++) { tNode[i] = -1; tCode1[i] = 0; @@ -318,17 +318,17 @@ static void THuff_MakeHuffTree(THuff* this) { //adds child nodes + comparison target nodes for (i = 0; i < 256; i++) { - tNode[i] = THuff_InsertHuffNode(this, i, this->Hed.HistGraph[i], nsLeaf, -1, -1); + tNode[i] = THuff_InsertHuffNode(self, i, self->Hed.HistGraph[i], nsLeaf, -1, -1); } //creates optimal tree for (i = 0; i < 256 - 1; i++) { //find smallest node - aa1 = THuff_MakeHuffTree_SerchMinNode(this, tNode); + aa1 = THuff_MakeHuffTree_SerchMinNode(self, tNode); //find value closest to smallest node - aa2 = THuff_MakeHuffTree_SerchNearNode(this, tNode, aa1); + aa2 = THuff_MakeHuffTree_SerchNearNode(self, tNode, aa1); //make new node joining both together - aa3 = THuff_InsertHuffNode(this, -1, this->Node[tNode[aa1]].Weight + this->Node[tNode[aa2]].Weight, nsBranch, tNode[aa1], tNode[aa2]); + aa3 = THuff_InsertHuffNode(self, -1, self->Node[tNode[aa1]].Weight + self->Node[tNode[aa2]].Weight, nsBranch, tNode[aa1], tNode[aa2]); //remove aa1/2 from comparison target nodes. tNode[aa1] = -1; tNode[aa2] = -1; @@ -337,63 +337,63 @@ static void THuff_MakeHuffTree(THuff* this) { } //finally make added node top of the tree - this->Root = aa3; + self->Root = aa3; //create stack for data expansion from tree info tCodePos = 0; - THuff_MakeHuffTree_MakeHuffCodeFromTree(this, tCode1, &tCodePos, this->Root); + THuff_MakeHuffTree_MakeHuffCodeFromTree(self, tCode1, &tCodePos, self->Root); } //------------------------------------------------------------------------------ //bit IO start process -static void THuff_BeginBitIO(THuff* this) { - this->IoCount = 0; - this->BitBuf = 0; - this->BitCount = 32; +static void THuff_BeginBitIO(THuff* self) { + self->IoCount = 0; + self->BitBuf = 0; + self->BitCount = 32; #if 0 - this->BitWriteLen = 0; + self->BitWriteLen = 0; #endif - this->CipherBuf = 0; + self->CipherBuf = 0; } //------------------------------------------------------------------------------ //bit IO end process -static void THuff_EndBitIO(THuff* this) { +static void THuff_EndBitIO(THuff* self) { #if 0 - if (this->IoCount == 2 && this->BitCount > 0) { - this->BitBuf = this->BitBuf ^ this->CipherBuf; - TStream_Write(this->Buff, BitBuf,4); + if (self->IoCount == 2 && self->BitCount > 0) { + self->BitBuf = self->BitBuf ^ self->CipherBuf; + TStream_Write(self->Buff, BitBuf,4); } #endif - THuff_BeginBitIO(this); + THuff_BeginBitIO(self); } //------------------------------------------------------------------------------ //read 1 bit from file -static int THuff_ReadBit(THuff* this) { +static int THuff_ReadBit(THuff* self) { int result; uint32_t aaa; - if (this->BitCount == 32) { - this->IoCount = 1; //ReadMode - if (this->Buff.Position < this->Buff.Size) { + if (self->BitCount == 32) { + self->IoCount = 1; //ReadMode + if (self->Buff.Position < self->Buff.Size) { //read - TStream_Read_Uint32(&this->Buff, &aaa); //Buff.Read(aaa,sizeof(DWORD)); - this->BitBuf = aaa ^ this->CipherBuf; + TStream_Read_Uint32(&self->Buff, &aaa); //Buff.Read(aaa,sizeof(DWORD)); + self->BitBuf = aaa ^ self->CipherBuf; //decryption phase - this->CipherBuf = THuff__ROR(this->CipherBuf, aaa & 7); - this->CipherBuf = this->CipherBuf ^ this->CipherList[aaa & 7]; + self->CipherBuf = THuff__ROR(self->CipherBuf, aaa & 7); + self->CipherBuf = self->CipherBuf ^ self->CipherList[aaa & 7]; } - this->BitCount = 0; + self->BitCount = 0; } //return 1 bit - result = this->BitBuf & 1; - this->BitBuf = this->BitBuf >> 1; + result = self->BitBuf & 1; + self->BitBuf = self->BitBuf >> 1; //advance BitCount - this->BitCount++; + self->BitCount++; return result; } @@ -401,12 +401,12 @@ static int THuff_ReadBit(THuff* this) { //------------------------------------------------------------------------------ //starts reading encoded data from stream -static void TStream_Read_THuffHedState(TStream* this, THuffHedState* Hed) { +static void TStream_Read_THuffHedState(TStream* self, THuffHedState* Hed) { uint8_t buf[0x410]; int i; - read_streamfile(buf, this->Position, sizeof(buf), this->File); - this->Position += sizeof(buf); + read_streamfile(buf, self->Position, sizeof(buf), self->File); + self->Position += sizeof(buf); /* 0x00: string size (always 3) */ memcpy(Hed->HedChar, buf+0x01, 0x03); @@ -417,25 +417,25 @@ static void TStream_Read_THuffHedState(TStream* this, THuffHedState* Hed) { Hed->FileSize = get_u64le(buf+0x408); /* seems always 0 */ } -static void THuff_BeginRead(THuff* this) { - TStream_Read_THuffHedState(&this->Buff, &this->Hed); //Buff.Read(Hed,sizeof(THuffHedState)); - THuff_MakeHuffTree(this); - this->BeginPos = this->Buff.Position; - THuff_BeginBitIO(this); - this->Mode = 1; +static void THuff_BeginRead(THuff* self) { + TStream_Read_THuffHedState(&self->Buff, &self->Hed); //Buff.Read(Hed,sizeof(THuffHedState)); + THuff_MakeHuffTree(self); + self->BeginPos = self->Buff.Position; + THuff_BeginBitIO(self); + self->Mode = 1; } #if 0 //------------------------------------------------------------------------------ //get file size before encoding -static int64_t THuff_GetFileSize(THuff* this) { - return this->Hed.FileSize; +static int64_t THuff_GetFileSize(THuff* self) { + return self->Hed.FileSize; } //------------------------------------------------------------------------------ //EOF detection -static int THuff_GetEOF(THuff* this) { - if (this->Buff.Position < this->Buff.Size) +static int THuff_GetEOF(THuff* self) { + if (self->Buff.Position < self->Buff.Size) return CW_FALSE; else return CW_TRUE; @@ -443,39 +443,39 @@ static int THuff_GetEOF(THuff* this) { #endif //------------------------------------------------------------------------------ //return to initial positon -static void THuff_MoveBeginPosition(THuff* this) { - THuff_EndBitIO(this); - this->Buff.Position = this->BeginPos; - THuff_BeginBitIO(this); +static void THuff_MoveBeginPosition(THuff* self) { + THuff_EndBitIO(self); + self->Buff.Position = self->BeginPos; + THuff_BeginBitIO(self); } //------------------------------------------------------------------------------ -static void THuff_GetPositionData(THuff* this, THuffPositionData* s) { - s->BitBuf = this->BitBuf; - s->BitCount = this->BitCount; - s->StreamPos = this->Buff.Position; - s->CipherBuf = this->CipherBuf; +static void THuff_GetPositionData(THuff* self, THuffPositionData* s) { + s->BitBuf = self->BitBuf; + s->BitCount = self->BitCount; + s->StreamPos = self->Buff.Position; + s->CipherBuf = self->CipherBuf; } //------------------------------------------------------------------------------ -static void THuff_SetPositionData(THuff* this, THuffPositionData* s) { - this->BitBuf = s->BitBuf; - this->BitCount = s->BitCount; - this->Buff.Position = s->StreamPos; - this->CipherBuf = s->CipherBuf; +static void THuff_SetPositionData(THuff* self, THuffPositionData* s) { + self->BitBuf = s->BitBuf; + self->BitCount = s->BitCount; + self->Buff.Position = s->StreamPos; + self->CipherBuf = s->CipherBuf; } //------------------------------------------------------------------------------ -static void THuff_SetCipherCode(THuff* this, uint32_t msk) { +static void THuff_SetCipherCode(THuff* self, uint32_t msk) { //creates mask list - this->CipherList[0] = msk / 3; - this->CipherList[1] = msk / 17; - this->CipherList[2] = msk / 7; - this->CipherList[3] = msk / 5; - this->CipherList[4] = msk / 3; - this->CipherList[5] = msk / 11; - this->CipherList[6] = msk / 13; - this->CipherList[7] = msk / 19; + self->CipherList[0] = msk / 3; + self->CipherList[1] = msk / 17; + self->CipherList[2] = msk / 7; + self->CipherList[3] = msk / 5; + self->CipherList[4] = msk / 3; + self->CipherList[5] = msk / 11; + self->CipherList[6] = msk / 13; + self->CipherList[7] = msk / 19; } //------------------------------------------------------------------------------ @@ -558,76 +558,76 @@ struct TCompressWaveData { //----------------------------------------------------------- //create TCompressWaveData* TCompressWaveData_Create(void) { - TCompressWaveData* this = malloc(sizeof(TCompressWaveData)); - if (!this) return NULL; + TCompressWaveData* self = malloc(sizeof(TCompressWaveData)); + if (!self) return NULL; #if 0 - this->Data = NULL; + self->Data = NULL; #endif - this->RH = NULL; - this->FWavePosition = 0; - this->FWaveLength = 0; - this->FVolume = PW_MAXVOLUME; - this->FSetVolume = PW_MAXVOLUME; - this->Ffade = 0; - this->FEndLoop = CW_FALSE; - this->FPlay = CW_FALSE; - this->NowRendering = CW_FALSE; - TCompressWaveData_SetCipherCode(this, 0); + self->RH = NULL; + self->FWavePosition = 0; + self->FWaveLength = 0; + self->FVolume = PW_MAXVOLUME; + self->FSetVolume = PW_MAXVOLUME; + self->Ffade = 0; + self->FEndLoop = CW_FALSE; + self->FPlay = CW_FALSE; + self->NowRendering = CW_FALSE; + TCompressWaveData_SetCipherCode(self, 0); - return this; + return self; } //----------------------------------------------------------- //free -void TCompressWaveData_Free(TCompressWaveData* this) { - if (!this) +void TCompressWaveData_Free(TCompressWaveData* self) { + if (!self) return; - //EXTRA: presumably for threading but OG lib doesn't properly set this to false on all errors + //EXTRA: presumably for threading but OG lib doesn't properly set self to false on all errors #if 0 //sync - while (this->NowRendering) { + while (self->NowRendering) { ; } #endif //free - if (this->RH != NULL) - THuff_Free(this->RH); + if (self->RH != NULL) + THuff_Free(self->RH); #if 0 - if (this->Data != NULL) - TMemoryStream_Free(this->Data); + if (self->Data != NULL) + TMemoryStream_Free(self->Data); #endif - free(this); + free(self); } //----------------------------------------------------------- //outpus 44100/16bit/stereo waveform to designed buffer -static void TCompressWaveData_Rendering_ReadPress(TCompressWaveData* this, int32_t* RFlg, int32_t* LFlg) { - if (this->Hed.Channel == 2) { - *RFlg = THuff_Read(this->RH); //STEREO - *LFlg = THuff_Read(this->RH); +static void TCompressWaveData_Rendering_ReadPress(TCompressWaveData* self, int32_t* RFlg, int32_t* LFlg) { + if (self->Hed.Channel == 2) { + *RFlg = THuff_Read(self->RH); //STEREO + *LFlg = THuff_Read(self->RH); } else { - *RFlg = THuff_Read(this->RH); //MONO + *RFlg = THuff_Read(self->RH); //MONO *LFlg = *RFlg; } } -static void TCompressWaveData_Rendering_WriteWave(TCompressWaveData* this, int16_t** buf1, int32_t RVol, int32_t LVol) { +static void TCompressWaveData_Rendering_WriteWave(TCompressWaveData* self, int16_t** buf1, int32_t RVol, int32_t LVol) { TLRWRITEBUFFER bbb = {0}; - if (this->Hed.Sample == 44100) { //44100 STEREO/MONO + if (self->Hed.Sample == 44100) { //44100 STEREO/MONO bbb.RBuf = RVol; bbb.LBuf = LVol; (*buf1)[0] = bbb.RBuf; (*buf1)[1] = bbb.LBuf; (*buf1) += 2; } - if (this->Hed.Sample == 22050) { //22050 STEREO/MONO - bbb.RBuf = (this->RBackBuf + RVol) / 2; - bbb.LBuf = (this->LBackBuf + LVol) / 2; + if (self->Hed.Sample == 22050) { //22050 STEREO/MONO + bbb.RBuf = (self->RBackBuf + RVol) / 2; + bbb.LBuf = (self->LBackBuf + LVol) / 2; (*buf1)[0] = bbb.RBuf; (*buf1)[1] = bbb.LBuf; (*buf1) += 2; @@ -638,12 +638,12 @@ static void TCompressWaveData_Rendering_WriteWave(TCompressWaveData* this, int16 (*buf1)[1] = bbb.LBuf; (*buf1) += 2; - this->RBackBuf = RVol; - this->LBackBuf = LVol; + self->RBackBuf = RVol; + self->LBackBuf = LVol; } } -int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t Len) { +int TCompressWaveData_Rendering(TCompressWaveData* self, int16_t* buf, uint32_t Len) { int result; int32_t RFlg, LFlg, RVol, LVol; int i, aaa; @@ -651,33 +651,33 @@ int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t int32_t PressLength, WaveStep; - this->NowRendering = CW_TRUE; + self->NowRendering = CW_TRUE; result = CW_FALSE; #if 0 - if (this->Data == NULL) { - this->NowRendering = CW_FALSE; + if (self->Data == NULL) { + self->NowRendering = CW_FALSE; return result; //exit; } #endif //fadeout song stop - if ((this->FVolume < 1) && (this->FSetVolume < 1)) { - this->FPlay = CW_FALSE; + if ((self->FVolume < 1) && (self->FSetVolume < 1)) { + self->FPlay = CW_FALSE; } - //if (abs(this->FSetVolume - this->FVolume) < this->Ffade) { - // this->FPlay = CW_FALSE; + //if (abs(self->FSetVolume - self->FVolume) < self->Ffade) { + // self->FPlay = CW_FALSE; //} //stop if FPlay (play flag) wasn't set - if (this->FPlay == CW_FALSE) { - this->NowRendering = CW_FALSE; + if (self->FPlay == CW_FALSE) { + self->NowRendering = CW_FALSE; return result; //exit; } //pre processing - RVol = this->Fvv1; - LVol = this->Fvv2; - if (this->Hed.Sample == 44100) + RVol = self->Fvv1; + LVol = self->Fvv2; + if (self->Hed.Sample == 44100) WaveStep = 4; else WaveStep = 8; @@ -689,76 +689,76 @@ int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t for (i = 0; i < PressLength; i++) { //crossed over? - if (this->FWavePosition > this->FWaveLength) { - if (this->FEndLoop == CW_TRUE) { //playback with loop? - TCompressWaveData_Previous(this); + if (self->FWavePosition > self->FWaveLength) { + if (self->FEndLoop == CW_TRUE) { //playback with loop? + TCompressWaveData_Previous(self); } else { //in case of playback without loop - this->FPlay = CW_FALSE; + self->FPlay = CW_FALSE; return result; //exit } } //loop related - if (this->Hed.LoopCount > this->FLoop) { + if (self->Hed.LoopCount > self->FLoop) { //if position is loop start, hold current flag/state //shr 3 matches 8 bit aligment - if ((this->Hed.LoopStart >> 3) == (this->FWavePosition >> 3)) { - TCompressWaveData_GetLoopState(this); + if ((self->Hed.LoopStart >> 3) == (self->FWavePosition >> 3)) { + TCompressWaveData_GetLoopState(self); } //if reached loop end do loop. - if ((this->Hed.LoopEnd >> 3) == (this->FWavePosition >> 3)) { - if (this->Hed.LoopCount != 255) - this->FLoop++; - TCompressWaveData_SetLoopState(this); + if ((self->Hed.LoopEnd >> 3) == (self->FWavePosition >> 3)) { + if (self->Hed.LoopCount != 255) + self->FLoop++; + TCompressWaveData_SetLoopState(self); } } //read - TCompressWaveData_Rendering_ReadPress(this, &RFlg, &LFlg); - this->Faa1 = this->Faa1 + this->Hed.Tbl[RFlg]; - this->Faa2 = this->Faa2 + this->Hed.Tbl[LFlg]; - this->Fvv1 = this->Fvv1 + this->Faa1; - this->Fvv2 = this->Fvv2 + this->Faa2; + TCompressWaveData_Rendering_ReadPress(self, &RFlg, &LFlg); + self->Faa1 = self->Faa1 + self->Hed.Tbl[RFlg]; + self->Faa2 = self->Faa2 + self->Hed.Tbl[LFlg]; + self->Fvv1 = self->Fvv1 + self->Faa1; + self->Fvv2 = self->Fvv2 + self->Faa2; //volume adjustment - aaa = this->FSetVolume - this->FVolume; - if (abs(aaa) < this->Ffade) { - this->FVolume = this->FSetVolume; + aaa = self->FSetVolume - self->FVolume; + if (abs(aaa) < self->Ffade) { + self->FVolume = self->FSetVolume; } else { if (aaa > 0) - this->FVolume = this->FVolume + this->Ffade; + self->FVolume = self->FVolume + self->Ffade; else - this->FVolume = this->FVolume - this->Ffade; + self->FVolume = self->FVolume - self->Ffade; } //threshold calcs (due to overflow) - if (this->Fvv1 > +32760) { - this->Fvv1 = +32760; - this->Faa1 = 0; + if (self->Fvv1 > +32760) { + self->Fvv1 = +32760; + self->Faa1 = 0; } - if (this->Fvv1 < -32760) { - this->Fvv1 = -32760; - this->Faa1 = 0; + if (self->Fvv1 < -32760) { + self->Fvv1 = -32760; + self->Faa1 = 0; } - if (this->Fvv2 > +32760) { - this->Fvv2 = +32760; - this->Faa2 = 0; + if (self->Fvv2 > +32760) { + self->Fvv2 = +32760; + self->Faa2 = 0; } - if (this->Fvv2 < -32760) { - this->Fvv2 = -32760; - this->Faa2 = 0; + if (self->Fvv2 < -32760) { + self->Fvv2 = -32760; + self->Faa2 = 0; } - aaa = (this->FVolume >> 20); - RVol = this->Fvv1 * aaa / 256; - LVol = this->Fvv2 * aaa / 256; + aaa = (self->FVolume >> 20); + RVol = self->Fvv1 * aaa / 256; + LVol = self->Fvv2 * aaa / 256; //expand to buffer - TCompressWaveData_Rendering_WriteWave(this, &buf1, RVol, LVol); + TCompressWaveData_Rendering_WriteWave(self, &buf1, RVol, LVol); //advance playback position - this->FWavePosition += WaveStep; + self->FWavePosition += WaveStep; } //remainder calcs @@ -766,10 +766,10 @@ int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t //example: 44100 / 4 = 11025...OK 44100 / 8 = 5512.5...NG // in that case appear as noise if (Len % 8 == 4) { - TCompressWaveData_Rendering_WriteWave(this, &buf1, RVol, LVol); + TCompressWaveData_Rendering_WriteWave(self, &buf1, RVol, LVol); } - this->NowRendering = CW_FALSE; + self->NowRendering = CW_FALSE; result = CW_TRUE; return result; } @@ -778,12 +778,12 @@ int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t //----------------------------------------------------------- //read compressed file from stream -static void TStream_Read_PRESSWAVEDATAHED(TStream* this, PRESSWAVEDATAHED* Hed) { +static void TStream_Read_PRESSWAVEDATAHED(TStream* self, PRESSWAVEDATAHED* Hed) { uint8_t buf[0x538]; int i, len; - read_streamfile(buf, this->Position, sizeof(buf), this->File); - this->Position += sizeof(buf); + read_streamfile(buf, self->Position, sizeof(buf), self->File); + self->Position += sizeof(buf); memcpy(Hed->HedChar, buf + 0x00, 8); Hed->Channel = get_u32le(buf + 0x08); @@ -806,15 +806,15 @@ static void TStream_Read_PRESSWAVEDATAHED(TStream* this, PRESSWAVEDATAHED* Hed) /* 0x948: data start */ } -int TCompressWaveData_LoadFromStream(TCompressWaveData* this, STREAMFILE* ss) { +int TCompressWaveData_LoadFromStream(TCompressWaveData* self, STREAMFILE* ss) { int result = CW_FALSE; TStream data = {0}; if (ss == NULL) return result; #if 0 - if (this->Data != NULL) - TMemoryStream_Free(this->Data); + if (self->Data != NULL) + TMemoryStream_Free(self->Data); #endif data.File = ss; //data = TMemoryStream.Create; @@ -824,32 +824,32 @@ int TCompressWaveData_LoadFromStream(TCompressWaveData* this, STREAMFILE* ss) { //get header info data.Position = 0; - TStream_Read_PRESSWAVEDATAHED(&data, &this->Hed); //data.Read(Hed,sizeof(PRESSWAVEDATAHED)); - this->FWaveLength = this->Hed.UnPressSize; - if (this->RH != NULL) - THuff_Free(this->RH); - this->RH = THuff_Create(&data); - if (!this->RH) return result; + TStream_Read_PRESSWAVEDATAHED(&data, &self->Hed); //data.Read(Hed,sizeof(PRESSWAVEDATAHED)); + self->FWaveLength = self->Hed.UnPressSize; + if (self->RH != NULL) + THuff_Free(self->RH); + self->RH = THuff_Create(&data); + if (!self->RH) return result; - THuff_SetCipherCode(this->RH, 0x00); - THuff_BeginRead(this->RH); + THuff_SetCipherCode(self->RH, 0x00); + THuff_BeginRead(self->RH); //initialize playback flag - TCompressWaveData_Stop(this); - TCompressWaveData_SetVolume(this, 1.0, 0.0); + TCompressWaveData_Stop(self); + TCompressWaveData_SetVolume(self, 1.0, 0.0); result = CW_TRUE; return result; } //------------------------------------------------------------------------------ //temp pause -void TCompressWaveData_Pause(TCompressWaveData* this) { - this->FPlay = CW_FALSE; +void TCompressWaveData_Pause(TCompressWaveData* self) { + self->FPlay = CW_FALSE; } //----------------------------------------------------------- //sets volume -void TCompressWaveData_SetVolume(TCompressWaveData* this, float vol, float fade) { +void TCompressWaveData_SetVolume(TCompressWaveData* self, float vol, float fade) { float aaa; //EXTRA: C float seemingly can't store PW_MAXVOLUME (268435455 becomes 268435456.0), so must cast to double @@ -862,108 +862,108 @@ void TCompressWaveData_SetVolume(TCompressWaveData* this, float vol, float fade) if (aaa < 0.0) aaa = 0.0; //calc volume increse if (fade < 0.01) { //with fade value - this->Ffade = 0; - this->FVolume = round(aaa * (double)PW_MAXVOLUME); - this->FSetVolume = this->FVolume; + self->Ffade = 0; + self->FVolume = round(aaa * (double)PW_MAXVOLUME); + self->FSetVolume = self->FVolume; } else { //without fade value - this->Ffade = round((double)PW_MAXVOLUME / fade / 44100); - this->FSetVolume = round(aaa * (double)PW_MAXVOLUME); + self->Ffade = round((double)PW_MAXVOLUME / fade / 44100); + self->FSetVolume = round(aaa * (double)PW_MAXVOLUME); } } //----------------------------------------------------------- //returns fade value -float TCompressWaveData_GetFade(TCompressWaveData* this) { - if ((this->Ffade == 0) || (abs(this->FVolume - this->FSetVolume) == 0)) { +float TCompressWaveData_GetFade(TCompressWaveData* self) { + if ((self->Ffade == 0) || (abs(self->FVolume - self->FSetVolume) == 0)) { return 0; //exit; } - return (abs(this->FVolume - this->FSetVolume)/44100) / this->Ffade; + return (abs(self->FVolume - self->FSetVolume)/44100) / self->Ffade; } //----------------------------------------------------------- //returns volume value -float TCompressWaveData_GetVolume(TCompressWaveData* this) { - return this->FVolume / PW_MAXVOLUME; +float TCompressWaveData_GetVolume(TCompressWaveData* self) { + return self->FVolume / PW_MAXVOLUME; } //------------------------------------------------------------------------------ //returns volume after fade -float TCompressWaveData_GetSetVolume(TCompressWaveData* this) { - return this->FSetVolume / PW_MAXVOLUME; +float TCompressWaveData_GetSetVolume(TCompressWaveData* self) { + return self->FSetVolume / PW_MAXVOLUME; } //------------------------------------------------------------------------------ //returns play time (current position). unit is secs -float TCompressWaveData_GetPlayTime(TCompressWaveData* this) { - return this->FWavePosition / (44100*4); +float TCompressWaveData_GetPlayTime(TCompressWaveData* self) { + return self->FWavePosition / (44100*4); } //----------------------------------------------------------- //returns song length. unit is secs -float TCompressWaveData_GetTotalTime(TCompressWaveData* this) { - return this->FWaveLength / (44100*4); +float TCompressWaveData_GetTotalTime(TCompressWaveData* self) { + return self->FWaveLength / (44100*4); } //----------------------------------------------------------- //play stop command. returns song to beginning -void TCompressWaveData_Stop(TCompressWaveData* this) { +void TCompressWaveData_Stop(TCompressWaveData* self) { //play flags to initial state - this->FWavePosition = 0; - this->Fvv1 = 0; - this->Faa1 = 0; - this->Fvv2 = 0; - this->Faa2 = 0; - this->LBackBuf = 0; - this->RBackBuf = 0; - TCompressWaveData_SetVolume(this, 1.0, 0); - this->FPlay = CW_FALSE; - this->FLoop = 0; + self->FWavePosition = 0; + self->Fvv1 = 0; + self->Faa1 = 0; + self->Fvv2 = 0; + self->Faa2 = 0; + self->LBackBuf = 0; + self->RBackBuf = 0; + TCompressWaveData_SetVolume(self, 1.0, 0); + self->FPlay = CW_FALSE; + self->FLoop = 0; #if 0 - if (this->Data == NULL) + if (self->Data == NULL) return; #endif - //EXTRA: presumably for threading but OG lib doesn't properly set this to false on all errors + //EXTRA: presumably for threading but OG lib doesn't properly set self to false on all errors #if 0 //sync - while (this->NowRendering) { + while (self->NowRendering) { ; } #endif //return to initial location - THuff_MoveBeginPosition(this->RH); + THuff_MoveBeginPosition(self->RH); } //----------------------------------------------------------- //returns song to beginning. difference vs STOP is that fade isn't initialized -void TCompressWaveData_Previous(TCompressWaveData* this) { +void TCompressWaveData_Previous(TCompressWaveData* self) { //play flags to initial state - this->FWavePosition = 0; - this->Fvv1 = 0; - this->Faa1 = 0; - this->Fvv2 = 0; - this->Faa2 = 0; - this->LBackBuf = 0; - this->RBackBuf = 0; - this->FLoop = 0; + self->FWavePosition = 0; + self->Fvv1 = 0; + self->Faa1 = 0; + self->Fvv2 = 0; + self->Faa2 = 0; + self->LBackBuf = 0; + self->RBackBuf = 0; + self->FLoop = 0; #if 0 - if (this->Data == NULL) + if (self->Data == NULL) return; #endif //return to initial location - THuff_MoveBeginPosition(this->RH); + THuff_MoveBeginPosition(self->RH); } //------------------------------------------------------------ //starts song playback -void TCompressWaveData_Play(TCompressWaveData* this, int loop) { - this->FPlay = CW_TRUE; - this->FEndLoop = loop; - if ((this->FVolume == 0) && (this->FSetVolume == 0)) - TCompressWaveData_SetVolume(this, 1.0,0); +void TCompressWaveData_Play(TCompressWaveData* self, int loop) { + self->FPlay = CW_TRUE; + self->FEndLoop = loop; + if ((self->FVolume == 0) && (self->FSetVolume == 0)) + TCompressWaveData_SetVolume(self, 1.0,0); } //------------------------------------------------------------ @@ -971,28 +971,28 @@ void TCompressWaveData_Play(TCompressWaveData* this, int loop) { //-------------------------------------------------------------- //record encoded file position //since it uses huffman needs to held those flags too -void TCompressWaveData_GetLoopState(TCompressWaveData* this) { - this->LPFaa1 = this->Faa1; - this->LPFaa2 = this->Faa2; - this->LPFvv1 = this->Fvv1; - this->LPFvv2 = this->Fvv2; - THuff_GetPositionData(this->RH, &this->PosData); +void TCompressWaveData_GetLoopState(TCompressWaveData* self) { + self->LPFaa1 = self->Faa1; + self->LPFaa2 = self->Faa2; + self->LPFvv1 = self->Fvv1; + self->LPFvv2 = self->Fvv2; + THuff_GetPositionData(self->RH, &self->PosData); } //-------------------------------------------------------------- //return to recorded encoded file position -void TCompressWaveData_SetLoopState(TCompressWaveData* this) { - this->Faa1 = this->LPFaa1; - this->Faa2 = this->LPFaa2; - this->Fvv1 = this->LPFvv1; - this->Fvv2 = this->LPFvv2; - THuff_SetPositionData(this->RH, &this->PosData); - this->FWavePosition = this->Hed.LoopStart; +void TCompressWaveData_SetLoopState(TCompressWaveData* self) { + self->Faa1 = self->LPFaa1; + self->Faa2 = self->LPFaa2; + self->Fvv1 = self->LPFvv1; + self->Fvv2 = self->LPFvv2; + THuff_SetPositionData(self->RH, &self->PosData); + self->FWavePosition = self->Hed.LoopStart; } //----------------------------------------------------------- //sets cipher code -void TCompressWaveData_SetCipherCode(TCompressWaveData* this, uint32_t Num) { - this->CipherCode = Num; +void TCompressWaveData_SetCipherCode(TCompressWaveData* self, uint32_t Num) { + self->CipherCode = Num; } diff --git a/src/coding/libs/compresswave_lib.h b/src/coding/libs/compresswave_lib.h index f97ffd85d..7bc84808f 100644 --- a/src/coding/libs/compresswave_lib.h +++ b/src/coding/libs/compresswave_lib.h @@ -4,24 +4,24 @@ typedef struct TCompressWaveData TCompressWaveData; -void TCompressWaveData_GetLoopState(TCompressWaveData* this); -void TCompressWaveData_SetLoopState(TCompressWaveData* this); +void TCompressWaveData_GetLoopState(TCompressWaveData* self); +void TCompressWaveData_SetLoopState(TCompressWaveData* self); TCompressWaveData* TCompressWaveData_Create(void); -void TCompressWaveData_Free(TCompressWaveData* this); -int TCompressWaveData_Rendering(TCompressWaveData* this, int16_t* buf, uint32_t Len); -int TCompressWaveData_LoadFromStream(TCompressWaveData* this, STREAMFILE* ss); -void TCompressWaveData_SetCipherCode(TCompressWaveData* this, uint32_t Num); +void TCompressWaveData_Free(TCompressWaveData* self); +int TCompressWaveData_Rendering(TCompressWaveData* self, int16_t* buf, uint32_t Len); +int TCompressWaveData_LoadFromStream(TCompressWaveData* self, STREAMFILE* ss); +void TCompressWaveData_SetCipherCode(TCompressWaveData* self, uint32_t Num); -void TCompressWaveData_Play(TCompressWaveData* this, int loop); -void TCompressWaveData_Stop(TCompressWaveData* this); -void TCompressWaveData_Previous(TCompressWaveData* this); -void TCompressWaveData_Pause(TCompressWaveData* this); -void TCompressWaveData_SetVolume(TCompressWaveData* this, float vol, float fade); -float TCompressWaveData_GetVolume(TCompressWaveData* this); -float TCompressWaveData_GetSetVolume(TCompressWaveData* this); -float TCompressWaveData_GetFade(TCompressWaveData* this); -float TCompressWaveData_GetPlayTime(TCompressWaveData* this); -float TCompressWaveData_GetTotalTime(TCompressWaveData* this); +void TCompressWaveData_Play(TCompressWaveData* self, int loop); +void TCompressWaveData_Stop(TCompressWaveData* self); +void TCompressWaveData_Previous(TCompressWaveData* self); +void TCompressWaveData_Pause(TCompressWaveData* self); +void TCompressWaveData_SetVolume(TCompressWaveData* self, float vol, float fade); +float TCompressWaveData_GetVolume(TCompressWaveData* self); +float TCompressWaveData_GetSetVolume(TCompressWaveData* self); +float TCompressWaveData_GetFade(TCompressWaveData* self); +float TCompressWaveData_GetPlayTime(TCompressWaveData* self); +float TCompressWaveData_GetTotalTime(TCompressWaveData* self); #endif /*_COMPRESSWAVE_LIB_H */ From e987ef2d47cdf935b5256874c5a84db4a93639da Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 23:13:12 +0200 Subject: [PATCH 06/17] cleanup: fix minor compiler warnings --- src/base/info.c | 2 +- src/base/mixer_ops_fade.c | 16 +- src/coding/adx_decoder.c | 2 +- src/coding/ffmpeg_decoder.c | 10 ++ src/coding/l5_555_decoder.c | 15 +- src/coding/libs/compresswave_lib.c | 12 +- src/coding/libs/g7221_lib.c | 2 +- src/coding/libs/tac_lib.c | 4 +- src/coding/psv_decoder.c | 256 ++++++++++++++--------------- src/coding/psx_decoder.c | 32 ++-- src/meta/bkhd.c | 4 +- src/meta/ea_eaac.c | 6 +- src/meta/mul.c | 2 +- src/meta/psb.c | 2 +- src/meta/ubi_bao.c | 2 +- src/meta/ubi_sb.c | 2 + src/meta/xnb_lz4mg.h | 8 +- src/util/m2_psb.c | 2 +- 18 files changed, 197 insertions(+), 182 deletions(-) diff --git a/src/base/info.c b/src/base/info.c index df3cea816..2a7a6ec8f 100644 --- a/src/base/info.c +++ b/src/base/info.c @@ -13,7 +13,7 @@ static void describe_get_time(int32_t samples, int sample_rate, double* p_time_mm, double* p_time_ss) { double seconds = (double)samples / sample_rate; *p_time_mm = (int)(seconds / 60.0); - *p_time_ss = seconds - *p_time_mm * 60.0f; + *p_time_ss = seconds - *p_time_mm * 60.0; if (*p_time_ss >= 59.999) /* avoid round up to 60.0 when printing to %06.3f */ *p_time_ss = 59.999; } diff --git a/src/base/mixer_ops_fade.c b/src/base/mixer_ops_fade.c index 1ee6e4848..973f64564 100644 --- a/src/base/mixer_ops_fade.c +++ b/src/base/mixer_ops_fade.c @@ -12,7 +12,7 @@ static inline float get_fade_gain_curve(char shape, float index) { return index; } - //TODO optimizations: interleave calcs, maybe use cosf, powf, etc? (with extra defines) + //TODO optimizations: interleave calcs /* (curve math mostly from SoX/FFmpeg) */ switch(shape) { @@ -20,17 +20,17 @@ static inline float get_fade_gain_curve(char shape, float index) { * (alt calculations with 'exp' from FFmpeg use (factor)*ln(0.1) = -NN.N... */ case 'E': /* exponential (for fade-outs, closer to natural decay of sound) */ - //gain = pow(0.1f, (1.0f - index) * 2.5f); - gain = exp(-5.75646273248511f * (1.0f - index)); + //gain = powf(0.1f, (1.0f - index) * 2.5f); + gain = expf(-5.75646273248511f * (1.0f - index)); break; case 'L': /* logarithmic (inverse of the above, maybe for crossfades) */ - //gain = 1 - pow(0.1f, (index) * 2.5f); - gain = 1 - exp(-5.75646273248511f * (index)); + //gain = 1 - powf(0.1f, (index) * 2.5f); + gain = 1 - expf(-5.75646273248511f * (index)); break; case 'H': /* raised sine wave or cosine wave (for more musical crossfades) */ - gain = (1.0f - cos(index * MIXING_PI)) / 2.0f; + gain = (1.0f - cosf(index * MIXING_PI)) / 2.0f; break; case 'Q': /* quarter of sine wave (for musical fades) */ @@ -38,7 +38,7 @@ static inline float get_fade_gain_curve(char shape, float index) { break; case 'p': /* parabola (maybe for crossfades) */ - gain = 1.0f - sqrt(1.0f - index); + gain = 1.0f - sqrtf(1.0f - index); break; case 'P': /* inverted parabola (maybe for fades) */ @@ -154,7 +154,7 @@ bool mixer_op_fade_is_active(mixer_t* mixer, int32_t current_start, int32_t curr /* check is current range falls within a fade * (assuming fades were already optimized on add) */ - if (mix->time_pre < 0 && vol_start == 1.0) { + if (mix->time_pre < 0 && vol_start == 1.0f) { fade_start = mix->time_start; /* ignore unused */ } else { diff --git a/src/coding/adx_decoder.c b/src/coding/adx_decoder.c index 732cd60d6..0fbe815e9 100644 --- a/src/coding/adx_decoder.c +++ b/src/coding/adx_decoder.c @@ -90,7 +90,7 @@ void decode_adx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, stream->adpcm_history2_32 = hist2; if ((coding_type == coding_CRI_ADX_enc_8 || coding_type == coding_CRI_ADX_enc_9) && !(i % 32)) { - for (i =0; i < stream->adx_channels; i++) { + for (i = 0; i < channelspacing; i++) { adx_next_key(stream); } } diff --git a/src/coding/ffmpeg_decoder.c b/src/coding/ffmpeg_decoder.c index 67c4971ca..ddfcad7ce 100644 --- a/src/coding/ffmpeg_decoder.c +++ b/src/coding/ffmpeg_decoder.c @@ -772,19 +772,29 @@ static void copy_samples(ffmpeg_codec_data* data, sample_t* outbuf, int samples_ switch (data->codecCtx->sample_fmt) { /* unused? */ case AV_SAMPLE_FMT_U8P: if (is_planar) { samples_u8p_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; } + // fall through case AV_SAMPLE_FMT_U8: samples_u8_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; + /* common */ case AV_SAMPLE_FMT_S16P: if (is_planar) { samples_s16p_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; } + // fall through case AV_SAMPLE_FMT_S16: samples_s16_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; + /* possibly FLAC and other lossless codecs */ case AV_SAMPLE_FMT_S32P: if (is_planar) { samples_s32p_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; } + // fall through case AV_SAMPLE_FMT_S32: samples_s32_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; + /* mainly MDCT-like codecs (Ogg, AAC, etc) */ case AV_SAMPLE_FMT_FLTP: if (is_planar) { samples_fltp_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed, data->invert_floats_set); break; } + // fall through case AV_SAMPLE_FMT_FLT: samples_flt_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed, data->invert_floats_set); break; + /* possibly PCM64 only (not enabled) */ case AV_SAMPLE_FMT_DBLP: if (is_planar) { samples_dblp_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; } + // fall through case AV_SAMPLE_FMT_DBL: samples_dbl_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; + default: break; } diff --git a/src/coding/l5_555_decoder.c b/src/coding/l5_555_decoder.c index 7b8a7aa4a..f7558b2d9 100644 --- a/src/coding/l5_555_decoder.c +++ b/src/coding/l5_555_decoder.c @@ -1,13 +1,15 @@ #include "coding.h" #include "../util.h" +/* AKA iShiftVal__8snd_strm */ static const int32_t l5_scales[32] = { 0x00001000, 0x0000144E, 0x000019C5, 0x000020B4, 0x00002981, 0x000034AC, 0x000042D9, 0x000054D6, 0x00006BAB, 0x000088A4, 0x0000AD69, 0x0000DC13, 0x0001174C, 0x00016275, 0x0001C1D8, 0x00023AE5, 0x0002D486, 0x0003977E, 0x00048EEE, 0x0005C8F3, 0x00075779, 0x0009513E, 0x000BD31C, 0x000F01B5, - 0x00130B82, 0x00182B83, 0x001EAC92, 0x0026EDB2, 0x00316777, 0x003EB2E6, 0x004F9232, 0x0064FBD1 + 0x00130B82, 0x00182B83, 0x001EAC92, 0x0026EDB2, 0x00316777, 0x003EB2E6, 0x004F9232, 0x0064FBD1, }; +/* reverse engineered from exe (SLPM_624.90's DecAdpcm__8snd_strmFRQ28snd_strm10SOUND_HEADiPsPUci / SLUS_212.07's @258D70)*/ void decode_l5_555(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { uint8_t frame[0x12] = {0}; off_t frame_offset; @@ -31,7 +33,7 @@ void decode_l5_555(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacin /* parse frame header */ frame_offset = stream->offset + bytes_per_frame * frames_in; read_streamfile(frame, frame_offset, bytes_per_frame, stream->streamfile); /* ignore EOF errors */ - header = get_u32le(frame); + header = get_u16le(frame); coef_index = (header >> 10) & 0x1f; pos_scale = l5_scales[(header >> 5) & 0x1f]; neg_scale = l5_scales[(header >> 0) & 0x1f]; @@ -41,18 +43,19 @@ void decode_l5_555(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacin coef3 = stream->adpcm_coef_3by32[coef_index * 3 + 2]; for (i = first_sample; i < first_sample + samples_to_do; i++) { - int32_t prediction, sample = 0; + /* sample is 64b in PS2 registers, though encoder probably won't let it get too high */ + int32_t prediction, sample; uint8_t nibbles = frame[0x02 + i/2]; sample = (i&1) ? get_low_nibble_signed(nibbles): get_high_nibble_signed(nibbles); - prediction = -(hist1 * coef1 + hist2 * coef2 + hist3 * coef3); + prediction = (hist1 * coef1 + hist2 * coef2 + hist3 * coef3); if (sample >= 0) - sample = (prediction + sample * pos_scale) >> 12; + sample = (sample * pos_scale - prediction) >> 12; else - sample = (prediction + sample * neg_scale) >> 12; + sample = (sample * neg_scale - prediction) >> 12; sample = clamp16(sample); outbuf[sample_count] = sample; diff --git a/src/coding/libs/compresswave_lib.c b/src/coding/libs/compresswave_lib.c index ac6f1b295..f90c8d10c 100644 --- a/src/coding/libs/compresswave_lib.c +++ b/src/coding/libs/compresswave_lib.c @@ -858,17 +858,17 @@ void TCompressWaveData_SetVolume(TCompressWaveData* self, float vol, float fade) aaa = vol; //set volume threshold - if (aaa > 1.0) aaa = 1.0; - if (aaa < 0.0) aaa = 0.0; + if (aaa > 1.0f) aaa = 1.0f; + if (aaa < 0.0f) aaa = 0.0f; //calc volume increse - if (fade < 0.01) { //with fade value + if (fade < 0.01f) { //with fade value self->Ffade = 0; - self->FVolume = round(aaa * (double)PW_MAXVOLUME); + self->FVolume = (int32_t)round((double)aaa * (double)PW_MAXVOLUME); self->FSetVolume = self->FVolume; } else { //without fade value - self->Ffade = round((double)PW_MAXVOLUME / fade / 44100); - self->FSetVolume = round(aaa * (double)PW_MAXVOLUME); + self->Ffade = (int32_t)round((double)PW_MAXVOLUME / (double)fade / 44100); + self->FSetVolume = (int32_t)round((double)aaa * (double)PW_MAXVOLUME); } } diff --git a/src/coding/libs/g7221_lib.c b/src/coding/libs/g7221_lib.c index 5550090ab..4c75937cf 100644 --- a/src/coding/libs/g7221_lib.c +++ b/src/coding/libs/g7221_lib.c @@ -1072,7 +1072,7 @@ static int unpack_frame(int bit_rate, const uint8_t* data, int frame_size, /*int if (test_errors) { int max_pad_bytes = 0x8; /* usually 0x04 and rarely ~0x08 */ int bits_left = 8 * expected_frame_size - bitpos; - int i, endpos, test_bits; + int endpos, test_bits; if (bits_left > 0) { diff --git a/src/coding/libs/tac_lib.c b/src/coding/libs/tac_lib.c index bed3fd1c6..1f1201640 100644 --- a/src/coding/libs/tac_lib.c +++ b/src/coding/libs/tac_lib.c @@ -1252,9 +1252,9 @@ int tac_decode_frame(tac_handle_t* handle, const uint8_t* block) { static inline int16_t clamp16f(float sample) { - if (sample > 32767.0) + if (sample > 32767.0f) return 32767; - else if (sample < -32768.0) + else if (sample < -32768.0f) return -32768; return (int16_t)sample; } diff --git a/src/coding/psv_decoder.c b/src/coding/psv_decoder.c index aee1daf00..0ff64cad9 100644 --- a/src/coding/psv_decoder.c +++ b/src/coding/psv_decoder.c @@ -20,134 +20,134 @@ /* ADPCM table */ static const float hevag_coefs_f[128][4] = { - {-0.0, -0.0, -0.0, -0.0 }, - { 0.9375, -0.0, -0.0, -0.0 }, - { 1.796875, -0.8125, -0.0, -0.0 }, - { 1.53125, -0.859375, -0.0, -0.0 }, - { 1.90625, -0.9375, -0.0, -0.0 }, - { 1.7982178, -0.86169434, -0.0, -0.0 }, - { 1.770874, -0.89916992, -0.0, -0.0 }, - { 1.6992188, -0.91821289, -0.0, -0.0 }, - { 1.6031494, -0.9375, -0.0, -0.0 }, - { 1.4682617, -0.9375, -0.0, -0.0 }, - { 1.3139648, -0.9375, -0.0, -0.0 }, - { 1.1424561, -0.9375, -0.0, -0.0 }, - { 0.95605469, -0.9375, -0.0, -0.0 }, - { 0.75695801, -0.9375, -0.0, -0.0 }, - { 0.54785156, -0.9375, -0.0, -0.0 }, - { 0.33166504, -0.9375, -0.0, -0.0 }, - { 0.11108398, -0.9375, -0.0, -0.0 }, - {-0.11108398, -0.9375, -0.0, -0.0 }, - {-0.33166504, -0.9375, -0.0, -0.0 }, - {-0.54785156, -0.9375, -0.0, -0.0 }, - {-0.75695801, -0.9375, -0.0, -0.0 }, - {-0.95605469, -0.9375, -0.0, -0.0 }, - {-1.1424561, -0.9375, -0.0, -0.0 }, - {-1.3139648, -0.9375, -0.0, -0.0 }, - {-1.4682617, -0.9375, -0.0, -0.0 }, - {-1.6031494, -0.9375, -0.0, -0.0 }, - {-1.6992188, -0.91821289, -0.0, -0.0 }, - {-1.770874, -0.89916992, -0.0, -0.0 }, - {-1.7982178, -0.86169434, -0.0, -0.0 }, - { 0.65625, -1.125, 0.40625, -0.375 }, - {-0.78125, -0.875, -0.40625, -0.28125 }, - {-1.28125, -0.90625, -0.4375, -0.125 }, - {-0.020385742, -0.33227539, -0.060302734, -0.066040039 }, - {-0.90698242, -0.27111816, -0.28051758, 0.051757812 }, - {-0.97668457, -0.38647461, -0.34350586, 0.03527832 }, - { 0.73461914, -0.57983398, 0.32336426, -0.15844727 }, - { 0.46362305, -0.84790039, 0.47302246, -0.1484375 }, - {-1.0054932, -0.31689453, -0.25280762, 0.027709961 }, - { 1.1229248, 0.24194336, -0.16870117, -0.28271484 }, - { 1.5894775, -0.37158203, -0.46289062, 0.15466309 }, - { 1.6005859, -0.54772949, -0.2746582, 0.20324707 }, - {-0.20361328, -0.45703125, -0.78808594, 0.10253906 }, - { 0.95446777, -0.52832031, 0.25769043, -0.061767578 }, - { 1.168335, -0.16308594, -0.092407227, 0.059448242 }, - { 1.2246094, -0.31274414, 0.036621094, 0.024291992 }, - {-0.57922363, -0.50317383, -0.66967773, -0.18225098 }, - {-0.71972656, 0.2902832, -0.58435059, -0.84802246 }, - {-0.14562988, -1.112915, -0.15100098, -0.38012695 }, - { 0.33972168, -0.86767578, -0.19226074, -0.17663574 }, - {-0.89526367, -0.25170898, -0.27001953, 0.054443359 }, - { 0.7479248, -0.3145752, -0.038452148, -0.0021972656 }, - { 1.1544189, -0.22680664, 0.012451172, 0.031494141 }, - { 0.96142578, -0.54724121, 0.25952148, -0.065673828 }, - {-0.87548828, -0.21911621, -0.25256348, 0.058837891 }, - {-0.89819336, -0.2565918, -0.27258301, 0.053710938 }, - {-1.1193848, -0.42834473, -0.32641602, -0.047729492 }, - {-0.32202148, -0.32312012, -0.23547363, -0.1998291 }, - { 0.2286377, 1.1209717, 0.22705078, -0.70141602 }, - { 1.1247559, 0.22692871, -0.13720703, -0.29626465 }, - { 1.6118164, -0.36767578, -0.50524902, 0.16723633 }, - { 1.5181885, -0.58496094, -0.03125, 0.075927734 }, - {-0.32385254, -0.13964844, -0.38842773, -0.83959961 }, - { 1.1390381, -0.12792969, -0.10107422, 0.061889648 }, - { 0.20043945, -0.075683594, -0.11547852, -0.51623535 }, - { 0.51831055, -0.92590332, -0.065063477, -0.27575684 }, - {-1.097168, -0.47497559, -0.34265137, 0.0053710938 }, - {-0.31274414, -0.3338623, -0.21118164, -0.23181152 }, - { 0.38842773, -0.058959961, -0.087158203, -0.17346191 }, - { 0.96887207, -0.46923828, 0.34436035, -0.12438965 }, - { 1.229126, -0.31848145, 0.038330078, 0.023803711 }, - { 1.0253906, -0.40246582, 0.18933105, -0.018920898 }, - {-1.0411377, -0.33874512, -0.296875, -0.041015625 }, - { 1.1568604, -0.22973633, 0.013183594, 0.03125 }, - { 0.0091552734, -0.27355957, -0.036376953, -0.84680176 }, - {-1.1160889, -0.5078125, -0.36169434, 0.00061035156 }, - {-0.88745117, -0.23901367, -0.26318359, 0.056152344 }, - {-0.33447266, 0.45715332, 0.72460938, -0.13293457 }, - { 1.0977783, 0.23779297, -0.083374023, -0.33007812 }, - { 1.5992432, -0.34606934, -0.47045898, 0.12878418 }, - { 1.164917, -0.23937988, 0.015869141, 0.030517578 }, - { 0.64355469, -0.52124023, 0.38134766, -0.38537598 }, - {-0.93945312, -0.41296387, -0.3548584, -0.055664062 }, - { 0.89221191, 0.3079834, 0.052978516, -0.30041504 }, - { 1.2542725, -0.34997559, 0.047729492, 0.020996094 }, - { 1.3354492, -0.45422363, 0.081176758, 0.01184082 }, - { 0.0029296875, -0.037841797, -0.15405273, 0.0390625 }, - {-0.99145508, -0.29431152, -0.28210449, -0.033081055 }, - {-1.0389404, -0.37438965, -0.28527832, 0.019897461 }, - { 0.039794922, -0.46948242, 0.051147461, -0.1138916 }, - { 1.0858154, 0.26782227, -0.066040039, -0.3515625 }, - { 1.4737549, -0.22900391, -0.24621582, -0.073364258 }, - { 1.0655518, -0.41784668, 0.2043457, -0.020629883 }, - { 1.5808105, -0.46960449, -0.36706543, 0.23754883 }, - { 1.2253418, -0.3137207, 0.036865234, 0.024169922 }, - { 1.1456299, -0.33654785, 0.12304688, 0.0050048828 }, - {-0.57617188, -0.61108398, -0.34814453, -0.14172363 }, - { 0.96057129, -0.52807617, 0.26062012, -0.061157227 }, - { 0.29907227, -1.0494385, 0.15856934, -0.33935547 }, - { 1.2441406, -0.33728027, 0.043945312, 0.022094727 }, - { 1.3809814, -0.51428223, 0.10168457, 0.0064697266 }, - { 1.239502, -0.33154297, 0.042114258, 0.022583008 }, - { 1.1765137, -0.17297363, -0.08996582, 0.058837891 }, - { 0.47045898, -0.5559082, 0.3470459, -0.41467285 }, - { 0.81774902, -0.6907959, 0.27453613, -0.13110352 }, - { 1.3527832, -0.47705078, 0.088867188, 0.009765625 }, - {-0.12524414, -1.1975098, -0.098266602, -0.42260742 }, - { 1.269043, -0.45727539, 0.16687012, -0.01171875 }, - { 1.2557373, 0.12060547, -0.23376465, -0.17541504 }, - { 0.9708252, 0.47338867, -0.093261719, -0.39831543 }, - { 1.5489502, -0.4119873, -0.40942383, 0.25378418 }, - { 0.81066895, 0.38647461, 0.028198242, -0.25500488 }, - {-0.28662109, -0.89770508, -0.23730469, -0.50317383 }, - { 1.1340332, -0.49304199, 0.23010254, -0.030029297 }, - { 0.56555176, -0.78161621, 0.21337891, -0.19763184 }, - { 1.3729248, -0.50354004, 0.097900391, 0.0074462891 }, - { 1.1971436, -0.27880859, 0.026733398, 0.027099609 }, - { 1.1884766, -0.1875, -0.086181641, 0.057739258 }, - { 1.0302734, -0.41943359, 0.19067383, -0.021484375 }, - { 1.1361084, -0.12463379, -0.10192871, 0.062133789 }, - { 0.20727539, -1.1016846, 0.083984375, -0.37072754 }, - { 1.2468262, -0.34069824, 0.044921875, 0.021850586 }, - { 1.0241699, 0.39648438, -0.092529297, -0.36486816 }, - { 0.87902832, 0.40478516, 0.0056152344, -0.3190918 }, - {-0.010742188, -0.95324707, -0.065673828, -0.5579834 }, - { 0.75598145, -0.63342285, 0.33691406, -0.15197754 }, - { 1.5045166, -0.1574707, -0.40087891, 0.030883789 }, - { 1.5947266, -0.49743652, -0.34472656, 0.22912598 }, - { 0.65100098, 0.36608887, 0.094604492, -0.13818359 }, + {-0.0f, -0.0f, -0.0f, -0.0f }, + { 0.9375f, -0.0f, -0.0f, -0.0f }, + { 1.796875f, -0.8125f, -0.0f, -0.0f }, + { 1.53125f, -0.859375f, -0.0f, -0.0f }, + { 1.90625f, -0.9375f, -0.0f, -0.0f }, + { 1.7982178f, -0.86169434f, -0.0f, -0.0f }, + { 1.770874f, -0.89916992f, -0.0f, -0.0f }, + { 1.6992188f, -0.91821289f, -0.0f, -0.0f }, + { 1.6031494f, -0.9375f, -0.0f, -0.0f }, + { 1.4682617f, -0.9375f, -0.0f, -0.0f }, + { 1.3139648f, -0.9375f, -0.0f, -0.0f }, + { 1.1424561f, -0.9375f, -0.0f, -0.0f }, + { 0.95605469f, -0.9375f, -0.0f, -0.0f }, + { 0.75695801f, -0.9375f, -0.0f, -0.0f }, + { 0.54785156f, -0.9375f, -0.0f, -0.0f }, + { 0.33166504f, -0.9375f, -0.0f, -0.0f }, + { 0.11108398f, -0.9375f, -0.0f, -0.0f }, + {-0.11108398f, -0.9375f, -0.0f, -0.0f }, + {-0.33166504f, -0.9375f, -0.0f, -0.0f }, + {-0.54785156f, -0.9375f, -0.0f, -0.0f }, + {-0.75695801f, -0.9375f, -0.0f, -0.0f }, + {-0.95605469f, -0.9375f, -0.0f, -0.0f }, + {-1.1424561f, -0.9375f, -0.0f, -0.0f }, + {-1.3139648f, -0.9375f, -0.0f, -0.0f }, + {-1.4682617f, -0.9375f, -0.0f, -0.0f }, + {-1.6031494f, -0.9375f, -0.0f, -0.0f }, + {-1.6992188f, -0.91821289f, -0.0f, -0.0f }, + {-1.770874f, -0.89916992f, -0.0f, -0.0f }, + {-1.7982178f, -0.86169434f, -0.0f, -0.0f }, + { 0.65625f, -1.125f, 0.40625f, -0.375f }, + {-0.78125f, -0.875f, -0.40625f, -0.28125f }, + {-1.28125f, -0.90625f, -0.4375f, -0.125f }, + {-0.020385742f, -0.33227539f, -0.060302734f, -0.066040039f }, + {-0.90698242f, -0.27111816f, -0.28051758f, 0.051757812f }, + {-0.97668457f, -0.38647461f, -0.34350586f, 0.03527832f }, + { 0.73461914f, -0.57983398f, 0.32336426f, -0.15844727f }, + { 0.46362305f, -0.84790039f, 0.47302246f, -0.1484375f }, + {-1.0054932f, -0.31689453f, -0.25280762f, 0.027709961f }, + { 1.1229248f, 0.24194336f, -0.16870117f, -0.28271484f }, + { 1.5894775f, -0.37158203f, -0.46289062f, 0.15466309f }, + { 1.6005859f, -0.54772949f, -0.2746582f, 0.20324707f }, + {-0.20361328f, -0.45703125f, -0.78808594f, 0.10253906f }, + { 0.95446777f, -0.52832031f, 0.25769043f, -0.061767578f }, + { 1.168335f, -0.16308594f, -0.092407227f, 0.059448242f }, + { 1.2246094f, -0.31274414f, 0.036621094f, 0.024291992f }, + {-0.57922363f, -0.50317383f, -0.66967773f, -0.18225098f }, + {-0.71972656f, 0.2902832f, -0.58435059f, -0.84802246f }, + {-0.14562988f, -1.112915f, -0.15100098f, -0.38012695f }, + { 0.33972168f, -0.86767578f, -0.19226074f, -0.17663574f }, + {-0.89526367f, -0.25170898f, -0.27001953f, 0.054443359f }, + { 0.7479248f, -0.3145752f, -0.038452148f, -0.0021972656f }, + { 1.1544189f, -0.22680664f, 0.012451172f, 0.031494141f }, + { 0.96142578f, -0.54724121f, 0.25952148f, -0.065673828f }, + {-0.87548828f, -0.21911621f, -0.25256348f, 0.058837891f }, + {-0.89819336f, -0.2565918f, -0.27258301f, 0.053710938f }, + {-1.1193848f, -0.42834473f, -0.32641602f, -0.047729492f }, + {-0.32202148f, -0.32312012f, -0.23547363f, -0.1998291f }, + { 0.2286377f, 1.1209717f, 0.22705078f, -0.70141602f }, + { 1.1247559f, 0.22692871f, -0.13720703f, -0.29626465f }, + { 1.6118164f, -0.36767578f, -0.50524902f, 0.16723633f }, + { 1.5181885f, -0.58496094f, -0.03125f, 0.075927734f }, + {-0.32385254f, -0.13964844f, -0.38842773f, -0.83959961f }, + { 1.1390381f, -0.12792969f, -0.10107422f, 0.061889648f }, + { 0.20043945f, -0.075683594f, -0.11547852f, -0.51623535f }, + { 0.51831055f, -0.92590332f, -0.065063477f, -0.27575684f }, + {-1.097168f, -0.47497559f, -0.34265137f, 0.0053710938f }, + {-0.31274414f, -0.3338623f, -0.21118164f, -0.23181152f }, + { 0.38842773f, -0.058959961f, -0.087158203f, -0.17346191f }, + { 0.96887207f, -0.46923828f, 0.34436035f, -0.12438965f }, + { 1.229126f, -0.31848145f, 0.038330078f, 0.023803711f }, + { 1.0253906f, -0.40246582f, 0.18933105f, -0.018920898f }, + {-1.0411377f, -0.33874512f, -0.296875f, -0.041015625f }, + { 1.1568604f, -0.22973633f, 0.013183594f, 0.03125f }, + { 0.0091552734f, -0.27355957f, -0.036376953f, -0.84680176f }, + {-1.1160889f, -0.5078125f, -0.36169434f, 0.00061035156f }, + {-0.88745117f, -0.23901367f, -0.26318359f, 0.056152344f }, + {-0.33447266f, 0.45715332f, 0.72460938f, -0.13293457f }, + { 1.0977783f, 0.23779297f, -0.083374023f, -0.33007812f }, + { 1.5992432f, -0.34606934f, -0.47045898f, 0.12878418f }, + { 1.164917f, -0.23937988f, 0.015869141f, 0.030517578f }, + { 0.64355469f, -0.52124023f, 0.38134766f, -0.38537598f }, + {-0.93945312f, -0.41296387f, -0.3548584f, -0.055664062f }, + { 0.89221191f, 0.3079834f, 0.052978516f, -0.30041504f }, + { 1.2542725f, -0.34997559f, 0.047729492f, 0.020996094f }, + { 1.3354492f, -0.45422363f, 0.081176758f, 0.01184082f }, + { 0.0029296875f, -0.037841797f, -0.15405273f, 0.0390625f }, + {-0.99145508f, -0.29431152f, -0.28210449f, -0.033081055f }, + {-1.0389404f, -0.37438965f, -0.28527832f, 0.019897461f }, + { 0.039794922f, -0.46948242f, 0.051147461f, -0.1138916f }, + { 1.0858154f, 0.26782227f, -0.066040039f, -0.3515625f }, + { 1.4737549f, -0.22900391f, -0.24621582f, -0.073364258f }, + { 1.0655518f, -0.41784668f, 0.2043457f, -0.020629883f }, + { 1.5808105f, -0.46960449f, -0.36706543f, 0.23754883f }, + { 1.2253418f, -0.3137207f, 0.036865234f, 0.024169922f }, + { 1.1456299f, -0.33654785f, 0.12304688f, 0.0050048828f }, + {-0.57617188f, -0.61108398f, -0.34814453f, -0.14172363f }, + { 0.96057129f, -0.52807617f, 0.26062012f, -0.061157227f }, + { 0.29907227f, -1.0494385f, 0.15856934f, -0.33935547f }, + { 1.2441406f, -0.33728027f, 0.043945312f, 0.022094727f }, + { 1.3809814f, -0.51428223f, 0.10168457f, 0.0064697266f }, + { 1.239502f, -0.33154297f, 0.042114258f, 0.022583008f }, + { 1.1765137f, -0.17297363f, -0.08996582f, 0.058837891f }, + { 0.47045898f, -0.5559082f, 0.3470459f, -0.41467285f }, + { 0.81774902f, -0.6907959f, 0.27453613f, -0.13110352f }, + { 1.3527832f, -0.47705078f, 0.088867188f, 0.009765625f }, + {-0.12524414f, -1.1975098f, -0.098266602f, -0.42260742f }, + { 1.269043f, -0.45727539f, 0.16687012f, -0.01171875f }, + { 1.2557373f, 0.12060547f, -0.23376465f, -0.17541504f }, + { 0.9708252f, 0.47338867f, -0.093261719f, -0.39831543f }, + { 1.5489502f, -0.4119873f, -0.40942383f, 0.25378418f }, + { 0.81066895f, 0.38647461f, 0.028198242f, -0.25500488f }, + {-0.28662109f, -0.89770508f, -0.23730469f, -0.50317383f }, + { 1.1340332f, -0.49304199f, 0.23010254f, -0.030029297f }, + { 0.56555176f, -0.78161621f, 0.21337891f, -0.19763184f }, + { 1.3729248f, -0.50354004f, 0.097900391f, 0.0074462891f }, + { 1.1971436f, -0.27880859f, 0.026733398f, 0.027099609f }, + { 1.1884766f, -0.1875f, -0.086181641f, 0.057739258f }, + { 1.0302734f, -0.41943359f, 0.19067383f, -0.021484375f }, + { 1.1361084f, -0.12463379f, -0.10192871f, 0.062133789f }, + { 0.20727539f, -1.1016846f, 0.083984375f, -0.37072754f }, + { 1.2468262f, -0.34069824f, 0.044921875f, 0.021850586f }, + { 1.0241699f, 0.39648438f, -0.092529297f, -0.36486816f }, + { 0.87902832f, 0.40478516f, 0.0056152344f, -0.3190918f }, + {-0.010742188f, -0.95324707f, -0.065673828f, -0.5579834f }, + { 0.75598145f, -0.63342285f, 0.33691406f, -0.15197754f }, + { 1.5045166f, -0.1574707f, -0.40087891f, 0.030883789f }, + { 1.5947266f, -0.49743652f, -0.34472656f, 0.22912598f }, + { 0.65100098f, 0.36608887f, 0.094604492f, -0.13818359f }, }; #if 0 diff --git a/src/coding/psx_decoder.c b/src/coding/psx_decoder.c index 70d004c72..bf620b4a9 100644 --- a/src/coding/psx_decoder.c +++ b/src/coding/psx_decoder.c @@ -3,23 +3,23 @@ /* PS-ADPCM table, defined as rational numbers (as in the spec) */ static const float ps_adpcm_coefs_f[16][2] = { - { 0.0 , 0.0 }, //{ 0.0 , 0.0 }, - { 0.9375 , 0.0 }, //{ 60.0 / 64.0 , 0.0 }, - { 1.796875 , -0.8125 }, //{ 115.0 / 64.0 , -52.0 / 64.0 }, - { 1.53125 , -0.859375 }, //{ 98.0 / 64.0 , -55.0 / 64.0 }, - { 1.90625 , -0.9375 }, //{ 122.0 / 64.0 , -60.0 / 64.0 }, + { 0.0f , 0.0f }, //{ 0.0 , 0.0 }, + { 0.9375f , 0.0f }, //{ 60.0 / 64.0 , 0.0 }, + { 1.796875f , -0.8125f }, //{ 115.0 / 64.0 , -52.0 / 64.0 }, + { 1.53125f , -0.859375f }, //{ 98.0 / 64.0 , -55.0 / 64.0 }, + { 1.90625f , -0.9375f }, //{ 122.0 / 64.0 , -60.0 / 64.0 }, /* extended table used in few PS3 games, found in ELFs */ - { 0.46875 , -0.0 }, //{ 30.0 / 64.0 , -0.0 / 64.0 }, - { 0.8984375 , -0.40625 }, //{ 57.5 / 64.0 , -26.0 / 64.0 }, - { 0.765625 , -0.4296875 }, //{ 49.0 / 64.0 , -27.5 / 64.0 }, - { 0.953125 , -0.46875 }, //{ 61.0 / 64.0 , -30.0 / 64.0 }, - { 0.234375 , -0.0 }, //{ 15.0 / 64.0 , -0.0 / 64.0 }, - { 0.44921875, -0.203125 }, //{ 28.75/ 64.0 , -13.0 / 64.0 }, - { 0.3828125 , -0.21484375}, //{ 24.5 / 64.0 , -13.75/ 64.0 }, - { 0.4765625 , -0.234375 }, //{ 30.5 / 64.0 , -15.0 / 64.0 }, - { 0.5 , -0.9375 }, //{ 32.0 / 64.0 , -60.0 / 64.0 }, - { 0.234375 , -0.9375 }, //{ 15.0 / 64.0 , -60.0 / 64.0 }, - { 0.109375 , -0.9375 }, //{ 7.0 / 64.0 , -60.0 / 64.0 }, + { 0.46875f , -0.0f }, //{ 30.0 / 64.0 , -0.0 / 64.0 }, + { 0.8984375f, -0.40625f }, //{ 57.5 / 64.0 , -26.0 / 64.0 }, + { 0.765625f , -0.4296875f }, //{ 49.0 / 64.0 , -27.5 / 64.0 }, + { 0.953125f , -0.46875f }, //{ 61.0 / 64.0 , -30.0 / 64.0 }, + { 0.234375f , -0.0f }, //{ 15.0 / 64.0 , -0.0 / 64.0 }, + { 0.44921875f,-0.203125f }, //{ 28.75/ 64.0 , -13.0 / 64.0 }, + { 0.3828125f, -0.21484375f}, //{ 24.5 / 64.0 , -13.75/ 64.0 }, + { 0.4765625f, -0.234375f }, //{ 30.5 / 64.0 , -15.0 / 64.0 }, + { 0.5f , -0.9375f }, //{ 32.0 / 64.0 , -60.0 / 64.0 }, + { 0.234375f , -0.9375f }, //{ 15.0 / 64.0 , -60.0 / 64.0 }, + { 0.109375f , -0.9375f }, //{ 7.0 / 64.0 , -60.0 / 64.0 }, }; /* PS-ADPCM table, defined as spec_coef*64 (for int implementations) */ diff --git a/src/meta/bkhd.c b/src/meta/bkhd.c index d1d3cbe05..e4d246c6b 100644 --- a/src/meta/bkhd.c +++ b/src/meta/bkhd.c @@ -148,8 +148,8 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) { vgmstream = init_vgmstream_adm3(temp_sf); if (!vgmstream) goto fail; } - else if (read_f32(subfile_offset + 0x02, temp_sf) >= 30.0 && - read_f32(subfile_offset + 0x02, temp_sf) <= 250.0) { + else if (read_f32(subfile_offset + 0x02, temp_sf) >= 30.0f && + read_f32(subfile_offset + 0x02, temp_sf) <= 250.0f) { is_wmid = 1; /* ignore Wwise's custom .wmid (similar to a regular midi but with simplified * chunks and custom fields: 0x00=MThd's division, 0x02: bpm (new), etc) */ diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index 8ea149d95..33fdff68c 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -71,7 +71,7 @@ typedef struct { uint32_t header_size; } eaac_header_t; -static VGMSTREAM* init_vgmstream_eaaudiocore_main(eaac_header_t* eaac, STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, bool standalone); +static VGMSTREAM* init_vgmstream_eaaudiocore_main(eaac_header_t* eaac, STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, meta_t meta_type, bool standalone); /* EA newest header from RwAudioCore (RenderWare?) / EAAudioCore library (still generated by sx.exe). @@ -244,7 +244,7 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMF } /* header done, setup decoding */ - return init_vgmstream_eaaudiocore_main(&eaac, sf_head, sf_data, header_offset, start_offset, meta_type, standalone); + return init_vgmstream_eaaudiocore_main(&eaac, sf_head, sf_data, header_offset, meta_type, standalone); fail: return NULL; } @@ -255,7 +255,7 @@ static STREAMFILE* setup_eaac_streamfile(eaac_header_t* ea, STREAMFILE* sf_head, static size_t calculate_eaac_size(STREAMFILE* sf, eaac_header_t* ea, uint32_t num_samples, off_t start_offset, int is_ram); -static VGMSTREAM* init_vgmstream_eaaudiocore_main(eaac_header_t* eaac, STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t _start_offset, meta_t meta_type, bool standalone) { +static VGMSTREAM* init_vgmstream_eaaudiocore_main(eaac_header_t* eaac, STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, meta_t meta_type, bool standalone) { VGMSTREAM* vgmstream = NULL; STREAMFILE *temp_sf = NULL, *sf = NULL, *sf_sns = NULL; diff --git a/src/meta/mul.c b/src/meta/mul.c index 613f7562e..b61627f8b 100644 --- a/src/meta/mul.c +++ b/src/meta/mul.c @@ -54,7 +54,7 @@ VGMSTREAM* init_vgmstream_mul(STREAMFILE* sf) { { float check1 = read_f32(0x38,sf); float check2 = read_f32(0x3c,sf); - if (!(check1 >= 1.0 && check1 <= 3000.0) && check2 != 1.0) + if (!(check1 >= 1.0f && check1 <= 3000.0f) && check2 != 1.0f) goto fail; } diff --git a/src/meta/psb.c b/src/meta/psb.c index cec0b3f1f..3c03b01c4 100644 --- a/src/meta/psb.c +++ b/src/meta/psb.c @@ -823,7 +823,7 @@ static int parse_psb(STREAMFILE* sf, psb_header_t* psb) { /* enforced by M2 code */ version = psb_node_get_float(&nroot, "version"); if (version < 1.02f || version > 1.02f) { - vgm_logi("PSB: unsupported version %f (report)\n", version); + vgm_logi("PSB: unsupported version %f (report)\n", (double)version); goto fail; } diff --git a/src/meta/ubi_bao.c b/src/meta/ubi_bao.c index 5d5ab4dd5..ff27b750d 100644 --- a/src/meta/ubi_bao.c +++ b/src/meta/ubi_bao.c @@ -990,7 +990,7 @@ static int parse_type_silence(ubi_bao_header* bao, off_t offset, STREAMFILE* sf) bao->duration = read_f32(h_offset + bao->cfg.silence_duration_float, sf); if (bao->duration <= 0.0f) { - VGM_LOG("UBI BAO: bad duration %f at %x\n", bao->duration, (uint32_t)offset); + VGM_LOG("UBI BAO: bad duration %f at %x\n", (double)bao->duration, (uint32_t)offset); goto fail; } diff --git a/src/meta/ubi_sb.c b/src/meta/ubi_sb.c index 2e8301fc9..49be60161 100644 --- a/src/meta/ubi_sb.c +++ b/src/meta/ubi_sb.c @@ -2494,6 +2494,8 @@ static int parse_header(ubi_sb_header* sb, STREAMFILE* sf, off_t offset, int ind sb->duration = 1.0f; break; } + + // fall through default: VGM_LOG("UBI SB: unknown header type %x at %x\n", sb->header_type, (uint32_t)offset); goto fail; diff --git a/src/meta/xnb_lz4mg.h b/src/meta/xnb_lz4mg.h index e6833472a..2d25386c5 100644 --- a/src/meta/xnb_lz4mg.h +++ b/src/meta/xnb_lz4mg.h @@ -156,8 +156,8 @@ static int lz4mg_decompress(lz4mg_stream_t* strm) { } while (next_len == LZ4MG_VARLEN_CONTINUE); ctx->state = SET_MATCH; - //break; // Falthrough for MSVC - + //break; // for MSVC (jump threading optimization compiler bug, fixed in ~2023-12) + // fall through case SET_MATCH: ctx->match_len += LZ4MG_MIN_MATCH_LEN; @@ -166,8 +166,8 @@ static int lz4mg_decompress(lz4mg_stream_t* strm) { ctx->match_pos = LZ4MG_WINDOW_SIZE + ctx->match_pos; ctx->state = COPY_MATCH; - //break; // Fallthrough for MSVC - + //break; // for MSVC (jump threading optimization compiler bug, fixed in ~2023-12) + // fall through case COPY_MATCH: while (ctx->match_len > 0) { if (dst_pos >= dst_size) diff --git a/src/util/m2_psb.c b/src/util/m2_psb.c index f8e272450..90276633a 100644 --- a/src/util/m2_psb.c +++ b/src/util/m2_psb.c @@ -812,7 +812,7 @@ static void print_internal(psb_node_t* curr, int depth) { break; case PSB_TYPE_FLOAT: - printf("%f,\n", res.flt); + printf("%f,\n", (double)res.flt); break; case PSB_TYPE_STRING: From 122de356c13092b83180986a0b63299a99660006 Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 23:25:41 +0200 Subject: [PATCH 07/17] cleanup: move layout helpers --- src/layout/layered.c | 78 ------------------ src/layout/layout.h | 2 - src/layout/segmented.c | 64 --------------- src/meta/9tav.c | 1 + src/meta/aix.c | 1 + src/meta/ea_eaac_mpf_mus.c | 1 + src/meta/ea_schl_abk.c | 1 + src/meta/ea_schl_map_mpf_mus.c | 1 + src/meta/psf.c | 1 + src/meta/sab.c | 4 +- src/meta/sps_n1.c | 1 + src/meta/txtp_process.c | 1 + src/util/layout_utils.c | 146 +++++++++++++++++++++++++++++++++ src/util/layout_utils.h | 4 + 14 files changed, 160 insertions(+), 146 deletions(-) diff --git a/src/layout/layered.c b/src/layout/layered.c index 2dc853dc2..d27fef6f0 100644 --- a/src/layout/layered.c +++ b/src/layout/layered.c @@ -233,81 +233,3 @@ void reset_layout_layered(layered_layout_data *data) { reset_vgmstream(data->layers[i]); } } - -/* helper for easier creation of layers */ -VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data) { - VGMSTREAM* vgmstream = NULL; - int i, channels, loop_flag, sample_rate, external_looping; - int32_t num_samples, loop_start, loop_end; - int delta = 1024; - coding_t coding_type = data->layers[0]->coding_type; - - /* get data */ - channels = data->output_channels; - - num_samples = 0; - loop_flag = 1; - loop_start = data->layers[0]->loop_start_sample; - loop_end = data->layers[0]->loop_end_sample; - external_looping = 0; - sample_rate = 0; - - for (i = 0; i < data->layer_count; i++) { - int32_t layer_samples = vgmstream_get_samples(data->layers[i]); - int layer_loop = data->layers[i]->loop_flag; - int32_t layer_loop_start = data->layers[i]->loop_start_sample; - int32_t layer_loop_end = data->layers[i]->loop_end_sample; - int layer_rate = data->layers[i]->sample_rate; - - /* internal has own config (and maybe looping), looping now must be done on layout level - * (instead of on each layer, that is faster) */ - if (data->layers[i]->config_enabled) { - loop_flag = 0; - layer_loop = 0; - external_looping = 1; - } - - /* all layers should share loop pointsto consider looping enabled, - * but allow some leeway (ex. Dragalia Lost bgm+vocals ~12 samples) */ - if (!layer_loop - || !(loop_start >= layer_loop_start - delta && loop_start <= layer_loop_start + delta) - || !(loop_end >= layer_loop_end - delta && loop_start <= layer_loop_end + delta)) { - loop_flag = 0; - loop_start = 0; - loop_end = 0; - } - - if (num_samples < layer_samples) /* max */ - num_samples = layer_samples; - - if (sample_rate < layer_rate) - sample_rate = layer_rate; - - if (coding_type == coding_SILENCE) - coding_type = data->layers[i]->coding_type; - } - - data->external_looping = external_looping; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = data->layers[0]->meta_type; - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - vgmstream->coding_type = coding_type; - - vgmstream->layout_type = layout_layered; - vgmstream->layout_data = data; - - return vgmstream; - -fail: - if (vgmstream) vgmstream->layout_data = NULL; - close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/layout/layout.h b/src/layout/layout.h index 6b4d15e51..97fd1cc57 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -30,7 +30,6 @@ void free_layout_segmented(segmented_layout_data* data); void reset_layout_segmented(segmented_layout_data* data); void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample); void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample); -VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment); /* layered layout */ /* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */ @@ -51,7 +50,6 @@ void free_layout_layered(layered_layout_data* data); void reset_layout_layered(layered_layout_data* data); void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample); void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample); -VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data); /* blocked layouts */ void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream); diff --git a/src/layout/segmented.c b/src/layout/segmented.c index bf0bd5790..1b549dd8e 100644 --- a/src/layout/segmented.c +++ b/src/layout/segmented.c @@ -289,67 +289,3 @@ void reset_layout_segmented(segmented_layout_data* data) { reset_vgmstream(data->segments[i]); } } - -/* helper for easier creation of segments */ -VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment) { - VGMSTREAM* vgmstream = NULL; - int channel_layout; - int i, sample_rate; - int32_t num_samples, loop_start, loop_end; - coding_t coding_type = data->segments[0]->coding_type; - - /* save data */ - channel_layout = data->segments[0]->channel_layout; - num_samples = 0; - loop_start = 0; - loop_end = 0; - sample_rate = 0; - for (i = 0; i < data->segment_count; i++) { - /* needs get_samples since element may use play settings */ - int32_t segment_samples = vgmstream_get_samples(data->segments[i]); - int segment_rate = data->segments[i]->sample_rate; - - if (loop_flag && i == loop_start_segment) - loop_start = num_samples; - - num_samples += segment_samples; - - if (loop_flag && i == loop_end_segment) - loop_end = num_samples; - - /* inherit first segment's layout but only if all segments' layout match */ - if (channel_layout != 0 && channel_layout != data->segments[i]->channel_layout) - channel_layout = 0; - - if (sample_rate < segment_rate) - sample_rate = segment_rate; - - if (coding_type == coding_SILENCE) - coding_type = data->segments[i]->coding_type; - } - - /* respect loop_flag even when no loop_end found as it's possible file loops are set outside */ - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(data->output_channels, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = data->segments[0]->meta_type; - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - vgmstream->coding_type = coding_type; - vgmstream->channel_layout = channel_layout; - - vgmstream->layout_type = layout_segmented; - vgmstream->layout_data = data; - - return vgmstream; - -fail: - if (vgmstream) vgmstream->layout_data = NULL; - close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/meta/9tav.c b/src/meta/9tav.c index 39ddd73b9..b6b90044a 100644 --- a/src/meta/9tav.c +++ b/src/meta/9tav.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../coding/coding.h" #include "../layout/layout.h" +#include "../util/layout_utils.h" #include "9tav_streamfile.h" /* 9TAV - from Metal Gear Solid 2/3 HD (Vita) */ diff --git a/src/meta/aix.c b/src/meta/aix.c index 50c974cd1..cb1f7808d 100644 --- a/src/meta/aix.c +++ b/src/meta/aix.c @@ -1,5 +1,6 @@ #include "meta.h" #include "../layout/layout.h" +#include "../util/layout_utils.h" #include "aix_streamfile.h" diff --git a/src/meta/ea_eaac_mpf_mus.c b/src/meta/ea_eaac_mpf_mus.c index 42de2bf9e..e43f7ac79 100644 --- a/src/meta/ea_eaac_mpf_mus.c +++ b/src/meta/ea_eaac_mpf_mus.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../util/endianness.h" #include "../layout/layout.h" +#include "../util/layout_utils.h" #include "../util/companion_files.h" diff --git a/src/meta/ea_schl_abk.c b/src/meta/ea_schl_abk.c index 057e654ce..9ca61cb2f 100644 --- a/src/meta/ea_schl_abk.c +++ b/src/meta/ea_schl_abk.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../layout/layout.h" #include "../util/endianness.h" +#include "../util/layout_utils.h" #define EA_BLOCKID_HEADER 0x5343486C /* "SCHl" */ diff --git a/src/meta/ea_schl_map_mpf_mus.c b/src/meta/ea_schl_map_mpf_mus.c index c9301006c..c0f2cbd68 100644 --- a/src/meta/ea_schl_map_mpf_mus.c +++ b/src/meta/ea_schl_map_mpf_mus.c @@ -2,6 +2,7 @@ #include "../util/endianness.h" #include "../layout/layout.h" #include "../util/companion_files.h" +#include "../util/layout_utils.h" #define EA_BLOCKID_HEADER 0x5343486C /* "SCHl" */ diff --git a/src/meta/psf.c b/src/meta/psf.c index 1a421ed3c..9333ee748 100644 --- a/src/meta/psf.c +++ b/src/meta/psf.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../layout/layout.h" #include "../coding/coding.h" +#include "../util/layout_utils.h" /* PSF single - Pivotal games single segment (external in some PC/Xbox or inside bigfiles) [The Great Escape, Conflict series] */ diff --git a/src/meta/sab.c b/src/meta/sab.c index b7b8fbc2b..e0a4a1aca 100644 --- a/src/meta/sab.c +++ b/src/meta/sab.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../coding/coding.h" #include "../layout/layout.h" +#include "../util/layout_utils.h" #include "sab_streamfile.h" typedef struct { @@ -234,7 +235,6 @@ static VGMSTREAM* build_layered_vgmstream(STREAMFILE* sf, sab_header* sab) { VGMSTREAM* vgmstream = NULL; STREAMFILE* temp_sf = NULL; layered_layout_data* data = NULL; - int i; if (sab->sound_count == 1 || !sab->is_stream) { return build_vgmstream(sf, sab); @@ -245,7 +245,7 @@ static VGMSTREAM* build_layered_vgmstream(STREAMFILE* sf, sab_header* sab) { if (!data) goto fail; /* de-chunk audio layers */ - for (i = 0; i < sab->sound_count; i++) { + for (int i = 0; i < sab->sound_count; i++) { temp_sf = setup_sab_streamfile(sf, sab->stream_offset, sab->sound_count, i, sab->block_size); if (!temp_sf) goto fail; diff --git a/src/meta/sps_n1.c b/src/meta/sps_n1.c index 35a8f41ce..f5c3af563 100644 --- a/src/meta/sps_n1.c +++ b/src/meta/sps_n1.c @@ -2,6 +2,7 @@ #include "../layout/layout.h" #include "../coding/coding.h" #include "../util/endianness.h" +#include "../util/layout_utils.h" /* also see init_vgmstream_dsp_sps_n1 and init_vgmstream_opus_sps_n1 */ diff --git a/src/meta/txtp_process.c b/src/meta/txtp_process.c index 63af2949c..69b2445e6 100644 --- a/src/meta/txtp_process.c +++ b/src/meta/txtp_process.c @@ -5,6 +5,7 @@ #include "../layout/layout.h" #include "../base/mixing.h" #include "../base/plugins.h" +#include "../util/layout_utils.h" /*******************************************************************************/ diff --git a/src/util/layout_utils.c b/src/util/layout_utils.c index b36bcaae0..8432cbb22 100644 --- a/src/util/layout_utils.c +++ b/src/util/layout_utils.c @@ -3,6 +3,7 @@ #include "../vgmstream.h" #include "../layout/layout.h" #include "../coding/coding.h" +#include "../base/plugins.h" typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*); @@ -147,3 +148,148 @@ bool layered_add_done(VGMSTREAM* vs) { fail: return false; } + + + +/* helper for easier creation of layers */ +VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data) { + VGMSTREAM* vgmstream = NULL; + int i, channels, loop_flag, sample_rate, external_looping; + int32_t num_samples, loop_start, loop_end; + int delta = 1024; + coding_t coding_type = data->layers[0]->coding_type; + + /* get data */ + channels = data->output_channels; + + num_samples = 0; + loop_flag = 1; + loop_start = data->layers[0]->loop_start_sample; + loop_end = data->layers[0]->loop_end_sample; + external_looping = 0; + sample_rate = 0; + + for (i = 0; i < data->layer_count; i++) { + int32_t layer_samples = vgmstream_get_samples(data->layers[i]); + int layer_loop = data->layers[i]->loop_flag; + int32_t layer_loop_start = data->layers[i]->loop_start_sample; + int32_t layer_loop_end = data->layers[i]->loop_end_sample; + int layer_rate = data->layers[i]->sample_rate; + + /* internal has own config (and maybe looping), looping now must be done on layout level + * (instead of on each layer, that is faster) */ + if (data->layers[i]->config_enabled) { + loop_flag = 0; + layer_loop = 0; + external_looping = 1; + } + + /* all layers should share loop pointsto consider looping enabled, + * but allow some leeway (ex. Dragalia Lost bgm+vocals ~12 samples) */ + if (!layer_loop + || !(loop_start >= layer_loop_start - delta && loop_start <= layer_loop_start + delta) + || !(loop_end >= layer_loop_end - delta && loop_start <= layer_loop_end + delta)) { + loop_flag = 0; + loop_start = 0; + loop_end = 0; + } + + if (num_samples < layer_samples) /* max */ + num_samples = layer_samples; + + if (sample_rate < layer_rate) + sample_rate = layer_rate; + + if (coding_type == coding_SILENCE) + coding_type = data->layers[i]->coding_type; + } + + data->external_looping = external_looping; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = data->layers[0]->meta_type; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + vgmstream->coding_type = coding_type; + + vgmstream->layout_type = layout_layered; + vgmstream->layout_data = data; + + return vgmstream; + +fail: + if (vgmstream) vgmstream->layout_data = NULL; + close_vgmstream(vgmstream); + return NULL; +} + + +/* helper for easier creation of segments */ +VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment) { + VGMSTREAM* vgmstream = NULL; + int channel_layout; + int i, sample_rate; + int32_t num_samples, loop_start, loop_end; + coding_t coding_type = data->segments[0]->coding_type; + + /* save data */ + channel_layout = data->segments[0]->channel_layout; + num_samples = 0; + loop_start = 0; + loop_end = 0; + sample_rate = 0; + for (i = 0; i < data->segment_count; i++) { + /* needs get_samples since element may use play settings */ + int32_t segment_samples = vgmstream_get_samples(data->segments[i]); + int segment_rate = data->segments[i]->sample_rate; + + if (loop_flag && i == loop_start_segment) + loop_start = num_samples; + + num_samples += segment_samples; + + if (loop_flag && i == loop_end_segment) + loop_end = num_samples; + + /* inherit first segment's layout but only if all segments' layout match */ + if (channel_layout != 0 && channel_layout != data->segments[i]->channel_layout) + channel_layout = 0; + + if (sample_rate < segment_rate) + sample_rate = segment_rate; + + if (coding_type == coding_SILENCE) + coding_type = data->segments[i]->coding_type; + } + + /* respect loop_flag even when no loop_end found as it's possible file loops are set outside */ + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(data->output_channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = data->segments[0]->meta_type; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + vgmstream->coding_type = coding_type; + vgmstream->channel_layout = channel_layout; + + vgmstream->layout_type = layout_segmented; + vgmstream->layout_data = data; + + return vgmstream; + +fail: + if (vgmstream) vgmstream->layout_data = NULL; + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/util/layout_utils.h b/src/util/layout_utils.h index fca8df652..cdf850df1 100644 --- a/src/util/layout_utils.h +++ b/src/util/layout_utils.h @@ -2,6 +2,7 @@ #define _LAYOUTS_UTIL_H #include "../vgmstream.h" +#include "../layout/layout.h" typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*); @@ -18,4 +19,7 @@ bool layered_add_codec(VGMSTREAM* vs, int layers, int layer_channels); /* call when done adding layers */ bool layered_add_done(VGMSTREAM* vs); + +VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data); +VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment); #endif From cfcca4e662080d2b80033132a0158404172c396e Mon Sep 17 00:00:00 2001 From: bnnm Date: Wed, 7 Aug 2024 23:39:57 +0200 Subject: [PATCH 08/17] cleanup: fix minor compiler warnings --- src/coding/atrac9_decoder.c | 42 +++++++++++++++--------------- src/coding/celt_fsb_decoder.c | 2 +- src/coding/coding.h | 4 +-- src/coding/mpeg_decoder.c | 4 +-- src/coding/vorbis_custom_decoder.c | 4 +-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/coding/atrac9_decoder.c b/src/coding/atrac9_decoder.c index 4e5849250..4fe86eb9a 100644 --- a/src/coding/atrac9_decoder.c +++ b/src/coding/atrac9_decoder.c @@ -50,9 +50,9 @@ atrac9_codec_data* init_atrac9(atrac9_config* cfg) { /* must hold at least one superframe and its samples */ data->data_buffer_size = data->info.superframeSize; /* extra leeway as Atrac9Decode seems to overread ~2 bytes (doesn't affect decoding though) */ - data->data_buffer = calloc(sizeof(uint8_t), data->data_buffer_size + 0x10); - /* while ATRAC9 uses float internally, Sony's API only return PCM16 */ - data->sample_buffer = calloc(sizeof(sample_t), data->info.channels * data->info.frameSamples * data->info.framesInSuperframe); + data->data_buffer = calloc(data->data_buffer_size + 0x10, sizeof(uint8_t)); + /* while ATRAC9 uses float internally, Sony's API only returns PCM16 */ + data->sample_buffer = calloc(data->info.channels * data->info.frameSamples * data->info.framesInSuperframe, sizeof(sample_t)); data->samples_to_discard = cfg->encoder_delay; @@ -221,7 +221,7 @@ void free_atrac9(atrac9_codec_data* data) { } -static int atrac9_parse_config(uint32_t atrac9_config, int *out_sample_rate, int *out_channels, size_t *out_frame_size, size_t *out_samples_per_frame) { +static int atrac9_parse_config(uint32_t config_data, int* p_sample_rate, int* p_channels, size_t* p_frame_size, size_t* p_samples_per_frame) { static const int sample_rate_table[16] = { 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 44100, 48000, 64000, 88200, 96000,128000,176400,192000 @@ -235,13 +235,13 @@ static int atrac9_parse_config(uint32_t atrac9_config, int *out_sample_rate, int }; int superframe_size, frames_per_superframe, samples_per_frame, samples_per_superframe; - uint32_t sync = (atrac9_config >> 24) & 0xff; /* 8b */ - uint8_t sample_rate_index = (atrac9_config >> 20) & 0x0f; /* 4b */ - uint8_t channels_index = (atrac9_config >> 17) & 0x07; /* 3b */ - /* uint8_t validation bit = (atrac9_config >> 16) & 0x01; */ /* 1b */ - size_t frame_size = (atrac9_config >> 5) & 0x7FF; /* 11b */ - size_t superframe_index = (atrac9_config >> 3) & 0x3; /* 2b */ - /* uint8_t unused = (atrac9_config >> 0) & 0x7);*/ /* 3b */ + uint32_t sync = (config_data >> 24) & 0xff; /* 8b */ + uint8_t sample_rate_index = (config_data >> 20) & 0x0f; /* 4b */ + uint8_t channels_index = (config_data >> 17) & 0x07; /* 3b */ + /* uint8_t validation bit = (config_data >> 16) & 0x01; */ /* 1b */ + size_t frame_size = (config_data >> 5) & 0x7FF; /* 11b */ + size_t superframe_index = (config_data >> 3) & 0x3; /* 2b */ + /* uint8_t unused = (config_data >> 0) & 0x7);*/ /* 3b */ superframe_size = ((frame_size+1) << superframe_index); frames_per_superframe = (1 << superframe_index); @@ -250,14 +250,14 @@ static int atrac9_parse_config(uint32_t atrac9_config, int *out_sample_rate, int if (sync != 0xFE) goto fail; - if (out_sample_rate) - *out_sample_rate = sample_rate_table[sample_rate_index]; - if (out_channels) - *out_channels = channel_table[channels_index]; - if (out_frame_size) - *out_frame_size = superframe_size; - if (out_samples_per_frame) - *out_samples_per_frame = samples_per_superframe; + if (p_sample_rate) + *p_sample_rate = sample_rate_table[sample_rate_index]; + if (p_channels) + *p_channels = channel_table[channels_index]; + if (p_frame_size) + *p_frame_size = superframe_size; + if (p_samples_per_frame) + *p_samples_per_frame = samples_per_superframe; return 1; fail: @@ -268,9 +268,9 @@ size_t atrac9_bytes_to_samples(size_t bytes, atrac9_codec_data* data) { return bytes / data->info.superframeSize * (data->info.frameSamples * data->info.framesInSuperframe); } -size_t atrac9_bytes_to_samples_cfg(size_t bytes, uint32_t atrac9_config) { +size_t atrac9_bytes_to_samples_cfg(size_t bytes, uint32_t config_data) { size_t frame_size, samples_per_frame; - if (!atrac9_parse_config(atrac9_config, NULL, NULL, &frame_size, &samples_per_frame)) + if (!atrac9_parse_config(config_data, NULL, NULL, &frame_size, &samples_per_frame)) return 0; return bytes / frame_size * samples_per_frame; } diff --git a/src/coding/celt_fsb_decoder.c b/src/coding/celt_fsb_decoder.c index 09e548ee1..bf31a15d6 100644 --- a/src/coding/celt_fsb_decoder.c +++ b/src/coding/celt_fsb_decoder.c @@ -67,7 +67,7 @@ celt_codec_data* init_celt_fsb(int channels, celt_lib_t version) { goto fail; } - data->sample_buffer = calloc(sizeof(sample), data->channel_mode * FSB_CELT_SAMPLES_PER_FRAME); + data->sample_buffer = calloc(data->channel_mode * FSB_CELT_SAMPLES_PER_FRAME, sizeof(sample_t)); if (!data->sample_buffer) goto fail; /* there is ~128 samples of encoder delay, but FMOD DLLs don't discard it? */ diff --git a/src/coding/coding.h b/src/coding/coding.h index 33d09bad4..2adb81f85 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -592,7 +592,7 @@ void reset_atrac9(atrac9_codec_data* data); 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); +size_t atrac9_bytes_to_samples_cfg(size_t bytes, uint32_t config_data); #endif @@ -767,4 +767,4 @@ int mpc_get_samples(STREAMFILE* sf, off_t offset, int32_t* p_samples, int32_t* p /* helper to pass a wrapped, clamped, fake extension-ed, SF to another meta */ STREAMFILE* setup_subfile_streamfile(STREAMFILE* sf, offv_t subfile_offset, size_t subfile_size, const char* extension); -#endif /*_CODING_H*/ +#endif diff --git a/src/coding/mpeg_decoder.c b/src/coding/mpeg_decoder.c index 2a25c0759..e5a404246 100644 --- a/src/coding/mpeg_decoder.c +++ b/src/coding/mpeg_decoder.c @@ -23,7 +23,7 @@ mpeg_codec_data* init_mpeg(STREAMFILE* sf, off_t start_offset, coding_t* coding_ if (!data) goto fail; data->buffer_size = MPEG_DATA_BUFFER_SIZE; - data->buffer = calloc(sizeof(uint8_t), data->buffer_size); + data->buffer = calloc(data->buffer_size, sizeof(uint8_t)); if (!data->buffer) goto fail; data->m = init_mpg123_handle(); @@ -176,7 +176,7 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* /* one per stream as sometimes mpg123 can't read the whole buffer in one pass */ data->streams[i].buffer_size = data->default_buffer_size; - data->streams[i].buffer = calloc(sizeof(uint8_t), data->streams[i].buffer_size); + data->streams[i].buffer = calloc(data->streams[i].buffer_size, sizeof(uint8_t)); if (!data->streams[i].buffer) goto fail; data->streams[i].channels_per_frame = data->channels_per_frame; diff --git a/src/coding/vorbis_custom_decoder.c b/src/coding/vorbis_custom_decoder.c index cfcf12f19..2a5b666a8 100644 --- a/src/coding/vorbis_custom_decoder.c +++ b/src/coding/vorbis_custom_decoder.c @@ -23,11 +23,11 @@ vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset, int ok; /* init stuff */ - data = calloc(1,sizeof(vorbis_custom_codec_data)); + data = calloc(1, sizeof(vorbis_custom_codec_data)); if (!data) goto fail; data->buffer_size = VORBIS_DEFAULT_BUFFER_SIZE; - data->buffer = calloc(sizeof(uint8_t), data->buffer_size); + data->buffer = calloc(data->buffer_size, sizeof(uint8_t)); if (!data->buffer) goto fail; /* keep around to decode too */ From 66280992554b92609f335fe4ac2abf039e1935c4 Mon Sep 17 00:00:00 2001 From: bnnm Date: Thu, 8 Aug 2024 00:24:40 +0200 Subject: [PATCH 09/17] cleanup: fix minor compiler warnings --- src/coding/acm_decoder.c | 12 +- src/coding/atrac9_decoder.c | 4 +- src/coding/celt_fsb_decoder.c | 4 +- src/coding/derf_decoder.c | 2 +- src/coding/ea_xas_decoder.c | 2 +- src/coding/ffmpeg_decoder_utils.c | 12 +- src/coding/g721_decoder.c | 572 ++++++++++++------------ src/coding/hca_decoder.c | 4 +- src/coding/ima_decoder.c | 4 +- src/coding/libs/nwa_lib.c | 2 +- src/coding/mp4_aac_decoder.c | 6 +- src/coding/mpeg_custom_utils_ealayer3.c | 10 +- src/coding/mpeg_custom_utils_eamp3.c | 6 +- src/coding/mpeg_decoder.c | 18 +- src/coding/ogg_vorbis_decoder.c | 4 +- src/coding/relic_decoder.c | 2 +- src/coding/sassc_decoder.c | 27 +- src/coding/ubi_adpcm_decoder.c | 4 +- src/coding/vorbis_custom_decoder.c | 2 +- src/streamtypes.h | 1 - 20 files changed, 348 insertions(+), 350 deletions(-) diff --git a/src/coding/acm_decoder.c b/src/coding/acm_decoder.c index 2261aa3f0..5d433506b 100644 --- a/src/coding/acm_decoder.c +++ b/src/coding/acm_decoder.c @@ -2,7 +2,7 @@ #include "libs/libacm.h" #include -/* libacm 1.2 (despite what libacm.h says) from: https://github.com/markokr/libacm */ +/* libacm 1.2 (despite libacm.h saying 1.1) from: https://github.com/markokr/libacm */ /* libacm interface */ @@ -26,10 +26,10 @@ acm_codec_data* init_acm(STREAMFILE* sf, int force_channel_number) { acm_codec_data* data = NULL; - data = calloc(1,sizeof(acm_codec_data)); + data = calloc(1, sizeof(acm_codec_data)); if (!data) goto fail; - data->io_config = calloc(1,sizeof(acm_io_config)); + data->io_config = calloc(1, sizeof(acm_io_config)); if (!data->io_config) goto fail; data->streamfile = reopen_streamfile(sf, 0); @@ -74,12 +74,12 @@ void decode_acm(acm_codec_data* data, sample_t* outbuf, int32_t samples_to_do, i while (samples_read < samples_to_do) { int32_t bytes_read_just_now = acm_read( acm, - (char*)(outbuf+samples_read*channelspacing), - (samples_to_do-samples_read)*sizeof(sample)*channelspacing, + (char*)(outbuf + samples_read * channelspacing), + (samples_to_do - samples_read) * sizeof(sample_t) * channelspacing, 0,2,1); if (bytes_read_just_now > 0) { - samples_read += bytes_read_just_now/sizeof(sample)/channelspacing; + samples_read += bytes_read_just_now / sizeof(sample_t) / channelspacing; } else { return; } diff --git a/src/coding/atrac9_decoder.c b/src/coding/atrac9_decoder.c index 4fe86eb9a..48ae132e8 100644 --- a/src/coding/atrac9_decoder.c +++ b/src/coding/atrac9_decoder.c @@ -89,7 +89,7 @@ void decode_atrac9(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do memcpy(outbuf + samples_done*channels, data->sample_buffer + data->samples_used*channels, - samples_to_get*channels * sizeof(sample)); + samples_to_get*channels * sizeof(sample_t)); samples_done += samples_to_get; } @@ -131,7 +131,7 @@ void decode_atrac9(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do decode_fail: /* on error just put some 0 samples */ VGM_LOG("ATRAC9: decode fail at %x, missing %i samples\n", (uint32_t)stream->offset, (samples_to_do - samples_done)); - memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample) * channels); + memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample_t) * channels); } void reset_atrac9(atrac9_codec_data* data) { diff --git a/src/coding/celt_fsb_decoder.c b/src/coding/celt_fsb_decoder.c index bf31a15d6..27308a32d 100644 --- a/src/coding/celt_fsb_decoder.c +++ b/src/coding/celt_fsb_decoder.c @@ -103,7 +103,7 @@ void decode_celt_fsb(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_ memcpy(outbuf + samples_done*channels, data->sample_buffer + data->samples_used*channels, - samples_to_get*channels * sizeof(sample)); + samples_to_get*channels * sizeof(sample_t)); samples_done += samples_to_get; } @@ -158,7 +158,7 @@ void decode_celt_fsb(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_ decode_fail: /* on error just put some 0 samples */ VGM_LOG("CELT: decode fail at %x, missing %i samples\n", (uint32_t)stream->offset, (samples_to_do - samples_done)); - memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample) * channels); + memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample_t) * channels); } void reset_celt_fsb(celt_codec_data* data) { diff --git a/src/coding/derf_decoder.c b/src/coding/derf_decoder.c index 08cc55d3d..f3c529b38 100644 --- a/src/coding/derf_decoder.c +++ b/src/coding/derf_decoder.c @@ -18,7 +18,7 @@ static const int derf_steps[96] = { }; /* Xilam DERF DPCM for Stupid Invaders (PC), decompiled from the exe */ -void decode_derf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { +void decode_derf(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { int i, sample_pos = 0, index; int32_t hist = stream->adpcm_history1_32; off_t frame_offset = stream->offset; /* frame size is 1 */ diff --git a/src/coding/ea_xas_decoder.c b/src/coding/ea_xas_decoder.c index 705d9b883..4de6c42dd 100644 --- a/src/coding/ea_xas_decoder.c +++ b/src/coding/ea_xas_decoder.c @@ -113,7 +113,7 @@ void decode_ea_xas_v1(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspa /* EA-XAS v0 (xas0), without complex layouts and closer to EA-XA. Somewhat based on daemon1's decoder. */ -void decode_ea_xas_v0(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { +void decode_ea_xas_v0(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { uint8_t frame[0x13] = {0}; off_t frame_offset; int frames_in, samples_done = 0, sample_count = 0; diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c index 571134942..b048dcb14 100644 --- a/src/coding/ffmpeg_decoder_utils.c +++ b/src/coding/ffmpeg_decoder_utils.c @@ -22,7 +22,7 @@ static int ffmpeg_make_riff_atrac3(uint8_t* buf, size_t buf_size, size_t sample_ put_u16le(buf+0x14, 0x0270); /* ATRAC3 codec */ put_u16le(buf+0x16, channels); put_u32le(buf+0x18, sample_rate); - put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong) */ + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong) */ put_u16le(buf+0x20, block_align); /* block align */ put_u16le(buf+0x24, 0x0e); /* extra data size */ @@ -215,7 +215,7 @@ static int ffmpeg_make_riff_atrac3plus(uint8_t* buf, int buf_size, uint32_t data put_u16le(buf+0x14, 0xfffe); /* WAVEFORMATEXTENSIBLE */ put_u16le(buf+0x16, channels); put_u32le(buf+0x18, sample_rate); - put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong) */ + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong) */ put_u32le(buf+0x20, block_align); /* block align */ put_u16le(buf+0x24, 0x22); /* extra data size */ @@ -417,7 +417,7 @@ static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size } } - put_u32le(buf+off+0x00, sample_rate*stream_channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ + put_u32le(buf+off+0x00, sample_rate*stream_channels / sizeof(sample_t)); /* average bytes per second (wrong, unneeded) */ put_u32le(buf+off+0x04, sample_rate); put_u32le(buf+off+0x08, 0); /* loop start */ put_u32le(buf+off+0x0c, 0); /* loop end */ @@ -477,7 +477,7 @@ static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size default: speakers = 0; break; } - bytecount = sample_count * channels * sizeof(sample); + bytecount = sample_count * channels * sizeof(sample_t); memcpy (buf+0x00, "RIFF", 0x04); put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ @@ -488,8 +488,8 @@ static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size put_u16le(buf+0x14, 0x0166); /* XMA2 */ put_u16le(buf+0x16, channels); put_u32le(buf+0x18, sample_rate); - put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ - put_u16le(buf+0x20, (uint16_t)(channels * sizeof(sample))); /* block align */ + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong, unneeded) */ + put_u16le(buf+0x20, (uint16_t)(channels * sizeof(sample_t))); /* block align */ put_u16le(buf+0x22, 16); /* bits per sample */ put_u16le(buf+0x24, 0x22); /* extra data size */ diff --git a/src/coding/g721_decoder.c b/src/coding/g721_decoder.c index c035a2239..8ba6a7bba 100644 --- a/src/coding/g721_decoder.c +++ b/src/coding/g721_decoder.c @@ -65,24 +65,24 @@ quan( */ static int fmult( - int an, - int srn) + int an, + int srn) { - short anmag, anexp, anmant; - short wanexp, wanmant; - short retval; + short anmag, anexp, anmant; + short wanexp, wanmant; + short retval; - anmag = (an > 0) ? an : ((-an) & 0x1FFF); - anexp = quan(anmag, power2, 15) - 6; - anmant = (anmag == 0) ? 32 : - (anexp >= 0) ? anmag >> anexp : anmag << -anexp; - wanexp = anexp + ((srn >> 6) & 0xF) - 13; + anmag = (an > 0) ? an : ((-an) & 0x1FFF); + anexp = quan(anmag, power2, 15) - 6; + anmant = (anmag == 0) ? 32 : + (anexp >= 0) ? anmag >> anexp : anmag << -anexp; + wanexp = anexp + ((srn >> 6) & 0xF) - 13; - wanmant = (anmant * (srn & 077) + 0x30) >> 4; - retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : - (wanmant >> -wanexp); + wanmant = (anmant * (srn & 077) + 0x30) >> 4; + retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : + (wanmant >> -wanexp); - return (((an ^ srn) < 0) ? -retval : retval); + return (((an ^ srn) < 0) ? -retval : retval); } /* @@ -94,25 +94,25 @@ fmult( */ void g72x_init_state( - struct g72x_state *state_ptr) + struct g72x_state *state_ptr) { - int cnta; - - state_ptr->yl = 34816; - state_ptr->yu = 544; - state_ptr->dms = 0; - state_ptr->dml = 0; - state_ptr->ap = 0; - for (cnta = 0; cnta < 2; cnta++) { - state_ptr->a[cnta] = 0; - state_ptr->pk[cnta] = 0; - state_ptr->sr[cnta] = 32; - } - for (cnta = 0; cnta < 6; cnta++) { - state_ptr->b[cnta] = 0; - state_ptr->dq[cnta] = 32; - } - state_ptr->td = 0; + int cnta; + + state_ptr->yl = 34816; + state_ptr->yu = 544; + state_ptr->dms = 0; + state_ptr->dml = 0; + state_ptr->ap = 0; + for (cnta = 0; cnta < 2; cnta++) { + state_ptr->a[cnta] = 0; + state_ptr->pk[cnta] = 0; + state_ptr->sr[cnta] = 32; + } + for (cnta = 0; cnta < 6; cnta++) { + state_ptr->b[cnta] = 0; + state_ptr->dq[cnta] = 32; + } + state_ptr->td = 0; } /* @@ -123,15 +123,15 @@ g72x_init_state( */ static int predictor_zero( - struct g72x_state *state_ptr) + struct g72x_state *state_ptr) { - int i; - int sezi; + int i; + int sezi; - sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); - for (i = 1; i < 6; i++) /* ACCUM */ - sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); - return (sezi); + sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); + for (i = 1; i < 6; i++) /* ACCUM */ + sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); + return (sezi); } /* * predictor_pole() @@ -141,10 +141,10 @@ predictor_zero( */ static int predictor_pole( - struct g72x_state *state_ptr) + struct g72x_state *state_ptr) { - return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + - fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); + return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + + fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); } /* * step_size() @@ -154,24 +154,24 @@ predictor_pole( */ static int step_size( - struct g72x_state *state_ptr) + struct g72x_state *state_ptr) { - int y; - int dif; - int al; - - if (state_ptr->ap >= 256) - return (state_ptr->yu); - else { - y = state_ptr->yl >> 6; - dif = state_ptr->yu - y; - al = state_ptr->ap >> 2; - if (dif > 0) - y += (dif * al) >> 6; - else if (dif < 0) - y += (dif * al + 0x3F) >> 6; - return (y); - } + int y; + int dif; + int al; + + if (state_ptr->ap >= 256) + return (state_ptr->yu); + else { + y = state_ptr->yl >> 6; + dif = state_ptr->yu - y; + al = state_ptr->ap >> 2; + if (dif > 0) + y += (dif * al) >> 6; + else if (dif < 0) + y += (dif * al + 0x3F) >> 6; + return (y); + } } /* @@ -183,25 +183,25 @@ step_size( */ static int reconstruct( - int sign, /* 0 for non-negative value */ - int dqln, /* G.72x codeword */ - int y) /* Step size multiplier */ + int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y) /* Step size multiplier */ { - short dql; /* Log of 'dq' magnitude */ - short dex; /* Integer part of log */ - short dqt; - short dq; /* Reconstructed difference signal sample */ - - dql = dqln + (y >> 2); /* ADDA */ - - if (dql < 0) { - return ((sign) ? -0x8000 : 0); - } else { /* ANTILOG */ - dex = (dql >> 7) & 15; - dqt = 128 + (dql & 127); - dq = (dqt << 7) >> (14 - dex); - return ((sign) ? (dq - 0x8000) : dq); - } + short dql; /* Log of 'dq' magnitude */ + short dex; /* Integer part of log */ + short dqt; + short dq; /* Reconstructed difference signal sample */ + + dql = dqln + (y >> 2); /* ADDA */ + + if (dql < 0) { + return ((sign) ? -0x8000 : 0); + } else { /* ANTILOG */ + dex = (dql >> 7) & 15; + dqt = 128 + (dql & 127); + dq = (dqt << 7) >> (14 - dex); + return ((sign) ? (dq - 0x8000) : dq); + } } @@ -212,212 +212,212 @@ reconstruct( */ static void update( - /*int code_size,*/ /* distinguish 723_40 with others */ - int y, /* quantizer step size */ - int wi, /* scale factor multiplier */ - int fi, /* for long/short term energies */ - int dq, /* quantized prediction difference */ - int sr, /* reconstructed signal */ - int dqsez, /* difference from 2-pole predictor */ - struct g72x_state *state_ptr) /* coder state pointer */ + /*int code_size,*/ /* distinguish 723_40 with others */ + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez, /* difference from 2-pole predictor */ + struct g72x_state *state_ptr) /* coder state pointer */ { - int cnt; - short mag, exp; /* Adaptive predictor, FLOAT A */ - short a2p; /* LIMC */ - short a1ul; /* UPA1 */ - short pks1; /* UPA2 */ - short fa1; - char tr; /* tone/transition detector */ - short ylint, thr2, dqthr; - short ylfrac, thr1; - short pk0; - - pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ - - mag = dq & 0x7FFF; /* prediction difference magnitude */ - /* TRANS */ - ylint = state_ptr->yl >> 15; /* exponent part of yl */ - ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ - thr1 = (32 + ylfrac) << ylint; /* threshold */ - thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ - dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ - if (state_ptr->td == 0) /* signal supposed voice */ - tr = 0; - else if (mag <= dqthr) /* supposed data, but small mag */ - tr = 0; /* treated as voice */ - else /* signal is data (modem) */ - tr = 1; - - /* - * Quantizer scale factor adaptation. - */ - - /* FUNCTW & FILTD & DELAY */ - /* update non-steady state step size multiplier */ - state_ptr->yu = y + ((wi - y) >> 5); - - /* LIMB */ - if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ - state_ptr->yu = 544; - else if (state_ptr->yu > 5120) - state_ptr->yu = 5120; - - /* FILTE & DELAY */ - /* update steady state step size multiplier */ - state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); - - /* - * Adaptive predictor coefficients. - */ - if (tr == 1) { /* reset a's and b's for modem signal */ - state_ptr->a[0] = 0; - state_ptr->a[1] = 0; - state_ptr->b[0] = 0; - state_ptr->b[1] = 0; - state_ptr->b[2] = 0; - state_ptr->b[3] = 0; - state_ptr->b[4] = 0; - state_ptr->b[5] = 0; + int cnt; + short mag, exp; /* Adaptive predictor, FLOAT A */ + short a2p; /* LIMC */ + short a1ul; /* UPA1 */ + short pks1; /* UPA2 */ + short fa1; + char tr; /* tone/transition detector */ + short ylint, thr2, dqthr; + short ylfrac, thr1; + short pk0; + + pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ + + mag = dq & 0x7FFF; /* prediction difference magnitude */ + /* TRANS */ + ylint = state_ptr->yl >> 15; /* exponent part of yl */ + ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ + thr1 = (32 + ylfrac) << ylint; /* threshold */ + thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ + dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ + if (state_ptr->td == 0) /* signal supposed voice */ + tr = 0; + else if (mag <= dqthr) /* supposed data, but small mag */ + tr = 0; /* treated as voice */ + else /* signal is data (modem) */ + tr = 1; + + /* + * Quantizer scale factor adaptation. + */ + + /* FUNCTW & FILTD & DELAY */ + /* update non-steady state step size multiplier */ + state_ptr->yu = y + ((wi - y) >> 5); + + /* LIMB */ + if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ + state_ptr->yu = 544; + else if (state_ptr->yu > 5120) + state_ptr->yu = 5120; + + /* FILTE & DELAY */ + /* update steady state step size multiplier */ + state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); + + /* + * Adaptive predictor coefficients. + */ + if (tr == 1) { /* reset a's and b's for modem signal */ + state_ptr->a[0] = 0; + state_ptr->a[1] = 0; + state_ptr->b[0] = 0; + state_ptr->b[1] = 0; + state_ptr->b[2] = 0; + state_ptr->b[3] = 0; + state_ptr->b[4] = 0; + state_ptr->b[5] = 0; a2p=0; /* won't be used, clear warning */ - } else { /* update a's and b's */ - pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ - - /* update predictor pole a[1] */ - a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); - if (dqsez != 0) { - fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; - if (fa1 < -8191) /* a2p = function of fa1 */ - a2p -= 0x100; - else if (fa1 > 8191) - a2p += 0xFF; - else - a2p += fa1 >> 5; - - if (pk0 ^ state_ptr->pk[1]) - /* LIMC */ - if (a2p <= -12160) - a2p = -12288; - else if (a2p >= 12416) - a2p = 12288; - else - a2p -= 0x80; - else if (a2p <= -12416) - a2p = -12288; - else if (a2p >= 12160) - a2p = 12288; - else - a2p += 0x80; - } - - /* TRIGB & DELAY */ - state_ptr->a[1] = a2p; - - /* UPA1 */ - /* update predictor pole a[0] */ - state_ptr->a[0] -= state_ptr->a[0] >> 8; - if (dqsez != 0) { - if (pks1 == 0) - state_ptr->a[0] += 192; - else - state_ptr->a[0] -= 192; + } else { /* update a's and b's */ + pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ + + /* update predictor pole a[1] */ + a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); + if (dqsez != 0) { + fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; + if (fa1 < -8191) /* a2p = function of fa1 */ + a2p -= 0x100; + else if (fa1 > 8191) + a2p += 0xFF; + else + a2p += fa1 >> 5; + + if (pk0 ^ state_ptr->pk[1]) + /* LIMC */ + if (a2p <= -12160) + a2p = -12288; + else if (a2p >= 12416) + a2p = 12288; + else + a2p -= 0x80; + else if (a2p <= -12416) + a2p = -12288; + else if (a2p >= 12160) + a2p = 12288; + else + a2p += 0x80; + } + + /* TRIGB & DELAY */ + state_ptr->a[1] = a2p; + + /* UPA1 */ + /* update predictor pole a[0] */ + state_ptr->a[0] -= state_ptr->a[0] >> 8; + if (dqsez != 0) { + if (pks1 == 0) + state_ptr->a[0] += 192; + else + state_ptr->a[0] -= 192; } - /* LIMD */ - a1ul = 15360 - a2p; - if (state_ptr->a[0] < -a1ul) - state_ptr->a[0] = -a1ul; - else if (state_ptr->a[0] > a1ul) - state_ptr->a[0] = a1ul; - - /* UPB : update predictor zeros b[6] */ - for (cnt = 0; cnt < 6; cnt++) { - /*if (code_size == 5)*/ /* for 40Kbps G.723 */ - /* state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;*/ - /*else*/ /* for G.721 and 24Kbps G.723 */ - state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; - if (dq & 0x7FFF) { /* XOR */ - if ((dq ^ state_ptr->dq[cnt]) >= 0) - state_ptr->b[cnt] += 128; - else - state_ptr->b[cnt] -= 128; - } - } - } - - for (cnt = 5; cnt > 0; cnt--) - state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; - /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ - if (mag == 0) { - state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; - } else { - exp = quan(mag, power2, 15); - state_ptr->dq[0] = (dq >= 0) ? - (exp << 6) + ((mag << 6) >> exp) : - (exp << 6) + ((mag << 6) >> exp) - 0x400; - } - - state_ptr->sr[1] = state_ptr->sr[0]; - /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ - if (sr == 0) { - state_ptr->sr[0] = 0x20; - } else if (sr > 0) { - exp = quan(sr, power2, 15); - state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); - } else if (sr > -32768) { - mag = -sr; - exp = quan(mag, power2, 15); - state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; - } else - state_ptr->sr[0] = 0xFC20; - - /* DELAY A */ - state_ptr->pk[1] = state_ptr->pk[0]; - state_ptr->pk[0] = pk0; - - /* TONE */ - if (tr == 1) /* this sample has been treated as data */ - state_ptr->td = 0; /* next one will be treated as voice */ - else if (a2p < -11776) /* small sample-to-sample correlation */ - state_ptr->td = 1; /* signal may be data */ - else /* signal is voice */ - state_ptr->td = 0; - - /* - * Adaptation speed control. - */ - state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ - state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ - - if (tr == 1) - state_ptr->ap = 256; - else if (y < 1536) /* SUBTC */ - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else if (state_ptr->td == 1) - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= - (state_ptr->dml >> 3)) - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else - state_ptr->ap += (-state_ptr->ap) >> 4; + /* LIMD */ + a1ul = 15360 - a2p; + if (state_ptr->a[0] < -a1ul) + state_ptr->a[0] = -a1ul; + else if (state_ptr->a[0] > a1ul) + state_ptr->a[0] = a1ul; + + /* UPB : update predictor zeros b[6] */ + for (cnt = 0; cnt < 6; cnt++) { + /*if (code_size == 5)*/ /* for 40Kbps G.723 */ + /* state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;*/ + /*else*/ /* for G.721 and 24Kbps G.723 */ + state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; + if (dq & 0x7FFF) { /* XOR */ + if ((dq ^ state_ptr->dq[cnt]) >= 0) + state_ptr->b[cnt] += 128; + else + state_ptr->b[cnt] -= 128; + } + } + } + + for (cnt = 5; cnt > 0; cnt--) + state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; + /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ + if (mag == 0) { + state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; + } else { + exp = quan(mag, power2, 15); + state_ptr->dq[0] = (dq >= 0) ? + (exp << 6) + ((mag << 6) >> exp) : + (exp << 6) + ((mag << 6) >> exp) - 0x400; + } + + state_ptr->sr[1] = state_ptr->sr[0]; + /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ + if (sr == 0) { + state_ptr->sr[0] = 0x20; + } else if (sr > 0) { + exp = quan(sr, power2, 15); + state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); + } else if (sr > -32768) { + mag = -sr; + exp = quan(mag, power2, 15); + state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; + } else + state_ptr->sr[0] = 0xFC20; + + /* DELAY A */ + state_ptr->pk[1] = state_ptr->pk[0]; + state_ptr->pk[0] = pk0; + + /* TONE */ + if (tr == 1) /* this sample has been treated as data */ + state_ptr->td = 0; /* next one will be treated as voice */ + else if (a2p < -11776) /* small sample-to-sample correlation */ + state_ptr->td = 1; /* signal may be data */ + else /* signal is voice */ + state_ptr->td = 0; + + /* + * Adaptation speed control. + */ + state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ + state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ + + if (tr == 1) + state_ptr->ap = 256; + else if (y < 1536) /* SUBTC */ + state_ptr->ap += (0x200 - state_ptr->ap) >> 4; + else if (state_ptr->td == 1) + state_ptr->ap += (0x200 - state_ptr->ap) >> 4; + else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= + (state_ptr->dml >> 3)) + state_ptr->ap += (0x200 - state_ptr->ap) >> 4; + else + state_ptr->ap += (-state_ptr->ap) >> 4; } /* * Maps G.721 code word to reconstructed scale factor normalized log * magnitude values. */ -static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, - 425, 373, 323, 273, 213, 135, 4, -2048}; +static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, -2048}; /* Maps G.721 code word to log of scale factor multiplier. */ -static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, - 1122, 355, 198, 112, 64, 41, 18, -12}; +static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12}; /* * Maps G.721 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ -static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, - 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; +static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, + 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; /* * g721_decoder() * @@ -429,39 +429,39 @@ static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, */ static int g721_decoder( - int i, - struct g72x_state *state_ptr) + int i, + struct g72x_state *state_ptr) { - short sezi, sei, sez, se; /* ACCUM */ - short y; /* MIX */ - short sr; /* ADDB */ - short dq; - short dqsez; + short sezi, sei, sez, se; /* ACCUM */ + short y; /* MIX */ + short sr; /* ADDB */ + short dq; + short dqsez; - i &= 0x0f; /* mask to get proper bits */ - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ + i &= 0x0f; /* mask to get proper bits */ + sezi = predictor_zero(state_ptr); + sez = sezi >> 1; + sei = sezi + predictor_pole(state_ptr); + se = sei >> 1; /* se = estimated signal */ - y = step_size(state_ptr); /* dynamic quantizer step size */ + y = step_size(state_ptr); /* dynamic quantizer step size */ - dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ + dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ - sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ - dqsez = sr - se + sez; /* pole prediction diff. */ + dqsez = sr - se + sez; /* pole prediction diff. */ - update(y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); + update(y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); - return (sr << 2); /* sr was 14-bit dynamic range */ + return (sr << 2); /* sr was 14-bit dynamic range */ } -void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { +void decode_g721(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { int i; int32_t sample_count; - for (i=first_sample,sample_count=0; ioffset+i/2,stream->streamfile)>>(i&1?4:0), diff --git a/src/coding/hca_decoder.c b/src/coding/hca_decoder.c index b75868912..d3dc56629 100644 --- a/src/coding/hca_decoder.c +++ b/src/coding/hca_decoder.c @@ -95,7 +95,7 @@ void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do) { memcpy(outbuf + samples_done*channels, data->sample_buffer + data->samples_consumed*channels, - samples_to_get*channels * sizeof(sample)); + samples_to_get*channels * sizeof(sample_t)); samples_done += samples_to_get; } @@ -110,7 +110,7 @@ void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do) { /* EOF/error */ if (data->current_block >= data->info.blockCount) { - memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample)); + memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t)); break; } diff --git a/src/coding/ima_decoder.c b/src/coding/ima_decoder.c index d7180d4d0..6bff9c2cf 100644 --- a/src/coding/ima_decoder.c +++ b/src/coding/ima_decoder.c @@ -1113,14 +1113,14 @@ void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspa /* write PCM samples, must be written to match header's num_samples (hist mustn't) */ max_samples_to_do = ((samples_to_do > header_samples) ? header_samples : samples_to_do); for (i = first_sample; i < max_samples_to_do; i++, sample_count += channelspacing) { - outbuf[sample_count] = read_16bit(offset + channel*sizeof(sample) + i*channelspacing*sizeof(sample),stream->streamfile); + outbuf[sample_count] = read_16bit(offset + channel * sizeof(sample_t) + i*channelspacing * sizeof(sample_t), stream->streamfile); first_sample++; samples_to_do--; } /* header done */ if (i == header_samples) { - stream->offset = offset + header_samples*channelspacing*sizeof(sample); + stream->offset = offset + header_samples*channelspacing * sizeof(sample_t); } } diff --git a/src/coding/libs/nwa_lib.c b/src/coding/libs/nwa_lib.c index d794c1726..442ed2301 100644 --- a/src/coding/libs/nwa_lib.c +++ b/src/coding/libs/nwa_lib.c @@ -205,7 +205,7 @@ static int getbits(const uint8_t** p_data, int* shift, int bits) { // NWADecode static void decode_block(NWAData* nwa, const uint8_t* data, int outdatasize) { - sample d[2]; + short d[2]; int i; int shift = 0; diff --git a/src/coding/mp4_aac_decoder.c b/src/coding/mp4_aac_decoder.c index 01cbf8caf..8b550293f 100644 --- a/src/coding/mp4_aac_decoder.c +++ b/src/coding/mp4_aac_decoder.c @@ -154,7 +154,7 @@ mp4_aac_codec_data* init_mp4_aac(STREAMFILE* sf) { } -static void convert_samples(INT_PCM * src, sample * dest, int32_t count) { +static void convert_samples(INT_PCM * src, sample_t* dest, int32_t count) { int32_t i; for ( i = 0; i < count; i++ ) { INT_PCM sample = *src++; @@ -164,7 +164,7 @@ static void convert_samples(INT_PCM * src, sample * dest, int32_t count) { } } -void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels) { +void decode_mp4_aac(mp4_aac_codec_data * data, sample_t* outbuf, int32_t samples_to_do, int channels) { int samples_done = 0; uint8_t * buffer = NULL; @@ -199,7 +199,7 @@ void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_ while ( samples_done < samples_to_do ) { if (data->sampleId >= data->numSamples) { - memset(outbuf, 0, (samples_to_do - samples_done) * stream_info->numChannels * sizeof(sample)); + memset(outbuf, 0, (samples_to_do - samples_done) * stream_info->numChannels * sizeof(sample_t)); break; } if (!MP4ReadSample( data->h_mp4file, data->track_id, ++data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) return; diff --git a/src/coding/mpeg_custom_utils_ealayer3.c b/src/coding/mpeg_custom_utils_ealayer3.c index 010931565..e86cc55e5 100644 --- a/src/coding/mpeg_custom_utils_ealayer3.c +++ b/src/coding/mpeg_custom_utils_ealayer3.c @@ -670,20 +670,20 @@ static void ealayer3_copy_pcm_block(uint8_t* outbuf, off_t pcm_offset, int pcm_n int16_t pcm_sample = get_s16be(pcm_block + pos); put_s16le(outbuf + pos, pcm_sample); - pos += sizeof(sample); + pos += sizeof(sample_t); } } else { /* all of ch0 first, then all of ch1 (EAL3 v1b only) */ int get_pos = 0; for (ch = 0; ch < channels_per_frame; ch++) { - int put_pos = sizeof(sample) * ch; + int put_pos = sizeof(sample_t) * ch; for (i = 0; i < pcm_number; i++) { int16_t pcm_sample = get_s16be(pcm_block + get_pos); put_s16le(outbuf + put_pos, pcm_sample); - get_pos += sizeof(sample); - put_pos += sizeof(sample) * channels_per_frame; + get_pos += sizeof(sample_t); + put_pos += sizeof(sample_t) * channels_per_frame; } } } @@ -697,7 +697,7 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d size_t bytes_filled; - bytes_filled = sizeof(sample) * ms->samples_filled * channels_per_frame; + bytes_filled = sizeof(sample_t) * ms->samples_filled * channels_per_frame; if (bytes_filled + eaf->pcm_size > ms->output_buffer_size) { VGM_LOG("EAL3: can't fill the sample buffer with 0x%x\n", eaf->pcm_size); goto fail; diff --git a/src/coding/mpeg_custom_utils_eamp3.c b/src/coding/mpeg_custom_utils_eamp3.c index 5993ac6dc..6b59e1e43 100644 --- a/src/coding/mpeg_custom_utils_eamp3.c +++ b/src/coding/mpeg_custom_utils_eamp3.c @@ -130,7 +130,7 @@ static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data int i; - bytes_filled = sizeof(sample) * ms->samples_filled * data->channels_per_frame; + bytes_filled = sizeof(sample_t) * ms->samples_filled * data->channels_per_frame; if (bytes_filled + eaf->pcm_size > ms->output_buffer_size) { VGM_LOG("EAMP3: can't fill the sample buffer with 0x%x\n", eaf->pcm_size); goto fail; @@ -141,9 +141,9 @@ static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data /* read + write PCM block samples (always LE) */ for (i = 0; i < eaf->pcm_number * data->channels_per_frame; i++) { - off_t pcm_offset = stream->offset + eaf->pre_size + eaf->mpeg_size + sizeof(sample)*i; + off_t pcm_offset = stream->offset + eaf->pre_size + eaf->mpeg_size + sizeof(sample_t)*i; int16_t pcm_sample = read_s16le(pcm_offset,stream->streamfile); - put_s16le(ms->output_buffer + bytes_filled + sizeof(sample) * i, pcm_sample); + put_s16le(ms->output_buffer + bytes_filled + sizeof(sample_t) * i, pcm_sample); } ms->samples_filled += eaf->pcm_number; diff --git a/src/coding/mpeg_decoder.c b/src/coding/mpeg_decoder.c index e5a404246..6363e258b 100644 --- a/src/coding/mpeg_decoder.c +++ b/src/coding/mpeg_decoder.c @@ -170,7 +170,7 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* if (!data->streams[i].handle) goto fail; /* size could be any value */ - data->streams[i].output_buffer_size = sizeof(sample) * data->channels_per_frame * data->samples_per_frame; + data->streams[i].output_buffer_size = sizeof(sample_t) * data->channels_per_frame * data->samples_per_frame; data->streams[i].output_buffer = calloc(data->streams[i].output_buffer_size, sizeof(uint8_t)); if (!data->streams[i].output_buffer) goto fail; @@ -260,7 +260,7 @@ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data /* end of stream, fill rest with 0s */ if (data->bytes_in_buffer <= 0) { VGM_ASSERT(samples_to_do < samples_done, "MPEG: end of stream, filling %i\n", (samples_to_do - samples_done)); - memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample)); + memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t)); break; } @@ -270,7 +270,7 @@ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data stream->offset += data->bytes_in_buffer; } - bytes_to_do = (samples_to_do-samples_done)*sizeof(sample)*channels; + bytes_to_do = (samples_to_do-samples_done)*sizeof(sample_t)*channels; /* feed new raw data to the decoder if needed, copy decoded results to output */ if (!data->buffer_used) { @@ -288,7 +288,7 @@ static void decode_mpeg_standard(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data VGM_ASSERT(rc != MPG123_NEED_MORE && rc != MPG123_OK, "MPEG: error %i\n", rc); /* update copied samples */ - samples_done += bytes_done/sizeof(sample)/channels; + samples_done += bytes_done / sizeof(sample_t) / channels; outbytes += bytes_done; } } @@ -430,7 +430,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* } - bytes_filled = sizeof(sample) * ms->samples_filled * channels_per_frame; + bytes_filled = sizeof(sample_t) * ms->samples_filled * channels_per_frame; /* feed new raw data to the decoder if needed, copy decoded results to frame buffer output */ if (!ms->buffer_used) { //;VGM_LOG("MPEG: feed new data and get samples\n"); @@ -447,7 +447,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* (unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled, &bytes_done); } - samples_filled = (bytes_done / sizeof(sample) / channels_per_frame); + samples_filled = (bytes_done / sizeof(sample_t) / channels_per_frame); /* discard for weird features (EALayer3 and PCM blocks, AWC and repeated frames) */ if (ms->decode_to_discard) { @@ -455,7 +455,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* size_t decode_to_discard = ms->decode_to_discard; if (decode_to_discard > samples_filled) decode_to_discard = samples_filled; - bytes_to_discard = sizeof(sample) * decode_to_discard * channels_per_frame; + bytes_to_discard = sizeof(sample_t) * decode_to_discard * channels_per_frame; bytes_done -= bytes_to_discard; ms->decode_to_discard -= decode_to_discard; @@ -478,9 +478,9 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* decode_fail: /* 0-fill but continue with other streams */ - bytes_filled = ms->samples_filled * channels_per_frame * sizeof(sample); + bytes_filled = ms->samples_filled * channels_per_frame * sizeof(sample_t); memset(ms->output_buffer + bytes_filled, 0, ms->output_buffer_size - bytes_filled); - ms->samples_filled = (ms->output_buffer_size / channels_per_frame / sizeof(sample)); + ms->samples_filled = (ms->output_buffer_size / channels_per_frame / sizeof(sample_t)); } diff --git a/src/coding/ogg_vorbis_decoder.c b/src/coding/ogg_vorbis_decoder.c index 88bf2f7bb..d1fecec61 100644 --- a/src/coding/ogg_vorbis_decoder.c +++ b/src/coding/ogg_vorbis_decoder.c @@ -219,7 +219,7 @@ void decode_ogg_vorbis(ogg_vorbis_codec_data* data, sample_t* outbuf, int32_t sa (char *)(outbuf), /* buffer */ (samples_to_do - samples_done) * sizeof(sample_t) * channels, /* length in bytes */ 0, /* pcm endianness */ - sizeof(sample), /* pcm size */ + sizeof(sample_t), /* pcm size */ 1, /* pcm signedness */ &data->bitstream); /* bitstream */ if (rc <= 0) goto fail; /* rc is bytes done (for all channels) */ @@ -234,7 +234,7 @@ void decode_ogg_vorbis(ogg_vorbis_codec_data* data, sample_t* outbuf, int32_t sa return; fail: VGM_LOG("OGG: error %lx during decode\n", rc); - memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample)); + memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t)); } /* vorbis encodes channels in non-standard order, so we remap during conversion to fix this oddity. diff --git a/src/coding/relic_decoder.c b/src/coding/relic_decoder.c index 319203a68..3d4c260cb 100644 --- a/src/coding/relic_decoder.c +++ b/src/coding/relic_decoder.c @@ -92,7 +92,7 @@ void decode_relic(VGMSTREAMCHANNEL* stream, relic_codec_data* data, sample_t* ou decode_fail: /* on error just put some 0 samples */ VGM_LOG("RELIC: decode fail, missing %i samples\n", samples_to_do); - memset(outbuf, 0, samples_to_do * data->channels * sizeof(sample)); + memset(outbuf, 0, samples_to_do * data->channels * sizeof(sample_t)); } void reset_relic(relic_codec_data* data) { diff --git a/src/coding/sassc_decoder.c b/src/coding/sassc_decoder.c index 59917bfd8..bbe5bfe08 100644 --- a/src/coding/sassc_decoder.c +++ b/src/coding/sassc_decoder.c @@ -4,30 +4,28 @@ /* Activision / EXAKT Entertainment's DPCM for Supercar Street Challenge */ #if 0 - To build table: -int32_t bring_round(int32_t v) -{ +int32_t bring_round(int32_t v) { return v | (v >> 12); } for (i=0x00;i<0x20;i++) - SASSC_steps[i] = bring_round(i<<4); + sassc_steps[i] = bring_round(i<<4); for (i=0x20;i<0x40;i++) - SASSC_steps[i] = bring_round(((i-0x20)*7+0x20)<<4); + sassc_steps[i] = bring_round(((i-0x20)*7+0x20)<<4); for (i=0x40;i<0x60;i++) - SASSC_steps[i] = bring_round(((i-0x40)*24+0x100)<<4); + sassc_steps[i] = bring_round(((i-0x40)*24+0x100)<<4); for (i=0x60;i<0x80;i++) - SASSC_steps[i] = bring_round(((i-0x60)*96+0x400)<<4); + sassc_steps[i] = bring_round(((i-0x60)*96+0x400)<<4); for (i=0x80;i<0xFF;i++) - SASSC_steps[i] = -SASSC_steps[i-0x80]; + sassc_steps[i] = -sassc_steps[i-0x80]; -SASSC_steps[0xFF] = SASSC_steps[0x7F]; +sassc_steps[0xFF] = sassc_steps[0x7F]; #endif -int32_t SASSC_steps[256] = -{ + +static const int32_t sassc_steps[256] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, @@ -63,13 +61,14 @@ int32_t SASSC_steps[256] = -53261, -54797, -56333, -57870, -59406, -60942, -62479, 64015, }; -void decode_sassc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { +void decode_sassc(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { int i; int32_t sample_count; int32_t hist = stream->adpcm_history1_32; - for(i=first_sample,sample_count=0; ioffset+i,stream->streamfile)]; + for (i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count += channelspacing) { + uint8_t index = read_u8(stream->offset + i, stream->streamfile); + hist = hist + sassc_steps[index]; outbuf[sample_count] = clamp16(hist); } diff --git a/src/coding/ubi_adpcm_decoder.c b/src/coding/ubi_adpcm_decoder.c index 729ff5241..e1577a5e7 100644 --- a/src/coding/ubi_adpcm_decoder.c +++ b/src/coding/ubi_adpcm_decoder.c @@ -139,8 +139,8 @@ void decode_ubi_adpcm(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to samples_to_get = samples_to_do - samples_done; memcpy(outbuf + samples_done*channels, - data->samples + data->samples_consumed*channels, - samples_to_get*channels * sizeof(sample)); + data->samples + data->samples_consumed * channels, + samples_to_get * channels * sizeof(sample_t)); samples_done += samples_to_get; } diff --git a/src/coding/vorbis_custom_decoder.c b/src/coding/vorbis_custom_decoder.c index 2a5b666a8..3514682f2 100644 --- a/src/coding/vorbis_custom_decoder.c +++ b/src/coding/vorbis_custom_decoder.c @@ -165,7 +165,7 @@ void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t sample decode_fail: /* on error just put some 0 samples */ VGM_LOG("VORBIS: decode fail at %x, missing %i samples\n", (uint32_t)stream->offset, (samples_to_do - samples_done)); - memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample)); + memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t)); } /* converts from internal Vorbis format to standard PCM (mostly from Xiph's decoder_example.c) */ diff --git a/src/streamtypes.h b/src/streamtypes.h index 5432756cc..27371653c 100644 --- a/src/streamtypes.h +++ b/src/streamtypes.h @@ -38,7 +38,6 @@ #endif /* _MSC_VER */ -typedef int16_t sample; //TODO: deprecated, remove typedef int16_t sample_t; #endif From 2bd2c3e5e99138dfb73f2862351b6d0d317c16ad Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 9 Aug 2024 00:14:14 +0200 Subject: [PATCH 10/17] cleanup: misc meta stuff --- cli/vgmstream123.c | 4 +- src/base/decode.c | 6 +- src/formats.c | 10 +-- src/meta/bgw.c | 145 ++++++++++++++++++++--------------------- src/meta/meta.h | 4 +- src/meta/ngc_dsp_ygo.c | 127 +++++++++++++++--------------------- src/meta/ps2_pcm.c | 94 +++++++++++++------------- src/meta/riff.c | 10 +-- src/vgmstream_init.c | 4 +- src/vgmstream_types.h | 12 ++-- 10 files changed, 193 insertions(+), 223 deletions(-) diff --git a/cli/vgmstream123.c b/cli/vgmstream123.c index e53fcb6cf..4d7f46053 100644 --- a/cli/vgmstream123.c +++ b/cli/vgmstream123.c @@ -342,7 +342,7 @@ static int play_vgmstream(const char* filename, song_settings_t* cfg) { if (!buffer) goto fail; } - max_buffer_samples = buffer_size / (input_channels * sizeof(sample)); + max_buffer_samples = buffer_size / (input_channels * sizeof(sample_t)); vgmstream_mixing_enable(vgmstream, max_buffer_samples, NULL, NULL); /* enable */ @@ -423,7 +423,7 @@ static int play_vgmstream(const char* filename, song_settings_t* cfg) { fflush(stdout); } - if (!ao_play(device, (char *)buffer, to_do * output_channels * sizeof(sample))) { + if (!ao_play(device, (char *)buffer, to_do * output_channels * sizeof(sample_t))) { fputs("\nAudio playback error\n", stderr); ao_close(device); device = NULL; diff --git a/src/base/decode.c b/src/base/decode.c index eaa45b1b4..4ea276798 100644 --- a/src/base/decode.c +++ b/src/base/decode.c @@ -502,7 +502,7 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) { return (0x40-0x04) * 2; case coding_NDS_PROCYON: return 30; - case coding_L5_555: + case coding_LEVEL5: return 32; case coding_LSF: return 54; @@ -729,7 +729,7 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) { return 0x40; case coding_NDS_PROCYON: return 0x10; - case coding_L5_555: + case coding_LEVEL5: return 0x12; case coding_LSF: return 0x1C; @@ -1447,7 +1447,7 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_ vgmstream->channels, vgmstream->samples_into_block, samples_to_do); } break; - case coding_L5_555: + case coding_LEVEL5: for (ch = 0; ch < vgmstream->channels; ch++) { decode_l5_555(&vgmstream->ch[ch], buffer+ch, vgmstream->channels, vgmstream->samples_into_block, samples_to_do); diff --git a/src/formats.c b/src/formats.c index 27ab3b7fd..167706069 100644 --- a/src/formats.c +++ b/src/formats.c @@ -864,7 +864,7 @@ static const coding_info coding_info_list[] = { {coding_NXAP, "Nex NXAP 4-bit ADPCM"}, {coding_TGC, "Tiger Game.com 4-bit ADPCM"}, {coding_NDS_PROCYON, "Procyon Studio Digital Sound Elements NDS 4-bit APDCM"}, - {coding_L5_555, "Level-5 0x555 4-bit ADPCM"}, + {coding_LEVEL5, "Level-5 4-bit ADPCM"}, {coding_LSF, "Gizmondo Studios Helsingborg LSF 4-bit ADPCM"}, {coding_MTAF, "Konami MTAF 4-bit ADPCM"}, {coding_MTA2, "Konami MTA2 4-bit ADPCM"}, @@ -1096,7 +1096,7 @@ static const meta_info meta_info_list[] = { {meta_RIFX_WAVE_smpl, "RIFX WAVE header (smpl looping)"}, {meta_XNB, "Microsoft XNA Game Studio header"}, {meta_SCD_PCM, "Lunar: Eternal Blue .PCM header"}, - {meta_PS2_PCM, "Konami .PCM header"}, + {meta_PCM_KCEJE, "Konami .PCM header"}, {meta_PS2_RKV, "Legacy of Kain - Blood Omen 2 RKV PS2 header"}, {meta_VAS_KCEO, "Konami .VAS header"}, {meta_LP_AP_LEP, "Konami LP/AP/LEP header"}, @@ -1120,8 +1120,8 @@ static const meta_info meta_info_list[] = { {meta_RSD, "Radical RSD header"}, {meta_ASD_NAXAT, "Naxat .ASD header"}, {meta_SPSD, "Sega Naomi SPSD header"}, - {meta_FFXI_BGW, "Square Enix .BGW header"}, - {meta_FFXI_SPW, "Square Enix .SPW header"}, + {meta_BGW, "Square Enix BGMStream header"}, + {meta_SPW, "Square Enix SeWave header"}, {meta_PS2_ASS, "SystemSoft .ASS header"}, {meta_NUB, "Namco NUB header"}, {meta_IDSP_NL, "Next Level IDSP header"}, @@ -1168,7 +1168,7 @@ static const meta_info meta_info_list[] = { {meta_NAOMI_ADPCM, "NAOMI/NAOMI2 Arcade games ADPCM header"}, {meta_SD9, "beatmania IIDX SD9 header"}, {meta_2DX9, "beatmania IIDX 2DX9 header"}, - {meta_DSP_YGO, "Konami custom DSP Header"}, + {meta_DSP_KCEJE, "Konami .DSP Header"}, {meta_PS2_VGV, "Rune: Viking Warlord VGV Header"}, {meta_GCUB, "Sega GCub header"}, {meta_NGC_SCK_DSP, "The Scorpion King SCK Header"}, diff --git a/src/meta/bgw.c b/src/meta/bgw.c index a73cdbd47..fd17521f8 100644 --- a/src/meta/bgw.c +++ b/src/meta/bgw.c @@ -4,47 +4,45 @@ /* BGW - from Final Fantasy XI (PC) music files */ -VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - STREAMFILE *temp_streamFile = NULL; +VGMSTREAM* init_vgmstream_bgw(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; uint32_t codec, file_size, block_size, sample_rate, block_align; int32_t loop_start; off_t start_offset; - int channel_count, loop_flag = 0; + int channels, loop_flag = 0; - /* check extensions */ - if ( !check_extensions(streamFile, "bgw") ) - goto fail; - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x42474d53 || /* "BGMS" */ - read_32bitBE(0x04,streamFile) != 0x74726561 || /* "trea" */ - read_32bitBE(0x08,streamFile) != 0x6d000000 ) /* "m\0\0\0" */ - goto fail; + /* checks */ + if (!is_id32be(0x00,sf, "BGMS") || !is_id32be(0x04,sf, "trea") || !is_id32be(0x08,sf, "m\0\0\0")) + return NULL; + + if (!check_extensions(sf, "bgw")) + return NULL; - codec = read_32bitLE(0x0c,streamFile); - file_size = read_32bitLE(0x10,streamFile); - /* file_id = read_32bitLE(0x14,streamFile); */ - block_size = read_32bitLE(0x18,streamFile); - loop_start = read_32bitLE(0x1c,streamFile); - sample_rate = (read_32bitLE(0x20,streamFile) + read_32bitLE(0x24,streamFile)) & 0x7FFFFFFF; /* bizarrely obfuscated sample rate */ - start_offset = read_32bitLE(0x28,streamFile); - /* 0x2c: unk (vol?) */ - /* 0x2d: unk (0x10?) */ - channel_count = read_8bit(0x2e,streamFile); - block_align = (uint8_t)read_8bit(0x2f,streamFile); - - if (file_size != get_streamfile_size(streamFile)) + codec = read_u32le(0x0c,sf); + file_size = read_u32le(0x10,sf); + //14: file_id + block_size = read_u32le(0x18,sf); + loop_start = read_s32le(0x1c,sf); + sample_rate = (read_u32le(0x20,sf) + read_u32le(0x24,sf)) & 0x7FFFFFFF; /* bizarrely obfuscated sample rate */ + start_offset = read_u32le(0x28,sf); + //2c: unk (vol?) + //2d: unk (bps?) + channels = read_s8(0x2e,sf); + block_align = read_u8(0x2f,sf); + + if (file_size != get_streamfile_size(sf)) goto fail; loop_flag = (loop_start > 0); /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels,loop_flag); if (!vgmstream) goto fail; - vgmstream->meta_type = meta_FFXI_BGW; + vgmstream->meta_type = meta_BGW; vgmstream->sample_rate = sample_rate; switch (codec) { @@ -64,16 +62,16 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 3: { /* ATRAC3 (encrypted) */ size_t data_size = file_size - start_offset; - int encoder_delay, block_align; + int encoder_delay, frame_size; encoder_delay = 1024*2 + 69*2; /* observed value, all files start at +2200 (PS-ADPCM also starts around 50-150 samples in) */ - block_align = 0xC0 * vgmstream->channels; /* 0x00 in header */ + frame_size = 0xC0 * vgmstream->channels; /* 0x00 in header */ vgmstream->num_samples = block_size - encoder_delay; /* atrac3_bytes_to_samples gives block_size */ - temp_streamFile = setup_bgw_atrac3_streamfile(streamFile, start_offset,data_size, 0xC0,channel_count); - if (!temp_streamFile) goto fail; + temp_sf = setup_bgw_atrac3_streamfile(sf, start_offset,data_size, 0xC0,channels); + if (!temp_sf) goto fail; - vgmstream->codec_data = init_ffmpeg_atrac3_raw(temp_streamFile, 0x00,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + vgmstream->codec_data = init_ffmpeg_atrac3_raw(temp_sf, 0x00, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, frame_size, encoder_delay); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -83,7 +81,8 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { vgmstream->loop_end_sample = vgmstream->num_samples; } - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); + temp_sf = NULL; break; } #endif @@ -93,59 +92,57 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { } - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; fail: - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); close_vgmstream(vgmstream); return NULL; } -/* SPW (SEWave) - from PlayOnline viewer for Final Fantasy XI (PC) */ -VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - STREAMFILE *temp_streamFile = NULL; +/* SPW (SEWave) - from PlayOnline viewer for Final Fantasy XI (PC) */ +VGMSTREAM* init_vgmstream_spw(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; uint32_t codec, file_size, block_size, sample_rate, block_align; int32_t loop_start; off_t start_offset; - int channel_count, loop_flag = 0; - - /* check extensions */ - if ( !check_extensions(streamFile, "spw") ) - goto fail; - - /* check header */ - if (read_32bitBE(0,streamFile) != 0x53655761 || /* "SeWa" */ - read_32bitBE(4,streamFile) != 0x76650000) /* "ve\0\0" */ - goto fail; - - file_size = read_32bitLE(0x08,streamFile); - codec = read_32bitLE(0x0c,streamFile); - /* file_id = read_32bitLE(0x10,streamFile);*/ - block_size = read_32bitLE(0x14,streamFile); - loop_start = read_32bitLE(0x18,streamFile); - sample_rate = (read_32bitLE(0x1c,streamFile) + read_32bitLE(0x20,streamFile)) & 0x7FFFFFFF; /* bizarrely obfuscated sample rate */ - start_offset = read_32bitLE(0x24,streamFile); - /* 0x2c: unk (0x00?) */ - /* 0x2d: unk (0x00/01?) */ - channel_count = read_8bit(0x2a,streamFile); + int channels, loop_flag = 0; + + /* checks */ + if (!is_id32be(0x00,sf, "SeWa") || !is_id32be(0x04,sf, "ve\0\0")) + return NULL; + + if (!check_extensions(sf, "spw")) + return NULL; + + file_size = read_u32le(0x08,sf); + codec = read_u32le(0x0c,sf); + //10: file_id + block_size = read_u32le(0x14,sf); + loop_start = read_s32le(0x18,sf); + sample_rate = (read_u32le(0x1c,sf) + read_u32le(0x20,sf)) & 0x7FFFFFFF; /* bizarrely obfuscated sample rate */ + start_offset = read_u32le(0x24,sf); + // 2c: unk (0x00?) + // 2d: unk (0x00/01?) + channels = read_s8(0x2a,sf); /*0x2b: unk (0x01 when PCM, 0x10 when VAG?) */ - block_align = read_8bit(0x2c,streamFile); + block_align = read_u8(0x2c,sf); - if (file_size != get_streamfile_size(streamFile)) + if (file_size != get_streamfile_size(sf)) goto fail; loop_flag = (loop_start > 0); /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels,loop_flag); if (!vgmstream) goto fail; - vgmstream->meta_type = meta_FFXI_SPW; + vgmstream->meta_type = meta_SPW; vgmstream->sample_rate = sample_rate; switch (codec) { @@ -178,16 +175,16 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 3: { /* ATRAC3 (encrypted) */ size_t data_size = file_size - start_offset; - int encoder_delay, block_align; + int encoder_delay, frame_size; encoder_delay = 1024*2 + 69*2; /* observed value, all files start at +2200 (PS-ADPCM also starts around 50-150 samples in) */ - block_align = 0xC0 * vgmstream->channels; /* 0x00 in header */ + frame_size = 0xC0 * vgmstream->channels; /* 0x00 in header */ vgmstream->num_samples = block_size - encoder_delay; /* atrac3_bytes_to_samples gives block_size */ - temp_streamFile = setup_bgw_atrac3_streamfile(streamFile, start_offset,data_size, 0xC0,channel_count); - if (!temp_streamFile) goto fail; + temp_sf = setup_bgw_atrac3_streamfile(sf, start_offset,data_size, 0xC0, channels); + if (!temp_sf) goto fail; - vgmstream->codec_data = init_ffmpeg_atrac3_raw(temp_streamFile, 0x00,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + vgmstream->codec_data = init_ffmpeg_atrac3_raw(temp_sf, 0x00, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, frame_size, encoder_delay); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -197,7 +194,8 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { vgmstream->loop_end_sample = vgmstream->num_samples; } - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); + temp_sf = NULL; break; } #endif @@ -206,15 +204,12 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { goto fail; } - - /* 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; fail: - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/meta.h b/src/meta/meta.h index 1721fef12..e606344bf 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -248,7 +248,7 @@ VGMSTREAM * init_vgmstream_mus_acm(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_scd_pcm(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_ps2_pcm(STREAMFILE * streamFile); +VGMSTREAM* init_vgmstream_pcm_kceje(STREAMFILE* sf); VGMSTREAM * init_vgmstream_ps2_rkv(STREAMFILE * streamFile); @@ -394,7 +394,7 @@ VGMSTREAM * init_vgmstream_sd9(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_2dx9(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE * streamFile); +VGMSTREAM* init_vgmstream_dsp_kceje(STREAMFILE* sf); VGMSTREAM * init_vgmstream_ps2_vgv(STREAMFILE * streamFile); diff --git a/src/meta/ngc_dsp_ygo.c b/src/meta/ngc_dsp_ygo.c index e53905ef0..8b5ef00ad 100644 --- a/src/meta/ngc_dsp_ygo.c +++ b/src/meta/ngc_dsp_ygo.c @@ -1,75 +1,52 @@ -#include "meta.h" -#include "../util.h" - -/* .dsp found in: - Hikaru No Go 3 (NGC) - Yu-Gi-Oh! The Falsebound Kingdom (NGC) - - 2010-01-31 - added loop stuff and some header checks... -*/ - -VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - int loop_flag; - int channel_count; - off_t start_offset; - int i; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("dsp",filename_extension(filename))) goto fail; - - /* check file size with size given in header */ - if ((read_32bitBE(0x0,streamFile)+0xE0) != (get_streamfile_size(streamFile))) - goto fail; - - loop_flag = (uint16_t)(read_16bitBE(0x2C,streamFile) != 0x0); - channel_count = 1; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0xE0; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x28,streamFile); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = read_32bitBE(0x20,streamFile); - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_DSP_YGO; - vgmstream->allow_dual_stereo = 1; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile)*14/16); - vgmstream->loop_end_sample = (read_32bitBE(0x34,streamFile)*14/16); - } - - // read coef stuff - { - for (i=0;i<16;i++) { - vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile); - } - } - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - } - } - - return vgmstream; - -fail: - /* clean up anything we may have opened */ - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* .dsp - from KCE Japan East GC games [Yu-Gi-Oh! The Falsebound Kingdom (GC), Hikaru No Go 3 (GC)] */ +VGMSTREAM* init_vgmstream_dsp_kceje(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int channels, loop_flag; + off_t start_offset; + + + /* checks */ + if (read_u32be(0x00,sf) + 0xE0 != get_streamfile_size(sf)) + return NULL; + if (read_u32be(0x04,sf) != 0x01) + return NULL; + if (read_u32be(0x08,sf) != 0x10000000) + return NULL; + if (read_u32be(0x0c,sf) != 0x00) + return NULL; + + /* .dsp: assumed (no names in .pac bigfile and refs to DSP streams) */ + if (!check_extensions(sf, "dsp")) + return NULL; + + channels = 1; + loop_flag = read_u16be(0x2C,sf) != 0x00; + start_offset = 0xE0; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_u32be(0x28,sf); + vgmstream->num_samples = read_u32be(0x20,sf); + vgmstream->loop_start_sample = dsp_bytes_to_samples(read_u32be(0x30,sf), 2); + vgmstream->loop_end_sample = dsp_bytes_to_samples(read_u32be(0x34,sf), 2); + vgmstream->allow_dual_stereo = true; + + vgmstream->meta_type = meta_DSP_KCEJE; + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_none; + + dsp_read_coefs_be(vgmstream, sf, 0x3c, 0x00); + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ps2_pcm.c b/src/meta/ps2_pcm.c index 07d1fbfc7..c9339bfb1 100644 --- a/src/meta/ps2_pcm.c +++ b/src/meta/ps2_pcm.c @@ -1,48 +1,46 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* .PCM - KCE Japan East PS2 games (Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses, 7 Blades) */ -VGMSTREAM * init_vgmstream_ps2_pcm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - /* check extension */ - if ( !check_extensions(streamFile,"pcm") ) - goto fail; - - /* check header (data_size vs num_samples) */ - if (pcm_bytes_to_samples(read_32bitLE(0x00,streamFile), 2, 16) != read_32bitLE(0x04,streamFile)) - goto fail; - /* should work too */ - //if (read_32bitLE(0x00,streamFile)+0x800 != get_streamfile_size(streamFile)) - // goto fail; - - loop_flag = (read_32bitLE(0x0C,streamFile) != 0x00); - channel_count = 2; - start_offset = 0x800; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->channels = channel_count; - vgmstream->sample_rate = 24000; - vgmstream->num_samples = read_32bitLE(0x04,streamFile); - vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile); - - vgmstream->coding_type = coding_PCM16LE; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x2; - vgmstream->meta_type = meta_PS2_PCM; - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* .PCM - from KCE Japan East PS2 games [Ephemeral Fantasia (PS2), Yu-Gi-Oh! The Duelists of the Roses (PS2), 7 Blades (PS2)] */ +VGMSTREAM* init_vgmstream_pcm_kceje(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + /* checks */ + uint32_t data_size = read_u32le(0x00,sf); + if (data_size > 0x00 && data_size + 0x800 >= get_streamfile_size(sf) && data_size + 0x1000 <= get_streamfile_size(sf)) + return NULL; /* usually 0x800 but may be padded */ + if (pcm16_bytes_to_samples(data_size, 2) != read_u32le(0x04,sf)) + return NULL; + + if (!check_extensions(sf,"pcm")) + return NULL; + + loop_flag = (read_s32le(0x0C,sf) != 0x00); + channels = 2; + start_offset = 0x800; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->channels = channels; + vgmstream->sample_rate = 24000; + vgmstream->num_samples = read_s32le(0x04,sf); + vgmstream->loop_start_sample = read_s32le(0x08,sf); + vgmstream->loop_end_sample = read_s32le(0x0C,sf); + + vgmstream->coding_type = coding_PCM16LE; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x02; + vgmstream->meta_type = meta_PCM_KCEJE; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/riff.c b/src/meta/riff.c index 8bb5e62ce..1d94fabe1 100644 --- a/src/meta/riff.c +++ b/src/meta/riff.c @@ -244,8 +244,8 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk /* real 0x300 is "Fujitsu FM Towns SND" with block align 0x01 */ break; - case 0x0555: /* Level-5 0x555 ADPCM (unofficial) */ - fmt->coding_type = coding_L5_555; + case 0x0555: /* Level-5 ADPCM (unofficial) */ + fmt->coding_type = coding_LEVEL5; fmt->interleave = 0x12; break; @@ -473,7 +473,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { file_size -= 0x40; /* [Megami no Etsubo (PSP)] (has extra padding in all files) */ else if (codec == 0x0011 && file_size - riff_size - 0x08 <= 0x900 && is_id32be(riff_size + 0x08, sf, "cont")) - riff_size = file_size - 0x08; /* [Shin Megami Tensei: Imagine (PC)] (extra "cont" info 0x800/0x900 chunk) */ + riff_size = file_size - 0x08; /* [Shin Megami Tensei: Imagine (PC)] (extra "cont" info 0x800/0x900 chunk) */ } @@ -738,7 +738,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { vgmstream->num_samples = pcm_bytes_to_samples(data_size, fmt.channels, fmt.bps); break; - case coding_L5_555: + case coding_LEVEL5: vgmstream->num_samples = data_size / 0x12 / fmt.channels * 32; /* coefs */ @@ -912,7 +912,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { vgmstream->loop_end_sample = loop_end_wsmp; vgmstream->meta_type = meta_RIFF_WAVE_wsmp; } - else if (fmt.coding_type == coding_L5_555 && mwv_ctrl_offset) { + else if (fmt.coding_type == coding_LEVEL5 && mwv_ctrl_offset) { vgmstream->loop_start_sample = read_s32le(mwv_ctrl_offset + 0x0c, sf); vgmstream->loop_end_sample = vgmstream->num_samples; vgmstream->meta_type = meta_RIFF_WAVE_MWV; diff --git a/src/vgmstream_init.c b/src/vgmstream_init.c index 625357ed2..0e96c86f2 100644 --- a/src/vgmstream_init.c +++ b/src/vgmstream_init.c @@ -81,7 +81,6 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_vig_kces, init_vgmstream_hxd, init_vgmstream_vsv, - init_vgmstream_ps2_pcm, init_vgmstream_ps2_rkv, init_vgmstream_lp_ap_lep, init_vgmstream_sdt, @@ -158,7 +157,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_naomi_adpcm, init_vgmstream_sd9, init_vgmstream_2dx9, - init_vgmstream_dsp_ygo, + init_vgmstream_dsp_kceje, init_vgmstream_ps2_vgv, init_vgmstream_gcub, init_vgmstream_maxis_xa, @@ -527,6 +526,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_tgc, init_vgmstream_rage_aud, init_vgmstream_asd_naxat, + init_vgmstream_pcm_kceje, /* need companion files */ init_vgmstream_pos, init_vgmstream_sli_loops, diff --git a/src/vgmstream_types.h b/src/vgmstream_types.h index 278588c13..1d133cf89 100644 --- a/src/vgmstream_types.h +++ b/src/vgmstream_types.h @@ -106,7 +106,7 @@ typedef enum { coding_TGC, /* Tiger Game.com 4-bit ADPCM */ coding_NDS_PROCYON, /* Procyon Studio ADPCM */ - coding_L5_555, /* Level-5 0x555 ADPCM */ + coding_LEVEL5, /* Level-5 ADPCM */ coding_LSF, /* lsf ADPCM (Fastlane Street Racing iPhone)*/ coding_MTAF, /* Konami MTAF ADPCM */ coding_MTA2, /* Konami MTA2 ADPCM */ @@ -265,7 +265,7 @@ typedef enum { meta_MUS_KROME, meta_DSP_WII_WSD, /* Phantom Brave (WII) */ meta_WII_NDP, /* Vertigo (Wii) */ - meta_DSP_YGO, /* Konami: Yu-Gi-Oh! The Falsebound Kingdom (NGC), Hikaru no Go 3 (NGC) */ + meta_DSP_KCEJE, meta_STRM, /* Nintendo STRM */ meta_RSTM, /* Nintendo RSTM (Revolution Stream, similar to STRM) */ @@ -345,7 +345,7 @@ typedef enum { meta_HXD, meta_VSV, meta_SCD_PCM, /* Lunar - Eternal Blue */ - meta_PS2_PCM, /* Konami KCEJ East: Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses, 7 Blades */ + meta_PCM_KCEJE, meta_PS2_RKV, /* Legacy of Kain - Blood Omen 2 (PS2) */ meta_VAS_KCEO, meta_LP_AP_LEP, @@ -429,8 +429,8 @@ typedef enum { meta_MUS_ACM, /* MUS playlist of InterPlay ACM files */ meta_DEC, /* Falcom PC games (Xanadu Next, Gurumin) */ meta_VS, /* Men in Black .vs */ - meta_FFXI_BGW, /* FFXI (PC) BGW */ - meta_FFXI_SPW, /* FFXI (PC) SPW */ + meta_BGW, + meta_SPW, meta_STS, meta_P2BT_MOVE_VISA, meta_GBTS, @@ -505,7 +505,7 @@ typedef enum { meta_EB_SF0, /* Excitebots .sf0 */ meta_MTAF, meta_ALP, - meta_WPD, /* Shuffle! (PC) */ + meta_WPD, meta_MN_STR, /* Mini Ninjas (PC/PS3/WII) */ meta_MSS, /* Guerilla: ShellShock Nam '67 (PS2/Xbox), Killzone (PS2) */ meta_PS2_HSF, /* Lowrider (PS2) */ From 373329adabc1816beffdf3663dffc82edda99e1e Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 9 Aug 2024 00:15:08 +0200 Subject: [PATCH 11/17] cleanup: renames --- src/libvgmstream.vcxproj | 4 ++-- src/libvgmstream.vcxproj.filters | 12 ++++++------ src/meta/{ngc_dsp_ygo.c => dsp_kceje.c} | 0 src/meta/{ps2_pcm.c => pcm_kceje.c} | 0 4 files changed, 8 insertions(+), 8 deletions(-) rename src/meta/{ngc_dsp_ygo.c => dsp_kceje.c} (100%) rename src/meta/{ps2_pcm.c => pcm_kceje.c} (100%) diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 9252ad52f..cc076d72e 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -454,6 +454,7 @@ + @@ -577,7 +578,6 @@ - @@ -604,6 +604,7 @@ + @@ -620,7 +621,6 @@ - diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 919f4461d..5d9523507 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1192,6 +1192,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files @@ -1561,9 +1564,6 @@ meta\Source Files - - meta\Source Files - meta\Source Files @@ -1642,6 +1642,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files @@ -1690,9 +1693,6 @@ meta\Source Files - - meta\Source Files - meta\Source Files diff --git a/src/meta/ngc_dsp_ygo.c b/src/meta/dsp_kceje.c similarity index 100% rename from src/meta/ngc_dsp_ygo.c rename to src/meta/dsp_kceje.c diff --git a/src/meta/ps2_pcm.c b/src/meta/pcm_kceje.c similarity index 100% rename from src/meta/ps2_pcm.c rename to src/meta/pcm_kceje.c From 0cb37f0dc76206ab08ad02b44fcce6675b19c4a5 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:26:53 +0200 Subject: [PATCH 12/17] cleanup: foobar misc + tweak file info --- fb2k/foo_filetypes.h | 60 +++--- fb2k/foo_prefs.cpp | 85 ++++---- fb2k/foo_streamfile.cpp | 8 +- fb2k/foo_vgmstream.cpp | 436 +++++++++++++++++++++++----------------- fb2k/foo_vgmstream.h | 45 ++++- 5 files changed, 368 insertions(+), 266 deletions(-) diff --git a/fb2k/foo_filetypes.h b/fb2k/foo_filetypes.h index c7e2c1ac7..aec135e01 100644 --- a/fb2k/foo_filetypes.h +++ b/fb2k/foo_filetypes.h @@ -1,28 +1,32 @@ -#ifndef _FOO_FILETYPES_H_ -#define _FOO_FILETYPES_H_ - -class input_file_type_v2_impl_vgmstream : public input_file_type_v2 { -public: - input_file_type_v2_impl_vgmstream() { - ext_list = vgmstream_get_formats(&ext_list_len); - } - unsigned get_count() { return ext_list_len; } - bool is_associatable(unsigned idx) { return true; } - void get_format_name(unsigned idx, pfc::string_base & out, bool isPlural) { - out.reset(); - pfc::stringToUpperAppend(out, ext_list[idx], pfc::strlen_utf8(ext_list[idx])); - out += " Audio File"; - if (isPlural) out += "s"; - } - void get_extensions(unsigned idx, pfc::string_base & out) { - out = ext_list[idx]; - } - -private: - const char ** ext_list; - size_t ext_list_len; -}; - -namespace { static service_factory_single_t g_filetypes; } - -#endif /*_FOO_FILETYPES_H_ */ +#ifndef _FOO_FILETYPES_H_ +#define _FOO_FILETYPES_H_ + +class input_file_type_v2_impl_vgmstream : public input_file_type_v2 { +public: + input_file_type_v2_impl_vgmstream() { + ext_list = vgmstream_get_formats(&ext_list_len); + } + + unsigned get_count() { return ext_list_len; } + + bool is_associatable(unsigned idx) { return true; } + + void get_format_name(unsigned idx, pfc::string_base & out, bool isPlural) { + out.reset(); + pfc::stringToUpperAppend(out, ext_list[idx], pfc::strlen_utf8(ext_list[idx])); + out += " Audio File"; + if (isPlural) out += "s"; + } + + void get_extensions(unsigned idx, pfc::string_base & out) { + out = ext_list[idx]; + } + +private: + const char ** ext_list; + size_t ext_list_len; +}; + +namespace { static service_factory_single_t g_filetypes; } + +#endif /*_FOO_FILETYPES_H_ */ diff --git a/fb2k/foo_prefs.cpp b/fb2k/foo_prefs.cpp index 97e338f7a..1673da670 100755 --- a/fb2k/foo_prefs.cpp +++ b/fb2k/foo_prefs.cpp @@ -5,10 +5,6 @@ #include #include "foo_prefs.h" -extern "C" { -#include "../src/vgmstream.h" -#include "../src/util.h" -} #include "foo_vgmstream.h" @@ -27,13 +23,13 @@ static cfg_bool cfg_ExtsCommonOn ({0x405af423,0x5037,0x4eae,{0xa6,0xe3,0x // Needs to be here in rder to access the static config void input_vgmstream::load_settings() { // no verification needed here, as it is done below - sscanf(cfg_FadeLength.get_ptr(),"%lf",&fade_seconds); - sscanf(cfg_LoopCount.get_ptr(),"%lf",&loop_count); - sscanf(cfg_FadeDelay.get_ptr(),"%lf",&fade_delay_seconds); + sscanf(cfg_FadeLength.get_ptr(), "%lf", &fade_seconds); + sscanf(cfg_LoopCount.get_ptr(), "%lf", &loop_count); + sscanf(cfg_FadeDelay.get_ptr(), "%lf", &fade_delay_seconds); loop_forever = cfg_LoopForever; ignore_loop = cfg_IgnoreLoop; disable_subsongs = cfg_DisableSubsongs; - sscanf(cfg_DownmixChannels.get_ptr(),"%d",&downmix_channels); + sscanf(cfg_DownmixChannels.get_ptr(), "%d", &downmix_channels); tagfile_disable = cfg_TagfileDisable; override_title = cfg_OverrideTitle; //exts_unknown_on = cfg_ExtsUnknownOn; @@ -43,13 +39,13 @@ void input_vgmstream::load_settings() { if (loop_count <= 0) loop_count = 1; } -void input_vgmstream::g_load_cfg(int *accept_unknown, int *accept_common) { - //todo improve - *accept_unknown = cfg_ExtsUnknownOn ? 1 : 0; - *accept_common = cfg_ExtsCommonOn ? 1 : 0; +void input_vgmstream::g_load_cfg(int* accept_unknown, int* accept_common) { + //TODO improve + *accept_unknown = cfg_ExtsUnknownOn; + *accept_common = cfg_ExtsCommonOn; } -const char * vgmstream_prefs::get_name() { +const char* vgmstream_prefs::get_name() { return input_vgmstream::g_get_name(); } @@ -61,50 +57,55 @@ GUID vgmstream_prefs::get_parent_guid() { return guid_input; } +static UINT get_check(bool value) { + return value ? BST_CHECKED : BST_UNCHECKED; +} + BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM) { - CheckDlgButton(IDC_LOOP_FOREVER, cfg_LoopForever?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_IGNORE_LOOP, cfg_IgnoreLoop?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_LOOP_NORMALLY, (!cfg_IgnoreLoop && !cfg_LoopForever)?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_LOOP_FOREVER, get_check(cfg_LoopForever)); + CheckDlgButton(IDC_IGNORE_LOOP, get_check(cfg_IgnoreLoop)); + CheckDlgButton(IDC_LOOP_NORMALLY, get_check(!cfg_IgnoreLoop && !cfg_LoopForever)); uSetDlgItemText(m_hWnd, IDC_LOOP_COUNT, cfg_LoopCount); uSetDlgItemText(m_hWnd, IDC_FADE_SECONDS, cfg_FadeLength); uSetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS, cfg_FadeDelay); - CheckDlgButton(IDC_DISABLE_SUBSONGS, cfg_DisableSubsongs?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_DISABLE_SUBSONGS, get_check(cfg_DisableSubsongs)); uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, cfg_DownmixChannels); - CheckDlgButton(IDC_TAGFILE_DISABLE, cfg_TagfileDisable?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_OVERRIDE_TITLE, cfg_OverrideTitle?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_EXTS_UNKNOWN_ON, cfg_ExtsUnknownOn?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_EXTS_COMMON_ON, cfg_ExtsCommonOn?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_TAGFILE_DISABLE, get_check(cfg_TagfileDisable)); + CheckDlgButton(IDC_OVERRIDE_TITLE, get_check(cfg_OverrideTitle)); + CheckDlgButton(IDC_EXTS_UNKNOWN_ON, get_check(cfg_ExtsUnknownOn)); + CheckDlgButton(IDC_EXTS_COMMON_ON, get_check(cfg_ExtsCommonOn)); return TRUE; } t_uint32 vgmstreamPreferences::get_state() { t_uint32 state = preferences_state::resettable; - if (HasChanged()) state |= preferences_state::changed; + if (HasChanged()) + state |= preferences_state::changed; return state; } void vgmstreamPreferences::reset() { - CheckDlgButton(IDC_LOOP_FOREVER, DEFAULT_LOOP_FOREVER?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_IGNORE_LOOP, DEFAULT_IGNORE_LOOP?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_LOOP_NORMALLY, (!DEFAULT_IGNORE_LOOP && !DEFAULT_LOOP_FOREVER)?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_LOOP_FOREVER, get_check(DEFAULT_LOOP_FOREVER)); + CheckDlgButton(IDC_IGNORE_LOOP, get_check(DEFAULT_IGNORE_LOOP)); + CheckDlgButton(IDC_LOOP_NORMALLY, get_check(!DEFAULT_IGNORE_LOOP && !DEFAULT_LOOP_FOREVER)); uSetDlgItemText(m_hWnd, IDC_LOOP_COUNT, DEFAULT_LOOP_COUNT); uSetDlgItemText(m_hWnd, IDC_FADE_SECONDS, DEFAULT_FADE_SECONDS); uSetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS, DEFAULT_FADE_DELAY_SECONDS); - CheckDlgButton(IDC_DISABLE_SUBSONGS, DEFAULT_DISABLE_SUBSONGS?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_DISABLE_SUBSONGS, get_check(DEFAULT_DISABLE_SUBSONGS)); uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, DEFAULT_DOWNMIX_CHANNELS); - CheckDlgButton(IDC_TAGFILE_DISABLE, DEFAULT_TAGFILE_DISABLE?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_OVERRIDE_TITLE, DEFAULT_OVERRIDE_TITLE?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_EXTS_UNKNOWN_ON, DEFAULT_EXTS_UNKNOWN_ON?BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(IDC_EXTS_COMMON_ON, DEFAULT_EXTS_COMMON_ON?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(IDC_TAGFILE_DISABLE, get_check(DEFAULT_TAGFILE_DISABLE)); + CheckDlgButton(IDC_OVERRIDE_TITLE, get_check(DEFAULT_OVERRIDE_TITLE)); + CheckDlgButton(IDC_EXTS_UNKNOWN_ON, get_check(DEFAULT_EXTS_UNKNOWN_ON)); + CheckDlgButton(IDC_EXTS_COMMON_ON, get_check(DEFAULT_EXTS_COMMON_ON)); } @@ -125,9 +126,8 @@ void vgmstreamPreferences::apply() { pfc::string buf; buf = uGetDlgItemText(m_hWnd, IDC_FADE_SECONDS); - if (sscanf(buf.get_ptr(),"%lf%n",&temp_fade_seconds,&consumed)<1 - || consumed!=strlen(buf.get_ptr()) || - temp_fade_seconds<0) { + if (sscanf(buf.get_ptr(), "%lf%n", &temp_fade_seconds, &consumed) < 1 + || consumed != strlen(buf.get_ptr()) || temp_fade_seconds < 0) { uMessageBox(m_hWnd, "Invalid value for Fade Length\n" "Must be a number greater than or equal to zero", @@ -136,9 +136,8 @@ void vgmstreamPreferences::apply() { } else cfg_FadeLength = buf.get_ptr(); buf = uGetDlgItemText(m_hWnd, IDC_LOOP_COUNT); - if (sscanf(buf.get_ptr(),"%lf%n",&temp_loop_count,&consumed)<1 - || consumed!=strlen(buf.get_ptr()) || - temp_loop_count<0) { + if (sscanf(buf.get_ptr(), "%lf%n", &temp_loop_count, &consumed) < 1 + || consumed != strlen(buf.get_ptr()) || temp_loop_count < 0) { uMessageBox(m_hWnd, "Invalid value for Loop Count\n" "Must be a number greater than or equal to zero", @@ -147,24 +146,22 @@ void vgmstreamPreferences::apply() { } else cfg_LoopCount = buf.get_ptr(); buf = uGetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS); - if (sscanf(buf.get_ptr(),"%lf%n",&temp_fade_delay_seconds,&consumed)<1 - || consumed!=strlen(buf.get_ptr()) || - temp_fade_delay_seconds<0) { + if (sscanf(buf.get_ptr(), "%lf%n", &temp_fade_delay_seconds, &consumed) < 1 + || consumed != strlen(buf.get_ptr()) || temp_fade_delay_seconds < 0) { uMessageBox(m_hWnd, "Invalid value for Fade Delay\n" "Must be a number", - "Error",MB_OK|MB_ICONERROR); + "Error", MB_OK|MB_ICONERROR); return; } else cfg_FadeDelay = buf.get_ptr(); buf = uGetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS); - if (sscanf(buf.get_ptr(),"%d%n",&temp_downmix_channels,&consumed)<1 - || consumed!=strlen(buf.get_ptr()) || - temp_downmix_channels<0) { + if (sscanf(buf.get_ptr(), "%d%n", &temp_downmix_channels, &consumed) < 1 + || consumed != strlen(buf.get_ptr()) || temp_downmix_channels < 0) { uMessageBox(m_hWnd, "Invalid value for Downmix Channels\n" "Must be a number greater than or equal to zero", - "Error",MB_OK|MB_ICONERROR); + "Error", MB_OK|MB_ICONERROR); return; } else cfg_DownmixChannels = buf.get_ptr(); diff --git a/fb2k/foo_streamfile.cpp b/fb2k/foo_streamfile.cpp index c4aa0a840..574fba55e 100644 --- a/fb2k/foo_streamfile.cpp +++ b/fb2k/foo_streamfile.cpp @@ -115,12 +115,15 @@ static size_t foo_read(FOO_STREAMFILE* sf, uint8_t* dst, offv_t offset, size_t l sf->offset = offset; /* last fread offset */ return read_total; } + static size_t foo_get_size(FOO_STREAMFILE* sf) { return sf->file_size; } + static offv_t foo_get_offset(FOO_STREAMFILE* sf) { return sf->offset; } + static void foo_get_name(FOO_STREAMFILE* sf, char* name, size_t name_size) { int copy_size = sf->name_len + 1; if (copy_size > name_size) @@ -138,6 +141,7 @@ static void foo_get_name(FOO_STREAMFILE* sf, char* name, size_t name_size) { } */ } + static void foo_close(FOO_STREAMFILE* sf) { sf->m_file.release(); //release alloc'ed ptr free(sf->name); @@ -247,11 +251,11 @@ static STREAMFILE* open_foo_streamfile_buffer_by_file(service_ptr_t m_file if (strncmp(filename, "unpack", 6) == 0) { const char* archfile_ptr = strrchr(this_sf->name, '|'); if (archfile_ptr) - this_sf->archfile_end = (intptr_t)archfile_ptr + 1 - (intptr_t)this_sf->name; // after "|"" + this_sf->archfile_end = (int)((intptr_t)archfile_ptr + 1 - (intptr_t)this_sf->name); // after "|"" const char* archpath_ptr = strrchr(this_sf->name, '\\'); if (archpath_ptr) - this_sf->archpath_end = (intptr_t)archpath_ptr + 1 - (intptr_t)this_sf->name; // after "\\" + this_sf->archpath_end = (int)((intptr_t)archpath_ptr + 1 - (intptr_t)this_sf->name); // after "\\" if (this_sf->archpath_end <= 0 || this_sf->archfile_end <= 0 || this_sf->archpath_end > this_sf->archfile_end || this_sf->archfile_end > this_sf->name_len || this_sf->archfile_end >= PATH_LIMIT) { diff --git a/fb2k/foo_vgmstream.cpp b/fb2k/foo_vgmstream.cpp index 5fc3443b8..b30ef60d5 100644 --- a/fb2k/foo_vgmstream.cpp +++ b/fb2k/foo_vgmstream.cpp @@ -59,7 +59,7 @@ input_vgmstream::input_vgmstream() { fade_delay_seconds = 0.0; loop_count = 2.0; loop_forever = false; - ignore_loop = 0; + ignore_loop = false; disable_subsongs = false; downmix_channels = 0; tagfile_disable = false; @@ -80,53 +80,48 @@ input_vgmstream::~input_vgmstream() { // called first when a new file is accepted, before playing it void input_vgmstream::open(service_ptr_t p_filehint, const char * p_path, t_input_open_reason p_reason, abort_callback & p_abort) { - if (!p_path) { // shouldn't be possible + if (!p_path) // shouldn't be possible throw exception_io_data(); - return; //??? - } filename = p_path; // allow non-existing files in some cases - bool infile_virtual = !filesystem::g_exists(p_path, p_abort) - && vgmstream_is_virtual_filename(filename) == 1; + bool infile_virtual = !filesystem::g_exists(p_path, p_abort) && vgmstream_is_virtual_filename(filename); // don't try to open virtual files as it'll fail // (doesn't seem to have any adverse effect, except maybe no stats) // setup_vgmstream also makes further checks before file is finally opened if (!infile_virtual) { // keep file stats around (timestamp, filesize) - if ( p_filehint.is_empty() ) + if ( p_filehint.is_empty() ) { input_open_file_helper( p_filehint, filename, p_reason, p_abort ); + } stats = p_filehint->get_stats( p_abort ); - uint32_t flags = stats2_legacy; //foobar2000_io.stats2_xxx, not sure about the implications + uint32_t flags = stats2_legacy; //foobar2000_io.stats2_xxx, not sure about implications stats2 = p_filehint->get_stats2_(flags, p_abort); // ??? } switch(p_reason) { - case input_open_decode: // prepare to retrieve info and decode - case input_open_info_read: // prepare to retrieve info - setup_vgmstream(p_abort); // must init vgmstream to get subsongs - break; - - case input_open_info_write: // prepare to retrieve info and tag - throw exception_io_data(); + case input_open_decode: // prepare to retrieve info and decode + case input_open_info_read: // prepare to retrieve info + // init vgmstream to get subsongs + setup_vgmstream(p_abort); break; - default: // nothing else should be possible + case input_open_info_write: // prepare to retrieve info and tag + default: throw exception_io_data(); - break; } } // called after opening file (possibly per subsong too) unsigned input_vgmstream::get_subsong_count() { - // if the plugin uses input_factory_t template and returns > 1 here when adding a song to the playlist, - // foobar will automagically "unpack" it by calling decode_initialize/get_info with all subsong indexes. - // There is no need to add any playlist code, only properly handle the subsong index. if (disable_subsongs) return 1; + // If the plugin uses input_factory_t template and returns > 1 here when adding a song to the playlist, + // foobar will automagically "unpack" it by calling decode_initialize/get_info with all subsong indexes. + // There is no need to add any playlist code, only properly handle the subsong index. // vgmstream ready as method is valid after open() with any reason int subsong_count = vgmstream->num_streams; @@ -142,117 +137,155 @@ unsigned input_vgmstream::get_subsong_count() { // called after get_subsong_count to play subsong N (even when count is 1) t_uint32 input_vgmstream::get_subsong(unsigned p_index) { - return p_index + 1; // translates index (0..N < subsong_count) for vgmstream: 1=first + // translates index (0..N < subsong_count) for vgmstream: 1=first + return p_index + 1; } // called before playing to get info -void input_vgmstream::get_info(t_uint32 p_subsong, file_info & p_info, abort_callback & p_abort) { - int length_in_ms=0, channels = 0, samplerate = 0; - int total_samples = -1; - int bitrate = 0; - int loop_flag = -1, loop_start = -1, loop_end = -1; - pfc::string8 description; - pfc::string8_fast temp; +void input_vgmstream::get_info(t_uint32 p_subsong, file_info& p_info, abort_callback& p_abort) { + vgmstream_info_t v_info = {}; // init default (not {0} since it has classes) - get_subsong_info(p_subsong, temp, &length_in_ms, &total_samples, &loop_flag, &loop_start, &loop_end, &samplerate, &channels, &bitrate, description, p_abort); + query_subsong_info(p_subsong, v_info, p_abort); + // export tags ('metadata' tab in file properties) + put_info_tags(p_info, v_info); + put_into_tagfile(p_info, p_abort); - /* set tag info (metadata tab in file properties) */ + // set technical info ('details' tab in file properties) + put_info_details(p_info, v_info); +} - /* Shows a custom subsong title by default with subsong name, to simplify for average users. - * This can be overriden and extended using the exported STREAM_x below and foobar's formatting. - * foobar defaults to filename minus extension if there is no meta "title" value. */ +void input_vgmstream::put_info_tags(file_info& p_info, vgmstream_info_t& v_info) { if (!override_title) { - p_info.meta_set("TITLE",temp); + /* Shows a default (sub)song title with stream name. + * This can be overriden and extended using the exported STREAM_x below and foobar's formatting. + * foobar defaults to filename minus extension if there is no meta "title" value. */ + p_info.meta_set("TITLE", v_info.title); } - if (get_description_tag(temp,description,"stream count: ")) p_info.meta_set("stream_count",temp); - if (get_description_tag(temp,description,"stream index: ")) p_info.meta_set("stream_index",temp); - if (get_description_tag(temp,description,"stream name: ")) p_info.meta_set("stream_name",temp); - if (loop_end) { - p_info.meta_set("loop_start", pfc::format_int(loop_start)); - p_info.meta_set("loop_end", pfc::format_int(loop_end)); - // has extra text info - //if (get_description_tag(temp,description,"loop start: ")) p_info.meta_set("loop_start",temp); - //if (get_description_tag(temp,description,"loop end: ")) p_info.meta_set("loop_end",temp); + + if (!v_info.stream_name.is_empty()) { + p_info.meta_set("stream_name", v_info.stream_name); } - /* get external file tags */ - //todo optimize and don't parse tags again for this session (not sure how), seems foobar - // calls get_info on every play even if the file hasn't changes, and won't refresh "meta" - // unless forced or closing playlist+exe - if (!tagfile_disable) { - //todo use foobar's fancy-but-arcane string functions - char tagfile_path[PATH_LIMIT]; - strcpy(tagfile_path, filename); - - char *path = strrchr(tagfile_path,'\\'); - if (path!=NULL) { - path[1] = '\0'; /* includes "\", remove after that from tagfile_path */ - strcat(tagfile_path,tagfile_name); + if (v_info.subsong_count > 1) { + p_info.meta_set("stream_count", pfc::format_int(v_info.subsong_count)); + p_info.meta_set("stream_index", pfc::format_int(v_info.subsong_index == 0 ? 1 : v_info.subsong_index)); + } + + if (v_info.loop_end > 0) { + p_info.meta_set("loop_start", pfc::format_int(v_info.loop_start)); + p_info.meta_set("loop_end", pfc::format_int(v_info.loop_end)); + } +} + +void input_vgmstream::put_into_tagfile(file_info& p_info, abort_callback& p_abort) { + if (tagfile_disable) + return; + //TODO: optimize and don't parse tags again for this session (not sure how). + // Seems foobar calls get_info on every play even if the file hasn't changed, + // and won't refresh "meta" unless forced or closing playlist + exe. + + //TODO: use foobar's fancy-but-arcane string functions + char tagfile_path[FOO_PATH_LIMIT]; + strcpy(tagfile_path, filename); + + char* path = strrchr(tagfile_path, '\\'); + if (path != NULL) { + path[1] = '\0'; // includes "\", remove after that from tagfile_path + strcat(tagfile_path, tagfile_name); + } + else { + // possible? + strcpy(tagfile_path, tagfile_name); + } + + STREAMFILE* sf_tags = open_foo_streamfile(tagfile_path, &p_abort, NULL); + if (sf_tags == NULL) + return; + + VGMSTREAM_TAGS* tags; + const char *tag_key, *tag_val; + + tags = vgmstream_tags_init(&tag_key, &tag_val); + + vgmstream_tags_reset(tags, filename); + while (vgmstream_tags_next_tag(tags, sf_tags)) { + if (replaygain_info::g_is_meta_replaygain(tag_key)) { + p_info.info_set_replaygain(tag_key, tag_val); + // there is set_replaygain_auto/set_replaygain_ex too but no doc } - else { /* ??? */ - strcpy(tagfile_path,tagfile_name); + else if (stricmp_utf8("ALBUMARTIST", tag_key) == 0) { + // normalize tag for foobar as otherwise can't understand it (though it's recognized in .ogg) + p_info.meta_set("ALBUM ARTIST", tag_val); } - - STREAMFILE* sf_tags = open_foo_streamfile(tagfile_path, &p_abort, NULL); - if (sf_tags != NULL) { - VGMSTREAM_TAGS* tags; - const char *tag_key, *tag_val; - - tags = vgmstream_tags_init(&tag_key, &tag_val); - vgmstream_tags_reset(tags, filename); - while (vgmstream_tags_next_tag(tags, sf_tags)) { - if (replaygain_info::g_is_meta_replaygain(tag_key)) { - p_info.info_set_replaygain(tag_key, tag_val); - /* there is info_set_replaygain_auto too but no doc */ - } - else if (stricmp_utf8("ALBUMARTIST", tag_key) == 0) - /* normalize as foobar won't handle (though it's accepted in .ogg) */ - p_info.meta_set("ALBUM ARTIST", tag_val); - else { - p_info.meta_set(tag_key, tag_val); - } - } - vgmstream_tags_close(tags); - close_streamfile(sf_tags); + else { + p_info.meta_set(tag_key, tag_val); } } + vgmstream_tags_close(tags); + close_streamfile(sf_tags); +} + +// include main info, note that order doesn't matter (foobar sorts by fixed order + name) +void input_vgmstream::put_info_details(file_info& p_info, vgmstream_info_t& v_info) { + p_info.info_set("vgmstream_version", PLUGIN_VERSION); //to make clearer vgmsrteam is actually opening the file + + // not quite accurate but some people are confused by "lossless" + // (could set lossless if PCM, but then again in vgm may be converted/"lossy" vs original source) + p_info.info_set("encoding", "lossy/lossless"); + + p_info.info_set_int("channels", v_info.channels); + p_info.info_set_int("samplerate", v_info.sample_rate); + p_info.info_set_int("bitspersample", v_info.bits_per_sample); + p_info.info_set_bitrate(v_info.bitrate / 1000); + + if (v_info.input_channels > 0 && v_info.channels != v_info.input_channels) { + p_info.info_set_int("input_channels", v_info.input_channels); + //p_info.info_set_int("output_channels", v_info.output_channels); + } + + p_info.set_length(v_info.play_length_s); - /* set technical info (details tab in file properties) */ - - p_info.info_set("vgmstream_version", PLUGIN_VERSION); - p_info.info_set_int("samplerate", samplerate); - p_info.info_set_int("channels", channels); - p_info.info_set_int("bitspersample", 16); - /* not quite accurate but some people are confused by "lossless" - * (could set lossless if PCM, but then again PCMFloat or PCM8 are converted/"lossy" in vgmstream) */ - p_info.info_set("encoding","lossy/lossless"); - p_info.info_set_bitrate(bitrate / 1000); - if (total_samples > 0) - p_info.info_set_int("stream_total_samples", total_samples); - if (loop_start >= 0 && loop_end > loop_start) { - if (!loop_flag) p_info.info_set("looping", "disabled"); - p_info.info_set_int("loop_start", loop_start); - p_info.info_set_int("loop_end", loop_end); + if (v_info.stream_samples > 0) { // ? + p_info.info_set_int("samples", v_info.stream_samples); } - p_info.set_length(((double)length_in_ms)/1000); - if (get_description_tag(temp,description,"encoding: ")) p_info.info_set("codec",temp); - if (get_description_tag(temp,description,"layout: ")) p_info.info_set("layout",temp); - if (get_description_tag(temp,description,"interleave: ",' ')) p_info.info_set("interleave",temp); - if (get_description_tag(temp,description,"interleave last block:",' ')) p_info.info_set("interleave_last_block",temp); + if (v_info.loop_end > 0) { + p_info.info_set_int("loop_start", v_info.loop_start); + p_info.info_set_int("loop_end", v_info.loop_end); + if (!v_info.loop_flag) + p_info.info_set("looping", "disabled"); + } - if (get_description_tag(temp,description,"block size: ")) p_info.info_set("block_size",temp); - if (get_description_tag(temp,description,"metadata from: ")) p_info.info_set("metadata_source",temp); - if (get_description_tag(temp,description,"stream count: ")) p_info.info_set("stream_count",temp); - if (get_description_tag(temp,description,"stream index: ")) p_info.info_set("stream_index",temp); - if (get_description_tag(temp,description,"stream name: ")) p_info.info_set("stream_name",temp); + p_info.info_set("codec", v_info.codec_name); + p_info.info_set("layout", v_info.layout_name); + p_info.info_set("metadata", v_info.meta_name); - if (get_description_tag(temp,description,"channel mask: ")) p_info.info_set("channel_mask",temp); - if (get_description_tag(temp,description,"output channels: ")) p_info.info_set("output_channels",temp); - if (get_description_tag(temp,description,"input channels: ")) p_info.info_set("input_channels",temp); + if (!v_info.stream_name.is_empty()) { + p_info.info_set("stream_name", v_info.stream_name); + } + if (v_info.subsong_count > 1) { + p_info.info_set_int("stream_count", v_info.subsong_count); + p_info.info_set_int("stream_index", v_info.subsong_index); + } + + if (!v_info.channel_mask.is_empty()) { + p_info.info_set("channel_mask", v_info.channel_mask); + } + + /* + // for >2ch foobar writes info like "Channels - 8: FL FR FC LFE BL BR FCL FCR", which may be undesirable? + if (v_info.channel_layout > 0) { + // there is info_set_channels_ex in newer SDKs too + p_info.info_set_wfx_chanMask(v_info.channel_layout); + } + */ + + //if (v_info.interleave > 0) p_info.info_set("interleave", v_info.interleave); + //if (v_info.interleave_last > 0) p_info.info_set("interleave_last_block", v_info.interleave_last); + //if (v_info.block_size > 0) p_info.info_set("block_size", v_info.block_size); } t_filestats input_vgmstream::get_file_stats(abort_callback & p_abort) { @@ -283,8 +316,10 @@ void input_vgmstream::decode_initialize(t_uint32 p_subsong, unsigned p_flags, ab // called when audio buffer needs to be filled bool input_vgmstream::decode_run(audio_chunk & p_chunk, abort_callback & p_abort) { - if (!decoding) return false; - if (!vgmstream) return false; + if (!decoding) + return false; + if (!vgmstream) + return false; int max_buffer_samples = SAMPLE_BUFFER_SIZE; int samples_to_do = max_buffer_samples; @@ -319,44 +354,46 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk, abort_callback & p_abort } // called when seeking -void input_vgmstream::decode_seek(double p_seconds, abort_callback & p_abort) { - int32_t seek_sample = (int)audio_math::time_to_samples(p_seconds, vgmstream->sample_rate); +void input_vgmstream::decode_seek(double p_seconds, abort_callback& p_abort) { + int64_t seek_sample = (int64_t)audio_math::time_to_samples(p_seconds, vgmstream->sample_rate); bool play_forever = vgmstream_get_play_forever(vgmstream); + // TODO: check play position after seek_sample and let seek clamp // possible when disabling looping without refreshing foobar's cached song length // (p_seconds can't go over seek bar with infinite looping on, though) if (seek_sample > length_samples) seek_sample = length_samples; - seek_vgmstream(vgmstream, seek_sample); + seek_vgmstream(vgmstream, (int32_t)seek_sample); decode_pos_samples = seek_sample; decode_pos_ms = decode_pos_samples * 1000LL / vgmstream->sample_rate; decoding = play_forever || decode_pos_samples < length_samples; } -bool input_vgmstream::decode_can_seek() {return true;} -bool input_vgmstream::decode_get_dynamic_info(file_info & p_out, double & p_timestamp_delta) { return false; } -bool input_vgmstream::decode_get_dynamic_info_track(file_info & p_out, double & p_timestamp_delta) {return false;} -void input_vgmstream::decode_on_idle(abort_callback & p_abort) {/*m_file->on_idle(p_abort);*/} +bool input_vgmstream::decode_can_seek() { return true; } +bool input_vgmstream::decode_get_dynamic_info(file_info& p_out, double& p_timestamp_delta) { return false; } +bool input_vgmstream::decode_get_dynamic_info_track(file_info& p_out, double& p_timestamp_delta) { return false; } +void input_vgmstream::decode_on_idle(abort_callback& p_abort) { /*m_file->on_idle(p_abort);*/ } -void input_vgmstream::retag_set_info(t_uint32 p_subsong, const file_info & p_info, abort_callback & p_abort) { /*throw exception_io_data();*/ } -void input_vgmstream::retag_commit(abort_callback & p_abort) { /*throw exception_io_data();*/ } -void input_vgmstream::remove_tags(abort_callback & p_abort) { /*throw exception_io_data();*/ } +void input_vgmstream::retag_set_info(t_uint32 p_subsong, const file_info& p_info, abort_callback& p_abort) { /*throw exception_io_data();*/ } +void input_vgmstream::retag_commit(abort_callback& p_abort) { /*throw exception_io_data();*/ } +void input_vgmstream::remove_tags(abort_callback& p_abort) { /*throw exception_io_data();*/ } -bool input_vgmstream::g_is_our_content_type(const char * p_content_type) { return false; } +bool input_vgmstream::g_is_our_content_type(const char* p_content_type) { return false; } // called to check if file can be processed by the plugin -bool input_vgmstream::g_is_our_path(const char * p_path, const char * p_extension) { +bool input_vgmstream::g_is_our_path(const char* p_path, const char* p_extension) { vgmstream_ctx_valid_cfg cfg = {0}; - cfg.is_extension = 1; + cfg.is_extension = true; input_vgmstream::g_load_cfg(&cfg.accept_unknown, &cfg.accept_common); return vgmstream_ctx_is_valid(p_extension, &cfg) > 0 ? true : false; } + // internal util to create a VGMSTREAM -VGMSTREAM* input_vgmstream::init_vgmstream_foo(t_uint32 p_subsong, const char * const filename, abort_callback & p_abort) { +VGMSTREAM* input_vgmstream::init_vgmstream_foo(t_uint32 p_subsong, const char* const filename, abort_callback& p_abort) { VGMSTREAM* vgmstream = NULL; /* Workaround for a foobar bug (mainly for complex TXTP): @@ -387,10 +424,8 @@ void input_vgmstream::setup_vgmstream(abort_callback & p_abort) { // subsong and filename are always defined before this vgmstream = init_vgmstream_foo(subsong, filename, p_abort); - if (!vgmstream) { + if (!vgmstream) throw exception_io_data(); - return; - } // default subsong is 0, meaning first init (vgmstream should open first stream, but not set stream_index). // if the stream_index is already set, then the subsong was opened directly by some means (txtp, playlist, etc). @@ -414,21 +449,33 @@ void input_vgmstream::setup_vgmstream(abort_callback & p_abort) { length_samples = vgmstream_get_samples(vgmstream); } +void input_vgmstream::apply_config(VGMSTREAM* vgmstream) { + vgmstream_cfg_t vcfg = {0}; + + vcfg.allow_play_forever = true; + vcfg.play_forever = loop_forever; + vcfg.loop_count = loop_count; + vcfg.fade_time = fade_seconds; + vcfg.fade_delay = fade_delay_seconds; + vcfg.ignore_loop = ignore_loop; + + vgmstream_apply_config(vgmstream, &vcfg); +} + // internal util to get info -void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & title, int *length_in_ms, int *total_samples, int *loop_flag, int *loop_start, int *loop_end, int *sample_rate, int *channels, int *bitrate, pfc::string_base & description, abort_callback & p_abort) { +void input_vgmstream::query_subsong_info(t_uint32 p_subsong, vgmstream_info_t& v_info, abort_callback& p_abort) { VGMSTREAM* infostream = NULL; bool is_infostream = false; - char temp[1024]; int info_channels; + char temp[1024]; - // reuse current vgmstream if not querying a new subsong - // if it's a direct subsong then subsong may be N while p_subsong 1 - // there is no need to recreate the infostream, there is only one subsong used + // Reuse current vgmstream if not querying a new subsong. + // If it's a direct subsong then subsong may be N while p_subsong = 1 + // so there is no need to recreate the infostream, only one subsong is used. if (subsong != p_subsong && !direct_subsong) { infostream = init_vgmstream_foo(p_subsong, filename, p_abort); - if (!infostream) { + if (!infostream) throw exception_io_data(); - } is_infostream = true; @@ -436,42 +483,67 @@ void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & ti vgmstream_mixing_autodownmix(infostream, downmix_channels); vgmstream_mixing_enable(infostream, 0, NULL /*&input_channels*/, &info_channels); - } else { + } + else { // vgmstream ready as get_info is valid after open() with any reason infostream = vgmstream; info_channels = output_channels; } + if (!infostream) + throw exception_io_data(); - if (length_in_ms) { - *length_in_ms = -1000; - if (infostream) { - *channels = info_channels; - *sample_rate = infostream->sample_rate; - *total_samples = infostream->num_samples; - *bitrate = get_vgmstream_average_bitrate(infostream); - *loop_flag = infostream->loop_flag; - *loop_start = infostream->loop_start_sample; - *loop_end = infostream->loop_end_sample; + /* basic info */ + { + v_info.channels = info_channels; + v_info.input_channels = infostream->channels; + v_info.sample_rate = infostream->sample_rate; + v_info.stream_samples = infostream->num_samples; + v_info.bitrate = get_vgmstream_average_bitrate(infostream); + v_info.loop_flag = infostream->loop_flag; + v_info.loop_start = infostream->loop_start_sample; + v_info.loop_end = infostream->loop_end_sample; + + v_info.subsong_count = infostream->num_streams; + v_info.subsong_index = infostream->stream_index; + if (v_info.subsong_index == 0) + v_info.subsong_index = 1; + + v_info.channel_layout = infostream->channel_layout; + + int64_t play_duration = vgmstream_get_samples(infostream); + v_info.play_length_s = (double)play_duration / (double)infostream->sample_rate; + + v_info.bits_per_sample = sizeof(short) * 8; + } - int num_samples = vgmstream_get_samples(infostream); - *length_in_ms = num_samples*1000LL / infostream->sample_rate; + // formatted info + { + pfc::string8 description; - describe_vgmstream(infostream, temp, sizeof(temp)); - description = temp; - } - } + describe_vgmstream(infostream, temp, sizeof(temp)); + description = temp; + + query_description_tag(v_info.codec_name, description, "encoding: "); + query_description_tag(v_info.layout_name, description, "layout: "); + query_description_tag(v_info.meta_name, description, "metadata from: "); + query_description_tag(v_info.stream_name, description, "stream name: "); + query_description_tag(v_info.channel_mask, description, "channel mask: "); + //query_description_tag(temp, description,"interleave: ",' '); + //query_description_tag(temp, description,"interleave last block:",' '); + //query_description_tag(temp, description,"block size: "); + } - /* infostream gets added with index 0 (other) or 1 (current) */ - if (infostream && title) { + // infostream gets added with index 0 (other) or 1 (current) + { vgmstream_title_t tcfg = {0}; - tcfg.remove_extension = 1; - tcfg.remove_archive = 1; + tcfg.remove_extension = true; + tcfg.remove_archive = true; const char* filename_str = filename; vgmstream_get_title(temp, sizeof(temp), filename_str, infostream, &tcfg); - title = temp; + v_info.title = temp; } // and only close if was querying a new subsong @@ -481,51 +553,41 @@ void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & ti } } -bool input_vgmstream::get_description_tag(pfc::string_base & temp, pfc::string_base const& description, const char *tag, char delimiter) { - // extract a "tag" from the description string - t_size pos = description.find_first(tag); - t_size eos; - if (pos != pfc::infinite_size) { - pos += strlen(tag); - eos = description.find_first(delimiter, pos); - if (eos == pfc::infinite_size) eos = description.length(); - temp.set_string(description + pos, eos - pos); - //console::formatter() << "tag=" << tag << ", delim=" << delimiter << "temp=" << temp << ", pos=" << pos << "" << eos; - return true; - } - return false; -} +// extract a "tag" from the description string +bool input_vgmstream::query_description_tag(pfc::string_base& tag_value, pfc::string_base const& description, const char* tag_key, char delimiter) { -void input_vgmstream::apply_config(VGMSTREAM* vgmstream) { - vgmstream_cfg_t vcfg = {0}; + t_size pos = description.find_first(tag_key); + if (pos == pfc::infinite_size) + return false; + pos += strlen(tag_key); - vcfg.allow_play_forever = 1; - vcfg.play_forever = loop_forever; - vcfg.loop_count = loop_count; - vcfg.fade_time = fade_seconds; - vcfg.fade_delay = fade_delay_seconds; - vcfg.ignore_loop = ignore_loop; + t_size eos = description.find_first(delimiter, pos); + if (eos == pfc::infinite_size) + eos = description.length(); - vgmstream_apply_config(vgmstream, &vcfg); + tag_value.set_string(description + pos, eos - pos); + return true; } + +// checks priority (foobar 1.4+) +bool input_vgmstream::g_is_low_merit() { + return true; +} + +// foobar recognizes plugin with this (meaning, different GUID = different plugin) GUID input_vgmstream::g_get_guid() { static const GUID guid = { 0x9e7263c7, 0x4cdd, 0x482c,{ 0x9a, 0xec, 0x5e, 0x71, 0x28, 0xcb, 0xc3, 0x4 } }; return guid; } -const char * input_vgmstream::g_get_name() { - return "vgmstream"; -} - GUID input_vgmstream::g_get_preferences_guid() { static const GUID guid = { 0x2b5d0302, 0x165b, 0x409c,{ 0x94, 0x74, 0x2c, 0x8c, 0x2c, 0xd7, 0x6a, 0x25 } }; return guid; } -// checks priority (foobar 1.4+) -bool input_vgmstream::g_is_low_merit() { - return true; +const char* input_vgmstream::g_get_name() { + return "vgmstream"; } // foobar plugin defs diff --git a/fb2k/foo_vgmstream.h b/fb2k/foo_vgmstream.h index e3f0ef309..e59feb511 100644 --- a/fb2k/foo_vgmstream.h +++ b/fb2k/foo_vgmstream.h @@ -1,12 +1,41 @@ #ifndef _FOO_VGMSTREAM_ #define _FOO_VGMSTREAM_ -#define SAMPLE_BUFFER_SIZE 1024 +#define SAMPLE_BUFFER_SIZE 1024 +#define FOO_PATH_LIMIT 4096 /* see vgmstream_limits.h*/ extern "C" { #include "../src/vgmstream.h" } +typedef struct { + pfc::string8_fast title; + pfc::string8_fast stream_name; + pfc::string8_fast layout_name; + pfc::string8_fast codec_name; + pfc::string8_fast meta_name; + pfc::string8_fast channel_mask; + + int channels; + int sample_rate; + + int input_channels; + int subsong_count; + int subsong_index; + + int bits_per_sample; + + int64_t stream_samples; + int64_t loop_start; + int64_t loop_end; + bool loop_flag; + + int bitrate; + uint32_t channel_layout; + + double play_length_s; + +} vgmstream_info_t; class input_vgmstream : public input_stubs { public: @@ -65,7 +94,7 @@ class input_vgmstream : public input_stubs { double fade_delay_seconds; double loop_count; bool loop_forever; - int ignore_loop; + bool ignore_loop; bool disable_subsongs; int downmix_channels; @@ -76,13 +105,19 @@ class input_vgmstream : public input_stubs { //bool exts_unknown_on; /* helpers */ + void load_settings(); + + void put_info_tags(file_info& p_info, vgmstream_info_t& v_info); + void put_into_tagfile(file_info& p_info, abort_callback& p_abort); + void put_info_details(file_info& p_info, vgmstream_info_t& v_info); + VGMSTREAM* init_vgmstream_foo(t_uint32 p_subsong, const char* const filename, abort_callback& p_abort); void setup_vgmstream(abort_callback& p_abort); - void load_settings(); - void get_subsong_info(t_uint32 p_subsong, pfc::string_base& title, int* length_in_ms, int* total_samples, int* loop_flag, int *loop_start, int* loop_end, int* sample_rate, int* channels, int* bitrate, pfc::string_base& description, abort_callback& p_abort); - bool get_description_tag(pfc::string_base& temp, pfc::string_base const& description, const char* tag, char delimiter = '\n'); void apply_config(VGMSTREAM* vgmstream); + void query_subsong_info(t_uint32 p_subsong, vgmstream_info_t& v_info, abort_callback& p_abort); + bool query_description_tag(pfc::string_base& temp, pfc::string_base const& description, const char* tag, char delimiter = '\n'); + static void g_load_cfg(int* accept_unknown, int* accept_common); }; From a8163717d270b79edd43a6f57a13567a9a7f0841 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:43:41 +0200 Subject: [PATCH 13/17] cleanup: misc --- .gitignore | 11 ++++------- cli/api_example.c | 8 ++++---- src/base/api_libsf.c | 2 +- src/base/info.c | 6 +++--- src/base/mixer_ops_fade.c | 2 +- src/base/sbuf.h | 2 +- src/libvgmstream_streamfile.h | 2 +- winamp/in_utils.c | 2 +- 8 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 2e22a21b8..06cca28a1 100644 --- a/.gitignore +++ b/.gitignore @@ -46,8 +46,8 @@ ipch # build /version_auto.h /dependencies -/bin/**/* -/tmp/**/* +/bin +/tmp /**/vgmstream-win.zip /**/foo_input_vgmstream.fb2k-component @@ -64,10 +64,7 @@ CMakeFiles /audacious/Makefile cmake_install.cmake -#doc build -doc/INFO.md -doc/_build - +# doc stuff changelog.txt formats-info.md -__pycache__ \ No newline at end of file +__pycache__ diff --git a/cli/api_example.c b/cli/api_example.c index d76870829..0fd82286e 100644 --- a/cli/api_example.c +++ b/cli/api_example.c @@ -26,7 +26,7 @@ static FILE* get_output_file(const char* filename) { } static libvgmstream_streamfile_t* get_streamfile(const char* filename) { - return libvgmstream_streamfile_from_filename(filename); + return libvgmstream_streamfile_open_from_stdio(filename); } static int api_example(const char* infile) { @@ -204,10 +204,10 @@ static libvgmstream_streamfile_t* test_libsf_open() { libvgmstream_streamfile_t* libsf = NULL; - libsf = libvgmstream_streamfile_from_filename("api.bin_wrong"); + libsf = libvgmstream_streamfile_open_from_stdio("api.bin_wrong"); assert(libsf == NULL); - libsf = libvgmstream_streamfile_from_filename("api.bin"); + libsf = libvgmstream_streamfile_open_from_stdio("api.bin"); assert(libsf != NULL); return libsf; @@ -335,7 +335,7 @@ static void test_lib_tags() { libvgmstream_tags_t* tags = NULL; bool more = false; - libsf = libvgmstream_streamfile_from_filename("sample_!tags.m3u"); + libsf = libvgmstream_streamfile_open_from_stdio("sample_!tags.m3u"); assert(libsf != NULL); tags = libvgmstream_tags_init(libsf); diff --git a/src/base/api_libsf.c b/src/base/api_libsf.c index fc9d0d06d..c2318bd71 100644 --- a/src/base/api_libsf.c +++ b/src/base/api_libsf.c @@ -132,7 +132,7 @@ static libvgmstream_streamfile_t* libvgmstream_streamfile_from_streamfile(STREAM } -LIBVGMSTREAM_API libvgmstream_streamfile_t* libvgmstream_streamfile_from_filename(const char* filename) { +LIBVGMSTREAM_API libvgmstream_streamfile_t* libvgmstream_streamfile_open_from_stdio(const char* filename) { STREAMFILE* sf = open_stdio_streamfile(filename); if (!sf) return NULL; diff --git a/src/base/info.c b/src/base/info.c index 2a7a6ec8f..8929d3fa8 100644 --- a/src/base/info.c +++ b/src/base/info.c @@ -52,7 +52,7 @@ void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) { } if (vgmstream->channel_layout) { - int cl = vgmstream->channel_layout; + uint32_t cl = vgmstream->channel_layout; /* not "channel layout: " to avoid mixups with "layout: " */ snprintf(temp,TEMPSIZE, "channel mask: 0x%x /", vgmstream->channel_layout); @@ -63,8 +63,8 @@ void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) { if (cl & speaker_LFE) concatn(length,desc," LFE"); if (cl & speaker_BL) concatn(length,desc," BL"); if (cl & speaker_BR) concatn(length,desc," BR"); - if (cl & speaker_FLC) concatn(length,desc," FLC"); - if (cl & speaker_FRC) concatn(length,desc," FRC"); + if (cl & speaker_FLC) concatn(length,desc," FLC"); //FCL is also common + if (cl & speaker_FRC) concatn(length,desc," FRC"); //FCR is also common if (cl & speaker_BC) concatn(length,desc," BC"); if (cl & speaker_SL) concatn(length,desc," SL"); if (cl & speaker_SR) concatn(length,desc," SR"); diff --git a/src/base/mixer_ops_fade.c b/src/base/mixer_ops_fade.c index 973f64564..f0670da07 100644 --- a/src/base/mixer_ops_fade.c +++ b/src/base/mixer_ops_fade.c @@ -34,7 +34,7 @@ static inline float get_fade_gain_curve(char shape, float index) { break; case 'Q': /* quarter of sine wave (for musical fades) */ - gain = sin(index * MIXING_PI / 2.0f); + gain = sinf(index * MIXING_PI / 2.0f); break; case 'p': /* parabola (maybe for crossfades) */ diff --git a/src/base/sbuf.h b/src/base/sbuf.h index c0e6c5006..329b08f43 100644 --- a/src/base/sbuf.h +++ b/src/base/sbuf.h @@ -6,7 +6,7 @@ // TODO decide if using float 1.0 style or 32767 style (fuzzy PCM changes when doing that) static inline void sbuf_copy_s16_to_f32(float* buf_f32, int16_t* buf_s16, int samples, int channels) { for (int s = 0; s < samples * channels; s++) { - buf_f32[s] = buf_s16[s]; // / 32767.0f + buf_f32[s] = (float)buf_s16[s]; // / 32767.0f } } diff --git a/src/libvgmstream_streamfile.h b/src/libvgmstream_streamfile.h index 19fdc4973..809765f47 100644 --- a/src/libvgmstream_streamfile.h +++ b/src/libvgmstream_streamfile.h @@ -60,7 +60,7 @@ static inline void libvgmstream_streamfile_close(libvgmstream_streamfile_t* libs } -LIBVGMSTREAM_API libvgmstream_streamfile_t* libvgmstream_streamfile_from_filename(const char* filename); +LIBVGMSTREAM_API libvgmstream_streamfile_t* libvgmstream_streamfile_open_from_stdio(const char* filename); #endif #endif diff --git a/winamp/in_utils.c b/winamp/in_utils.c index 573585109..6b96ed268 100644 --- a/winamp/in_utils.c +++ b/winamp/in_utils.c @@ -40,7 +40,7 @@ void build_extension_list(char* winamp_list, int winamp_list_size) { for (i = 0; i < ext_list_len; i++) { int used = add_extension(winamp_list, winamp_list_size - description_size, ext_list[i]); if (used <= 0) { - vgm_logi("build_extension_list: not enough buf for all exts\n"); + //vgm_logi("build_extension_list: not enough buf for all exts\n"); break; } winamp_list += used; From f605e69a696f64779cf4966ffa22e13d4ad800a4 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:43:58 +0200 Subject: [PATCH 14/17] cleanup: disable some msvc warnings --- Directory.Build.props | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Directory.Build.props b/Directory.Build.props index 3d9381dbb..b59223277 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,6 +6,12 @@ + + + C4267;C4244 + + v143 From 6e5b04176144b227b0763fd21808f3d017adecd0 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:46:26 +0200 Subject: [PATCH 15/17] doc --- .github/formats-info.py | 1 + doc/FORMATS.md | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/formats-info.py b/.github/formats-info.py index a5ffdfa96..04b0b6ed6 100644 --- a/.github/formats-info.py +++ b/.github/formats-info.py @@ -52,6 +52,7 @@ 'txth.c','txtp.c','genh.c', 'silence.c', 'mp4_faac.c', 'deblock_streamfile.c', 'ps_headerless.c', 'zwdsp.c', + 'txtp_parser.c', 'txtp_process.c', ] EXT_RENAMES = {'...': '(any)', '': '(extensionless)'} diff --git a/doc/FORMATS.md b/doc/FORMATS.md index be5cddeb9..7033d8188 100644 --- a/doc/FORMATS.md +++ b/doc/FORMATS.md @@ -272,7 +272,7 @@ different internally (encrypted, different versions, etc) and not always can be - RIFX WAVE header (smpl looping) [*RIFX_WAVE_smpl*] - *riff*: `.wav .lwav .xwav .mwv .da .dax .cd .med .snd .adx .adp .xss .xsew .adpcm .adw .wd .(extensionless) .sbv .wvx .str .at3 .rws .aud .at9 .ckd .saf .ima .nsa .pcm .xvag .ogg .logg .p1d .xms .mus .dat .ldat .wma .lwma .caf .wax .voi .se` - *rifx*: `.wav .lwav` - - Codecs: AICA_int PCM32LE PCM24LE PCM16BE PCM16LE PCM8_U MSADPCM IMA PCMFLOAT MS_IMA AICA MPEG_custom XBOX_IMA MS_IMA_3BIT DVI_IMA L5_555 OGG_VORBIS ATRAC9 ATRAC3 MPEG MSADPCM_mono + - Codecs: AICA_int PCM32LE PCM24LE PCM16BE PCM16LE PCM8_U MSADPCM IMA PCMFLOAT MS_IMA AICA MPEG_custom XBOX_IMA MS_IMA_3BIT DVI_IMA LEVEL5 OGG_VORBIS ATRAC9 ATRAC3 MPEG MSADPCM_mono - **nwa.c** - VisualArt's NWA header (NWAINFO.INI looping) [*NWA_NWAINFOINI*] - VisualArt's NWA header (Gameexe.ini looping) [*NWA_GAMEEXEINI*] @@ -389,10 +389,6 @@ different internally (encrypted, different versions, etc) and not always can be - Square Enix .vsv Header [*VSV*] - *vsv*: `.vsv .psh` - Codecs: PSX -- **ps2_pcm.c** - - Konami .PCM header [*PS2_PCM*] - - *ps2_pcm*: `.pcm` - - Codecs: PCM16LE - **rkv.c** - Legacy of Kain - Blood Omen 2 RKV PS2 header [*PS2_RKV*] - Legacy of Kain - Blood Omen 2 RKV GC header [*NGC_RKV*] @@ -503,8 +499,8 @@ different internally (encrypted, different versions, etc) and not always can be - Subfiles: *ogg_vorbis_config* - Codecs: PCM16LE PCM16BE PSX XBOX_IMA_mch XBOX_IMA NGC_DSP NGC_DSP_subint RAD_IMA OGG FFmpeg(various) ATRAC3 XMA - **bgw.c** - - Square Enix .BGW header [*FFXI_BGW*] - - Square Enix .SPW header [*FFXI_SPW*] + - Square Enix BGMStream header [*BGW*] + - Square Enix SeWave header [*SPW*] - *bgw*: `.bgw` - *spw*: `.spw` - Codecs: PSX_cfg ATRAC3 PCM16LE @@ -676,9 +672,9 @@ different internally (encrypted, different versions, etc) and not always can be - beatmania IIDX 2DX9 header [*2DX9*] - *2dx9*: `.2dx9` - Codecs: MSADPCM -- **ngc_dsp_ygo.c** - - Konami custom DSP Header [*DSP_YGO*] - - *dsp_ygo*: `.dsp` +- **dsp_kceje.c** + - Konami .DSP Header [*DSP_KCEJE*] + - *dsp_kceje*: `.dsp` - Codecs: NGC_DSP - **ps2_vgv.c** - Rune: Viking Warlord VGV Header [*PS2_VGV*] @@ -894,7 +890,7 @@ different internally (encrypted, different versions, etc) and not always can be - *alp*: `.tun .pcm` - Codecs: HV_IMA - **wpd.c** - - WPD 'DPW' header [*WPD*] + - Navel WPD header [*WPD*] - *wpd*: `.wpd` - Codecs: PCM16LE - **mn_str.c** @@ -1095,7 +1091,7 @@ different internally (encrypted, different versions, etc) and not always can be - Rockstar AWC header [*AWC*] - *awc*: `.awc` - Subfiles: *riff* - - Codecs: PCM16BE PCM16LE AWC_IMA XMA2 MPEG VORBIS_custom ATRAC9 NGC_DSP + - Codecs: PCM16BE PCM16LE AWC_IMA XMA2 MPEG_custom MPEG VORBIS_custom ATRAC9 NGC_DSP - **opus.c** - Nintendo Switch OPUS header [*OPUS*] - *opus_std*: `.opus .lopus .bgm .opu .ogg .logg + .psi` @@ -1878,6 +1874,10 @@ different internally (encrypted, different versions, etc) and not always can be - Naxat .ASD header [*ASD_NAXAT*] - *asd_naxat*: `.asd` - Codecs: PCM16LE +- **pcm_kceje.c** + - Konami .PCM header [*PCM_KCEJE*] + - *pcm_kceje*: `.pcm` + - Codecs: PCM16LE - **pos.c** - RIFF WAVE header (.pos looping) [*RIFF_WAVE_POS*] - *pos*: `.pos + .wav` @@ -2014,7 +2014,7 @@ are used in few games. - Konami MTA2 ADPCM - FMOD FADPCM ADPCM - Procyon Studio ADPCM - - Level-5 0x555 ADPCM + - Level-5 ADPCM - Konami XMD ADPCM - Argonaut ASF ADPCM - Tantalus ADPCM From 0709ad1d87e2f12d5915203a24ac702f2b383500 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:46:33 +0200 Subject: [PATCH 16/17] Add HCA keys --- src/meta/hca_keys.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/meta/hca_keys.h b/src/meta/hca_keys.h index b0c18cbb5..f6c64daf9 100644 --- a/src/meta/hca_keys.h +++ b/src/meta/hca_keys.h @@ -1320,6 +1320,12 @@ static const hcakey_info hcakey_list[] = { // Reynatis (Switch) {5963496778882477625}, // 52C298B97479EE39 + // Buddysma!! ~Smartphone Start! Buddyfight (Android) + {8132462270}, // 00000001E4BB86BE + + // Code Geass: Lost Stories (Android) + {9182735170}, // 0000000223556B42 + }; #endif/*_HCA_KEYS_H_*/ From edcffe05c41e95dd25095d75e71921a0c346dff8 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 10 Aug 2024 23:48:36 +0200 Subject: [PATCH 17/17] Fix some custom/buggy .dsp --- src/meta/ngc_dsp_std.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/meta/ngc_dsp_std.c b/src/meta/ngc_dsp_std.c index 20d8e8d5c..28461e49e 100644 --- a/src/meta/ngc_dsp_std.c +++ b/src/meta/ngc_dsp_std.c @@ -1,11 +1,12 @@ #include "meta.h" #include "../layout/layout.h" #include "../coding/coding.h" +#include "../util/endianness.h" /* If these variables are packed properly in the struct (one after another) * then this is actually how they are laid out in the file, albeit big-endian */ -struct dsp_header { +typedef struct { uint32_t sample_count; /* 0x00 */ uint32_t nibble_count; /* 0x04 (includes frame headers) */ uint32_t sample_rate; /* 0x08 (generally 22/32/44/48kz but games like Wario World set 32028hz to adjust for GC's rate) */ @@ -26,13 +27,13 @@ struct dsp_header { uint16_t block_size; /* 0x4c */ /* padding/reserved up to 0x60, DSPADPCM.exe from GC adds garbage here (uninitialized MSVC memory?) * [ex. Batallion Wars (GC), Timesplitters 2 (GC)], 0xcccc...cccc with DSPADPCMD */ -}; +} dsp_header_t; /* read and do basic validations to the above struct */ -static bool read_dsp_header_endian(struct dsp_header *header, off_t offset, STREAMFILE* sf, int big_endian) { - uint32_t (*get_u32)(const uint8_t*) = big_endian ? get_u32be : get_u32le; - uint16_t (*get_u16)(const uint8_t*) = big_endian ? get_u16be : get_u16le; - int16_t (*get_s16)(const uint8_t*) = big_endian ? get_s16be : get_s16le; +static bool read_dsp_header_endian(dsp_header_t* header, off_t offset, STREAMFILE* sf, bool big_endian) { + get_u32_t get_u32 = big_endian ? get_u32be : get_u32le; + get_u16_t get_u16 = big_endian ? get_u16be : get_u16le; + get_s16_t get_s16 = big_endian ? get_s16be : get_s16le; uint8_t buf[0x60]; int zero_coefs; @@ -71,9 +72,11 @@ static bool read_dsp_header_endian(struct dsp_header *header, off_t offset, STRE header->loop_start_offset = get_u32(buf+0x10); header->loop_end_offset = get_u32(buf+0x14); + //TODO: test if games react to changed initial offset + /* Dr. Muto uses 0, and some custom Metroid Prime loop start, so probably ignored by the hardware */ header->initial_offset = get_u32(buf+0x18); - if (header->initial_offset != 2 && header->initial_offset != 0) - goto fail; /* Dr. Muto uses 0 */ + if (header->initial_offset != 2 && header->initial_offset != 0 && header->initial_offset != header->loop_start_offset) + goto fail; zero_coefs = 0; for (int i = 0; i < 16; i++) { @@ -110,10 +113,10 @@ static bool read_dsp_header_endian(struct dsp_header *header, off_t offset, STRE fail: return false; } -static int read_dsp_header_be(struct dsp_header *header, off_t offset, STREAMFILE* file) { +static int read_dsp_header_be(dsp_header_t *header, off_t offset, STREAMFILE* file) { return read_dsp_header_endian(header, offset, file, 1); } -static int read_dsp_header_le(struct dsp_header *header, off_t offset, STREAMFILE* file) { +static int read_dsp_header_le(dsp_header_t *header, off_t offset, STREAMFILE* file) { return read_dsp_header_endian(header, offset, file, 0); } @@ -154,7 +157,7 @@ static VGMSTREAM* init_vgmstream_dsp_common(STREAMFILE* sf, dsp_meta* dspm) { VGMSTREAM* vgmstream = NULL; int i, j; int loop_flag; - struct dsp_header ch_header[COMMON_DSP_MAX_CHANNELS]; + dsp_header_t ch_header[COMMON_DSP_MAX_CHANNELS]; if (dspm->channels > dspm->max_channels) @@ -306,7 +309,7 @@ static VGMSTREAM* init_vgmstream_dsp_common(STREAMFILE* sf, dsp_meta* dspm) { /* .dsp - standard mono dsp as generated by DSPADPCM.exe */ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - struct dsp_header header; + dsp_header_t header; const size_t header_size = 0x60; off_t start_offset; int i, channels; @@ -338,7 +341,7 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { // (but .dsp is the common case, so it'd be slower) { int ko; - struct dsp_header header2; + dsp_header_t header2; /* ignore headers one after another */ ko = !read_dsp_header_be(&header2, header_size, sf); @@ -427,7 +430,7 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { /* .dsp - little endian dsp, possibly main Switch .dsp [LEGO Worlds (Switch)] */ VGMSTREAM* init_vgmstream_ngc_dsp_std_le(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - struct dsp_header header; + dsp_header_t header; const size_t header_size = 0x60; off_t start_offset; int i, channels; @@ -450,7 +453,7 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std_le(STREAMFILE* sf) { * In many cases these will pass all the other checks, including the * predictor/scale check if the first byte is 0 */ { - struct dsp_header header2; + dsp_header_t header2; int ko; ko = !read_dsp_header_le(&header2, header_size, sf); @@ -510,7 +513,7 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std_le(STREAMFILE* sf) { /* .dsp - standard multi-channel dsp as generated by DSPADPCM.exe (later revisions) */ VGMSTREAM* init_vgmstream_ngc_mdsp_std(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - struct dsp_header header; + dsp_header_t header; const size_t header_size = 0x60; off_t start_offset; int i, c, channels;