Linux bluetooth development
 help / color / mirror / Atom feed
From: Johan Hedberg <johan.hedberg@gmail.com>
To: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Cc: linux-bluetooth@vger.kernel.org,
	Siarhei Siamashka <siarhei.siamashka@nokia.com>
Subject: Re: [PATCH] sbc: overflow bugfix and audio decoding quality improvement
Date: Wed, 19 Oct 2011 11:23:01 +0300	[thread overview]
Message-ID: <20111019082301.GA4297@fusion.localdomain> (raw)
In-Reply-To: <1318814678-25640-1-git-send-email-siarhei.siamashka@gmail.com>

Hi Siarhei,

On Mon, Oct 17, 2011, Siarhei Siamashka wrote:
> The "(((audio_sample << 1) | 1) << frame->scale_factor[ch][sb])"
> part of expression
>     "frame->sb_sample[blk][ch][sb] =
>         (((audio_sample << 1) | 1) << frame->scale_factor[ch][sb]) /
>         levels[ch][sb] - (1 << frame->scale_factor[ch][sb])"
> in "sbc_unpack_frame" function can sometimes overflow 32-bit signed int.
> This problem can be reproduced by first using bitpool 128 and encoding
> some random noise data, and then feeding it to sbc decoder. The obvious
> thing to do would be to change "audio_sample" variable type to uint32_t.
> 
> However the problem is a little bit more complicated. According
> to the section "12.6.2 Scale Factors" of A2DP spec:
>     scalefactor[ch][sb] = pow(2.0, (scale_factor[ch][sb] + 1))
> 
> And according to "12.6.4 Reconstruction of the Subband Samples":
>     sb_sample[blk][ch][sb] = scalefactor[ch][sb] *
>         ((audio_sample[blk][ch][sb]*2.0+1.0) / levels[ch][sb]-1.0);
> 
> Hence the current code for calculating "sb_sample[blk][ch][sb]" is
> not quite correct, because it loses one least significant bit of
> sample data and passes twice smaller sample values to the synthesis
> filter (the filter also deviates from the spec to compensate this).
> This all has quite a noticeable impact on audio quality. Moreover,
> it makes sense to keep a few extra bits of precision here in order
> to minimize rounding errors. So the proposed patch introduces a new
> SBCDEC_FIXED_EXTRA_BITS constant and uses uint64_t data type
> for intermediate calculations in order to safeguard against
> overflows. This patch intentionally addresses only the quality
> issue, but performance can be also improved later (like replacing
> division with multiplication by reciprocal).
> 
> Test for the difference of sbc encoding/decoding roundtrip vs.
> the original audio file for joint stereo, bitpool 128, 8 subbands
> and http://media.xiph.org/sintel/sintel-master-st.flac sample
> demonstrates some quality improvement:
> 
> === before ===
>     --- comparing original / sbc_encoder.exe + sbcdec ---
>     stddev:    4.64 PSNR: 82.97 bytes:170495708/170496000
> === after ===
>     --- comparing original / sbc_encoder.exe + sbcdec ---
>     stddev:    1.95 PSNR: 90.50 bytes:170495708/170496000
> ---
>  sbc/sbc.c        |   11 +++++++----
>  sbc/sbc_tables.h |    6 ++++--
>  2 files changed, 11 insertions(+), 6 deletions(-)

Applied. Thanks!

Additionally I pushed another patch to try to reduce the massive
indentation in the nested for-loops. In general whenever you've got the
following kind of pattern in a loop:

	if (some condition) {
		lots
		of
		stuff
		...
	} else
		just_a_single_statement;

You can avoid indentation for the larger branch by changing this to:

	if (inverted condition) {
		just_a_single_statement;
		continue;
	}

	lots
	of
	stuff
	...

And if you just have a long if-branch without an else part at all it
becomes even simpler:

	if (inverted condition)
		continue;

	<what used to be within a long if-branch>

Johan

      reply	other threads:[~2011-10-19  8:23 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-17  1:24 [PATCH] sbc: overflow bugfix and audio decoding quality improvement Siarhei Siamashka
2011-10-19  8:23 ` Johan Hedberg [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20111019082301.GA4297@fusion.localdomain \
    --to=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=siarhei.siamashka@gmail.com \
    --cc=siarhei.siamashka@nokia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox