sox-devel@lists.sourceforge.net unofficial mirror
 help / color / mirror / code / Atom feed
* silence patch
@ 2020-09-05  1:59 fbk-qriry
  2020-09-05 11:16 ` Måns Rullgård
  0 siblings, 1 reply; 2+ messages in thread
From: fbk-qriry @ 2020-09-05  1:59 UTC (permalink / raw)
  To: sox-devel


There is a bug in the "silence" effect that appears to
have been introduced in 2009 with commit bbb403.

In function aboveThreshold() the value being scaled
is effectively the result of a sqrt but when it
gets scaled the value is not rounded but coarsely truncated instead.
Truncation is wrong. Rounding is right.

Prior to this commit the value was effectively
rounded to the nearest whole value (according to
the precision). Without the following patch the "silence"
results are considerably different to earlier versions.

For example:

  value        old masked  current
  -----        ----------  -------
  0x009bd6ae   0x0000009c  0x009b0000
  0x00a170b8   0x000000a1  0x00a10000

The 0x009bd6ae used to be correctly rounded to 0x9c whereas
the current version effectively truncates the value to 0x9b.

That is a serious flaw that should have been picked up
during testing. But better discovered 11 years later by a
random member of the public than never.

The patch:

======================================================================
--- sox-downstream-sox-14.4.2.0.modified/src/silence.c.jw
+++ sox-downstream-sox-14.4.2.0.modified/src/silence.c
@@ -277,9 +277,15 @@
 {
   /* When scaling low bit data, noise values got scaled way up */
   /* Only consider the original bits when looking for silence */
-  sox_sample_t masked_value = value & (-1 << (32 - effp->in_signal.precision));
+  double scaled_value;
+  sox_sample_t rounded_value = value;
 
-  double scaled_value = (double)masked_value / SOX_SAMPLE_MAX;
+  /* before we mask we should round the value */
+  if (effp->in_signal.precision < 32)
+    rounded_value += (1 << (32 - effp->in_signal.precision - 1));
+  rounded_value &= (-1 << (32 - effp->in_signal.precision));
+
+  scaled_value = (double)rounded_value / SOX_SAMPLE_MAX;
 
   if (unit == '%')
     scaled_value *= 100;
======================================================================

:JW



_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: silence patch
  2020-09-05  1:59 silence patch fbk-qriry
@ 2020-09-05 11:16 ` Måns Rullgård
  0 siblings, 0 replies; 2+ messages in thread
From: Måns Rullgård @ 2020-09-05 11:16 UTC (permalink / raw)
  To: fbk-qriry; +Cc: sox-devel

fbk-qriry@zacglen.net writes:

> There is a bug in the "silence" effect that appears to
> have been introduced in 2009 with commit bbb403.
>
> In function aboveThreshold() the value being scaled
> is effectively the result of a sqrt but when it
> gets scaled the value is not rounded but coarsely truncated instead.
> Truncation is wrong. Rounding is right.
>
> Prior to this commit the value was effectively
> rounded to the nearest whole value (according to
> the precision). Without the following patch the "silence"
> results are considerably different to earlier versions.
>
> For example:
>
>   value        old masked  current
>   -----        ----------  -------
>   0x009bd6ae   0x0000009c  0x009b0000
>   0x00a170b8   0x000000a1  0x00a10000
>
> The 0x009bd6ae used to be correctly rounded to 0x9c whereas
> the current version effectively truncates the value to 0x9b.
>
> That is a serious flaw that should have been picked up
> during testing. But better discovered 11 years later by a
> random member of the public than never.

The only serious flaw I see here is your condescending tone.

> The patch:
>
> ======================================================================
> --- sox-downstream-sox-14.4.2.0.modified/src/silence.c.jw
> +++ sox-downstream-sox-14.4.2.0.modified/src/silence.c
> @@ -277,9 +277,15 @@
>  {
>    /* When scaling low bit data, noise values got scaled way up */
>    /* Only consider the original bits when looking for silence */
> -  sox_sample_t masked_value = value & (-1 << (32 - effp->in_signal.precision));
> +  double scaled_value;
> +  sox_sample_t rounded_value = value;
>
> -  double scaled_value = (double)masked_value / SOX_SAMPLE_MAX;
> +  /* before we mask we should round the value */
> +  if (effp->in_signal.precision < 32)
> +    rounded_value += (1 << (32 - effp->in_signal.precision - 1));
> +  rounded_value &= (-1 << (32 - effp->in_signal.precision));
> +
> +  scaled_value = (double)rounded_value / SOX_SAMPLE_MAX;
>
>    if (unit == '%')
>      scaled_value *= 100;
> ======================================================================
>
> :JW
>

-- 
Måns Rullgård


_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-05 11:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-05  1:59 silence patch fbk-qriry
2020-09-05 11:16 ` Måns Rullgård

Code repositories for project(s) associated with this inbox:

	https://80x24.org/mirrors/sox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).