From 5005788fb5c553765d1ff134798bb5c77126b101 Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 3 May 2024 13:41:31 +0200 Subject: [PATCH 1/4] doc/util --- src/meta/deblock_streamfile.c | 2 +- src/streamfile.c | 6 +++--- src/streamfile.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/meta/deblock_streamfile.c b/src/meta/deblock_streamfile.c index bd1b5305..b218c6e3 100644 --- a/src/meta/deblock_streamfile.c +++ b/src/meta/deblock_streamfile.c @@ -18,7 +18,7 @@ static size_t deblock_io_read(STREAMFILE* sf, uint8_t* dest, off_t offset, size_ /* re-start when previous offset (can't map logical<>physical offsets) */ if (data->logical_offset < 0 || offset < data->logical_offset) { - ;VGM_LOG("DEBLOCK: restart offset=%lx + %x, po=%lx, lo=%lx\n", offset, length, data->physical_offset, data->logical_offset); + //;VGM_LOG("DEBLOCK: restart offset=%lx + %x, po=%lx, lo=%lx\n", offset, length, data->physical_offset, data->logical_offset); data->physical_offset = data->cfg.stream_start; data->logical_offset = 0x00; data->block_size = 0; diff --git a/src/streamfile.c b/src/streamfile.c index 8566febf..183c76bc 100644 --- a/src/streamfile.c +++ b/src/streamfile.c @@ -1002,7 +1002,6 @@ STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size) { /* ************************************************************************* */ -/* debug util, mainly for custom IO testing */ void dump_streamfile(STREAMFILE* sf, int num) { #ifdef VGM_DEBUG_OUTPUT offv_t offset = 0; @@ -1019,7 +1018,7 @@ void dump_streamfile(STREAMFILE* sf, int num) { if (!f) return; } - VGM_LOG("dump streamfile: size %x\n", get_streamfile_size(sf)); + VGM_LOG("dump streamfile %i: size %x\n", num, get_streamfile_size(sf)); while (offset < get_streamfile_size(sf)) { uint8_t buf[0x8000]; size_t bytes; @@ -1032,8 +1031,9 @@ void dump_streamfile(STREAMFILE* sf, int num) { if (f) fwrite(buf, sizeof(uint8_t), bytes, f); - else + else if (num == -1) VGM_LOGB(buf, bytes, 0); + //else: don't do anything (read test) offset += bytes; } diff --git a/src/streamfile.h b/src/streamfile.h index d3e89091..f41039a9 100644 --- a/src/streamfile.h +++ b/src/streamfile.h @@ -151,7 +151,7 @@ static inline size_t get_streamfile_size(STREAMFILE* sf) { return sf->get_size(sf); } - +/* debug util, mainly for custom IO testing (num = writes file N, -1 = printfs, -2 = only reads) */ void dump_streamfile(STREAMFILE* sf, int num); #endif From 88c5abba00b234cf927fb205f7e55d9c52ec98b2 Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 3 May 2024 13:45:59 +0200 Subject: [PATCH 2/4] Add RAGE aud MPEG [GTA IV (PS3)] --- src/coding/coding.h | 3 +- src/coding/mpeg_custom_utils.c | 10 +-- src/coding/mpeg_decoder.c | 9 +-- src/meta/rage_aud.c | 58 ++++++++++------- src/meta/rage_aud_streamfile.h | 110 +++++++++++++++++++++++---------- 5 files changed, 124 insertions(+), 66 deletions(-) diff --git a/src/coding/coding.h b/src/coding/coding.h index f26193c9..8f19ff2d 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -519,7 +519,8 @@ int mpeg_get_sample_rate(mpeg_codec_data* data); long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data); uint32_t mpeg_get_tag_size(STREAMFILE* sf, uint32_t offset, uint32_t header); -int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info); +bool mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info); +bool mpeg_get_frame_info_h(uint32_t header, mpeg_frame_info* info); int test_ahx_key(STREAMFILE* sf, off_t offset, crikey_t* crikey); #endif diff --git a/src/coding/mpeg_custom_utils.c b/src/coding/mpeg_custom_utils.c index b86c9c38..01636782 100644 --- a/src/coding/mpeg_custom_utils.c +++ b/src/coding/mpeg_custom_utils.c @@ -8,7 +8,7 @@ int mpeg_custom_setup_init_default(STREAMFILE* sf, off_t start_offset, mpeg_code /* get frame info at offset */ - if ( !mpeg_get_frame_info(sf, start_offset, &info)) + if (!mpeg_get_frame_info(sf, start_offset, &info)) goto fail; switch(info.layer) { case 1: *coding_type = coding_MPEG_layer1; break; @@ -264,7 +264,7 @@ fail: * Gets info from a MPEG frame header at offset. Normally you would use mpg123_info but somehow * it's wrong at times (maybe because we use an ancient version) so here we do our thing. */ -static int mpeg_get_frame_info_h(uint32_t header, mpeg_frame_info* info) { +bool mpeg_get_frame_info_h(uint32_t header, mpeg_frame_info* info) { /* index tables */ static const int versions[4] = { /* MPEG 2.5 */ 3, /* reserved */ -1, /* MPEG 2 */ 2, /* MPEG 1 */ 1 }; static const int layers[4] = { -1,3,2,1 }; @@ -330,12 +330,12 @@ static int mpeg_get_frame_info_h(uint32_t header, mpeg_frame_info* info) { default: goto fail; } - return 1; + return true; fail: - return 0; + return false; } -int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info) { +bool mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info) { uint32_t header = read_u32be(offset, sf); return mpeg_get_frame_info_h(header, info); } diff --git a/src/coding/mpeg_decoder.c b/src/coding/mpeg_decoder.c index c3de6cca..2092ae06 100644 --- a/src/coding/mpeg_decoder.c +++ b/src/coding/mpeg_decoder.c @@ -113,9 +113,9 @@ fail: /* Init custom MPEG, with given type and config */ -mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* coding_type, int channels, mpeg_custom_t type, mpeg_custom_config* config) { +mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* coding_type, int channels, mpeg_custom_t type, mpeg_custom_config* cfg) { mpeg_codec_data* data = NULL; - int i, ok; + int ok; /* init codec */ data = calloc(1, sizeof(mpeg_codec_data)); @@ -124,7 +124,8 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* /* keep around to decode */ data->custom = 1; data->type = type; - memcpy(&data->config, config, sizeof(mpeg_custom_config)); + if (cfg) + memcpy(&data->config, cfg, sizeof(mpeg_custom_config)); data->config.channels = channels; data->default_buffer_size = MPEG_DATA_BUFFER_SIZE; @@ -161,7 +162,7 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* data->streams_size += 1; data->streams = calloc(data->streams_size, sizeof(mpeg_custom_stream*)); - for (i = 0; i < data->streams_size; i++) { + for (int i = 0; i < data->streams_size; i++) { data->streams[i] = calloc(1, sizeof(mpeg_custom_stream)); data->streams[i]->m = init_mpg123_handle(); /* decoder not shared as may need several frames to decode)*/ if (!data->streams[i]->m) goto fail; diff --git a/src/meta/rage_aud.c b/src/meta/rage_aud.c index f10fb088..93b4bef0 100644 --- a/src/meta/rage_aud.c +++ b/src/meta/rage_aud.c @@ -1,6 +1,7 @@ #include "meta.h" #include "../coding/coding.h" #include "../layout/layout.h" +#include "../util.h" #include "../util/endianness.h" #include "rage_aud_streamfile.h" @@ -22,7 +23,7 @@ typedef struct { uint32_t stream_size; } aud_header; -static int parse_aud_header(STREAMFILE* sf, aud_header* aud); +static bool parse_aud_header(STREAMFILE* sf, aud_header* aud); static layered_layout_data* build_layered_rage_aud(STREAMFILE* sf, aud_header* aud); @@ -88,15 +89,14 @@ VGMSTREAM* init_vgmstream_rage_aud(STREAMFILE* sf) { #ifdef VGM_USE_MPEG case 0x0100: { /* MPEG (PS3) */ - mpeg_custom_config cfg = {0}; if (aud.is_streamed) { - goto fail; + vgmstream->layout_data = build_layered_rage_aud(sf, &aud); + if (!vgmstream->layout_data) goto fail; + vgmstream->layout_type = layout_layered; + vgmstream->coding_type = coding_MPEG_custom; } else { - cfg.chunk_size = aud.block_chunk; - cfg.big_endian = aud.big_endian; - - vgmstream->codec_data = init_mpeg_custom(sf, aud.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, &cfg); + vgmstream->codec_data = init_mpeg_custom(sf, aud.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, NULL); if (!vgmstream->codec_data) goto fail; vgmstream->layout_type = layout_none; } @@ -126,7 +126,7 @@ fail: } /* Parse Rockstar's AUD header (much info from SparkIV). */ -static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { +static bool parse_aud_header(STREAMFILE* sf, aud_header* aud) { int target_subsong = sf->stream_index; read_u64_t read_u64; read_u32_t read_u32; @@ -139,8 +139,8 @@ static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { read_u16 = aud->big_endian ? read_u16be : read_u16le; uint64_t table_offset = read_u64(0x00, sf); - if (table_offset > 0x18000) /* typically 0x1c~0x1000, seen 0x17BE8 */ - return 0; + if (table_offset > 0x20000 || table_offset < 0x1c) /* typically 0x1c~0x1000, seen ~0x19000 */ + return false; /* use bank's stream count to detect */ aud->is_streamed = (read_u32(0x10, sf) == 0); @@ -160,14 +160,14 @@ static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { aud->stream_offset = read_u32(0x2c, sf); channel_info_offset = channel_table_offset + aud->channels * 0x10; - /* block count is off in rare XMA streams: + /* block count is off in rare XMA streams, though we only need it to check the header: * GTA4 - Header says 2 blocks, actually has 3 - EP1_SFX/RP03_ML * MCLA - Header says 3 blocks, actually has 4 - AUDIO/X360/SFX/AMBIENCE_STREAM/AMB_QUADSHOT_MALL_ADVERT_09 */ uint32_t expected_size = aud->block_count * aud->block_chunk + aud->stream_offset; if (expected_size != get_streamfile_size(sf) && expected_size + aud->block_chunk != get_streamfile_size(sf)) { - VGM_LOG("RAGE AUD: bad file size\n"); - goto fail; + //;VGM_LOG("RAGE AUD: bad file size\n"); + return false; } /* channel table (one entry per channel, points to channel info) */ @@ -186,7 +186,8 @@ static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { aud->codec = read_u32(channel_info_offset + 0x1c, sf); /* (when codec is IMA) */ /* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */ - /* rest: unknown data */ + /* rest: unknown data (varies per codec?) */ + /* in MC:LA there is samples-per-frame and frame size table for MPEG */ /* block table (one entry per block) */ /* 0x00: data size processed up to this block (doesn't count block padding) */ @@ -207,11 +208,11 @@ static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { /* 0x14(4): unknown */ aud->stream_offset = read_u32(0x18, sf); /* base start_offset */ - if (target_subsong == 0) target_subsong = 1; - if (target_subsong < 0 || target_subsong > aud->total_subsongs || aud->total_subsongs < 1) goto fail; - if (stream_table_offset != 0x1c) - goto fail; + return false; + if (!check_subsongs(&target_subsong, aud->total_subsongs)) + return false; + stream_info_offset = stream_table_offset + 0x10 * aud->total_subsongs; /* stream table (one entry per stream, points to stream info) */ @@ -234,13 +235,13 @@ static int parse_aud_header(STREAMFILE* sf, aud_header* aud) { /* 0x20(8): adpcm states offset, 0x38: num states? (reference for seeks?) */ /* rest: unknown data */ + /* GTA IV PS3's 0x7D27B1E8' #165 and #166 seem to point to the same wrong offset pointing to the middle of data + * (original bug/unused? maybe should allow MPEG resync?) */ + aud->channels = 1; } - return 1; - -fail: - return 0; + return true; } /* ************************************************************************* */ @@ -279,11 +280,20 @@ static VGMSTREAM* build_blocks_vgmstream(STREAMFILE* sf, aud_header* aud, int ch vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - //TODO //xma_fix_raw_samples(vgmstream, temp_sf, substream_offset, substream_size, 0, 0,0); /* samples are ok? */ break; } #endif + +#ifdef VGM_USE_MPEG + case 0x0100: { /* MPEG (PS3) */ + vgmstream->codec_data = init_mpeg_custom(temp_sf, substream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, NULL); + if (!vgmstream->codec_data) goto fail; + vgmstream->layout_type = layout_none; + break; + } +#endif + default: goto fail; } @@ -293,7 +303,7 @@ static VGMSTREAM* build_blocks_vgmstream(STREAMFILE* sf, aud_header* aud, int ch close_streamfile(temp_sf); return vgmstream; fail: - ;VGM_LOG("AUD: can't open decoder\n"); + ;VGM_LOG("RAGE AUD: can't open decoder\n"); close_vgmstream(vgmstream); close_streamfile(temp_sf); return NULL; diff --git a/src/meta/rage_aud_streamfile.h b/src/meta/rage_aud_streamfile.h index 7e73a6f4..e1b915d8 100644 --- a/src/meta/rage_aud_streamfile.h +++ b/src/meta/rage_aud_streamfile.h @@ -3,27 +3,30 @@ #include "deblock_streamfile.h" #include "../util/endianness.h" #include "../util/log.h" +#include "../coding/coding.h" -#define RAGE_AUD_MAX_MUSIC_CHANNELS 7 /* max known */ +#define RAGE_AUD_MAX_MUSIC_CHANNELS 7 /* known max */ +#define RAGE_AUD_FRAME_SIZE 0x800 /* ************************************************************************* */ typedef struct { - int start_entry; /* innacurate! */ + int start_entry; int entries; int32_t channel_skip; int32_t channel_samples; + uint32_t channel_size; /* size of this channel's data (not including padding) */ uint32_t frame_size; /* derived */ - uint32_t chunk_start; /* relative to block offset */ - uint32_t chunk_size; /* size of this channel's data (not including padding) */ + uint32_t chunk_start; /* relative to block offset */ + uint32_t chunk_size; /* size of this channel's data (may include padding) */ } rage_aud_block_t; typedef struct { int big_endian; - uint8_t codec; + int codec; int channels; uint32_t block_offset; uint32_t header_size; @@ -36,26 +39,30 @@ typedef struct { * - ... * - frames from channel N * - usually there is padding between channels or blocks - * + * * Header format: * - base header (for all channels) * 0x00: seek info offset (within block) * 0x08: seek table offset * 0x10: seek table offset * - channel info (per channel) - * 0x00: start entry for that channel? - * may be off by +1/+2? - * 0x04: frames in this channel (may be different between channels) - * 0x08: samples to discard in the beginning of this block (MPEG/XMA2) - * this seems to repeat XMA frames, which decoders don't like, so maybe they just skip whole frames + * 0x00: start entry/frame for that channel + * Sometimes a channel has N frames while next channel start_entry N+1/2, meaning last frames will be blank/padding + * 0x04: entries/frames in this channel (may be different between channels) + * This refers to 1 logical chunk of N sub-frames (XMA1=single XMA super-frame, MPEG=N VBR frames). + * May be partially/fully blank in MPEG and sizes/paddings aren't very consistent even in similar files (MA:LA's HANGOUT_CROWD_*). + * 0x08: samples to discard in the beginning of this block? (MPEG/XMA2) + * When this is set, channel repeats XMA/MPEG super-frames from prev block. However discard doesn't seem to match + * repeated samples, and skip value may be very small too (ex. just 4 skip samples but repeats make 8416 samples). + * So maybe they just skip data like we do below and don't actually use this value. * 0x0c: samples in channel without discard? (for MPEG/XMA2 can vary between channels) * (next fields only exists for MPEG) - * 0x10: close to number of frames but varies a bit? - * 0x14: channel chunk size (not counting padding) - * - seek table (entries for all channels) + * 0x10: close to number of VBR frames but varies a bit? + * 0x14: channel data size (not including padding between channels) + * - seek table (entries for all channels, 1 per frame) * 0x00: start? * 0x04: end? - * - padding until this block's end + * - padding up to data start */ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { read_s32_t read_s32 = bi->big_endian ? read_s32be : read_s32le; @@ -63,6 +70,7 @@ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { uint32_t channel_entry_size, seek_entry_size; uint32_t offset = bi->block_offset; int channels = bi->channels; + /* read stupid block crap + derived info at once so hopefully it's a bit easier to understand */ switch(bi->codec) { @@ -70,8 +78,13 @@ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { channel_entry_size = 0x10; seek_entry_size = 0x08; break; + case 0x0100: /* MPEG */ + channel_entry_size = 0x18; + seek_entry_size = 0x08; + break; default: - goto fail; + VGM_LOG("RAGE AUD: unknown codec %x\n", bi->codec); + return false; } /* base header */ @@ -85,7 +98,9 @@ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { bi->blk[ch].entries = read_s32(offset + 0x04, sf); bi->blk[ch].channel_skip = read_s32(offset + 0x08, sf); bi->blk[ch].channel_samples = read_s32(offset + 0x0c, sf); - /* others: optional */ + if (bi->codec == 0x0100) { /* MPEG */ + bi->blk[ch].channel_size = read_s32(offset + 0x14, sf); + } offset += channel_entry_size; } @@ -97,15 +112,15 @@ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { /* derived info */ for (int ch = 0; ch < channels; ch++) { + bi->blk[ch].frame_size = RAGE_AUD_FRAME_SIZE; /* XMA1 super-frame or MPEG chunk of N VBR frames */ + bi->blk[ch].chunk_size = bi->blk[ch].entries * bi->blk[ch].frame_size; /* full size between channels, may be padded */ + switch(bi->codec) { case 0x0000: /* XMA1 */ - bi->blk[ch].frame_size = 0x800; - bi->blk[ch].chunk_size = bi->blk[ch].entries * bi->blk[ch].frame_size; + bi->blk[ch].channel_size = bi->blk[ch].chunk_size; /* no padding */ break; - - /* in MPEG frames seem to be VBR, so would need channel chunk size */ default: - goto fail; + break; } } @@ -115,20 +130,22 @@ static bool read_rage_aud_block(STREAMFILE* sf, rage_aud_block_info_t* bi) { * a table as big as prev blocks, repeating old values for unused entries, so final header size is consistent */ if (!bi->header_size) bi->header_size = offset - bi->block_offset; - offset = bi->block_offset + align_size_to_block(bi->header_size, 0x800); + offset = bi->block_offset + align_size_to_block(bi->header_size, RAGE_AUD_FRAME_SIZE); } /* set frame starts per channel */ + uint32_t header_chunk = offset - bi->block_offset; for (int ch = 0; ch < channels; ch++) { - bi->blk[ch].chunk_start = offset - bi->block_offset; - offset += bi->blk[ch].chunk_size; + bi->blk[ch].chunk_start = header_chunk + bi->blk[ch].start_entry * bi->blk[ch].frame_size; + + /* unlike AWC there may be unknown padding between channels, so needs start_entry to calc offset */ + //bi->blk[ch].chunk_start = offset - bi->block_offset; + //offset += bi->blk[ch].chunk_size; } /* beyond this is padding until chunk_start */ return true; -fail: - return false; } /* Find data that repeats in the beginning of a new block at the end of last block. @@ -138,15 +155,41 @@ static uint32_t get_block_repeated_size(STREAMFILE* sf, rage_aud_block_info_t* b if (bi->blk[channel].channel_skip == 0) return 0; - if (bi->block_offset >= get_streamfile_size(sf)) - return 0; switch(bi->codec) { case 0x0000: { /* XMA1 */ - /* when data repeats seems to clone the last (super-)frame */ + /* when data repeats seems to clone the last super-frame */ return bi->blk[channel].frame_size; } + case 0x0100: { /* MPEG */ + /* first super-frame will repeat N VBR old sub-frames, without crossing frame_size. + * ex. repeated frames' size could be set to 0x774 (7 sub-frames) if adding 1 more would take >0x800. + * After last sub-frame there may be padding up to frame_size (GTA4 only?). */ + uint8_t frame[RAGE_AUD_FRAME_SIZE]; + uint32_t offset = bi->block_offset + bi->blk[channel].chunk_start; + + read_streamfile(frame, offset, sizeof(frame), sf); + + /* read sub-frames until padding or end */ + int skip_size = 0x00; + while (skip_size < sizeof(frame) - 0x04) { + if (frame[skip_size] == 0x00) /* padding found */ + return RAGE_AUD_FRAME_SIZE; + + mpeg_frame_info info = {0}; + uint32_t header = get_u32be(frame + skip_size); + if (!mpeg_get_frame_info_h(header, &info)) /* ? */ + return RAGE_AUD_FRAME_SIZE; + + if (skip_size + info.frame_size > sizeof(frame)) /* not a repeated frame */ + return skip_size; + skip_size += info.frame_size; + } + + return skip_size; /* skip_size fills frame size */ + } + default: ;VGM_LOG("RAGE_AUD: found channel skip in codec %x\n", bi->codec); /* not seen */ return 0; @@ -165,6 +208,9 @@ static void block_callback(STREAMFILE *sf, deblock_io_data* data) { bi.codec = data->cfg.track_type; bi.header_size = data->cfg.config; + if (bi.block_offset >= get_streamfile_size(sf)) + return; + if (!read_rage_aud_block(sf, &bi)) return; //??? data->cfg.config = bi.header_size; /* fixed for all blocks but calc'd on first one */ @@ -173,11 +219,11 @@ static void block_callback(STREAMFILE *sf, deblock_io_data* data) { data->block_size = data->cfg.chunk_size; data->skip_size = bi.blk[channel].chunk_start + repeat_size; - data->data_size = bi.blk[channel].chunk_size - repeat_size; + data->data_size = bi.blk[channel].channel_size - repeat_size; } /* deblocks RAGE_AUD blocks */ -static STREAMFILE* setup_rage_aud_streamfile(STREAMFILE* sf, uint32_t stream_offset, uint32_t stream_size, uint32_t block_size, int channels, int channel, uint8_t codec, int big_endian) { +static STREAMFILE* setup_rage_aud_streamfile(STREAMFILE* sf, uint32_t stream_offset, uint32_t stream_size, uint32_t block_size, int channels, int channel, int codec, bool big_endian) { STREAMFILE* new_sf = NULL; deblock_config_t cfg = {0}; From d520593fcb0dd3516a80455722c26d4a19f1063e Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 3 May 2024 13:48:23 +0200 Subject: [PATCH 3/4] Fix some MPEG .awc [GTA V (PS3)] --- src/meta/awc.c | 60 +++++++++++--------- src/meta/awc_streamfile.h | 115 +++++++++++++++++++++++++++----------- 2 files changed, 117 insertions(+), 58 deletions(-) diff --git a/src/meta/awc.c b/src/meta/awc.c index 21e08ddc..554a30a5 100644 --- a/src/meta/awc.c +++ b/src/meta/awc.c @@ -6,9 +6,10 @@ #include "awc_decryption_streamfile.h" typedef struct { - int big_endian; - int is_encrypted; - int is_streamed; /* implicit: streams=music, sfx=memory */ + bool big_endian; + bool is_encrypted; + bool is_streamed; /* implicit: streams=music, sfx=memory */ + bool is_alt; int total_subsongs; @@ -115,15 +116,17 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { #ifdef VGM_USE_MPEG case 0x07: { /* MPEG (PS3) */ - mpeg_custom_config cfg = {0}; - - cfg.chunk_size = awc.block_chunk; - cfg.big_endian = awc.big_endian; - - vgmstream->codec_data = init_mpeg_custom(sf_body, awc.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_AWC, &cfg); - if (!vgmstream->codec_data) goto fail; - vgmstream->layout_type = layout_none; - + if (awc.is_streamed) { + vgmstream->layout_data = build_layered_awc(sf_body, &awc); + if (!vgmstream->layout_data) goto fail; + vgmstream->layout_type = layout_layered; + vgmstream->coding_type = coding_FFmpeg; + } + else { + vgmstream->codec_data = init_mpeg_custom(sf_body, awc.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, NULL); + if (!vgmstream->codec_data) goto fail; + vgmstream->layout_type = layout_none; + } break; } #endif @@ -280,7 +283,7 @@ static int parse_awc_header(STREAMFILE* sf, awc_header* awc) { /* flags = 8b (always FF) + 8b (actual flags) + 16b (version, 00=rarely, 01=common) */ if ((flags & 0xFF00FFFF) != 0xFF000001 || (flags & 0x00F00000)) { VGM_LOG("AWC: unknown flags 0x%08x\n", flags); - goto fail; + return false; } /* stream tag starts (ex. stream#0 = 0, stream#1 = 4, stream#2 = 7: to read tags from stream#2 skip to 7th tag) */ @@ -288,17 +291,16 @@ static int parse_awc_header(STREAMFILE* sf, awc_header* awc) { offset += 0x2 * entries; /* seems to indicate chunks are not ordered (ie. header structures from tags may go after data), usually for non-streams */ - //if (flags % 0x00020000) - // awc->is_unordered = 1; + //if (flags & 0x00020000) + // awc->is_unordered = true; - /* stream/multichannel flag (rare, GTA5/RDR2) */ - //if (flags % 0x00040000) - // awc->is_multichannel = 1; + /* stream/multichannel flag? (GTA5, some RDR2), can be used to detect some odd behavior in GTA5 vs RDR1 */ + if (flags & 0x00040000) + awc->is_alt = true; /* encrypted data chunk (most of GTA5 PC for licensed audio) */ if (flags & 0x00080000) - awc->is_encrypted = 1; - + awc->is_encrypted = true; /* When first stream hash/id is 0 AWC it has fake entry with info for all channels = music, sfx pack otherwise. * sfx = N single streams, music = N interleaved mono channels (even for MP3/XMA/Vorbis/etc). @@ -439,12 +441,12 @@ static int parse_awc_header(STREAMFILE* sf, awc_header* awc) { } awc->num_samples = read_u32(tag_offset + 0x00,sf); - /* 0x04: -1? */ + /* 0x04: -1? (loop related?) */ awc->sample_rate = read_u16(tag_offset + 0x08,sf); /* 0x0a: headroom */ - /* 0x0c: unknown */ - /* 0x0e: unknown */ - /* 0x10: unknown */ + /* 0x0c: unknown (loop related?) */ + /* 0x0e: unknown (loop related?) */ + /* 0x10: unknown (loop related?) */ /* 0x12: null? */ awc->codec = read_u8(tag_offset + 0x13, sf); /* 0x14: ? (PS3 only, for any codec) */ @@ -561,7 +563,7 @@ static VGMSTREAM* build_blocks_vgmstream(STREAMFILE* sf, awc_header* awc, int ch /* setup custom IO streamfile that removes AWC's odd blocks (not perfect but serviceable) */ - temp_sf = setup_awc_streamfile(sf, awc->stream_offset, awc->stream_size, awc->block_chunk, awc->channels, channel, awc->codec, awc->big_endian); + temp_sf = setup_awc_streamfile(sf, awc->stream_offset, awc->stream_size, awc->block_chunk, awc->channels, channel, awc->codec, awc->big_endian, awc->is_alt); if (!temp_sf) goto fail; substream_offset = 0x00; @@ -591,6 +593,14 @@ static VGMSTREAM* build_blocks_vgmstream(STREAMFILE* sf, awc_header* awc, int ch break; } #endif +#ifdef VGM_USE_MPEG + case 0x07: { /* MPEG (PS3) */ + vgmstream->codec_data = init_mpeg_custom(temp_sf, substream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, NULL); + if (!vgmstream->codec_data) goto fail; + vgmstream->layout_type = layout_none; + break; + } +#endif #ifdef VGM_USE_VORBIS case 0x08: { vorbis_custom_config cfg = {0}; diff --git a/src/meta/awc_streamfile.h b/src/meta/awc_streamfile.h index aa7b67cb..b05c5729 100644 --- a/src/meta/awc_streamfile.h +++ b/src/meta/awc_streamfile.h @@ -4,20 +4,22 @@ #include "../util/endianness.h" #define AWC_MAX_MUSIC_CHANNELS 32 /* seen ~24 */ +#define AWC_FRAME_SIZE 0x800 /* ************************************************************************* */ typedef struct { - int start_entry; /* innacurate! */ + int start_entry; /* inaccurate! */ int entries; int32_t channel_skip; int32_t channel_samples; + uint32_t channel_size; /* size of this channel's data (not including padding) */ uint32_t frame_size; /* derived */ - uint32_t chunk_start; /* relative to block offset */ - uint32_t chunk_size; /* size of this channel's data (not including padding) */ + uint32_t chunk_start; /* relative to block offset */ + uint32_t chunk_size; /* size of this channel's data (may include padding) */ } awc_block_t; typedef struct { @@ -34,26 +36,28 @@ typedef struct { * - ... * - frames from channel N * - usually there is padding between channels or blocks (usually 0s but seen 0x97 in AT9) - * + * * Header format: - * - per channel (frame start table) - * 0x00: start entry for that channel? (-1 in vorbis) - * may be off by +1/+2? - * ex. on block 0, ch0/1 have 0x007F frames, a start entry is: ch0=0x0000, ch1=0x007F (MP3) - * ex. on block 0, ch0/1 have 0x02A9 frames, a start entry is: ch0=0x0000, ch1=0x02AA (AT9) !! - * (sum of all values from all channels may go beyond all posible frames, no idea) - * 0x04: frames in this channel (may be different between channels) - * 'frames' here may be actual single decoder frames or a chunk of frames + * - channel info (per channel) + * 0x00: start entry/frame for that channel? (-1 in vorbis, innacurate in MPEG/AT9, ? in XMA) + * Unlike RAGE-aud, this value isn't useful to calculate data offsets and possibly just used for seek table. + * ex. on block 0, ch0/1 have 0x02A9 frames, start entry is: ch0=0x0000, ch1=0x02AA (AT9) !! (would be 1 frame into ch2) + * 0x04: entries/frames in this channel (may be different between channels) + * This refers to 1 logical chunk of N sub-frames + * MPEG padding works differently vs RAGE-aud too. * 0x08: samples to discard in the beginning of this block (MPEG/XMA2/Vorbis only?) + * When this is set, channel repeats XMA/MPEG super-frames from prev block. However discard doesn't seem to match + * repeated samples, and skip value may be smaller (ex. just 1152 skip samples but repeats make 4608 samples). + * So maybe they just skip data like we do below and don't actually use this value. * 0x0c: samples in channel (for MPEG/XMA2 can vary between channels) * full samples without removing samples to discard * (next fields only exists for MPEG, Vorbis or some IMA versions) * 0x10: (MPEG only, empty otherwise) close to number of frames but varies a bit? * 0x14: (MPEG only, empty otherwise) channel chunk size (not counting padding) - * - for each channel (seek table) - * 32b * entries = global samples per frame in each block (for MPEG probably per full frame) - * (AT9 doesn't have a seek table as it's CBR) - * - per channel (ATRAC9/DSP extra info): + * - seek table (entries for all channels, 1 per frame) + * 0x00: global samples per frame in each block (for MPEG probably per full frame) + * (AT9 doesn't have a seek table as it's CBR) + * - extra info (per channel, ATRAC9/DSP ony): * 0x00: "D11A" * 0x04: frame size * 0x06: frame samples @@ -61,11 +65,7 @@ typedef struct { * 0x0a: sample rate * 0x0c: ATRAC9 config (repeated but same for all blocks) or "D11E" (DSP) * 0x10-0x70: padding with 0x77 (ATRAC3) or standard DSP header for original full file (DSP) - * - padding until channel data start, depending on codec (DSP/ATRAC9: one, others: aligned to 0x800) - * - per channel: - * 0xNN: channel frames - * 0xNN: may have padding between channels depending on codec (mainly MPEG/XMA) - * - padding until this block's end + * - padding up to data start, depending on codec (DSP/ATRAC9: none, others: aligned to 0x800) */ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { read_s32_t read_s32 = bi->big_endian ? read_s32be : read_s32le; @@ -74,6 +74,7 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { uint32_t channel_entry_size, seek_entry_size, extra_entry_size, header_padding; uint32_t offset = bi->block_offset; int channels = bi->channels; + /* read stupid block crap + derived info at once so hopefully it's a bit easier to understand */ switch(bi->codec) { @@ -83,6 +84,7 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { extra_entry_size = 0x00; header_padding = 0x800; break; + case 0x07: /* MPEG */ case 0x08: /* Vorbis */ channel_entry_size = 0x18; seek_entry_size = 0x04; @@ -96,7 +98,7 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { header_padding = 0x00; break; default: - goto fail; + return false; } /* channel info table */ @@ -105,7 +107,9 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { bi->blk[ch].entries = read_s32(offset + 0x04, sf); bi->blk[ch].channel_skip = read_s32(offset + 0x08, sf); bi->blk[ch].channel_samples = read_s32(offset + 0x0c, sf); - /* others: optional */ + if (bi->codec == 0x07) { /* MPEG */ + bi->blk[ch].channel_size = read_s32(offset + 0x14, sf); + } offset += channel_entry_size; } @@ -123,17 +127,22 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { /* each 'frame'/entry in Vorbis is actually N vorbis frames then padding up to 0x800 * (more or less like a big Ogg page or XMA 'frame'). Padding is considered part of * the data and handled by the decoder, since sfx (non-blocked) algo have it. */ - bi->blk[ch].frame_size = 0x800; + bi->blk[ch].frame_size = AWC_FRAME_SIZE; bi->blk[ch].chunk_size = bi->blk[ch].entries * bi->blk[ch].frame_size; + bi->blk[ch].channel_size = bi->blk[ch].chunk_size; + break; + case 0x07: /* MPEG */ + bi->blk[ch].frame_size = AWC_FRAME_SIZE; /* approximate but not used like RAGE-aud */ + bi->blk[ch].chunk_size = align_size_to_block(bi->blk[ch].channel_size, 0x10); + //bi->blk[ch].channel_size = (pre-loaded); break; - case 0x0F: /* ATRAC9 */ bi->blk[ch].frame_size = read_u16(offset + 0x04, sf); bi->blk[ch].chunk_size = bi->blk[ch].entries * bi->blk[ch].frame_size; + bi->blk[ch].channel_size = bi->blk[ch].chunk_size; break; - default: - goto fail; + return false; } offset += extra_entry_size; } @@ -154,14 +163,12 @@ static bool read_awc_block(STREAMFILE* sf, awc_block_info_t* bi) { /* beyond this is padding until chunk_start */ return true; -fail: - return false; } /* Find data that repeats in the beginning of a new block at the end of last block. * When a new block starts there is some repeated data + channel_skip (for seeking + encoder delay?). * Detect it so decoder may ignore it. */ -static uint32_t get_block_repeated_size(STREAMFILE* sf, awc_block_info_t* bi, int channel) { +static uint32_t get_block_repeated_size(STREAMFILE* sf, awc_block_info_t* bi, int channel, bool is_alt) { if (bi->blk[channel].channel_skip == 0) return 0; @@ -172,6 +179,44 @@ static uint32_t get_block_repeated_size(STREAMFILE* sf, awc_block_info_t* bi, in /* when data repeats seems to clone the last (super-)frame */ return bi->blk[channel].frame_size; + case 0x07: { /* MPEG */ + /* first super-frame will repeat N VBR old sub-frames, without crossing frame_size. + * In GTA5 repeated sub-frames seems to match exactly repeated samples, while RDR seems to match 1 full frame (like RAGE-aud). + * ex. RDR: repeated frames' size could be set to 0x774 (7 sub-frames) if adding 1 more would take >0x800. + * ex. GTA5: repeated frames' samples could be set to 3456 = 3 * 1152 = size 0x420 + * This behavior may be hardcoded but seems detectable by a flag set in every(?) streamed GTA5 file (all platforms though). */ + uint8_t frame[AWC_FRAME_SIZE]; + uint32_t offset = bi->block_offset + bi->blk[channel].chunk_start; + + read_streamfile(frame, offset, sizeof(frame), sf); + + int frames = 0; + int max_frames = is_alt ? bi->blk[channel].channel_skip / 1152 : 999; + + /* read sub-frames until padding or end */ + int skip_size = 0x00; + while (skip_size < sizeof(frame) - 0x04) { + if (frames == max_frames) + return skip_size; + + if (frame[skip_size] == 0x00) /* possible? */ + return AWC_FRAME_SIZE; + + mpeg_frame_info info = {0}; + uint32_t header = get_u32be(frame + skip_size); + if (!mpeg_get_frame_info_h(header, &info)) /* ? */ + return AWC_FRAME_SIZE; + + if (skip_size + info.frame_size > sizeof(frame)) /* not a repeated frame */ + return skip_size; + skip_size += info.frame_size; + + frames++; + } + + return skip_size; /* skip_size fills frame size */ + } + case 0x0F: /* ATRAC9 */ default: VGM_LOG("AWC: found channel skip in codec %x\n", bi->codec); /* not seen */ @@ -190,18 +235,21 @@ static void block_callback(STREAMFILE *sf, deblock_io_data* data) { bi.channels = data->cfg.track_count; bi.codec = data->cfg.track_type; + if (bi.block_offset >= get_streamfile_size(sf)) + return; + if (!read_awc_block(sf, &bi)) return; //??? - uint32_t repeat_size = get_block_repeated_size(sf, &bi, channel); + uint32_t repeat_size = get_block_repeated_size(sf, &bi, channel, data->cfg.config); data->block_size = data->cfg.chunk_size; data->skip_size = bi.blk[channel].chunk_start + repeat_size; - data->data_size = bi.blk[channel].chunk_size - repeat_size; + data->data_size = bi.blk[channel].channel_size - repeat_size; } /* deblocks AWC blocks */ -static STREAMFILE* setup_awc_streamfile(STREAMFILE* sf, uint32_t stream_offset, uint32_t stream_size, uint32_t block_size, int channels, int channel, uint8_t codec, int big_endian) { +static STREAMFILE* setup_awc_streamfile(STREAMFILE* sf, uint32_t stream_offset, uint32_t stream_size, uint32_t block_size, int channels, int channel, uint8_t codec, bool big_endian, bool is_alt) { STREAMFILE* new_sf = NULL; deblock_config_t cfg = {0}; @@ -215,6 +263,7 @@ static STREAMFILE* setup_awc_streamfile(STREAMFILE* sf, uint32_t stream_offset, cfg.chunk_size = block_size; cfg.track_type = codec; cfg.big_endian = big_endian; + cfg.config = is_alt; //cfg.physical_offset = stream_offset; //cfg.logical_size = awc_io_size(sf, &cfg); /* force init */ cfg.block_callback = block_callback; From 511a13b7d0a20599f00be895d02bde31ef009f05 Mon Sep 17 00:00:00 2001 From: bnnm Date: Fri, 3 May 2024 13:51:28 +0200 Subject: [PATCH 4/4] cleanup: remove unused MPEG_AWC --- src/coding/coding.h | 1 - src/coding/mpeg_custom_utils_awc.c | 184 ----------------------------- src/coding/mpeg_decoder.c | 2 - src/libvgmstream.vcxproj | 1 - src/libvgmstream.vcxproj.filters | 3 - 5 files changed, 191 deletions(-) delete mode 100644 src/coding/mpeg_custom_utils_awc.c diff --git a/src/coding/coding.h b/src/coding/coding.h index 8f19ff2d..0cbd1691 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -482,7 +482,6 @@ typedef enum { MPEG_EAL32P, /* EALayer3 v2 "PCM", custom frames with v2 header + bigger PCM blocks? */ MPEG_EAL32S, /* EALayer3 v2 "Spike", custom frames with v2 header + smaller PCM blocks? */ MPEG_LYN, /* N streams of fixed interleave */ - MPEG_AWC, /* N streams in block layout (music) or absolute offsets (sfx) */ MPEG_EAMP3 /* custom frame header + MPEG frame + PCM blocks */ } mpeg_custom_t; diff --git a/src/coding/mpeg_custom_utils_awc.c b/src/coding/mpeg_custom_utils_awc.c deleted file mode 100644 index fafcad36..00000000 --- a/src/coding/mpeg_custom_utils_awc.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "mpeg_decoder.h" - -#ifdef VGM_USE_MPEG - -/** - * AWC music uses blocks (sfx doesn't), the fun part being each channel has different num_samples/frames - * per block, so it's unsuitable for the normal "blocked" layout and parsed here instead. - * Channel data is separate within the block (first all frames of ch0, then ch1, etc), padded, and sometimes - * the last few frames of a channel are repeated in the new block (marked with the "discard samples" field). - */ - -/* block header size, algined/padded to 0x800 */ -static size_t get_block_header_size(STREAMFILE *streamFile, off_t offset, mpeg_codec_data *data) { - size_t header_size = 0; - int i; - int entries = data->config.channels; - int32_t (*read_32bit)(off_t,STREAMFILE*) = data->config.big_endian ? read_32bitBE : read_32bitLE; - - for (i = 0; i < entries; i++) { - header_size += 0x18; - header_size += read_32bit(offset + 0x18*i + 0x04, streamFile) * 0x04; /* entries in the table */ - } - - if (header_size % 0x800) /* padded */ - header_size += 0x800 - (header_size % 0x800); - - return header_size; -} - -/* find data that repeats in the beginning of a new block at the end of last block */ -static size_t get_repeated_data_size(STREAMFILE *streamFile, off_t new_offset, off_t last_offset) { - uint8_t new_frame[0x1000];/* buffer to avoid fseek back and forth */ - mpeg_frame_info info; - off_t off; - int i; - - /* read block first frame */ - if ( !mpeg_get_frame_info(streamFile, new_offset, &info)) - goto fail; - if (info.frame_size > 0x1000) - goto fail; - if (read_streamfile(new_frame,new_offset, info.frame_size,streamFile) != info.frame_size) - goto fail; - - /* find the frame in last bytes of prev block */ - off = last_offset - 0x4000; /* typical max is 5-10 frames of ~0x200, no way to know exact size */ - while (off < last_offset) { - /* compare frame vs prev block data */ - for (i = 0; i < info.frame_size; i++) { - if ((uint8_t)read_8bit(off+i,streamFile) != new_frame[i]) - break; - } - - /* frame fully compared? */ - if (i == info.frame_size) - return last_offset - off; - else - off += i+1; - } - -fail: - VGM_LOG("AWC: can't find repeat size, new=0x%08x, last=0x%08x\n", (uint32_t)new_offset, (uint32_t)last_offset); - return 0; /* keep on truckin' */ -} - - -/* init config and validate */ -int mpeg_custom_setup_init_awc(STREAMFILE *streamFile, off_t start_offset, mpeg_codec_data *data, coding_t *coding_type) { - mpeg_frame_info info; - int is_music; - - /* start_offset can point to a block header that always starts with 0 (music) or normal data (sfx) */ - is_music = read_32bitBE(start_offset, streamFile) == 0x00000000; - if (is_music) - start_offset += get_block_header_size(streamFile, start_offset, data); - - /* get frame info at offset */ - if ( !mpeg_get_frame_info(streamFile, start_offset, &info)) - goto fail; - switch(info.layer) { - case 1: *coding_type = coding_MPEG_layer1; break; - case 2: *coding_type = coding_MPEG_layer2; break; - case 3: *coding_type = coding_MPEG_layer3; break; - default: goto fail; - } - data->channels_per_frame = info.channels; - data->samples_per_frame = info.frame_samples; - - - /* extra checks */ - if (is_music) { - if (data->config.chunk_size <= 0) - goto fail; /* needs block size */ - } - - /* no big encoder delay added (for sfx they can start in less than ~300 samples) */ - - return 1; -fail: - return 0; -} - - -/* writes data to the buffer and moves offsets, parsing AWC blocks */ -int mpeg_custom_parse_frame_awc(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream) { - mpeg_custom_stream *ms = data->streams[num_stream]; - mpeg_frame_info info; - size_t current_data_size = 0, data_offset; - size_t file_size = get_streamfile_size(stream->streamfile); - int i; - - - /* blocked layout used for music */ - if (data->config.chunk_size) { - off_t last_offset = stream->offset; /* when block end needs to be known */ - - /* block ended for this channel, move to next block start */ - if (ms->current_size_count > 0 && ms->current_size_count == ms->current_size_target) { - //mpg123_open_feed(ms->m); //todo reset maybe needed? - - data_offset = stream->offset - stream->channel_start_offset; /* ignoring header */ - data_offset -= data_offset % data->config.chunk_size; /* start of current block */ - stream->offset = stream->channel_start_offset + data_offset + data->config.chunk_size; - - ms->current_size_count = 0; - ms->current_size_target = 0; - } - - /* just in case, shouldn't happen */ - if (stream->offset >= file_size) { - goto fail; - } - - /* block starts for this channel, point to mpeg data */ - if (ms->current_size_count == 0) { - int32_t (*read_32bit)(off_t,STREAMFILE*) = data->config.big_endian ? read_32bitBE : read_32bitLE; - off_t channel_offset = 0; - - /* block has a header with base info per channel and table per channel (see blocked_awc.c) */ - ms->decode_to_discard = read_32bit(stream->offset + 0x18*num_stream + 0x08, stream->streamfile); - ms->current_size_target = read_32bit(stream->offset + 0x18*num_stream + 0x14, stream->streamfile); - - for (i = 0; i < num_stream; i++) { /* num_stream serves as channel */ - size_t channel_size = read_32bit(stream->offset + 0x18*i + 0x14, stream->streamfile); - if (channel_size % 0x10) /* 32b aligned */ - channel_size += 0x10 - channel_size % 0x10; - - channel_offset += channel_size; - } - - //;VGM_ASSERT(ms->decode_to_discard > 0, "AWC: s%i discard of %x found at chunk %lx\n", num_stream, ms->decode_to_discard, stream->offset); - stream->offset += channel_offset + get_block_header_size(stream->streamfile, stream->offset, data); - - /* A new block may repeat frame bytes from prev block, and decode_to_discard has the number of repeated samples. - * However in RDR PS3 (not GTA5?) the value can be off (ie. discards 1152 but the repeat decodes to ~1152*4). - * I can't figure out why, so just find and skip the repeat data manually (probably better for mpg123 too) */ - if (ms->decode_to_discard) { - size_t repeat = get_repeated_data_size(stream->streamfile, stream->offset, last_offset); - if (repeat > 0) - ms->decode_to_discard = 0; - stream->offset += repeat; - ms->current_size_target -= repeat; - } - } - } - - - /* update frame */ - if ( !mpeg_get_frame_info(stream->streamfile, stream->offset, &info) ) - goto fail; - current_data_size = info.frame_size; - - ms->bytes_in_buffer = read_streamfile(ms->buffer,stream->offset, current_data_size, stream->streamfile); - - stream->offset += current_data_size; - - ms->current_size_count += current_data_size; - - return 1; -fail: - return 0; -} - -#endif diff --git a/src/coding/mpeg_decoder.c b/src/coding/mpeg_decoder.c index 2092ae06..75738b97 100644 --- a/src/coding/mpeg_decoder.c +++ b/src/coding/mpeg_decoder.c @@ -136,7 +136,6 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t* case MPEG_EAL31b: case MPEG_EAL32P: case MPEG_EAL32S: ok = mpeg_custom_setup_init_ealayer3(sf, start_offset, data, coding_type); break; - case MPEG_AWC: ok = mpeg_custom_setup_init_awc(sf, start_offset, data, coding_type); break; case MPEG_EAMP3: ok = mpeg_custom_setup_init_eamp3(sf, start_offset, data, coding_type); break; default: ok = mpeg_custom_setup_init_default(sf, start_offset, data, coding_type); break; } @@ -410,7 +409,6 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data* case MPEG_EAL32P: case MPEG_EAL32S: ok = mpeg_custom_parse_frame_ealayer3(stream, data, num_stream); break; case MPEG_AHX: ok = mpeg_custom_parse_frame_ahx(stream, data, num_stream); break; - case MPEG_AWC: ok = mpeg_custom_parse_frame_awc(stream, data, num_stream); break; case MPEG_EAMP3: ok = mpeg_custom_parse_frame_eamp3(stream, data, num_stream); break; default: ok = mpeg_custom_parse_frame_default(stream, data, num_stream); break; } diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 33313a33..726f87e0 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -251,7 +251,6 @@ - diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index c72a7ba7..217f50ba 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -574,9 +574,6 @@ coding\Source Files - - coding\Source Files - coding\Source Files