Fix FSB5 loop end +1 samples and tweaks

This commit is contained in:
bnnm 2019-09-24 23:56:27 +02:00
parent d8fce9de7f
commit 0b98aff930
2 changed files with 33 additions and 16 deletions

View File

@ -305,16 +305,16 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
/* for MPEG and CELT sometimes full loops are given with around/exact 1 frame less than num_samples,
* probably to account for encoder/decoder delay (ex. The Witcher 2, Hard Reset, Timeshift) */
if (fsb.codec == CELT)
full_loop = fsb.loop_start == 0 && fsb.loop_end >= fsb.num_samples - 512; /* maybe around 300? */
full_loop = fsb.loop_start - 512 <= 0 && fsb.loop_end >= fsb.num_samples - 512; /* aproximate */
else if (fsb.codec == MPEG)
full_loop = fsb.loop_start == 0 && fsb.loop_end >= fsb.num_samples - 1152;
full_loop = fsb.loop_start - 1152 <= 0 && fsb.loop_end >= fsb.num_samples - 1152; /* WWF Legends of Wrestlemania uses 2 frames? */
else
full_loop = fsb.loop_start == 0 && fsb.loop_end == fsb.num_samples;
/* in seconds (lame but no better way) */
is_small = fsb.num_samples < 20 * fsb.sample_rate;
//;VGM_LOG("FSB loop start=%i, loop end=%i, samples=%i, mode=%x\n", fsb.loop_start, fsb.loop_end, fsb.num_samples, fsb.mode);
//;VGM_LOG("FSB: loop start=%i, loop end=%i, samples=%i, mode=%x\n", fsb.loop_start, fsb.loop_end, fsb.num_samples, fsb.mode);
//;VGM_LOG("FSB: enable=%i, full=%i, small=%i\n",enable_loop,full_loop,is_small );
fsb.loop_flag = !(fsb.mode & FSOUND_LOOP_OFF); /* disabled manually */

View File

@ -147,23 +147,39 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
break;
case 0x03: /* loop info */
fsb5.loop_start = read_32bitLE(extraflag_offset+0x04,streamFile);
if (extraflag_size > 0x04) /* probably not needed */
if (extraflag_size > 0x04) { /* probably not needed */
fsb5.loop_end = read_32bitLE(extraflag_offset+0x08,streamFile);
fsb5.loop_end += 1; /* correct compared to FMOD's tools */
}
/* when start is 0 seems the song repeats with no real looping (ex. Sonic Boom Fire & Ice jingles) */
fsb5.loop_flag = (fsb5.loop_start != 0x00);
/* autodetect unwanted loops */
{
/* like FSB4 jingles/sfx/music do full loops for no reason, but happens a lot less.
* Most songs loop normally now with proper values [ex. Shantae, FFX] */
int full_loop, ajurika_loops;
/* ignore wrong loops in some files [Pac-Man CE2 Plus (Switch) pce2p_bgm_ajurika_*.fsb] */
if (fsb5.loop_start == 0x3c && fsb5.loop_end == 0x007F007F &&
fsb5.num_samples > fsb5.loop_end + 100000) { /* arbitrary limit */
fsb5.loop_flag = 0;
/* could use the same checks as FSB4 but simplified (ex. Sonic Boom Fire & Ice jingles) */
full_loop = fsb5.loop_start != 0x00;
/* wrong values in some files [Pac-Man CE2 Plus (Switch) pce2p_bgm_ajurika_*.fsb] */
ajurika_loops = fsb5.loop_start == 0x3c && fsb5.loop_end == 0x007F007F &&
fsb5.num_samples > fsb5.loop_end + 100000; /* arbitrary limit */
//;VGM_LOG("FSB5: loop start=%i, loop end=%i, samples=%i\n", fsb5.loop_start, fsb5.loop_end, fsb5.num_samples);
fsb5.loop_flag = 1;
if (!full_loop || ajurika_loops) {
VGM_LOG("FSB5: disabled unwanted loop\n");
fsb5.loop_flag = 0;
}
}
break;
case 0x04: /* free comment, or maybe SFX info */
break;
//case 0x05: /* Unknown (32b) */ //todo multistream marker?
// /* found in Tearaway Vita, value 0, first stream only */
// break;
case 0x05: /* unknown 32b */ //todo multistream marker?
/* found in Tearaway Vita, value 0, first stream only */
VGM_LOG("FSB5: flag %x with value %08x\n", extraflag_type, read_32bitLE(extraflag_offset+0x04,streamFile));
break;
case 0x06: /* XMA seek table */
/* no need for it */
break;
@ -186,9 +202,10 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
* (xN entries)
*/
break;
//case 0x0d: /* Unknown (32b) */
// /* found in some XMA2/Vorbis/FADPCM */
// break;
case 0x0d: /* unknown 32b (config? usually 0x3fnnnn00 BE) */
/* found in some XMA2/Vorbis/FADPCM */
VGM_LOG("FSB5: flag %x with value %08x\n", extraflag_type, read_32bitLE(extraflag_offset+0x04,streamFile));
break;
default:
VGM_LOG("FSB5: unknown extraflag 0x%x at %x + 0x04 (size 0x%x)\n", extraflag_type, (uint32_t)extraflag_offset, extraflag_size);
break;