From 7214dfbef750e48929bcd4e5b5d7bbf317bd0035 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 13 Oct 2019 18:55:52 +0200 Subject: [PATCH] Fix ATRAC3 clips caused by incorrectly inverted PCM16 --- src/coding/ffmpeg_decoder.c | 24 ++++++++---------------- src/coding/ffmpeg_decoder_utils.c | 4 ++-- src/vgmstream.h | 2 +- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/coding/ffmpeg_decoder.c b/src/coding/ffmpeg_decoder.c index b1dac8dc..4b57cd41 100644 --- a/src/coding/ffmpeg_decoder.c +++ b/src/coding/ffmpeg_decoder.c @@ -52,14 +52,6 @@ static void remap_audio(sample_t *outbuf, int sample_count, int channels, int *c } } -static void invert_audio(sample_t *outbuf, int sample_count, int channels) { - int i; - - for (i = 0; i < sample_count*channels; i++) { - outbuf[i] = -outbuf[i]; - } -} - /** * Special patching for FFmpeg's buggy seek code. * @@ -629,17 +621,19 @@ static void samples_s32p_to_s16(sample_t* obuf, int32_t** ibuf, int ichs, int sa } } } -static void samples_flt_to_s16(sample_t* obuf, float* ibuf, int ichs, int samples, int skip) { +static void samples_flt_to_s16(sample_t* obuf, float* ibuf, int ichs, int samples, int skip, int invert) { int s, total_samples = samples * ichs; + float scale = invert ? -32768.0f : 32768.0f; for (s = 0; s < total_samples; s++) { - obuf[s] = clamp16(ibuf[skip*ichs + s] * 32768.0f); + obuf[s] = clamp16(ibuf[skip*ichs + s] * scale); } } -static void samples_fltp_to_s16(sample_t* obuf, float** ibuf, int ichs, int samples, int skip) { +static void samples_fltp_to_s16(sample_t* obuf, float** ibuf, int ichs, int samples, int skip, int invert) { int s, ch; + float scale = invert ? -32768.0f : 32768.0f; for (ch = 0; ch < ichs; ch++) { for (s = 0; s < samples; s++) { - obuf[s*ichs + ch] = clamp16(ibuf[ch][skip + s] * 32768.0f); + obuf[s*ichs + ch] = clamp16(ibuf[ch][skip + s] * scale); } } } @@ -681,8 +675,8 @@ static void copy_samples(ffmpeg_codec_data *data, sample_t *outbuf, int samples_ case AV_SAMPLE_FMT_S32: samples_s32_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; case AV_SAMPLE_FMT_S32P: samples_s32p_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; /* mainly MDCT-like codecs (Ogg, AAC, etc) */ - case AV_SAMPLE_FMT_FLT: samples_flt_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; - case AV_SAMPLE_FMT_FLTP: samples_fltp_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; + case AV_SAMPLE_FMT_FLT: samples_flt_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed, data->invert_floats_set); break; + case AV_SAMPLE_FMT_FLTP: samples_fltp_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed, data->invert_floats_set); break; /* possibly PCM64 only (not enabled) */ case AV_SAMPLE_FMT_DBL: samples_dbl_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; case AV_SAMPLE_FMT_DBLP: samples_dblp_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; @@ -692,8 +686,6 @@ static void copy_samples(ffmpeg_codec_data *data, sample_t *outbuf, int samples_ if (data->channel_remap_set) remap_audio(outbuf, samples_to_do, channels, data->channel_remap); - if (data->invert_audio_set) - invert_audio(outbuf, samples_to_do, channels); } /* decode samples of any kind of FFmpeg format */ diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c index 83a94c22..3b674310 100644 --- a/src/coding/ffmpeg_decoder_utils.c +++ b/src/coding/ffmpeg_decoder_utils.c @@ -66,7 +66,7 @@ ffmpeg_codec_data * init_ffmpeg_atrac3_raw(STREAMFILE *sf, off_t offset, size_t /* invert ATRAC3: waveform is inverted vs official tools (not noticeable but for accuracy) */ if (is_at3) { - ffmpeg_data->invert_audio_set = 1; + ffmpeg_data->invert_floats_set = 1; } return ffmpeg_data; @@ -159,7 +159,7 @@ ffmpeg_codec_data * init_ffmpeg_atrac3_riff(STREAMFILE *sf, off_t offset, int* o /* invert ATRAC3: waveform is inverted vs official tools (not noticeable but for accuracy) */ if (is_at3) { - ffmpeg_data->invert_audio_set = 1; + ffmpeg_data->invert_floats_set = 1; } /* multichannel fix: LFE channel should be reordered on decode (ATRAC3Plus only, only 1/2/6/8ch exist): diff --git a/src/vgmstream.h b/src/vgmstream.h index 71f38754..1badfdbe 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -1192,7 +1192,7 @@ typedef struct { // config int channel_remap_set; int channel_remap[32]; /* map of channel > new position */ - int invert_audio_set; + int invert_floats_set; int skip_samples_set; /* flag to know skip samples were manually added from vgmstream */ int force_seek; /* flags for special seeking in faulty formats */ int bad_init;