Fix XVAG MPEG encoder delay/gapless looping

This commit is contained in:
bnnm 2019-06-29 13:24:53 +02:00
parent b82a2c964a
commit c7aaabf573
3 changed files with 31 additions and 8 deletions

View File

@ -78,18 +78,23 @@ int mpeg_custom_setup_init_default(STREAMFILE *streamFile, off_t start_offset, m
//todo: test more: this improves the output, but seems formats aren't usually prepared
// (and/or the num_samples includes all possible samples in file, so by discarding some it'll reach EOF)
#if 0
/* set encoder delay (samples to skip at the beginning of a stream) if needed, which varies with encoder used */
switch(data->type) {
case MPEG_AHX: data->skip_samples = 480; break; /* observed default */
case MPEG_P3D: data->skip_samples = info.frame_samples; break; /* matches Radical ADPCM (PC) output */
//case MPEG_AHX: data->skip_samples = 480; break; /* observed default */
//case MPEG_P3D: data->skip_samples = info.frame_samples; break; /* matches Radical ADPCM (PC) output */
/* FSBs (with FMOD DLLs) don't seem to need it. Particularly a few games (all from Wayforward?)
* contain audible garbage at the beginning, but it's actually there in-game too */
case MPEG_FSB: data->skip_samples = 0;
default: break;
//case MPEG_FSB: data->skip_samples = 0; break;
case MPEG_XVAG: /* set in header and needed for gapless looping */
data->skip_samples = data->config.skip_samples; break;
default:
break;
}
data->samples_to_discard = data->skip_samples;
#endif
return 1;
fail:

View File

@ -160,11 +160,28 @@ VGMSTREAM * init_vgmstream_xvag(STREAMFILE *streamFile) {
if (xvag.layers > 1 && !(xvag.layers*1 == vgmstream->channels || xvag.layers*2 == vgmstream->channels)) goto fail;
/* "mpin": mpeg info */
/* 0x00/04: mpeg version/layer? other: unknown or repeats of "fmat" */
if (!find_chunk(streamFile, 0x6D70696E,first_offset,0, &chunk_offset,NULL, xvag.big_endian, 1)) /*"mpin"*/
goto fail;
cfg.chunk_size = read_32bit(chunk_offset+0x1c,streamFile); /* fixed frame size */
/* all layers/subsongs share the same config; not very useful but for posterity:
* - 0x00: mpeg version
* - 0x04: mpeg layer
* - 0x08: bit rate
* - 0x0c: sample rate
* - 0x10: some version? (0x01-0x03)?
* - 0x14: channels per stream?
* - 0x18: channels per stream or total channels?
* - 0x1c: fixed frame size (always CBR)
* - 0x20: encoder delay (usually but not always 1201)
* - 0x24: number of samples
* - 0x28: some size?
* - 0x2c: ? (0x02)
* - 0x30: ? (0x00, 0x80)
* - 0x34: data size
* (rest is padding)
* */
cfg.chunk_size = read_32bit(chunk_offset+0x1c,streamFile);
cfg.skip_samples = read_32bit(chunk_offset+0x20,streamFile);
cfg.interleave = cfg.chunk_size * xvag.factor;
vgmstream->codec_data = init_mpeg_custom(streamFile, start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_XVAG, &cfg);

View File

@ -1030,6 +1030,7 @@ typedef struct {
int interleave; /* size of stream interleave */
int encryption; /* encryption mode */
int big_endian;
int skip_samples;
/* for AHX */
int cri_type;
uint16_t cri_key1;