From: "Christian Hoene" <hoene@uni-tuebingen.de>
To: "'BlueZ development'" <bluez-devel@lists.sourceforge.net>
Cc: 'Frans de Bont' <frans.de.bont@philips.com>
Subject: Re: [Bluez-devel] REALLY Bad encoding performance of Linux SBC audio codec
Date: Wed, 29 Oct 2008 16:30:55 +0100 [thread overview]
Message-ID: <004e01c939db$5c241760$146c4620$@de> (raw)
In-Reply-To: <1225136516.7157.22.camel@californication>
[-- Attachment #1: Type: text/plain, Size: 2493 bytes --]
Hello,
Sorry Bad news.
the encoding and decodng performance of bluez's SBC is really bad.
I just used the latest sbcenc program from bluez-4.17 and compared it to the
reference
Attached you will find wav-files encoded with the Bluetooth reference
implementation and bluez
Filelist
========
compare.sh is the scrip that I use to compare both codec
versions
refsop01.wav the original sample
tmp.ref.sbc with reference encoded
tmp.bluez.sbc with bluez encoded
tmp.ref.sw.wav with reference encoded and decoded (has good quality)
tmp.bluez.sw.wav with bluez encoded and decoded (has bad quality ODG=)
tmp.refbluez.sw.wav with reference encoded and with bluez decoded (has bad
quality)
tmp.bluezref.sw.wav with bluez encoded and with reference decoded (has
medium quality)
Both the bluez encoder and decoder do not work as good as the reference
implementation.
I also conducted some perceptual audio tests with ITU BS.1387 (PEAQ), which
confirm these results.
With best regards,
Christian
PS:
Attached also an enhanced version for sbc/sbcenc.c, which considers more
command line options.
> -----Original Message-----
> From: Marcel Holtmann [mailto:marcel@holtmann.org]
> Sent: Monday, October 27, 2008 8:42 PM
> To: BlueZ development
> Subject: Re: [Bluez-devel] Bad encoding performance of Linux SBC audio
> codec
>
> Hi Brad,
>
> > > I am sorry to say that the audio quality of the open source version
> of SBC
> > > is far worse than the reference implementation.
> >
> > If you are using the standalone "sbc" project at sourceforge, then
> you
> > should try the version inside bluez. The standalone used to simply be
> > slower, but we identified & fixed some quality issues too that should
> > be backported.
>
> the standalone version should not be used at all at the moment. All
> efforts should go into the version included in bluez-4.x.tar.gz.
>
> Regards
>
> Marcel
>
>
>
> -----------------------------------------------------------------------
> --
> This SF.Net email is sponsored by the Moblin Your Move Developer's
> challenge
> Build the coolest Linux based applications with Moblin SDK & win great
> prizes
> Grand prize is a trip for two to an Open Source event anywhere in the
> world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Bluez-devel mailing list
> Bluez-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bluez-devel
[-- Attachment #2: sbcenc.c --]
[-- Type: application/octet-stream, Size: 6060 bytes --]
/*
*
* Bluetooth low-complexity, subband codec (SBC) encoder
*
* Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <sys/stat.h>
#include "sbc.h"
#include "formats.h"
int verbose=0;
static ssize_t __read(int fd, void *buf, size_t count)
{
ssize_t len, pos = 0;
while (count > 0) {
len = read(fd, buf + pos, count);
if (len <= 0)
return len;
count -= len;
pos += len;
}
return pos;
}
static ssize_t __write(int fd, const void *buf, size_t count)
{
ssize_t len, pos = 0;
while (count > 0) {
len = write(fd, buf + pos, count);
if (len <= 0)
return len;
count -= len;
pos += len;
}
return pos;
}
static void encode(char *filename, int subbands, int bitpool, int joint, int SNR)
{
struct au_header *au_hdr;
unsigned char input[2048], output[2048];
sbc_t sbc;
int fd, len, size, count, encoded;
if (strcmp(filename, "-")) {
fd = open(filename, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Can't open file %s: %s\n",
filename, strerror(errno));
return;
}
} else
fd = fileno(stdin);
len = __read(fd, input, sizeof(input));
if (len < sizeof(*au_hdr)) {
if (fd > fileno(stderr))
fprintf(stderr, "Can't read header from file %s: %s\n",
filename, strerror(errno));
else
perror("Can't read audio header");
goto done;
}
au_hdr = (struct au_header *) input;
if (au_hdr->magic != AU_MAGIC ||
BE_INT(au_hdr->hdr_size) > 128 ||
BE_INT(au_hdr->hdr_size) < 24 ||
BE_INT(au_hdr->encoding) != AU_FMT_LIN16) {
fprintf(stderr, "Data is not in Sun/NeXT audio S16_BE format\n");
goto done;
}
sbc_init(&sbc, 0L);
switch (BE_INT(au_hdr->sample_rate)) {
case 16000:
sbc.frequency = SBC_FREQ_16000;
break;
case 32000:
sbc.frequency = SBC_FREQ_32000;
break;
case 44100:
sbc.frequency = SBC_FREQ_44100;
break;
case 48000:
sbc.frequency = SBC_FREQ_48000;
break;
}
int srate = BE_INT(au_hdr->sample_rate);
sbc.subbands = subbands == 4 ? SBC_SB_4 : SBC_SB_8;
if (BE_INT(au_hdr->channels) == 1)
sbc.mode = SBC_MODE_MONO;
else if (joint)
sbc.mode = SBC_MODE_JOINT_STEREO;
else
sbc.mode = SBC_MODE_STEREO;
sbc.endian = SBC_BE;
count = BE_INT(au_hdr->data_size);
size = len - BE_INT(au_hdr->hdr_size);
memmove(input, input + BE_INT(au_hdr->hdr_size), size);
sbc.bitpool = bitpool;
sbc.allocation = SNR ? SBC_AM_SNR : SBC_AM_LOUDNESS;
if(verbose) {
fprintf(stderr,"encoding %s with rate %d, %d subbands, %d bits, AM %s, and mode %s\n",
filename,srate,subbands,bitpool,
sbc.allocation==SBC_AM_SNR?"SNR":"LOUDNESS",
sbc.mode==SBC_MODE_MONO?"MONO":sbc.mode==SBC_MODE_STEREO?"STEREO":"JOINTSTEREO");
}
while (1) {
if (size < sizeof(input)) {
len = __read(fd, input + size, sizeof(input) - size);
if (len == 0 && size == 0)
break;
if (len < 0) {
perror("Can't read audio data");
break;
}
size += len;
}
len = sbc_encode(&sbc, input, size,
output, sizeof(output), &encoded);
if (len < size)
memmove(input, input + len, size - len);
size -= len;
len = __write(fileno(stdout), output, encoded);
if (len == 0)
break;
if (len < 0 || len != encoded) {
perror("Can't write SBC output");
break;
}
}
sbc_finish(&sbc);
done:
if (fd > fileno(stderr))
close(fd);
}
static void usage(void)
{
printf("SBC encoder utility ver %s\n", VERSION);
printf("Copyright (c) 2004-2008 Marcel Holtmann\n\n");
printf("Usage:\n"
"\tsbcenc [options] file(s)\n"
"\n");
printf("Options:\n"
"\t-h, --help Display help\n"
"\t-v, --verbose Verbose mode\n"
"\t-s, --subbands Number of subbands to use (4 or 8)\n"
"\t-b, --bitpool Bitpool value (default is 32)\n"
"\t-j, --joint Joint stereo\n"
"\t-S, --SNR Use SNR mode (default is loudness)\n"
"\n");
}
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
{ "verbose", 0, 0, 'v' },
{ "subbands", 1, 0, 's' },
{ "bitpool", 1, 0, 'b' },
{ "joint", 0, 0, 'j' },
{ "SNR", 0, 0, 'S' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
int i, opt, subbands = 8, bitpool = 32, joint = 0, SNR=0;
while ((opt = getopt_long(argc, argv, "+hvs:b:jS", main_options, NULL)) != -1) {
switch(opt) {
case 'h':
usage();
exit(0);
case 'v':
verbose = 1;
break;
case 's':
subbands = atoi(optarg);
if (subbands != 8 && subbands != 4) {
fprintf(stderr, "Invalid subbands %d!\n",
subbands);
exit(1);
}
break;
case 'b':
bitpool = atoi(optarg);
break;
case 'j':
joint = 1;
break;
case 'S':
SNR = 1;
break;
default:
exit(1);
}
}
argc -= optind;
argv += optind;
optind = 0;
if (argc < 1) {
usage();
exit(1);
}
for (i = 0; i < argc; i++)
encode(argv[i], subbands, bitpool, joint, SNR);
return 0;
}
[-- Attachment #3: compare.tar.gz --]
[-- Type: application/octet-stream, Size: 6122532 bytes --]
[-- Attachment #4: Type: text/plain, Size: 363 bytes --]
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
[-- Attachment #5: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
next prev parent reply other threads:[~2008-10-29 15:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-27 9:54 [Bluez-devel] Bad encoding performance of Linux SBC audio codec Christian Hoene
2008-10-27 18:03 ` Marcel Holtmann
2008-10-27 19:13 ` Brad Midgley
2008-10-27 19:41 ` Marcel Holtmann
2008-10-29 15:30 ` Christian Hoene [this message]
2008-10-29 22:27 ` [Bluez-devel] REALLY " Luiz Augusto von Dentz
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='004e01c939db$5c241760$146c4620$@de' \
--to=hoene@uni-tuebingen.de \
--cc=bluez-devel@lists.sourceforge.net \
--cc=frans.de.bont@philips.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