From 01209f887f9b96f0c75ebf07f9d9961f38125553 Mon Sep 17 00:00:00 2001 From: UltraFuzzy <> Date: Wed, 17 Sep 2025 18:28:30 -0500 Subject: [PATCH 1/4] Set ebur128 peak flag to show both true and sample peaks. --- src/cyanrip_encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cyanrip_encode.c b/src/cyanrip_encode.c index 23e9af0..8a3294e 100644 --- a/src/cyanrip_encode.c +++ b/src/cyanrip_encode.c @@ -386,7 +386,7 @@ static int init_filtering(cyanrip_ctx *ctx, cyanrip_filt_ctx *s, const char *filter_desc = hdcd ? "hdcd" : deemphasis ? "aemphasis=type=cd" : - peak ? "ebur128=peak=true,anullsink" : + peak ? "ebur128=peak=true+sample+true,anullsink" : NULL; ret = avfilter_graph_parse_ptr(s->graph, filter_desc, &inputs, &outputs, NULL); From 973bb88c1eb74e4e0cba70cbb184cde1afc697a0 Mon Sep 17 00:00:00 2001 From: UltraFuzzy <> Date: Wed, 17 Sep 2025 20:35:46 -0500 Subject: [PATCH 2/4] Add reporting of sample peak in terms of relative amplitude by calculation from ebur128 dBFS and by iteration over samples. --- src/cyanrip_main.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/cyanrip_main.c b/src/cyanrip_main.c index 0a30135..52db3be 100644 --- a/src/cyanrip_main.c +++ b/src/cyanrip_main.c @@ -584,6 +584,22 @@ static void track_read_extra(cyanrip_ctx *ctx, cyanrip_track *t) } } +static double sample_peak_rel_amp(const uint8_t *data, const int bytes) { + const int16_t* samples = (int16_t*)data; + const int bytes_per_sample = 2; + const int sample_num = bytes / bytes_per_sample; + + /* At least int32 needed to accomodate abs(-INT16_MIN) */ + int_fast32_t sample_peak = 0; + for (int i = 0; i < sample_num; ++i) { + const int_fast32_t abs_sample = abs((int_fast32_t)samples[i]); + sample_peak = FFMAX(sample_peak, abs_sample); + } + + const double sample_peak_max = abs(INT16_MIN); + return (double)sample_peak/sample_peak_max; +} + static int cyanrip_rip_track(cyanrip_ctx *ctx, cyanrip_track *t) { int ret = 0; @@ -649,6 +665,7 @@ repeat_ripping:; } int64_t frame_last_read = av_gettime_relative(); + double track_sample_peak_rel_amp_precise = 0.0; /* Read the actual CD data */ for (int i = 0; i < frames; i++) { @@ -692,6 +709,11 @@ repeat_ripping:; /* Update checksums */ crip_process_checksums(&checksum_ctx, data, bytes); + /* Update sample peak */ + const double frame_sample_peak_rel_amp_precise = sample_peak_rel_amp(data, bytes); + track_sample_peak_rel_amp_precise = + FFMAX(frame_sample_peak_rel_amp_precise, track_sample_peak_rel_amp_precise); + /* Decode and encode */ if (!ctx->settings.ripping_retries || repeat_mode_encode) { ret = cyanrip_send_pcm_to_encoders(ctx, t->enc_ctx, ctx->settings.outputs_num, @@ -872,6 +894,14 @@ repeat_ripping:; t->total_repeats = total_repeats; if (!quit_now && !ret) { cyanrip_finalize_encoding(ctx, t); + const double track_true_peak_rel_amp_ebu = pow(10, t->ebu_true_peak/20); + const double track_sample_peak_rel_amp_ebu = pow(10, t->ebu_sample_peak/20); + cyanrip_log(ctx, 0, " Sample peak relative amplitude (calculated from ebur128 dBFS):\n"); + cyanrip_log(ctx, 0, " Peak: %f\n\n", track_sample_peak_rel_amp_ebu); + cyanrip_log(ctx, 0, " Sample peak relative amplitude (precise):\n"); + cyanrip_log(ctx, 0, " Peak: %f\n\n", track_sample_peak_rel_amp_precise); + cyanrip_log(ctx, 0, " True peak relative amplitude (calculated from ebur128 dBFS):\n"); + cyanrip_log(ctx, 0, " Peak: %f\n\n", track_true_peak_rel_amp_ebu); if (ctx->settings.enable_replaygain) crip_replaygain_meta_track(ctx, t); cyanrip_log_track_end(ctx, t); From 5ed2c08cc697d4f99f3e408276d0838b9e2c2e94 Mon Sep 17 00:00:00 2001 From: UltraFuzzy <> Date: Sat, 20 Sep 2025 08:26:22 -0500 Subject: [PATCH 3/4] typo --- src/cyanrip_encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cyanrip_encode.c b/src/cyanrip_encode.c index 8a3294e..7a1a22d 100644 --- a/src/cyanrip_encode.c +++ b/src/cyanrip_encode.c @@ -386,7 +386,7 @@ static int init_filtering(cyanrip_ctx *ctx, cyanrip_filt_ctx *s, const char *filter_desc = hdcd ? "hdcd" : deemphasis ? "aemphasis=type=cd" : - peak ? "ebur128=peak=true+sample+true,anullsink" : + peak ? "ebur128=peak=true+sample,anullsink" : NULL; ret = avfilter_graph_parse_ptr(s->graph, filter_desc, &inputs, &outputs, NULL); From d2383a6302d742a8ae45c86bad9ae856e78bc913 Mon Sep 17 00:00:00 2001 From: UltraFuzzy <> Date: Fri, 10 Oct 2025 05:34:27 -0500 Subject: [PATCH 4/4] Improve sample_peak_rel_amp(). --- src/cyanrip_main.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cyanrip_main.c b/src/cyanrip_main.c index 52db3be..377f2fa 100644 --- a/src/cyanrip_main.c +++ b/src/cyanrip_main.c @@ -589,15 +589,22 @@ static double sample_peak_rel_amp(const uint8_t *data, const int bytes) { const int bytes_per_sample = 2; const int sample_num = bytes / bytes_per_sample; - /* At least int32 needed to accomodate abs(-INT16_MIN) */ - int_fast32_t sample_peak = 0; + /* At least 32 bits needed to accomodate abs(INT16_MIN) */ + int32_t sample_peak = 0; for (int i = 0; i < sample_num; ++i) { - const int_fast32_t abs_sample = abs((int_fast32_t)samples[i]); - sample_peak = FFMAX(sample_peak, abs_sample); + /* int is usually 32-bit but technically it can be 16-bit. Make sure + * we're using a wide enough abs() just in case someone runs this on a + * toaster. + */ + #if (INT_MAX >= 32768) + sample_peak = FFMAX(sample_peak, abs(samples[i])); + #else + sample_peak = FFMAX(sample_peak, labs(samples[i])); + #endif } - const double sample_peak_max = abs(INT16_MIN); - return (double)sample_peak/sample_peak_max; + /* The greatest sample absolute value is abs(INT16_MIN) = 32768 */ + return (double)sample_peak/32768.0; } static int cyanrip_rip_track(cyanrip_ctx *ctx, cyanrip_track *t)