mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-30 20:03:44 +01:00
Fix Wwise Vorbis with header triad and remove disable flag
This commit is contained in:
parent
ddf974a31a
commit
70f5dc4684
@ -3,8 +3,7 @@
|
|||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
#include <vorbis/codec.h>
|
#include <vorbis/codec.h>
|
||||||
|
|
||||||
#define WWISE_VORBIS_ON 1 //todo remove once battle-tested
|
#define WWISE_VORBIS_ON 0 //todo remove once battle-tested
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
#include "wwise_vorbis_utils.h"
|
#include "wwise_vorbis_utils.h"
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +12,6 @@
|
|||||||
static void pcm_convert_float_to_16(vorbis_codec_data * data, sample * outbuf, int samples_to_do, float ** pcm);
|
static void pcm_convert_float_to_16(vorbis_codec_data * data, sample * outbuf, int samples_to_do, float ** pcm);
|
||||||
static int vorbis_make_header_identification(uint8_t * buf, size_t bufsize, int channels, int sample_rate, int blocksize_short, int blocksize_long);
|
static int vorbis_make_header_identification(uint8_t * buf, size_t bufsize, int channels, int sample_rate, int blocksize_short, int blocksize_long);
|
||||||
static int vorbis_make_header_comment(uint8_t * buf, size_t bufsize);
|
static int vorbis_make_header_comment(uint8_t * buf, size_t bufsize);
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inits a raw Wwise vorbis stream.
|
* Inits a raw Wwise vorbis stream.
|
||||||
@ -31,7 +29,6 @@ static int vorbis_make_header_comment(uint8_t * buf, size_t bufsize);
|
|||||||
*/
|
*/
|
||||||
vorbis_codec_data * init_wwise_vorbis_codec_data(STREAMFILE *streamFile, off_t start_offset, int channels, int sample_rate, int blocksize_0_exp, int blocksize_1_exp,
|
vorbis_codec_data * init_wwise_vorbis_codec_data(STREAMFILE *streamFile, off_t start_offset, int channels, int sample_rate, int blocksize_0_exp, int blocksize_1_exp,
|
||||||
wwise_setup_type setup_type, wwise_header_type header_type, wwise_packet_type packet_type, int big_endian) {
|
wwise_setup_type setup_type, wwise_header_type header_type, wwise_packet_type packet_type, int big_endian) {
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
vorbis_codec_data * data = NULL;
|
vorbis_codec_data * data = NULL;
|
||||||
size_t header_size, packet_size;
|
size_t header_size, packet_size;
|
||||||
|
|
||||||
@ -62,20 +59,21 @@ vorbis_codec_data * init_wwise_vorbis_codec_data(STREAMFILE *streamFile, off_t s
|
|||||||
/* normal identificacion packet */
|
/* normal identificacion packet */
|
||||||
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
||||||
if (!header_size || packet_size > data->buffer_size) goto fail;
|
if (!header_size || packet_size > data->buffer_size) goto fail;
|
||||||
if (read_streamfile(data->buffer,offset+header_size,packet_size, streamFile)!=packet_size) goto fail;
|
data->op.bytes = read_streamfile(data->buffer,offset+header_size,packet_size, streamFile);
|
||||||
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) goto fail; /* parse identification header */
|
||||||
offset += header_size + packet_size;
|
offset += header_size + packet_size;
|
||||||
|
|
||||||
/* normal comment packet */
|
/* normal comment packet */
|
||||||
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
||||||
if (!header_size || packet_size > data->buffer_size) goto fail;
|
if (!header_size || packet_size > data->buffer_size) goto fail;
|
||||||
if (read_streamfile(data->buffer,offset+header_size,packet_size, streamFile)!=packet_size) goto fail;
|
data->op.bytes = read_streamfile(data->buffer,offset+header_size,packet_size, streamFile);
|
||||||
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 ) goto fail; /* parse comment header */
|
||||||
offset += header_size + packet_size;
|
offset += header_size + packet_size;
|
||||||
|
|
||||||
/* modified setup packet */ //todo doesn't seem needed, may be copied as -is
|
/* normal setup packet */
|
||||||
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
header_size = wwise_vorbis_get_header(streamFile, offset, data->header_type, (int*)&data->op.granulepos, &packet_size, big_endian);
|
||||||
data->op.bytes = wwise_vorbis_rebuild_setup(data->buffer, data->buffer_size, streamFile, offset, data, big_endian, channels);
|
if (!header_size || packet_size > data->buffer_size) goto fail;
|
||||||
|
data->op.bytes = read_streamfile(data->buffer,offset+header_size,packet_size, streamFile);
|
||||||
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) goto fail; /* parse setup header */
|
||||||
offset += header_size + packet_size;
|
offset += header_size + packet_size;
|
||||||
}
|
}
|
||||||
@ -110,7 +108,6 @@ vorbis_codec_data * init_wwise_vorbis_codec_data(STREAMFILE *streamFile, off_t s
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
free_wwise_vorbis(data);
|
free_wwise_vorbis(data);
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +115,6 @@ fail:
|
|||||||
* Decodes raw Wwise Vorbis
|
* Decodes raw Wwise Vorbis
|
||||||
*/
|
*/
|
||||||
void decode_wwise_vorbis(VGMSTREAM * vgmstream, sample * outbuf, int32_t samples_to_do, int channels) {
|
void decode_wwise_vorbis(VGMSTREAM * vgmstream, sample * outbuf, int32_t samples_to_do, int channels) {
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
VGMSTREAMCHANNEL *stream = &vgmstream->ch[0];
|
VGMSTREAMCHANNEL *stream = &vgmstream->ch[0];
|
||||||
vorbis_codec_data * data = vgmstream->codec_data;
|
vorbis_codec_data * data = vgmstream->codec_data;
|
||||||
size_t stream_size = get_streamfile_size(stream->streamfile);
|
size_t stream_size = get_streamfile_size(stream->streamfile);
|
||||||
@ -210,10 +206,9 @@ void decode_wwise_vorbis(VGMSTREAM * vgmstream, sample * outbuf, int32_t samples
|
|||||||
decode_fail:
|
decode_fail:
|
||||||
/* on error just put some 0 samples */
|
/* on error just put some 0 samples */
|
||||||
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample));
|
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WWISE_VORBIS_ON
|
/* *************************************************** */
|
||||||
|
|
||||||
static void pcm_convert_float_to_16(vorbis_codec_data * data, sample * outbuf, int samples_to_do, float ** pcm) {
|
static void pcm_convert_float_to_16(vorbis_codec_data * data, sample * outbuf, int samples_to_do, float ** pcm) {
|
||||||
/* mostly from Xiph's decoder_example.c */
|
/* mostly from Xiph's decoder_example.c */
|
||||||
@ -235,8 +230,6 @@ static void pcm_convert_float_to_16(vorbis_codec_data * data, sample * outbuf, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************************************************** */
|
|
||||||
|
|
||||||
static int vorbis_make_header_identification(uint8_t * buf, size_t bufsize, int channels, int sample_rate, int blocksize_0_exp, int blocksize_1_exp) {
|
static int vorbis_make_header_identification(uint8_t * buf, size_t bufsize, int channels, int sample_rate, int blocksize_0_exp, int blocksize_1_exp) {
|
||||||
int bytes = 0x1e;
|
int bytes = 0x1e;
|
||||||
uint8_t blocksizes;
|
uint8_t blocksizes;
|
||||||
@ -274,12 +267,9 @@ static int vorbis_make_header_comment(uint8_t * buf, size_t bufsize) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* *************************************** */
|
/* *************************************** */
|
||||||
|
|
||||||
void free_wwise_vorbis(vorbis_codec_data * data) {
|
void free_wwise_vorbis(vorbis_codec_data * data) {
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -290,22 +280,18 @@ void free_wwise_vorbis(vorbis_codec_data * data) {
|
|||||||
|
|
||||||
free(data->buffer);
|
free(data->buffer);
|
||||||
free(data);
|
free(data);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_wwise_vorbis(VGMSTREAM *vgmstream) {
|
void reset_wwise_vorbis(VGMSTREAM *vgmstream) {
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
vorbis_codec_data *data = vgmstream->codec_data;
|
vorbis_codec_data *data = vgmstream->codec_data;
|
||||||
|
|
||||||
/* Seeking is provided by the Ogg layer, so with raw vorbis we need seek tables instead.
|
/* Seeking is provided by the Ogg layer, so with raw vorbis we need seek tables instead.
|
||||||
* To avoid having to parse different formats we'll just discard until the expected sample */
|
* To avoid having to parse different formats we'll just discard until the expected sample */
|
||||||
vorbis_synthesis_restart(&data->vd);
|
vorbis_synthesis_restart(&data->vd);
|
||||||
data->samples_to_discard = 0;
|
data->samples_to_discard = 0;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void seek_wwise_vorbis(VGMSTREAM *vgmstream, int32_t num_sample) {
|
void seek_wwise_vorbis(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||||
#if WWISE_VORBIS_ON
|
|
||||||
vorbis_codec_data *data = vgmstream->codec_data;
|
vorbis_codec_data *data = vgmstream->codec_data;
|
||||||
|
|
||||||
/* Seeking is provided by the Ogg layer, so with raw vorbis we need seek tables instead.
|
/* Seeking is provided by the Ogg layer, so with raw vorbis we need seek tables instead.
|
||||||
@ -314,7 +300,6 @@ void seek_wwise_vorbis(VGMSTREAM *vgmstream, int32_t num_sample) {
|
|||||||
data->samples_to_discard = num_sample;
|
data->samples_to_discard = num_sample;
|
||||||
if (vgmstream->loop_ch) /* this func is only using for looping though */
|
if (vgmstream->loop_ch) /* this func is only using for looping though */
|
||||||
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset;
|
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,7 +20,6 @@ typedef struct {
|
|||||||
} ww_stream;
|
} ww_stream;
|
||||||
|
|
||||||
static int generate_vorbis_packet(ww_stream * ow, ww_stream * iw, STREAMFILE *streamFile, off_t offset, vorbis_codec_data * data, int big_endian);
|
static int generate_vorbis_packet(ww_stream * ow, ww_stream * iw, STREAMFILE *streamFile, off_t offset, vorbis_codec_data * data, int big_endian);
|
||||||
static int generate_vorbis_setup_from_triad(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile);
|
|
||||||
static int generate_vorbis_setup(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile);
|
static int generate_vorbis_setup(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile);
|
||||||
|
|
||||||
static int codebook_library_copy(ww_stream * ow, ww_stream * iw);
|
static int codebook_library_copy(ww_stream * ow, ww_stream * iw);
|
||||||
@ -136,11 +135,7 @@ int wwise_vorbis_rebuild_setup(uint8_t * obuf, size_t obufsize, STREAMFILE *stre
|
|||||||
iw.bufsize = ibufsize;
|
iw.bufsize = ibufsize;
|
||||||
iw.b_off = 0;
|
iw.b_off = 0;
|
||||||
|
|
||||||
if (data->setup_type == HEADER_TRIAD) {
|
|
||||||
rc = generate_vorbis_setup_from_triad(&ow,&iw, data, channels, packet_size, streamFile);
|
|
||||||
} else {
|
|
||||||
rc = generate_vorbis_setup(&ow,&iw, data, channels, packet_size, streamFile);
|
rc = generate_vorbis_setup(&ow,&iw, data, channels, packet_size, streamFile);
|
||||||
}
|
|
||||||
if (!rc) goto fail;
|
if (!rc) goto fail;
|
||||||
|
|
||||||
if (ow.b_off % 8 != 0) {
|
if (ow.b_off % 8 != 0) {
|
||||||
@ -280,58 +275,6 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse a partially modified Wwise setup packet.
|
|
||||||
* (ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4) */
|
|
||||||
static int generate_vorbis_setup_from_triad(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile) {
|
|
||||||
int i;
|
|
||||||
uint32_t c = 0;
|
|
||||||
|
|
||||||
/* other packets from the triad should be memcpy'ed externally as they are untouched */
|
|
||||||
|
|
||||||
/* type */
|
|
||||||
r_bits(iw, 8,&c);
|
|
||||||
w_bits(ow, 8, c);
|
|
||||||
|
|
||||||
/* 'vorbis' */
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
r_bits(iw, 8,&c);
|
|
||||||
w_bits(iw, 8, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* codebook count */
|
|
||||||
{
|
|
||||||
uint32_t codebook_count_less1 = 0, codebook_count = 0;
|
|
||||||
|
|
||||||
r_bits(iw, 8,&codebook_count_less1);
|
|
||||||
w_bits(iw, 8, codebook_count_less1);
|
|
||||||
codebook_count = codebook_count_less1 + 1;
|
|
||||||
|
|
||||||
/* rebuild codebooks */
|
|
||||||
for (i = 0; i < codebook_count; i++) {
|
|
||||||
if(!codebook_library_copy(ow, iw)) goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rest of setup is untouched, copy bits */
|
|
||||||
{
|
|
||||||
uint32_t bitly = 0;
|
|
||||||
uint32_t total_bits_read = iw->b_off;
|
|
||||||
uint32_t setup_packet_size_bits = packet_size*8;
|
|
||||||
|
|
||||||
while (total_bits_read < setup_packet_size_bits) {
|
|
||||||
r_bits(iw, 1,&bitly);
|
|
||||||
w_bits(ow, 1, bitly);
|
|
||||||
total_bits_read = iw->b_off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
fail:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Rebuild a Wwise setup (simplified with removed stuff), recreating all six setup parts.
|
/* 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) */
|
* (ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4) */
|
||||||
static int generate_vorbis_setup(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile) {
|
static int generate_vorbis_setup(ww_stream * ow, ww_stream * iw, vorbis_codec_data * data, int channels, size_t packet_size, STREAMFILE *streamFile) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user