summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Beurden <mvanb1@gmail.com>2022-07-01 07:36:48 +0200
committerGitHub <noreply@github.com>2022-07-01 07:36:48 +0200
commit633ab36ec51bada8737459e51cc54441544e63b2 (patch)
tree83fac30bee3a9b7b90539c382c66ca9980b73bae
parent10c0a5f610446d04c7e2794a0884acb22bb5859f (diff)
downloadflac-633ab36ec51bada8737459e51cc54441544e63b2.tar.gz
Small fixes needed for 32-bit capability (#379)
* Change replaygain analysis so it is able to handle 32-bit PCM * Increase FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE to 32 * Fix switch-case fallthrough
-rw-r--r--include/FLAC/format.h8
-rw-r--r--src/libFLAC/stream_decoder.c1
-rw-r--r--src/share/grabbag/replaygain.c23
3 files changed, 15 insertions, 17 deletions
diff --git a/include/FLAC/format.h b/include/FLAC/format.h
index 28eda599..3e8d7e55 100644
--- a/include/FLAC/format.h
+++ b/include/FLAC/format.h
@@ -113,13 +113,11 @@ extern "C" {
/** The maximum sample resolution permitted by libFLAC.
*
- * \warning
* FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However,
- * the reference encoder/decoder is currently limited to 24 bits because
- * of prevalent 32-bit math, so make sure and use this value when
- * appropriate.
+ * the reference encoder/decoder used to be limited to 24 bits. This
+ * value was used to signal that limit.
*/
-#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u)
+#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (32u)
/** The maximum sample rate permitted by the format. The value is
* ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A>
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
index fe8c451a..66a4b979 100644
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -2432,6 +2432,7 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
break;
case 7:
decoder->private_->frame.header.bits_per_sample = 32;
+ break;
default:
FLAC__ASSERT(0);
break;
diff --git a/src/share/grabbag/replaygain.c b/src/share/grabbag/replaygain.c
index fb23a474..6e98eb59 100644
--- a/src/share/grabbag/replaygain.c
+++ b/src/share/grabbag/replaygain.c
@@ -48,6 +48,11 @@
#endif
#define local_max(a,b) ((a)>(b)?(a):(b))
+#ifdef abs32
+#undef abs32
+#endif
+#define abs32(a) (((a)==INT32_MIN)?INT32_MAX:abs(a))
+
static const char *reference_format_ = "%s=%2.1f dB";
static const char *gain_format_ = "%s=%+2.2f dB";
static const char *peak_format_ = "%s=%1.8f";
@@ -134,14 +139,8 @@ FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__
FLAC__int32 block_peak = 0, s;
uint32_t i, j;
- FLAC__ASSERT(bps >= 4 && bps <= FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE);
- FLAC__ASSERT(FLAC__MIN_BITS_PER_SAMPLE == 4);
- /*
- * We use abs() on a FLAC__int32 which is undefined for the most negative value.
- * If the reference codec ever handles 32bps we will have to write a special
- * case here.
- */
- FLAC__ASSERT(FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE < 32);
+ FLAC__ASSERT(bps >= FLAC__MIN_BITS_PER_SAMPLE && bps <= FLAC__MAX_BITS_PER_SAMPLE);
+ FLAC__ASSERT(FLAC__MIN_BITS_PER_SAMPLE == 4 && FLAC__MAX_BITS_PER_SAMPLE == 32);
if(bps == 16) {
if(is_stereo) {
@@ -180,7 +179,7 @@ FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__
}
}
}
- else { /* bps must be < 32 according to above assertion */
+ else {
const double scale = (
(bps > 16)?
(double)1. / (double)(1u << (bps - 16)) :
@@ -194,12 +193,12 @@ FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)(scale * (double)s);
- s = abs(s);
+ s = abs32(s);
block_peak = local_max(block_peak, s);
s = input[1][j];
rbuffer[i] = (flac_float_t)(scale * (double)s);
- s = abs(s);
+ s = abs32(s);
block_peak = local_max(block_peak, s);
}
samples -= n;
@@ -214,7 +213,7 @@ FLAC__bool grabbag__replaygain_analyze(const FLAC__int32 * const input[], FLAC__
for(i = 0; i < n; i++, j++) {
s = input[0][j];
lbuffer[i] = (flac_float_t)(scale * (double)s);
- s = abs(s);
+ s = abs32(s);
block_peak = local_max(block_peak, s);
}
samples -= n;