diff --git a/src/coding/coding.h b/src/coding/coding.h index 2a9d9257..6e36600b 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -276,4 +276,19 @@ void xma2_parse_xma2_chunk(STREAMFILE *streamFile, off_t chunk_offset, int * cha size_t atrac3_bytes_to_samples(size_t bytes, int full_block_align); size_t atrac3plus_bytes_to_samples(size_t bytes, int full_block_align); + + +/* An internal struct to pass around and simulate a bitstream. */ +typedef enum { BITSTREAM_MSF, BITSTREAM_VORBIS } vgm_bitstream_t; +typedef struct { + uint8_t * buf; /* buffer to read/write*/ + size_t bufsize; /* max size of the buffer */ + off_t b_off; /* current offset in bits inside the buffer */ + off_t info_offset; /* for logging */ + vgm_bitstream_t mode; /* read/write modes */ +} vgm_bitstream; + +int r_bits(vgm_bitstream * ib, int num_bits, uint32_t * value); +int w_bits(vgm_bitstream * ob, int num_bits, uint32_t value); + #endif /*_CODING_H*/ diff --git a/src/coding/coding_utils.c b/src/coding/coding_utils.c index a5733146..d0cec7fc 100644 --- a/src/coding/coding_utils.c +++ b/src/coding/coding_utils.c @@ -835,3 +835,149 @@ size_t atrac3plus_bytes_to_samples(size_t bytes, int full_block_align) { * so (full_block_align / channels) DOESN'T give the size of a single channel (common in ATRAC3plus) */ return (bytes / full_block_align) * 2048; } + + +/* ******************************************** */ +/* BITSTREAM */ +/* ******************************************** */ + + +/* Read bits (max 32) from buf and update the bit offset. Vorbis packs values in LSB order and byte by byte. + * (ex. from 2 bytes 00100111 00000001 we can could read 4b=0111 and 6b=010010, 6b=remainder (second value is split into the 2nd byte) */ +static int r_bits_vorbis(vgm_bitstream * ib, int num_bits, uint32_t * value) { + off_t off, pos; + int i, bit_buf, bit_val; + if (num_bits == 0) return 1; + if (num_bits > 32 || num_bits < 0 || ib->b_off + num_bits > ib->bufsize*8) goto fail; + + *value = 0; /* set all bits to 0 */ + off = ib->b_off / 8; /* byte offset */ + pos = ib->b_off % 8; /* bit sub-offset */ + for (i = 0; i < num_bits; i++) { + bit_buf = (1U << pos) & 0xFF; /* bit check for buf */ + bit_val = (1U << i); /* bit to set in value */ + + if (ib->buf[off] & bit_buf) /* is bit in buf set? */ + *value |= bit_val; /* set bit */ + + pos++; /* new byte starts */ + if (pos%8 == 0) { + pos = 0; + off++; + } + } + + ib->b_off += num_bits; + return 1; +fail: + return 0; +} + +/* Write bits (max 32) to buf and update the bit offset. Vorbis packs values in LSB order and byte by byte. + * (ex. writing 1101011010 from b_off 2 we get 01101011 00001101 (value split, and 11 in the first byte skipped)*/ +static int w_bits_vorbis(vgm_bitstream * ob, int num_bits, uint32_t value) { + off_t off, pos; + int i, bit_val, bit_buf; + if (num_bits == 0) return 1; + if (num_bits > 32 || num_bits < 0 || ob->b_off + num_bits > ob->bufsize*8) goto fail; + + + off = ob->b_off / 8; /* byte offset */ + pos = ob->b_off % 8; /* bit sub-offset */ + for (i = 0; i < num_bits; i++) { + bit_val = (1U << i); /* bit check for value */ + bit_buf = (1U << pos) & 0xFF; /* bit to set in buf */ + + if (value & bit_val) /* is bit in val set? */ + ob->buf[off] |= bit_buf; /* set bit */ + else + ob->buf[off] &= ~bit_buf; /* unset bit */ + + pos++; /* new byte starts */ + if (pos%8 == 0) { + pos = 0; + off++; + } + } + + ob->b_off += num_bits; + return 1; +fail: + return 0; +} + + +/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSF). */ +static int r_bits_msf(vgm_bitstream * ib, int num_bits, uint32_t * value) { + off_t off, pos; + int i, bit_buf, bit_val; + if (num_bits == 0) return 1; + if (num_bits > 32 || num_bits < 0 || ib->b_off + num_bits > ib->bufsize*8) goto fail; + + *value = 0; /* set all bits to 0 */ + off = ib->b_off / 8; /* byte offset */ + pos = ib->b_off % 8; /* bit sub-offset */ + for (i = 0; i < num_bits; i++) { + bit_buf = (1U << (8-1-pos)) & 0xFF; /* bit check for buf */ + bit_val = (1U << (num_bits-1-i)); /* bit to set in value */ + + if (ib->buf[off] & bit_buf) /* is bit in buf set? */ + *value |= bit_val; /* set bit */ + + pos++; + if (pos%8 == 0) { /* new byte starts */ + pos = 0; + off++; + } + } + + ib->b_off += num_bits; + return 1; +fail: + return 0; +} + +/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSF). */ +static int w_bits_msf(vgm_bitstream * ob, int num_bits, uint32_t value) { + off_t off, pos; + int i, bit_val, bit_buf; + if (num_bits == 0) return 1; + if (num_bits > 32 || num_bits < 0 || ob->b_off + num_bits > ob->bufsize*8) goto fail; + + + off = ob->b_off / 8; /* byte offset */ + pos = ob->b_off % 8; /* bit sub-offset */ + for (i = 0; i < num_bits; i++) { + bit_val = (1U << (num_bits-1-i)); /* bit check for value */ + bit_buf = (1U << (8-1-pos)) & 0xFF; /* bit to set in buf */ + + if (value & bit_val) /* is bit in val set? */ + ob->buf[off] |= bit_buf; /* set bit */ + else + ob->buf[off] &= ~bit_buf; /* unset bit */ + + pos++; + if (pos%8 == 0) { /* new byte starts */ + pos = 0; + off++; + } + } + + ob->b_off += num_bits; + return 1; +fail: + return 0; +} + +int r_bits(vgm_bitstream * ib, int num_bits, uint32_t * value) { + if (ib->mode == BITSTREAM_VORBIS) + return r_bits_vorbis(ib,num_bits,value); + else + return r_bits_msf(ib,num_bits,value); +} +int w_bits(vgm_bitstream * ob, int num_bits, uint32_t value) { + if (ob->mode == BITSTREAM_VORBIS) + return w_bits_vorbis(ob,num_bits,value); + else + return w_bits_msf(ob,num_bits,value); +} diff --git a/src/coding/mpeg_custom_utils_ealayer3.c b/src/coding/mpeg_custom_utils_ealayer3.c index f99d814c..84f6cc74 100644 --- a/src/coding/mpeg_custom_utils_ealayer3.c +++ b/src/coding/mpeg_custom_utils_ealayer3.c @@ -25,14 +25,6 @@ #define EALAYER3_MAX_GRANULES 2 #define EALAYER3_MAX_CHANNELS 2 -/* helper to simulate a bitstream */ -typedef struct { - uint8_t * buf; /* buffer to read/write*/ - size_t bufsize; /* max size of the buffer */ - off_t b_off; /* current offset in bits inside the buffer */ - off_t info_offset; /* for logs */ -} ealayer3_bitstream; - /* parsed info from a single EALayer3 frame */ typedef struct { /* EALayer3 v1 header */ @@ -81,18 +73,14 @@ typedef struct { } ealayer3_frame_info; -static int ealayer3_parse_frame(mpeg_codec_data *data, ealayer3_bitstream *is, ealayer3_frame_info * eaf); -static int ealayer3_parse_frame_v1(ealayer3_bitstream *is, ealayer3_frame_info * eaf, int channels_per_frame, int is_v1b); -static int ealayer3_parse_frame_v2(ealayer3_bitstream *is, ealayer3_frame_info * eaf); -static int ealayer3_parse_frame_common(ealayer3_bitstream *is, ealayer3_frame_info * eaf); -static int ealayer3_rebuild_mpeg_frame(ealayer3_bitstream* is_0, ealayer3_frame_info* eaf_0, ealayer3_bitstream* is_1, ealayer3_frame_info* eaf_1, ealayer3_bitstream* os); +static int ealayer3_parse_frame(mpeg_codec_data *data, vgm_bitstream *is, ealayer3_frame_info * eaf); +static int ealayer3_parse_frame_v1(vgm_bitstream *is, ealayer3_frame_info * eaf, int channels_per_frame, int is_v1b); +static int ealayer3_parse_frame_v2(vgm_bitstream *is, ealayer3_frame_info * eaf); +static int ealayer3_parse_frame_common(vgm_bitstream *is, ealayer3_frame_info * eaf); +static int ealayer3_rebuild_mpeg_frame(vgm_bitstream* is_0, ealayer3_frame_info* eaf_0, vgm_bitstream* is_1, ealayer3_frame_info* eaf_1, vgm_bitstream* os); static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream, ealayer3_frame_info * eaf); static int ealayer3_skip_data(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream, int at_start); -static int r_bits(ealayer3_bitstream * iw, int num_bits, uint32_t * value); -static int w_bits(ealayer3_bitstream * ow, int num_bits, uint32_t value); - - /* **************************************************************************** */ /* EXTERNAL API */ /* **************************************************************************** */ @@ -101,7 +89,7 @@ static int w_bits(ealayer3_bitstream * ow, int num_bits, uint32_t value); int mpeg_custom_setup_init_ealayer3(STREAMFILE *streamFile, off_t start_offset, mpeg_codec_data *data, coding_t *coding_type) { int ok; ealayer3_frame_info eaf; - ealayer3_bitstream is = {0}; + vgm_bitstream is = {0}; uint8_t ibuf[EALAYER3_EA_FRAME_BUFFER_SIZE]; //;VGM_LOG("init at %lx\n", start_offset); @@ -135,7 +123,7 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL *stream, mpeg_codec_data * off_t info_offset = stream->offset; ealayer3_frame_info eaf_0, eaf_1; - ealayer3_bitstream is_0 = {0}, is_1 = {0}, os = {0}; + vgm_bitstream is_0 = {0}, is_1 = {0}, os = {0}; uint8_t ibuf_0[EALAYER3_EA_FRAME_BUFFER_SIZE], ibuf_1[EALAYER3_EA_FRAME_BUFFER_SIZE]; /* read first frame/granule, or PCM-only frame (found alone at the end of SCHl streams) */ @@ -213,7 +201,7 @@ fail: /* INTERNAL HELPERS */ /* **************************************************************************** */ -static int ealayer3_parse_frame(mpeg_codec_data *data, ealayer3_bitstream *is, ealayer3_frame_info * eaf) { +static int ealayer3_parse_frame(mpeg_codec_data *data, vgm_bitstream *is, ealayer3_frame_info * eaf) { int ok; /* make sure as there is re-parsing in loops */ @@ -235,7 +223,7 @@ fail: /* read V1"a" (in SCHl) and V1"b" (in SNS) EALayer3 frame */ -static int ealayer3_parse_frame_v1(ealayer3_bitstream *is, ealayer3_frame_info * eaf, int channels_per_frame, int is_v1b) { +static int ealayer3_parse_frame_v1(vgm_bitstream *is, ealayer3_frame_info * eaf, int channels_per_frame, int is_v1b) { int ok; /* read EA-frame V1 header */ @@ -282,7 +270,7 @@ fail: /* read V2"PCM" and V2"Spike" EALayer3 frame (exactly the same but V2P seems to have bigger * PCM blocks and maybe smaller frames) */ -static int ealayer3_parse_frame_v2(ealayer3_bitstream *is, ealayer3_frame_info * eaf) { +static int ealayer3_parse_frame_v2(vgm_bitstream *is, ealayer3_frame_info * eaf) { int ok; /* read EA-frame V2 header */ @@ -328,7 +316,7 @@ fail: /* parses an EALayer3 frame (common part) */ -static int ealayer3_parse_frame_common(ealayer3_bitstream *is, ealayer3_frame_info * eaf) { +static int ealayer3_parse_frame_common(vgm_bitstream *is, ealayer3_frame_info * eaf) { /* index tables */ static const int versions[4] = { /* MPEG 2.5 */ 3, /* reserved */ -1, /* MPEG 2 */ 2, /* MPEG 1 */ 1 }; static const int sample_rates[4][4] = { /* [version_index][sample rate index] */ @@ -412,7 +400,7 @@ fail: /* converts an EALAYER3 frame to a standard MPEG frame from pre-parsed info */ -static int ealayer3_rebuild_mpeg_frame(ealayer3_bitstream* is_0, ealayer3_frame_info* eaf_0, ealayer3_bitstream* is_1, ealayer3_frame_info* eaf_1, ealayer3_bitstream* os) { +static int ealayer3_rebuild_mpeg_frame(vgm_bitstream* is_0, ealayer3_frame_info* eaf_0, vgm_bitstream* is_1, ealayer3_frame_info* eaf_1, vgm_bitstream* os) { uint32_t c = 0; int i,j; int expected_bitrate_index, expected_frame_size; @@ -663,7 +651,7 @@ fail: static int ealayer3_skip_data(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream, int at_start) { int ok, i; ealayer3_frame_info eaf; - ealayer3_bitstream is = {0}; + vgm_bitstream is = {0}; uint8_t ibuf[EALAYER3_EA_FRAME_BUFFER_SIZE]; int skips = at_start ? num_stream : data->streams_size - 1 - num_stream; @@ -685,68 +673,4 @@ fail: return 0; } -/* ********************************************* */ - -/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSF). */ -static int r_bits(ealayer3_bitstream * is, int num_bits, uint32_t * value) { - off_t off, pos; - int i, bit_buf, bit_val; - if (num_bits == 0) return 1; - if (num_bits > 32 || num_bits < 0 || is->b_off + num_bits > is->bufsize*8) goto fail; - - *value = 0; /* set all bits to 0 */ - off = is->b_off / 8; /* byte offset */ - pos = is->b_off % 8; /* bit sub-offset */ - for (i = 0; i < num_bits; i++) { - bit_buf = (1U << (8-1-pos)) & 0xFF; /* bit check for buf */ - bit_val = (1U << (num_bits-1-i)); /* bit to set in value */ - - if (is->buf[off] & bit_buf) /* is bit in buf set? */ - *value |= bit_val; /* set bit */ - - pos++; - if (pos%8 == 0) { /* new byte starts */ - pos = 0; - off++; - } - } - - is->b_off += num_bits; - return 1; -fail: - return 0; -} - -/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSF). */ -static int w_bits(ealayer3_bitstream * os, int num_bits, uint32_t value) { - off_t off, pos; - int i, bit_val, bit_buf; - if (num_bits == 0) return 1; - if (num_bits > 32 || num_bits < 0 || os->b_off + num_bits > os->bufsize*8) goto fail; - - - off = os->b_off / 8; /* byte offset */ - pos = os->b_off % 8; /* bit sub-offset */ - for (i = 0; i < num_bits; i++) { - bit_val = (1U << (num_bits-1-i)); /* bit check for value */ - bit_buf = (1U << (8-1-pos)) & 0xFF; /* bit to set in buf */ - - if (value & bit_val) /* is bit in val set? */ - os->buf[off] |= bit_buf; /* set bit */ - else - os->buf[off] &= ~bit_buf; /* unset bit */ - - pos++; - if (pos%8 == 0) { /* new byte starts */ - pos = 0; - off++; - } - } - - os->b_off += num_bits; - return 1; -fail: - return 0; -} - #endif diff --git a/src/coding/mpeg_decoder.h b/src/coding/mpeg_decoder.h index f69be767..94e31b13 100644 --- a/src/coding/mpeg_decoder.h +++ b/src/coding/mpeg_decoder.h @@ -2,6 +2,7 @@ #define _MPEG_DECODER_H_ #include "../vgmstream.h" +#include "../coding/coding.h" /* used by mpeg_decoder.c, but scattered in other .c files */ #ifdef VGM_USE_MPEG diff --git a/src/coding/vorbis_custom_decoder.h b/src/coding/vorbis_custom_decoder.h index 80f5a58c..0801d91c 100644 --- a/src/coding/vorbis_custom_decoder.h +++ b/src/coding/vorbis_custom_decoder.h @@ -2,6 +2,7 @@ #define _VORBIS_CUSTOM_DECODER_H_ #include "../vgmstream.h" +#include "../coding/coding.h" /* used by vorbis_custom_decoder.c, but scattered in other .c files */ #ifdef VGM_USE_VORBIS diff --git a/src/coding/vorbis_custom_utils_vid1.c b/src/coding/vorbis_custom_utils_vid1.c index 225c3fbb..1f5adad1 100644 --- a/src/coding/vorbis_custom_utils_vid1.c +++ b/src/coding/vorbis_custom_utils_vid1.c @@ -8,15 +8,6 @@ /* DEFS */ /* **************************************************************************** */ -/* An internal struct to pass around and simulate a bitstream. */ -typedef struct { - uint8_t * buf; /* buffer to read/write*/ - size_t bufsize; /* max size of the buffer */ - off_t b_off; /* current offset in bits inside the buffer */ -} vgm_bitstream; - -static int r_bits(vgm_bitstream * iw, int num_bits, uint32_t * value); - static int get_packet_header(STREAMFILE *streamFile, off_t *offset, size_t *size); static int build_header_comment(uint8_t * buf, size_t bufsize); @@ -137,6 +128,7 @@ static int get_packet_header(STREAMFILE *streamFile, off_t *offset, size_t *size ib.buf = ibuf; ib.bufsize = ibufsize; ib.b_off = 0; + ib.mode = BITSTREAM_VORBIS; /* read using Vorbis weird LSF */ r_bits(&ib, 4,&size_bits); @@ -157,35 +149,4 @@ fail: return 0; } -/* Read bits (max 32) from buf and update the bit offset. Vorbis packs values in LSB order and byte by byte. - * (ex. from 2 bytes 00100111 00000001 we can could read 4b=0111 and 6b=010010, 6b=remainder (second value is split into the 2nd byte) */ -static int r_bits(vgm_bitstream * ib, int num_bits, uint32_t * value) { - off_t off, pos; - int i, bit_buf, bit_val; - if (num_bits == 0) return 1; - if (num_bits > 32 || num_bits < 0 || ib->b_off + num_bits > ib->bufsize*8) goto fail; - - *value = 0; /* set all bits to 0 */ - off = ib->b_off / 8; /* byte offset */ - pos = ib->b_off % 8; /* bit sub-offset */ - for (i = 0; i < num_bits; i++) { - bit_buf = (1U << pos) & 0xFF; /* bit check for buf */ - bit_val = (1U << i); /* bit to set in value */ - - if (ib->buf[off] & bit_buf) /* is bit in buf set? */ - *value |= bit_val; /* set bit */ - - pos++; /* new byte starts */ - if (pos%8 == 0) { - pos = 0; - off++; - } - } - - ib->b_off += num_bits; - return 1; -fail: - return 0; -} - #endif diff --git a/src/coding/vorbis_custom_utils_wwise.c b/src/coding/vorbis_custom_utils_wwise.c index 8155ab56..7fba9417 100644 --- a/src/coding/vorbis_custom_utils_wwise.c +++ b/src/coding/vorbis_custom_utils_wwise.c @@ -13,25 +13,17 @@ /* DEFS */ /* **************************************************************************** */ -/* An internal struct to pass around and simulate a bitstream. - * Mainly to keep code cleaner and somewhat closer to ww2ogg */ -typedef struct { - uint8_t * buf; /* buffer to read/write*/ - size_t bufsize; /* max size of the buffer */ - off_t b_off; /* current offset in bits inside the buffer */ -} ww_bitstream; - 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 get_packet_header(STREAMFILE *streamFile, off_t offset, wwise_header_t header_type, int * granulepos, size_t * packet_size, int big_endian); static int rebuild_packet(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian); static int rebuild_setup(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian, int channels); -static int ww2ogg_generate_vorbis_packet(ww_bitstream * ow, ww_bitstream * iw, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian); -static int ww2ogg_generate_vorbis_setup(ww_bitstream * ow, ww_bitstream * iw, vorbis_custom_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile); -static int ww2ogg_codebook_library_copy(ww_bitstream * ow, ww_bitstream * iw); -static int ww2ogg_codebook_library_rebuild(ww_bitstream * ow, ww_bitstream * iw, size_t cb_size, STREAMFILE *streamFile); -static int ww2ogg_codebook_library_rebuild_by_id(ww_bitstream * ow, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE *streamFile); +static int ww2ogg_generate_vorbis_packet(vgm_bitstream * ow, vgm_bitstream * iw, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian); +static int ww2ogg_generate_vorbis_setup(vgm_bitstream * ow, vgm_bitstream * iw, vorbis_custom_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile); +static int ww2ogg_codebook_library_copy(vgm_bitstream * ow, vgm_bitstream * iw); +static int ww2ogg_codebook_library_rebuild(vgm_bitstream * ow, vgm_bitstream * iw, size_t cb_size, STREAMFILE *streamFile); +static int ww2ogg_codebook_library_rebuild_by_id(vgm_bitstream * ow, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE *streamFile); static int ww2ogg_tremor_ilog(unsigned int v); static unsigned int ww2ogg_tremor_book_maptype1_quantvals(unsigned int entries, unsigned int dimensions); @@ -39,9 +31,6 @@ static int load_wvc(uint8_t * ibuf, size_t ibufsize, uint32_t codebook_id, wwise static int load_wvc_file(uint8_t * buf, size_t bufsize, uint32_t codebook_id, STREAMFILE *streamFile); static int load_wvc_array(uint8_t * buf, size_t bufsize, uint32_t codebook_id, wwise_setup_t setup_type); -static int r_bits(ww_bitstream * iw, int num_bits, uint32_t * value); -static int w_bits(ww_bitstream * ow, int num_bits, uint32_t value); - /* **************************************************************************** */ /* EXTERNAL API */ @@ -165,7 +154,7 @@ static int get_packet_header(STREAMFILE *streamFile, off_t offset, wwise_header_ /* Transforms a Wwise data packet into a real Vorbis one (depending on config) */ static int rebuild_packet(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian) { - ww_bitstream ow, iw; + vgm_bitstream ow, iw; int rc, granulepos; size_t header_size, packet_size; @@ -183,11 +172,13 @@ static int rebuild_packet(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFil /* prepare helper structs */ ow.buf = obuf; ow.bufsize = obufsize; - ow.b_off = 0 ; + ow.b_off = 0; + ow.mode = BITSTREAM_VORBIS; iw.buf = ibuf; iw.bufsize = ibufsize; iw.b_off = 0; + iw.mode = BITSTREAM_VORBIS; rc = ww2ogg_generate_vorbis_packet(&ow,&iw, streamFile,offset, data, big_endian); if (!rc) goto fail; @@ -206,7 +197,7 @@ fail: /* Transforms a Wwise setup packet into a real Vorbis one (depending on config). */ static int rebuild_setup(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian, int channels) { - ww_bitstream ow, iw; + vgm_bitstream ow, iw; int rc, granulepos; size_t header_size, packet_size; @@ -226,10 +217,12 @@ static int rebuild_setup(uint8_t * obuf, size_t obufsize, STREAMFILE *streamFile ow.buf = obuf; ow.bufsize = obufsize; ow.b_off = 0; + ow.mode = BITSTREAM_VORBIS; iw.buf = ibuf; iw.bufsize = ibufsize; iw.b_off = 0; + iw.mode = BITSTREAM_VORBIS; rc = ww2ogg_generate_vorbis_setup(&ow,&iw, data, channels, packet_size, streamFile); if (!rc) goto fail; @@ -295,7 +288,7 @@ static int build_header_comment(uint8_t * buf, size_t bufsize) { /* Copy packet as-is or rebuild first byte if mod_packets is used. * (ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-720004.3) */ -static int ww2ogg_generate_vorbis_packet(ww_bitstream * ow, ww_bitstream * iw, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian) { +static int ww2ogg_generate_vorbis_packet(vgm_bitstream * ow, vgm_bitstream * iw, STREAMFILE *streamFile, off_t offset, vorbis_custom_codec_data * data, int big_endian) { int i,granule; size_t header_size, packet_size, data_size; @@ -350,10 +343,13 @@ static int ww2ogg_generate_vorbis_packet(ww_bitstream * ow, ww_bitstream * iw, S /* get next first byte to read next_mode_number */ uint32_t next_mode_number; uint8_t nbuf[1]; - ww_bitstream nw; + vgm_bitstream nw; + nw.buf = nbuf; nw.bufsize = 1; nw.b_off = 0; + nw.mode = BITSTREAM_VORBIS; + if (read_streamfile(nw.buf, next_offset + next_header_size, nw.bufsize, streamFile) != nw.bufsize) goto fail; @@ -409,7 +405,7 @@ fail: /* Rebuild a Wwise setup (simplified with removed stuff), recreating all six setup parts. * (ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4) */ -static int ww2ogg_generate_vorbis_setup(ww_bitstream * ow, ww_bitstream * iw, vorbis_custom_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile) { +static int ww2ogg_generate_vorbis_setup(vgm_bitstream * ow, vgm_bitstream * iw, vorbis_custom_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile) { int i,j,k; uint32_t codebook_count = 0, floor_count = 0, residue_count = 0; uint32_t codebook_count_less1 = 0; @@ -798,7 +794,7 @@ fail: /* copies Vorbis codebooks (untouched, but size uncertain) */ -static int ww2ogg_codebook_library_copy(ww_bitstream * ow, ww_bitstream * iw) { +static int ww2ogg_codebook_library_copy(vgm_bitstream * ow, vgm_bitstream * iw) { int i; uint32_t id = 0, dimensions = 0, entries = 0; uint32_t ordered = 0, lookup_type = 0; @@ -914,7 +910,7 @@ fail: /* rebuilds a Wwise codebook into a Vorbis codebook */ -static int ww2ogg_codebook_library_rebuild(ww_bitstream * ow, ww_bitstream * iw, size_t cb_size, STREAMFILE *streamFile) { +static int ww2ogg_codebook_library_rebuild(vgm_bitstream * ow, vgm_bitstream * iw, size_t cb_size, STREAMFILE *streamFile) { int i; uint32_t id = 0, dimensions = 0, entries = 0; uint32_t ordered = 0, lookup_type = 0; @@ -1038,11 +1034,11 @@ fail: } /* rebuilds an external Wwise codebook referenced by id to a Vorbis codebook */ -static int ww2ogg_codebook_library_rebuild_by_id(ww_bitstream * ow, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE *streamFile) { +static int ww2ogg_codebook_library_rebuild_by_id(vgm_bitstream * ow, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE *streamFile) { size_t ibufsize = 0x8000; /* arbitrary max size of a codebook */ uint8_t ibuf[0x8000]; /* Wwise codebook buffer */ size_t cb_size; - ww_bitstream iw; + vgm_bitstream iw; cb_size = load_wvc(ibuf,ibufsize, codebook_id, setup_type, streamFile); if (cb_size == 0) goto fail; @@ -1050,6 +1046,7 @@ static int ww2ogg_codebook_library_rebuild_by_id(ww_bitstream * ow, uint32_t cod iw.buf = ibuf; iw.bufsize = ibufsize; iw.b_off = 0; + iw.mode = BITSTREAM_VORBIS; return ww2ogg_codebook_library_rebuild(ow, &iw, cb_size, streamFile); fail: @@ -1228,70 +1225,4 @@ fail: return 0; } -/* ********************************************* */ - -/* Read bits (max 32) from buf and update the bit offset. Vorbis packs values in LSB order and byte by byte. - * (ex. from 2 bytes 00100111 00000001 we can could read 4b=0111 and 6b=010010, 6b=remainder (second value is split into the 2nd byte) */ -static int r_bits(ww_bitstream * iw, int num_bits, uint32_t * value) { - off_t off, pos; - int i, bit_buf, bit_val; - if (num_bits == 0) return 1; - if (num_bits > 32 || num_bits < 0 || iw->b_off + num_bits > iw->bufsize*8) goto fail; - - *value = 0; /* set all bits to 0 */ - off = iw->b_off / 8; /* byte offset */ - pos = iw->b_off % 8; /* bit sub-offset */ - for (i = 0; i < num_bits; i++) { - bit_buf = (1U << pos) & 0xFF; /* bit check for buf */ - bit_val = (1U << i); /* bit to set in value */ - - if (iw->buf[off] & bit_buf) /* is bit in buf set? */ - *value |= bit_val; /* set bit */ - - pos++; /* new byte starts */ - if (pos%8 == 0) { - pos = 0; - off++; - } - } - - iw->b_off += num_bits; - return 1; -fail: - return 0; -} - -/* Write bits (max 32) to buf and update the bit offset. Vorbis packs values in LSB order and byte by byte. - * (ex. writing 1101011010 from b_off 2 we get 01101011 00001101 (value split, and 11 in the first byte skipped)*/ -static int w_bits(ww_bitstream * ow, int num_bits, uint32_t value) { - off_t off, pos; - int i, bit_val, bit_buf; - if (num_bits == 0) return 1; - if (num_bits > 32 || num_bits < 0 || ow->b_off + num_bits > ow->bufsize*8) goto fail; - - - off = ow->b_off / 8; /* byte offset */ - pos = ow->b_off % 8; /* bit sub-offset */ - for (i = 0; i < num_bits; i++) { - bit_val = (1U << i); /* bit check for value */ - bit_buf = (1U << pos) & 0xFF; /* bit to set in buf */ - - if (value & bit_val) /* is bit in val set? */ - ow->buf[off] |= bit_buf; /* set bit */ - else - ow->buf[off] &= ~bit_buf; /* unset bit */ - - pos++; /* new byte starts */ - if (pos%8 == 0) { - pos = 0; - off++; - } - } - - ow->b_off += num_bits; - return 1; -fail: - return 0; -} - #endif