mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 23:10:10 +01:00
Merge pull request #1167 from bnnm/vorbis-misc
- Add SNDZ .szd extension - Fix missing end samples in Wwise Vorbis - Fix some Wwise Convolution Reverb wem - Fix truncated ATRAC9 .wem
This commit is contained in:
commit
5aeecc7fd4
@ -409,6 +409,7 @@ typedef struct {
|
||||
|
||||
uint32_t setup_id; /* external setup */
|
||||
int big_endian; /* flag */
|
||||
uint32_t stream_end; /* optional, to avoid overreading into next subsong or chunk */
|
||||
|
||||
/* Wwise Vorbis config */
|
||||
wwise_setup_t setup_type;
|
||||
|
@ -65,6 +65,9 @@ vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset,
|
||||
/* write output */
|
||||
config->data_start_offset = data->config.data_start_offset;
|
||||
|
||||
if (!data->config.stream_end) {
|
||||
data->config.stream_end = get_streamfile_size(sf);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
@ -78,19 +81,11 @@ fail:
|
||||
void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels) {
|
||||
VGMSTREAMCHANNEL *stream = &vgmstream->ch[0];
|
||||
vorbis_custom_codec_data* data = vgmstream->codec_data;
|
||||
size_t stream_size = get_streamfile_size(stream->streamfile);
|
||||
//data->op.packet = data->buffer;/* implicit from init */
|
||||
int samples_done = 0;
|
||||
|
||||
while (samples_done < samples_to_do) {
|
||||
|
||||
/* extra EOF check for edge cases */
|
||||
if (stream->offset >= stream_size) {
|
||||
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample) * channels);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (data->samples_full) { /* read more samples */
|
||||
int samples_to_get;
|
||||
float **pcm;
|
||||
@ -123,6 +118,12 @@ void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t sample
|
||||
else { /* read more data */
|
||||
int ok, rc;
|
||||
|
||||
/* extra EOF check */
|
||||
if (stream->offset >= data->config.stream_end) {
|
||||
/* may need to drain samples? (not a thing in vorbis due to packet types?) */
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
/* not actually needed, but feels nicer */
|
||||
data->op.granulepos += samples_to_do; /* can be changed next if desired */
|
||||
data->op.packetno++;
|
||||
|
@ -532,6 +532,7 @@ static const char* extension_list[] = {
|
||||
"sxd",
|
||||
"sxd2",
|
||||
"sxd3",
|
||||
"szd",
|
||||
"szd1",
|
||||
"szd3",
|
||||
|
||||
|
@ -206,10 +206,13 @@ VGMSTREAM* init_vgmstream_bkhd_fx(STREAMFILE* sf) {
|
||||
/* Not an actual stream but typically convolution reverb models and other FX plugin helpers.
|
||||
* Useless but to avoid "subsong not playing" complaints. */
|
||||
|
||||
if (read_u32(0x00, sf) == 0x0400 &&
|
||||
/* Wwise Convolution Reverb */
|
||||
if ((read_u32(0x00, sf) == 0x00000400 || /* common */
|
||||
read_u32(0x00, sf) == 0x00020400 ) && /* Elden Ring */
|
||||
read_u32(0x04, sf) == 0x0800) {
|
||||
sample_rate = read_u32(0x08, sf);
|
||||
channels = read_u32(0x0c, sf) & 0xFF; /* 0x31 at 0x0d in PC, field is 32b vs X360 */
|
||||
|
||||
/* 0x10: some id or small size? (related to entries?) */
|
||||
/* 0x14/18: some float? */
|
||||
entries = read_u32(0x1c, sf);
|
||||
|
@ -477,6 +477,7 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) {
|
||||
cfg.channels = fsb5.channels;
|
||||
cfg.sample_rate = fsb5.sample_rate;
|
||||
cfg.setup_id = read_u32le(fsb5.extradata_offset,sf);
|
||||
cfg.stream_end = fsb5.stream_offset + fsb5.stream_size;
|
||||
|
||||
vgmstream->codec_data = init_vorbis_custom(sb, fsb5.stream_offset, VORBIS_FSB, &cfg);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
|
@ -73,7 +73,30 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
}
|
||||
|
||||
|
||||
/* typical chunks: WAVE, RGND, NAME (strings for WAVE or RGND), SEQD (related to SFX), WSUR, WMKR, BUSS */
|
||||
/* Format per chunk:
|
||||
* - 0x00: id
|
||||
* - 0x04: SGX: unknown; SGD/SGH: chunk length
|
||||
* - 0x08: null
|
||||
* - 0x0c: entries */
|
||||
|
||||
/* typical chunks (with some entry info):
|
||||
* - WAVE: wave data (see below)
|
||||
* - RGND: programs info, notably:
|
||||
* - 0x18: min note range
|
||||
* - 0x19: max note range
|
||||
* - 0x1C: root note
|
||||
* - 0x34: WAVE id
|
||||
* > sample_rate = wave_sample_rate * (2 ^ (1/12)) ^ (target_note - root_note)
|
||||
* - NAME: strings for other chunks
|
||||
* - 0x00: sub-id?
|
||||
* - 0x02: type? (possibly: 0000=bank, 0x2xxx=SEQD/WAVE, 0x3xxx=WSUR, 0x4xxx=BUSS, 0x6xxx=CONF)
|
||||
* - 0x04: absolute offset
|
||||
* - SEQD: related to SFX (sequences?), entries seem to be offsets to name offset + seq (ps1?) offset
|
||||
* - WSUR: ?
|
||||
* - WMKR: ?
|
||||
* - CONF: ? (name offset + config offset)
|
||||
* - BUSS: bus config?
|
||||
|
||||
/* WAVE chunk (size 0x10 + files * 0x38 + optional padding) */
|
||||
if (is_sgx) { /* position after chunk+size */
|
||||
if (!is_id32be(0x10,sf_head, "WAVE"))
|
||||
@ -83,7 +106,6 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
if (!find_chunk_le(sf_head, get_id32be("WAVE"),0x10,0, &chunk_offset, NULL))
|
||||
goto fail;
|
||||
}
|
||||
/* 0x04 SGX: unknown; SGD/SGH: chunk length, 0x08 null */
|
||||
|
||||
/* check multi-streams (usually only SE containers; Puppeteer) */
|
||||
total_subsongs = read_s32le(chunk_offset+0x04,sf_head);
|
||||
@ -95,18 +117,18 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
|
||||
uint32_t stream_offset;
|
||||
chunk_offset += 0x08 + 0x38 * (target_subsong-1); /* position in target header*/
|
||||
|
||||
/* 0x00 ? (00/01/02) */
|
||||
/* 0x00: ? (00/01/02) */
|
||||
if (!is_sgx) /* meaning unknown in .sgx; offset 0 = not a stream (a RGND sample) */
|
||||
name_offset = read_u32le(chunk_offset+0x04,sf_head);
|
||||
codec = read_u8(chunk_offset+0x08,sf_head);
|
||||
channels = read_u8(chunk_offset+0x09,sf_head);
|
||||
/* 0x0a null */
|
||||
/* 0x0a: null */
|
||||
sample_rate = read_s32le(chunk_offset+0x0c,sf_head);
|
||||
|
||||
/* 0x10: info_type, meaning of the next value
|
||||
* (00=null, 30/40=data size without padding (ADPCM, ATRAC3plus), 80/A0=block size (AC3) */
|
||||
/* 0x14: info_value (see above) */
|
||||
/* 0x18: unknown (ex. 0x0008/0010/3307/CC02/etc)x2 */
|
||||
/* 0x18: unknown (ex. 0x0008/0010/3307/CC02/etc, RGND related?) x2 */
|
||||
/* 0x1c: null */
|
||||
|
||||
num_samples = read_s32le(chunk_offset+0x20,sf_head);
|
||||
|
@ -26,8 +26,8 @@ VGMSTREAM* init_vgmstream_sndz(STREAMFILE* sf) {
|
||||
|
||||
|
||||
/* .szd1: header + .szd2 = data
|
||||
* .szd3: szd1 + szd2 */
|
||||
if (!check_extensions(sf, "szd1,szd3"))
|
||||
* .szd/szd3: szd1 + szd2 */
|
||||
if (!check_extensions(sf, "szd1,szd,szd3"))
|
||||
goto fail;
|
||||
|
||||
/* parse chunk table and WAVS with offset to offset to WAVD */
|
||||
|
@ -172,6 +172,7 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) {
|
||||
cfg.channels = ww.channels;
|
||||
cfg.sample_rate = ww.sample_rate;
|
||||
cfg.big_endian = ww.big_endian;
|
||||
cfg.stream_end = ww.data_offset + ww.data_size;
|
||||
|
||||
if (ww.block_size != 0 || ww.bits_per_sample != 0) goto fail; /* always 0 for Worbis */
|
||||
|
||||
@ -237,7 +238,7 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) {
|
||||
uint32_t setup_id = read_u32be(start_offset + setup_offset + 0x06, sf);
|
||||
|
||||
/* if the setup after header starts with "(data)BCV" it's an inline codebook) */
|
||||
if ((setup_id & 0x00FFFFFF) == 0x00424356) { /* 0"BCV" */
|
||||
if ((setup_id & 0x00FFFFFF) == get_id32be("\0BCV")) {
|
||||
cfg.setup_type = WWV_FULL_SETUP;
|
||||
}
|
||||
/* if the setup is suspiciously big it's probably trimmed inline codebooks */
|
||||
@ -582,7 +583,7 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) {
|
||||
case mapping_2POINT1_xiph: /* 2ch+1ch, 2 streams */
|
||||
case mapping_STEREO: cfg.coupled_count = 1; break; /* 2ch, 1 stream */
|
||||
default: cfg.coupled_count = 0; break; /* 1ch, 1 stream */
|
||||
//TODO: AK OPUS doesn't seem to handles others mappings, though AK's .h imply they exist (uses 0 coupleds?)
|
||||
//TODO: AK OPUS doesn't seem to handle others mappings, though AK's .h imply they exist (uses 0 coupleds?)
|
||||
}
|
||||
|
||||
/* total number internal OPUS streams (should be >0) */
|
||||
@ -650,6 +651,11 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = read_s32(ww.fmt_offset + 0x1c, sf);
|
||||
|
||||
if (ww.prefetch) {
|
||||
vgmstream->num_samples = atrac9_bytes_to_samples_cfg(ww.file_size - start_offset, cfg.config_data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -932,8 +938,8 @@ static int parse_wwise(STREAMFILE* sf, wwise_header* ww) {
|
||||
}
|
||||
|
||||
if (ww->codec == PCM || ww->codec == IMA || ww->codec == VORBIS || ww->codec == DSP || ww->codec == XMA2 ||
|
||||
ww->codec == OPUSNX || ww->codec == OPUS || ww->codec == OPUSWW || ww->codec == PTADPCM || ww->codec == XWMA) {
|
||||
ww->prefetch = 1; /* only seen those, probably all exist (XWMA, AAC, HEVAG, ATRAC9?) */
|
||||
ww->codec == OPUSNX || ww->codec == OPUS || ww->codec == OPUSWW || ww->codec == PTADPCM || ww->codec == XWMA || ww->codec == ATRAC9) {
|
||||
ww->prefetch = 1; /* only seen those, probably all exist (missing XWMA, AAC, HEVAG) */
|
||||
} else {
|
||||
vgm_logi("WWISE: wrong expected size, maybe prefetch (report)\n");
|
||||
goto fail;
|
||||
@ -945,7 +951,7 @@ static int parse_wwise(STREAMFILE* sf, wwise_header* ww) {
|
||||
* From init bank and CAkSound's sources, those may be piped through their plugins. They come in
|
||||
* .opuspak (no names), have wrong riff/data sizes and only seem used for sfx (other audio is Vorbis). */
|
||||
if (ww->format == 0xFFFE && ww->prefetch) {
|
||||
if (read_u32be(ww->data_offset + 0x00, sf) == 0x4F676753) {
|
||||
if (is_id32be(ww->data_offset + 0x00, sf, "OggS")) {
|
||||
ww->codec = OPUSCPR;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user