vorbis: cleanup

This commit is contained in:
bnnm 2024-03-23 23:57:45 +01:00
parent bb185027ed
commit 1ed15ed25a
10 changed files with 189 additions and 239 deletions

View File

@ -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_ */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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};

View File

@ -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;

View File

@ -279,6 +279,7 @@
<ClCompile Include="coding\ubi_adpcm_decoder.c" />
<ClCompile Include="coding\vadpcm_decoder.c" />
<ClCompile Include="coding\vorbis_custom_decoder.c" />
<ClCompile Include="coding\vorbis_custom_utils.c" />
<ClCompile Include="coding\vorbis_custom_utils_awc.c" />
<ClCompile Include="coding\vorbis_custom_utils_fsb.c" />
<ClCompile Include="coding\vorbis_custom_utils_ogl.c" />

View File

@ -658,6 +658,9 @@
<ClCompile Include="coding\vorbis_custom_decoder.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\vorbis_custom_utils.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\vorbis_custom_utils_awc.c">
<Filter>coding\Source Files</Filter>
</ClCompile>