diff --git a/src/coding/vorbis_custom_decoder.h b/src/coding/vorbis_custom_decoder.h index c913d8bf..b9d8ca8a 100644 --- a/src/coding/vorbis_custom_decoder.h +++ b/src/coding/vorbis_custom_decoder.h @@ -54,4 +54,11 @@ int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL* stream, vorbis_custom_code int vorbis_custom_parse_packet_awc(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data); #endif/* VGM_USE_VORBIS */ +/* other utils to make/parse vorbis stuff */ +int build_header_comment(uint8_t* buf, int bufsize); +int build_header_identification(uint8_t* buf, int bufsize, vorbis_custom_config* cfg); +void load_blocksizes(vorbis_custom_config* cfg, int blocksize_short, int blocksize_long); +bool load_header_packet(STREAMFILE* sf, vorbis_custom_codec_data* data, uint32_t packet_size, int packet_skip, uint32_t* p_offset); + + #endif/*_VORBIS_CUSTOM_DECODER_H_ */ diff --git a/src/coding/vorbis_custom_utils.c b/src/coding/vorbis_custom_utils.c new file mode 100644 index 00000000..f9368f9e --- /dev/null +++ b/src/coding/vorbis_custom_utils.c @@ -0,0 +1,93 @@ +#include "vorbis_custom_decoder.h" + +#ifdef VGM_USE_VORBIS +int build_header_comment(uint8_t* buf, int bufsize) { + int bytes = 0x19; + + if (bytes > bufsize) return 0; + + put_u8 (buf+0x00, 0x03); /* packet_type (comments) */ + memcpy (buf+0x01, "vorbis", 6); /* id */ + put_u32le(buf+0x07, 0x09); /* vendor_length */ + memcpy (buf+0x0b, "vgmstream", 9); /* vendor_string */ + put_u32le(buf+0x14, 0x00); /* user_comment_list_length */ + put_u8 (buf+0x18, 0x01); /* framing_flag (fixed) */ + + return bytes; +} + +int build_header_identification(uint8_t* buf, int bufsize, vorbis_custom_config* cfg) { + int bytes = 0x1e; + + if (bytes > bufsize) + return 0; + + uint8_t blocksizes = (cfg->blocksize_0_exp << 4) | (cfg->blocksize_1_exp); + + put_u8 (buf+0x00, 0x01); /* packet_type (id) */ + memcpy (buf+0x01, "vorbis", 6); /* id */ + put_u32le(buf+0x07, 0x00); /* vorbis_version (fixed) */ + put_u8 (buf+0x0b, cfg->channels); /* audio_channels */ + put_u32le(buf+0x0c, cfg->sample_rate); /* audio_sample_rate */ + put_u32le(buf+0x10, 0x00); /* bitrate_maximum (optional hint) */ + put_u32le(buf+0x14, 0x00); /* bitrate_nominal (optional hint) */ + put_u32le(buf+0x18, 0x00); /* bitrate_minimum (optional hint) */ + put_u8 (buf+0x1c, blocksizes); /* blocksize_0 + blocksize_1 nibbles */ + put_u8 (buf+0x1d, 0x01); /* framing_flag (fixed) */ + + return bytes; +} + +bool make_header_identification(vorbis_custom_codec_data* data, vorbis_custom_config* cfg) { + + data->op.bytes = build_header_comment(data->buffer, data->buffer_size); + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + return false; + return true; +} + +void load_blocksizes(vorbis_custom_config* cfg, int blocksize_short, int blocksize_long) { + uint8_t exp_blocksize_0, exp_blocksize_1; + + /* guetto log2 for allowed blocksizes (2-exp), could be improved */ + switch(blocksize_long) { + case 64: exp_blocksize_0 = 6; break; + case 128: exp_blocksize_0 = 7; break; + case 256: exp_blocksize_0 = 8; break; + case 512: exp_blocksize_0 = 9; break; + case 1024: exp_blocksize_0 = 10; break; + case 2048: exp_blocksize_0 = 11; break; + case 4096: exp_blocksize_0 = 12; break; + case 8192: exp_blocksize_0 = 13; break; + default: exp_blocksize_0 = 0; + } + switch(blocksize_short) { + case 64: exp_blocksize_1 = 6; break; + case 128: exp_blocksize_1 = 7; break; + case 256: exp_blocksize_1 = 8; break; + case 512: exp_blocksize_1 = 9; break; + case 1024: exp_blocksize_1 = 10; break; + case 2048: exp_blocksize_1 = 11; break; + case 4096: exp_blocksize_1 = 12; break; + case 8192: exp_blocksize_1 = 13; break; + default: exp_blocksize_1 = 0; + } + + cfg->blocksize_0_exp = exp_blocksize_0; + cfg->blocksize_1_exp = exp_blocksize_1; +} + +bool load_header_packet(STREAMFILE* sf, vorbis_custom_codec_data* data, uint32_t packet_size, int packet_skip, uint32_t* p_offset) { + if (packet_size > data->buffer_size) + goto fail; + + data->op.bytes = read_streamfile(data->buffer, *p_offset + packet_skip, packet_size, sf); + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + goto fail; + *p_offset += packet_skip + packet_size; + + return true; +fail: + return false; +} +#endif/* VGM_USE_VORBIS */ \ No newline at end of file diff --git a/src/coding/vorbis_custom_utils_awc.c b/src/coding/vorbis_custom_utils_awc.c index b87793aa..bba5cce1 100644 --- a/src/coding/vorbis_custom_utils_awc.c +++ b/src/coding/vorbis_custom_utils_awc.c @@ -9,49 +9,35 @@ /* **************************************************************************** */ /** - * AWC removes the Ogg layer and uses 32b frame sizes for headers and 16b frame sizes for data + * AWC uses 32b frame sizes for headers and 16b frame sizes for data, + * with standard header packet triad. */ int vorbis_custom_setup_init_awc(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) { - off_t offset = data->config.header_offset; - size_t packet_size; + uint32_t offset = data->config.header_offset; + uint32_t packet_size; - /* read 3 packets with triad (id/comment/setup), each with an AWC header */ - - /* normal identificacion packet */ packet_size = read_u32le(offset, sf); - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer, offset + 0x04, packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + if (!load_header_packet(sf, data, packet_size, 0x04, &offset)) /* identificacion packet */ goto fail; - offset += 0x04 + packet_size; - /* normal comment packet */ packet_size = read_u32le(offset, sf); - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer, offset + 0x04, packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0) + if (!load_header_packet(sf, data, packet_size, 0x04, &offset)) /* comment packet */ goto fail; - offset += 0x04 + packet_size; - /* normal setup packet */ packet_size = read_u32le(offset, sf); - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer, offset + 0x04, packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + if (!load_header_packet(sf, data, packet_size, 0x04, &offset)) /* setup packet */ goto fail; - offset += 0x04 + packet_size; - /* data starts separate */ + /* data starts separate from headers */ data->config.data_start_offset = start_offset; return 1; - fail: return 0; } /* as AWC was coded by wackos, frames are forced to fit 0x800 chunks and rest is padded, in both sfx and music/blocked modes - * (ex. read frame until 0x7A0 + next frame is size 0x140 > pads 0x60 and last goes to next chunk) */ + * (ex. read frame until 0x7A0 + next frame is size 0x140 > pads 0x60 and last goes to next chunk) */ static inline off_t find_padding_awc(off_t offset, vorbis_custom_codec_data* data) { offset = offset - data->config.data_start_offset; @@ -61,7 +47,7 @@ static inline off_t find_padding_awc(off_t offset, vorbis_custom_codec_data* dat int vorbis_custom_parse_packet_awc(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data) { size_t bytes; - /* get next packet size from the AWC 16b header, except between chunks */ + /* get next packet size, except between chunks */ data->op.bytes = read_u16le(stream->offset, stream->streamfile); if (data->op.bytes == 0) { // || (stream->offset - start & 0x800) < 0x01 //todo could pad near block end? stream->offset += find_padding_awc(stream->offset, data); @@ -78,7 +64,6 @@ int vorbis_custom_parse_packet_awc(VGMSTREAMCHANNEL* stream, vorbis_custom_codec if (bytes != data->op.bytes) goto fail; /* wrong packet? */ return 1; - fail: return 0; } diff --git a/src/coding/vorbis_custom_utils_fsb.c b/src/coding/vorbis_custom_utils_fsb.c index 2a25a565..d44bcb74 100644 --- a/src/coding/vorbis_custom_utils_fsb.c +++ b/src/coding/vorbis_custom_utils_fsb.c @@ -13,8 +13,6 @@ /* DEFS */ /* **************************************************************************** */ -static int build_header_identification(uint8_t* buf, size_t bufsize, int channels, int sample_rate, int blocksize_short, int blocksize_long); -static int build_header_comment(uint8_t* buf, size_t bufsize); static int build_header_setup(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf); #if !(FSB_VORBIS_USE_PRECOMPILED_FVS) @@ -36,20 +34,21 @@ static int load_fvs_array(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREA int vorbis_custom_setup_init_fsb(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) { vorbis_custom_config cfg = data->config; - data->op.bytes = build_header_identification(data->buffer, data->buffer_size, cfg.channels, cfg.sample_rate, 256, 2048); /* FSB default block sizes */ - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse identification header */ + load_blocksizes(&cfg, 256, 2048); /* FSB default */ + + data->op.bytes = build_header_identification(data->buffer, data->buffer_size, &cfg); + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* identification packet */ + goto fail; data->op.bytes = build_header_comment(data->buffer, data->buffer_size); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) goto fail; /* parse comment header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* comment packet */ + goto fail; data->op.bytes = build_header_setup(data->buffer, data->buffer_size, cfg.setup_id, sf); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse setup header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* setup packet */ + goto fail; return 1; - fail: return 0; } @@ -78,66 +77,6 @@ fail: /* INTERNAL HELPERS */ /* **************************************************************************** */ -static int build_header_identification(uint8_t* buf, size_t bufsize, int channels, int sample_rate, int blocksize_short, int blocksize_long) { - int bytes = 0x1e; - uint8_t blocksizes, exp_blocksize_0, exp_blocksize_1; - - if (bytes > bufsize) return 0; - - /* guetto log2 for allowed blocksizes (2-exp), could be improved */ - switch(blocksize_long) { - case 64: exp_blocksize_0 = 6; break; - case 128: exp_blocksize_0 = 7; break; - case 256: exp_blocksize_0 = 8; break; - case 512: exp_blocksize_0 = 9; break; - case 1024: exp_blocksize_0 = 10; break; - case 2048: exp_blocksize_0 = 11; break; - case 4096: exp_blocksize_0 = 12; break; - case 8192: exp_blocksize_0 = 13; break; - default: return 0; - } - switch(blocksize_short) { - case 64: exp_blocksize_1 = 6; break; - case 128: exp_blocksize_1 = 7; break; - case 256: exp_blocksize_1 = 8; break; - case 512: exp_blocksize_1 = 9; break; - case 1024: exp_blocksize_1 = 10; break; - case 2048: exp_blocksize_1 = 11; break; - case 4096: exp_blocksize_1 = 12; break; - case 8192: exp_blocksize_1 = 13; break; - default: return 0; - } - blocksizes = (exp_blocksize_0 << 4) | (exp_blocksize_1); - - put_u8 (buf+0x00, 0x01); /* packet_type (id) */ - memcpy (buf+0x01, "vorbis", 6); /* id */ - put_u32le(buf+0x07, 0x00); /* vorbis_version (fixed) */ - put_u8 (buf+0x0b, channels); /* audio_channels */ - put_s32le(buf+0x0c, sample_rate); /* audio_sample_rate */ - put_u32le(buf+0x10, 0x00); /* bitrate_maximum (optional hint) */ - put_u32le(buf+0x14, 0x00); /* bitrate_nominal (optional hint) */ - put_u32le(buf+0x18, 0x00); /* bitrate_minimum (optional hint) */ - put_u8 (buf+0x1c, blocksizes); /* blocksize_0 + blocksize_1 nibbles */ - put_u8 (buf+0x1d, 0x01); /* framing_flag (fixed) */ - - return bytes; -} - -static int build_header_comment(uint8_t* buf, size_t bufsize) { - int bytes = 0x19; - - if (bytes > bufsize) return 0; - - put_u8 (buf+0x00, 0x03); /* packet_type (comments) */ - memcpy (buf+0x01, "vorbis", 6); /* id */ - put_u32le(buf+0x07, 0x09); /* vendor_length */ - memcpy (buf+0x0b, "vgmstream", 9); /* vendor_string */ - put_u32le(buf+0x14, 0x00); /* user_comment_list_length */ - put_u8 (buf+0x18, 0x01); /* framing_flag (fixed) */ - - return bytes; -} - static int build_header_setup(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf) { int bytes; diff --git a/src/coding/vorbis_custom_utils_ogl.c b/src/coding/vorbis_custom_utils_ogl.c index bafa949c..79b601e3 100644 --- a/src/coding/vorbis_custom_utils_ogl.c +++ b/src/coding/vorbis_custom_utils_ogl.c @@ -9,41 +9,29 @@ /* **************************************************************************** */ /** - * OGL removes the Ogg layer and uses 16b packet headers, that have the size of the next packet, but - * the lower 2b need to be removed (usually 00 but 01 for the id packet, not sure about the meaning). + * OGL uses 16b packet headers (14b size + 2b flags, usually 00 but 01 for the id packet), + * with standard header packet triad. */ int vorbis_custom_setup_init_ogl(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) { - off_t offset = start_offset; - size_t packet_size; + uint32_t offset = start_offset; + uint32_t packet_size; - /* read 3 packets with triad (id/comment/setup), each with an OGL header */ + packet_size = read_u16le(offset, sf) >> 2; + if (!load_header_packet(sf, data, packet_size, 0x02, &offset)) /* identificacion packet */ + goto fail; - /* normal identificacion packet */ - packet_size = (uint16_t)read_16bitLE(offset, sf) >> 2; - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse identification header */ - offset += 2+packet_size; + packet_size = read_u16le(offset, sf) >> 2; + if (!load_header_packet(sf, data, packet_size, 0x02, &offset)) /* comment packet */ + goto fail; - /* normal comment packet */ - packet_size = (uint16_t)read_16bitLE(offset, sf) >> 2; - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) goto fail; /* parse comment header */ - offset += 2+packet_size; - - /* normal setup packet */ - packet_size = (uint16_t)read_16bitLE(offset, sf) >> 2; - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse setup header */ - offset += 2+packet_size; + packet_size = read_u16le(offset, sf) >> 2; + if (!load_header_packet(sf, data, packet_size, 0x02, &offset)) /* setup packet */ + goto fail; /* data starts after triad */ data->config.data_start_offset = offset; return 1; - fail: return 0; } @@ -52,18 +40,17 @@ fail: int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data) { size_t bytes; - /* get next packet size from the OGL 16b header (upper 14b) */ - data->op.bytes = (uint16_t)read_16bitLE(stream->offset, stream->streamfile) >> 2; + /* get next packet size */ + data->op.bytes = read_u16le(stream->offset, stream->streamfile) >> 2; stream->offset += 2; if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) goto fail; /* EOF or end padding */ /* read raw block */ - bytes = read_streamfile(data->buffer,stream->offset, data->op.bytes,stream->streamfile); + bytes = read_streamfile(data->buffer, stream->offset, data->op.bytes, stream->streamfile); stream->offset += data->op.bytes; if (bytes != data->op.bytes) goto fail; /* wrong packet? */ return 1; - fail: return 0; } diff --git a/src/coding/vorbis_custom_utils_sk.c b/src/coding/vorbis_custom_utils_sk.c index c7a96bc3..eb796e79 100644 --- a/src/coding/vorbis_custom_utils_sk.c +++ b/src/coding/vorbis_custom_utils_sk.c @@ -7,7 +7,7 @@ /* DEFS */ /* **************************************************************************** */ -static int get_page_info(STREAMFILE* sf, off_t page_offset, off_t* p_packet_offset, size_t* p_packet_size, int* p_page_packets, int target_packet); +static bool get_page_info(STREAMFILE* sf, off_t page_offset, off_t* p_packet_offset, size_t* p_packet_size, int* p_page_packets, int target_packet); static int build_header(uint8_t* buf, size_t bufsize, STREAMFILE* sf, off_t packet_offset, size_t packet_size); @@ -19,7 +19,7 @@ static int build_header(uint8_t* buf, size_t bufsize, STREAMFILE* sf, off_t pack * SK just replaces the id 0x4F676753 ("OggS") by 0x11534B10 (\11"SK"\10), and the word "vorbis" by "SK" * in init packets (for obfuscation, surely). So essentially we are parsing regular Ogg here. * - * A simpler way to implement this would be in ogg_vorbis_file with read callbacks (pretend this is proof of concept). + * A simpler way to implement this may be using ogg_vorbis_file with read callbacks (pretend this is proof of concept). */ int vorbis_custom_setup_init_sk(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) { off_t offset = start_offset; @@ -27,7 +27,7 @@ int vorbis_custom_setup_init_sk(STREAMFILE* sf, off_t start_offset, vorbis_custo size_t id_size = 0, comment_size = 0, setup_size = 0; int page_packets; - /* rebuild header packets, they are standard except the "vorbis" keyword is replaced by "SK" */ + /* standard header packets except the "vorbis" keyword is replaced by "SK" */ /* first page has the id packet */ if (!get_page_info(sf, offset, &id_offset, &id_size, &page_packets, 0)) goto fail; @@ -69,12 +69,12 @@ int vorbis_custom_parse_packet_sk(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_ off_t packet_offset = 0; size_t packet_size = 0; int page_packets; - int res; + bool ok; /* read OggS/SK page and get current packet */ - res = get_page_info(stream->streamfile, stream->offset, &packet_offset, &packet_size, &page_packets, data->current_packet); + ok = get_page_info(stream->streamfile, stream->offset, &packet_offset, &packet_size, &page_packets, data->current_packet); data->current_packet++; - if (!res || packet_size > data->buffer_size) goto fail; + if (!ok || packet_size > data->buffer_size) goto fail; /* read raw block */ data->op.bytes = read_streamfile(data->buffer, packet_offset, packet_size, stream->streamfile); @@ -113,7 +113,7 @@ fail: * 0x--(n): data * Reference: https://xiph.org/ogg/doc/framing.html */ -static int get_page_info(STREAMFILE* sf, off_t page_offset, off_t* p_packet_offset, size_t* p_packet_size, int* p_page_packets, int target_packet) { +static bool get_page_info(STREAMFILE* sf, off_t page_offset, off_t* p_packet_offset, size_t* p_packet_size, int* p_page_packets, int target_packet) { off_t table_offset, current_packet_offset, target_packet_offset = 0; size_t total_packets_size = 0, current_packet_size = 0, target_packet_size = 0; int page_packets = 0; @@ -121,18 +121,18 @@ static int get_page_info(STREAMFILE* sf, off_t page_offset, off_t* p_packet_offs int i; - if (read_32bitBE(page_offset+0x00, sf) != 0x11534B10) /* \11"SK"\10 */ + if (read_u32be(page_offset+0x00, sf) != 0x11534B10) /* \11"SK"\10 */ goto fail; /* not a valid page */ /* No point on validating other stuff, but they look legal enough (CRC too it seems) */ - segments = (uint8_t)read_8bit(page_offset+0x1a, sf); + segments = read_u8(page_offset+0x1a, sf); table_offset = page_offset + 0x1b; current_packet_offset = page_offset + 0x1b + segments; /* first packet starts after segments */ /* process segments */ for (i = 0; i < segments; i++) { - uint8_t segment_size = (uint8_t)read_8bit(table_offset, sf); + uint8_t segment_size = read_u8(table_offset, sf); total_packets_size += segment_size; current_packet_size += segment_size; table_offset += 0x01; @@ -169,19 +169,21 @@ fail: return 0; } -/* rebuild a "SK" header packet to a "vorbis" one */ +/* rebuild a custom header packet into a "vorbis" one */ static int build_header(uint8_t* buf, size_t bufsize, STREAMFILE* sf, off_t packet_offset, size_t packet_size) { int bytes; + int vorbis_word_size = 0x02; /* "SK" */ - if (0x07+packet_size-0x03 > bufsize) return 0; - - put_u8(buf+0x00, read_8bit(packet_offset,sf)); /* packet_type */ - memcpy(buf+0x01, "vorbis", 6); /* id */ - bytes = read_streamfile(buf+0x07,packet_offset+0x03, packet_size-0x03,sf); /* copy rest (all except id+"SK") */ - if (packet_size-0x03 != bytes) + if (0x07 + packet_size - 0x01 - vorbis_word_size > bufsize) return 0; - return 0x07+packet_size-0x03; + put_u8(buf+0x00, read_u8(packet_offset,sf)); /* packet_type */ + memcpy(buf+0x01, "vorbis", 6); /* id */ + bytes = read_streamfile(buf+0x07, packet_offset + 0x01 + vorbis_word_size, packet_size - 0x01 - vorbis_word_size, sf); /* copy rest (all except id+"(vorbis word)") */ + if (packet_size - 0x03 != bytes) + return 0; + + return 0x07 + packet_size - 0x03; } #endif diff --git a/src/coding/vorbis_custom_utils_vid1.c b/src/coding/vorbis_custom_utils_vid1.c index c902d37b..b0665345 100644 --- a/src/coding/vorbis_custom_utils_vid1.c +++ b/src/coding/vorbis_custom_utils_vid1.c @@ -10,8 +10,7 @@ /* DEFS */ /* **************************************************************************** */ -static int get_packet_header(STREAMFILE* sf, off_t* offset, size_t* size); -static int build_header_comment(uint8_t* buf, size_t bufsize); +static int get_packet_header(STREAMFILE* sf, uint32_t* offset, uint32_t* size); /* **************************************************************************** */ @@ -20,36 +19,27 @@ static int build_header_comment(uint8_t* buf, size_t bufsize); /** * VID1 removes the Ogg layer and uses a block layout with custom packet headers. + * Has standard id/setup packets but removes comment packet. * * Info from hcs's vid1_2ogg: https://github.com/hcs64/vgm_ripping/tree/master/demux/vid1_2ogg */ int vorbis_custom_setup_init_vid1(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) { - off_t offset = start_offset; - size_t packet_size = 0; + uint32_t offset = start_offset; + uint32_t packet_size = 0; - /* read header packets (id/setup), each with an VID1 header */ - - /* normal identificacion packet */ get_packet_header(sf, &offset, &packet_size); - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer,offset,packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse identification header */ - offset += packet_size; + if (!load_header_packet(sf, data, packet_size, 0x00, &offset)) /* identificacion packet */ + goto fail; - /* generate comment packet */ data->op.bytes = build_header_comment(data->buffer, data->buffer_size); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) goto fail; /* parse comment header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0)/* comment packet */ + goto fail; - /* normal setup packet */ get_packet_header(sf, &offset, &packet_size); - if (packet_size > data->buffer_size) goto fail; - data->op.bytes = read_streamfile(data->buffer,offset,packet_size, sf); - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse setup header */ - offset += packet_size; + if (!load_header_packet(sf, data, packet_size, 0x00, &offset)) /* setup packet */ + goto fail; return 1; - fail: return 0; } @@ -60,23 +50,23 @@ int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL* stream, vorbis_custom_code /* test block start */ - if (read_32bitBE(stream->offset + 0x00,stream->streamfile) == 0x4652414D) { /* "FRAM" */ + if (is_id32be(stream->offset + 0x00,stream->streamfile, "FRAM")) { stream->offset += 0x20; - if (read_32bitBE(stream->offset + 0x00,stream->streamfile) == 0x56494444) { /* "VIDD"*/ - stream->offset += read_32bitBE(stream->offset + 0x04, stream->streamfile); + if (is_id32be(stream->offset + 0x00,stream->streamfile, "VIDD")) { + stream->offset += read_u32be(stream->offset + 0x04, stream->streamfile); } - if (read_32bitBE(stream->offset + 0x00,stream->streamfile) == 0x41554444) { /* "AUDD" */ + if (is_id32be(stream->offset + 0x00,stream->streamfile, "AUDD")) { data->block_offset = stream->offset; - data->block_size = read_32bitBE(stream->offset + 0x0c,stream->streamfile); + data->block_size = read_u32be(stream->offset + 0x0c,stream->streamfile); stream->offset += 0x14; /* actual start, rest is chunk sizes and maybe granule info */ } } /* get packet info the VID1 header */ - get_packet_header(stream->streamfile, &stream->offset, (size_t*)&data->op.bytes); + get_packet_header(stream->streamfile, (uint32_t*)&stream->offset, (uint32_t*)&data->op.bytes); if (data->op.bytes == 0 || data->op.bytes > data->buffer_size) goto fail; /* EOF or end padding */ /* read raw block */ @@ -88,7 +78,7 @@ int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL* stream, vorbis_custom_code /* test block end (weird size calc but seems ok) */ if ((stream->offset - (data->block_offset + 0x14)) >= (data->block_size - 0x06)) { - stream->offset = data->block_offset + read_32bitBE(data->block_offset + 0x04,stream->streamfile); + stream->offset = data->block_offset + read_u32be(data->block_offset + 0x04,stream->streamfile); } return 1; @@ -102,23 +92,8 @@ fail: /* INTERNAL HELPERS */ /* **************************************************************************** */ -static int build_header_comment(uint8_t* buf, size_t bufsize) { - int bytes = 0x19; - - if (bytes > bufsize) return 0; - - put_u8 (buf+0x00, 0x03); /* packet_type (comments) */ - memcpy (buf+0x01, "vorbis", 6); /* id */ - put_u32le(buf+0x07, 0x09); /* vendor_length */ - memcpy (buf+0x0b, "vgmstream", 9); /* vendor_string */ - put_u32le(buf+0x14, 0x00); /* user_comment_list_length */ - put_u8 (buf+0x18, 0x01); /* framing_flag (fixed) */ - - return bytes; -} - /* read header in Vorbis bitpacking format */ -static int get_packet_header(STREAMFILE* sf, off_t* offset, size_t* size) { +static int get_packet_header(STREAMFILE* sf, uint32_t* offset, uint32_t* size) { uint8_t ibuf[0x04]; /* header buffer */ size_t ibufsize = 0x04; /* header ~max */ bitstream_t ib = {0}; diff --git a/src/coding/vorbis_custom_utils_wwise.c b/src/coding/vorbis_custom_utils_wwise.c index eb09445d..00657d8b 100644 --- a/src/coding/vorbis_custom_utils_wwise.c +++ b/src/coding/vorbis_custom_utils_wwise.c @@ -23,9 +23,6 @@ typedef struct { uint8_t inxt[0x01]; } wpacket_t; -static size_t build_header_identification(uint8_t* buf, size_t bufsize, vorbis_custom_config* cfg); -static size_t build_header_comment(uint8_t* buf, size_t bufsize); - static int read_packet(wpacket_t* wp, uint8_t* ibuf, size_t ibufsize, STREAMFILE* sf, off_t offset, vorbis_custom_codec_data* data, int is_setup); static size_t rebuild_packet(uint8_t* obuf, size_t obufsize, wpacket_t* wp, STREAMFILE* sf, off_t offset, vorbis_custom_codec_data* data); static size_t rebuild_setup(uint8_t* obuf, size_t obufsize, wpacket_t* wp, STREAMFILE* sf, off_t offset, vorbis_custom_codec_data* data); @@ -64,44 +61,43 @@ int vorbis_custom_setup_init_wwise(STREAMFILE* sf, off_t start_offset, vorbis_cu ok = read_packet(&wp, data->buffer, data->buffer_size, sf, offset, data, 1); if (!ok) goto fail; data->op.bytes = wp.packet_size; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + goto fail; offset += wp.header_size + wp.packet_size; /* normal comment packet */ ok = read_packet(&wp, data->buffer, data->buffer_size, sf, offset, data, 1); if (!ok) goto fail; data->op.bytes = wp.packet_size; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + goto fail; offset += wp.header_size + wp.packet_size; /* normal setup packet */ ok = read_packet(&wp, data->buffer, data->buffer_size, sf, offset, data, 1); if (!ok) goto fail; data->op.bytes = wp.packet_size; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) + goto fail; offset += wp.header_size + wp.packet_size; } else { /* rebuild headers */ - /* new identificacion packet */ data->op.bytes = build_header_identification(data->buffer, data->buffer_size, &data->config); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse identification header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* identification packet */ + goto fail; - /* new comment packet */ data->op.bytes = build_header_comment(data->buffer, data->buffer_size); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) goto fail; /* parse comment header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) /* comment packet */ + goto fail; - /* rebuild setup packet */ data->op.bytes = rebuild_setup(data->buffer, data->buffer_size, &wp, sf, start_offset, data); - if (!data->op.bytes) goto fail; - if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse setup header */ + if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* setup packet */ + goto fail; } return 1; - fail: return 0; } @@ -259,44 +255,6 @@ fail: return 0; } -static size_t build_header_identification(uint8_t* buf, size_t bufsize, vorbis_custom_config* cfg) { - size_t bytes = 0x1e; - uint8_t blocksizes; - - if (bytes > bufsize) return 0; - - blocksizes = (cfg->blocksize_0_exp << 4) | (cfg->blocksize_1_exp); - - put_u8 (buf+0x00, 0x01); /* packet_type (id) */ - memcpy (buf+0x01, "vorbis", 6); /* id */ - put_u32le(buf+0x07, 0x00); /* vorbis_version (fixed) */ - put_u8 (buf+0x0b, cfg->channels); /* audio_channels */ - put_u32le(buf+0x0c, cfg->sample_rate);/* audio_sample_rate */ - put_u32le(buf+0x10, 0x00); /* bitrate_maximum (optional hint) */ - put_u32le(buf+0x14, 0x00); /* bitrate_nominal (optional hint) */ - put_u32le(buf+0x18, 0x00); /* bitrate_minimum (optional hint) */ - put_u8 (buf+0x1c, blocksizes); /* blocksize_0 + blocksize_1 nibbles */ - put_u8 (buf+0x1d, 0x01); /* framing_flag (fixed) */ - - return bytes; -} - -static size_t build_header_comment(uint8_t* buf, size_t bufsize) { - size_t bytes = 0x19; - - if (bytes > bufsize) return 0; - - put_u8 (buf+0x00, 0x03); /* packet_type (comments) */ - memcpy (buf+0x01, "vorbis", 6); /* id */ - put_u32le(buf+0x07, 0x09); /* vendor_length */ - memcpy (buf+0x0b, "vgmstream", 9); /* vendor_string */ - put_u32le(buf+0x14, 0x00); /* user_comment_list_length */ - put_u8 (buf+0x18, 0x01); /* framing_flag (fixed) */ - - return bytes; -} - - /* copy packet bytes, where input/output bufs may not be byte-aligned (so no memcpy) */ static int copy_bytes(bitstream_t* ob, bitstream_t* ib, uint32_t bytes) { int i; diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 4c4104f7..9de1b449 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -279,6 +279,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 9e74b3d1..81d9d348 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -658,6 +658,9 @@ coding\Source Files + + coding\Source Files + coding\Source Files