Imported Upstream version 1.2 sandbox/kevinthierry/upstream upstream upstream/1.2
authorKévin THIERRY <kevin.thierry@open.eurogiciel.org>
Wed, 12 Nov 2014 15:14:49 +0000 (16:14 +0100)
committerKévin THIERRY <kevin.thierry@open.eurogiciel.org>
Wed, 12 Nov 2014 15:14:49 +0000 (16:14 +0100)
ChangeLog
Makefile.am
Makefile.in
TODO
config.h.in
configure
configure.ac
sbc/sbc.c
sbc/sbc.h
sbc/sbc.sym
sbc/sbc_tables.h

index b1b71f39f150d2f7b9423457254e903e2efae4be..5c0a27418afe0aca1f38f09d8f0115e3bdb7615b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+ver 1.2:
+       Add support for setup from A2DP configuration data.
+       Add support for enabling high precision build.
+
 ver 1.1:
        Add support for mSBC encoding and decoding functionality.
 
index 5954c321765747162a945d5b1db12431377ef645..8eb687c3bffbc54a3bcd1294b179b564d99abc74 100644 (file)
@@ -6,9 +6,9 @@ AM_MAKEFLAGS = --no-print-directory
 # Interfaces added:            CURRENT++ REVISION=0 AGE++
 # Interfaces removed:          CURRENT++ REVISION=0 AGE=0
 
-SBC_CURRENT = 2
+SBC_CURRENT = 3
 SBC_REVISION = 0
-SBC_AGE = 1
+SBC_AGE = 2
 
 sbc_headers = sbc/sbc.h
 
index 385a38dfb80c635f4fd8f4ea340f37f5986c32f1..6914933bec2d3b7a658d04ff6d13ca61f7bec742 100644 (file)
@@ -328,9 +328,9 @@ AM_MAKEFLAGS = --no-print-directory
 # Interfaces changed:          CURRENT++ REVISION=0
 # Interfaces added:            CURRENT++ REVISION=0 AGE++
 # Interfaces removed:          CURRENT++ REVISION=0 AGE=0
-SBC_CURRENT = 2
+SBC_CURRENT = 3
 SBC_REVISION = 0
-SBC_AGE = 1
+SBC_AGE = 2
 sbc_headers = sbc/sbc.h
 sbc_sources = sbc/sbc.c sbc/sbc_private.h sbc/sbc_math.h sbc/sbc_tables.h \
                sbc/sbc_primitives.h sbc/sbc_primitives.c \
diff --git a/TODO b/TODO
index 09832a9aead2d45568e8b2b2f34e80593ef5bf11..a0b53ce2b9a21fc14894b9724402398374ce8f2a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -14,36 +14,41 @@ Background
   Higher complexity tasks should be refined into several lower complexity tasks
   once the task is better understood.
 
-NEON instruction set
-====================
+Encoder optimizations
+=====================
 
-- The neon optimization code is split in two parts. Sample reordering and blocks
-encoding. There is a neon optimization for encoding SBC. But mSBC is not
-supported by this optimizer because the reordering has been specifically for
-mSBC.
+- Currently, only the decoder is optimized to take advantage of advanced
+  processor instruction sets. In use cases like HFP 1.6, optimizing the
+  encoder will bring a significant latency, power and performance advantage.
+  For example, the MMX encoder is 3 to 6 time faster than the SIMD encoder.
+
+  Priority: High
+  Complexity: C8
+
+- Use a log2 table for byte integer scale factors calculation (sum log2
+  results for high and low bytes) fill bitpool by 16 bits instead of one
+  at a time in bits allocation/bitpool generation port to the dsp
+
+  Priority: Medium
+  Complexity: C2
+
+- The neon optimization code is split in two parts. Sample reordering and
+  blocks encoding. There is a neon optimization for encoding SBC. But mSBC
+  is not supported by this optimizer because the reordering has been
+  specifically for mSBC.
 
   Priority: Low
   Complexity: C2
 
-SSE instruction set
-===================
+Decoder optimizations
+=====================
 
-- The decoder is optimized to take advantage of advanced processor instruction
-sets. Currently implemented are MMX, arm neon, arm v6 and iwmmxt. SSE3 is
-is available since almost 10 years now, on a large range of Intel processors.
-It should be interesting to implement it and to compare with MMX implementation
-on Intel processors.
+- The decoder is optimized to take advantage of advanced processor
+  instruction sets. Currently implemented are MMX, arm neon, arm v6
+  and iwmmxt. SSE3 is available since almost 10 years now, on a large
+  range of Intel processors. It should be interesting to implement it
+  and to compare with MMX implementation on Intel processors.
 
   Priority: Medium
   Complexity: C4
 
-Decoder improvements
-====================
-
-- Currently, only the decoder is optimized to take advantage of advanced
-processor instruction sets. In use cases like HFP 1.6, optimizing the encoder
-will bring a significant latency, power and performance advantage. For exemple,
-the MMX encoder is 3 to 6 time faster than the SIMD encoder.
-
-  Priority: High
-  Complexity: C8
index 423fcf8f0a0e50430440c21540c5cf30b85744e8..80600c048d419351253595574b5f9c7279dfc3bc 100644 (file)
@@ -55,6 +55,9 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
+/* Define to 1 to enable high precision build of SBC encoder */
+#undef SBC_HIGH_PRECISION
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
index c27cca12249631c3749e0ea2abf4bfc647ac2883..8d3c600b69cbcad0441102345402936c48e2f86a 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sbc 1.1.
+# Generated by GNU Autoconf 2.69 for sbc 1.2.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sbc'
 PACKAGE_TARNAME='sbc'
-PACKAGE_VERSION='1.1'
-PACKAGE_STRING='sbc 1.1'
+PACKAGE_VERSION='1.2'
+PACKAGE_STRING='sbc 1.2'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -773,6 +773,7 @@ enable_libtool_lock
 enable_optimization
 enable_debug
 enable_pie
+enable_high_precision
 enable_tools
 enable_tester
 '
@@ -1330,7 +1331,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures sbc 1.1 to adapt to many kinds of systems.
+\`configure' configures sbc 1.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1400,7 +1401,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sbc 1.1:";;
+     short | recursive ) echo "Configuration of sbc 1.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1422,6 +1423,7 @@ Optional Features:
   --disable-optimization  disable code optimization through compiler
   --enable-debug          enable compiling with debugging information
   --enable-pie            enable position independent executables flag
+  --enable-high-precision enable SBC high precision support
   --disable-tools         disable SBC tools
   --disable-tester        disable SBC tester
 
@@ -1519,7 +1521,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sbc configure 1.1
+sbc configure 1.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1797,7 +1799,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by sbc $as_me 1.1, which was
+It was created by sbc $as_me 1.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2613,7 +2615,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='sbc'
- VERSION='1.1'
+ VERSION='1.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -11358,6 +11360,17 @@ if test "${enable_pie+set}" = set; then :
 fi
 
 
+# Check whether --enable-high-precision was given.
+if test "${enable_high_precision+set}" = set; then :
+  enableval=$enable_high_precision; enable_high_precision=${enableval}
+fi
+
+if (test "${enable_high_precision}" = "yes"); then
+
+$as_echo "#define SBC_HIGH_PRECISION 1" >>confdefs.h
+
+fi
+
 # Check whether --enable-tools was given.
 if test "${enable_tools+set}" = set; then :
   enableval=$enable_tools; enable_tools=${enableval}
@@ -12117,7 +12130,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sbc $as_me 1.1, which was
+This file was extended by sbc $as_me 1.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12183,7 +12196,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sbc config.status 1.1
+sbc config.status 1.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index c052616b91d2735e138cf4575bede160a0ca04f8..77c15e8cef71a936566bd79727123515f3cea8e7 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.60)
-AC_INIT(sbc, 1.1)
+AC_INIT(sbc, 1.2)
 
 AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
 AC_CONFIG_HEADERS(config.h)
@@ -44,6 +44,14 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
        fi
 ])
 
+AC_ARG_ENABLE(high-precision, AC_HELP_STRING([--enable-high-precision],
+                                       [enable SBC high precision support]),
+                                       [enable_high_precision=${enableval}])
+if (test "${enable_high_precision}" = "yes"); then
+       AC_DEFINE(SBC_HIGH_PRECISION, 1,
+               [Define to 1 to enable high precision build of SBC encoder])
+fi
+
 AC_ARG_ENABLE(tools, AC_HELP_STRING([--disable-tools],
                [disable SBC tools]), [enable_tools=${enableval}])
 AM_CONDITIONAL(TOOLS, test "${enable_tools}" != "no")
index c589217876bfaebd4e63ef3ac7b4922fcf597b37..534027edafcf63d4a4ceb6b077622226c4560065 100644 (file)
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
  *
  */
 
-/* todo items:
-
-  use a log2 table for byte integer scale factors calculation (sum log2 results
-  for high and low bytes) fill bitpool by 16 bits instead of one at a time in
-  bits allocation/bitpool generation port to the dsp
-
-*/
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 #define MSBC_SYNCWORD  0xAD
 #define MSBC_BLOCKS    15
 
+#define A2DP_SAMPLING_FREQ_16000               (1 << 3)
+#define A2DP_SAMPLING_FREQ_32000               (1 << 2)
+#define A2DP_SAMPLING_FREQ_44100               (1 << 1)
+#define A2DP_SAMPLING_FREQ_48000               (1 << 0)
+
+#define A2DP_CHANNEL_MODE_MONO                 (1 << 3)
+#define A2DP_CHANNEL_MODE_DUAL_CHANNEL         (1 << 2)
+#define A2DP_CHANNEL_MODE_STEREO               (1 << 1)
+#define A2DP_CHANNEL_MODE_JOINT_STEREO         (1 << 0)
+
+#define A2DP_BLOCK_LENGTH_4                    (1 << 3)
+#define A2DP_BLOCK_LENGTH_8                    (1 << 2)
+#define A2DP_BLOCK_LENGTH_12                   (1 << 1)
+#define A2DP_BLOCK_LENGTH_16                   (1 << 0)
+
+#define A2DP_SUBBANDS_4                                (1 << 1)
+#define A2DP_SUBBANDS_8                                (1 << 0)
+
+#define A2DP_ALLOCATION_SNR                    (1 << 1)
+#define A2DP_ALLOCATION_LOUDNESS               (1 << 0)
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct a2dp_sbc {
+       uint8_t channel_mode:4;
+       uint8_t frequency:4;
+       uint8_t allocation_method:2;
+       uint8_t subbands:2;
+       uint8_t block_length:4;
+       uint8_t min_bitpool;
+       uint8_t max_bitpool;
+} __attribute__ ((packed));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct a2dp_sbc {
+       uint8_t frequency:4;
+       uint8_t channel_mode:4;
+       uint8_t block_length:4;
+       uint8_t subbands:2;
+       uint8_t allocation_method:2;
+       uint8_t min_bitpool;
+       uint8_t max_bitpool;
+} __attribute__ ((packed));
+
+#else
+#error "Unknown byte order"
+#endif
+
 /* This structure contains an unpacked SBC frame.
    Yes, there is probably quite some unused space herein */
 struct sbc_frame {
@@ -954,7 +995,7 @@ static void sbc_encoder_init(bool msbc, struct sbc_encoder_state *state,
 }
 
 struct sbc_priv {
-       int init;
+       bool init;
        bool msbc;
        struct SBC_ALIGNED sbc_frame frame;
        struct SBC_ALIGNED sbc_decoder_state dec_state;
@@ -1046,6 +1087,122 @@ SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags)
        return 0;
 }
 
+static int sbc_set_a2dp(sbc_t *sbc, unsigned long flags,
+                                       const void *conf, size_t conf_len)
+{
+       const struct a2dp_sbc *a2dp;
+
+       if (conf_len != sizeof(*a2dp))
+               return -EINVAL;
+
+       a2dp = conf;
+
+       switch (a2dp->frequency) {
+       case A2DP_SAMPLING_FREQ_16000:
+               sbc->frequency = SBC_FREQ_16000;
+               break;
+       case A2DP_SAMPLING_FREQ_32000:
+               sbc->frequency = SBC_FREQ_32000;
+               break;
+       case A2DP_SAMPLING_FREQ_44100:
+               sbc->frequency = SBC_FREQ_44100;
+               break;
+       case A2DP_SAMPLING_FREQ_48000:
+               sbc->frequency = SBC_FREQ_48000;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (a2dp->channel_mode) {
+       case A2DP_CHANNEL_MODE_MONO:
+               sbc->mode = SBC_MODE_MONO;
+               break;
+       case A2DP_CHANNEL_MODE_DUAL_CHANNEL:
+               sbc->mode = SBC_MODE_DUAL_CHANNEL;
+               break;
+       case A2DP_CHANNEL_MODE_STEREO:
+               sbc->mode = SBC_MODE_STEREO;
+               break;
+       case A2DP_CHANNEL_MODE_JOINT_STEREO:
+               sbc->mode = SBC_MODE_JOINT_STEREO;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (a2dp->allocation_method) {
+       case A2DP_ALLOCATION_SNR:
+               sbc->allocation = SBC_AM_SNR;
+               break;
+       case A2DP_ALLOCATION_LOUDNESS:
+               sbc->allocation = SBC_AM_LOUDNESS;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (a2dp->subbands) {
+       case A2DP_SUBBANDS_4:
+               sbc->subbands = SBC_SB_4;
+               break;
+       case A2DP_SUBBANDS_8:
+               sbc->subbands = SBC_SB_8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (a2dp->block_length) {
+       case A2DP_BLOCK_LENGTH_4:
+               sbc->blocks = SBC_BLK_4;
+               break;
+       case A2DP_BLOCK_LENGTH_8:
+               sbc->blocks = SBC_BLK_8;
+               break;
+       case A2DP_BLOCK_LENGTH_12:
+               sbc->blocks = SBC_BLK_12;
+               break;
+       case A2DP_BLOCK_LENGTH_16:
+               sbc->blocks = SBC_BLK_16;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
+                                       const void *conf, size_t conf_len)
+{
+       int err;
+
+       err = sbc_init(sbc, flags);
+       if (err < 0)
+               return err;
+
+       err = sbc_set_a2dp(sbc, flags, conf, conf_len);
+       if (err < 0) {
+               sbc_finish(sbc);
+               return err;
+       }
+
+       return 0;
+}
+
+int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
+                                       const void *conf, size_t conf_len)
+{
+       int err;
+
+       err = sbc_reinit(sbc, flags);
+       if (err < 0)
+               return err;
+
+       return sbc_set_a2dp(sbc, flags, conf, conf_len);
+}
+
 SBC_EXPORT ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len)
 {
        return sbc_decode(sbc, input, input_len, NULL, 0, NULL);
@@ -1067,7 +1224,7 @@ SBC_EXPORT ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
 
        if (!priv->init) {
                sbc_decoder_init(&priv->dec_state, &priv->frame);
-               priv->init = 1;
+               priv->init = true;
 
                sbc->frequency = priv->frame.frequency;
                sbc->mode = priv->frame.mode;
@@ -1155,7 +1312,7 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
                priv->frame.length = sbc_get_frame_length(sbc);
 
                sbc_encoder_init(priv->msbc, &priv->enc_state, &priv->frame);
-               priv->init = 1;
+               priv->init = true;
        } else if (priv->frame.bitpool != sbc->bitpool) {
                priv->frame.length = sbc_get_frame_length(sbc);
                priv->frame.bitpool = sbc->bitpool;
@@ -1339,7 +1496,7 @@ SBC_EXPORT int sbc_reinit(sbc_t *sbc, unsigned long flags)
 
        priv = sbc->priv;
 
-       if (priv->init == 1)
+       if (priv->init)
                memset(sbc->priv, 0, sizeof(struct sbc_priv));
 
        sbc_set_defaults(sbc, flags);
index 5f8a1fc139ce592bf3faa16a0a71de3d9dffb655..d6f123e4d47ec80b255a51e7e05710005e1de6ed 100644 (file)
--- a/sbc/sbc.h
+++ b/sbc/sbc.h
@@ -3,6 +3,7 @@
  *  Bluetooth low-complexity, subband codec (SBC) library
  *
  *  Copyright (C) 2008-2010  Nokia Corporation
+ *  Copyright (C) 2012-2014  Intel Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
  *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
@@ -84,6 +85,10 @@ typedef struct sbc_struct sbc_t;
 int sbc_init(sbc_t *sbc, unsigned long flags);
 int sbc_reinit(sbc_t *sbc, unsigned long flags);
 int sbc_init_msbc(sbc_t *sbc, unsigned long flags);
+int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
+                                       const void *conf, size_t conf_len);
+int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
+                                       const void *conf, size_t conf_len);
 
 ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
 
index 3a47c12f369f9bf3959640b42e1418c1eb8f2f69..0642a0b6c0e166fff1690df6573ff9b0f1d29189 100644 (file)
@@ -1,7 +1,6 @@
 SBC_1.0 {
 global:
        sbc_init;
-       sbc_init_msbc;
        sbc_reinit;
        sbc_finish;
 
@@ -16,3 +15,12 @@ global:
 local:
        *;
 };
+SBC_1.1 {
+global:
+       sbc_init_msbc;
+} SBC_1.0;
+SBC_1.2 {
+global:
+       sbc_init_a2dp;
+       sbc_reinit_a2dp;
+} SBC_1.1;
index 25e24e6a43ddfbe2a6bf9e1a4c63b503c440e006..24a8bffd0050798d21a10e7a95026afca96e336f 100644 (file)
@@ -136,10 +136,6 @@ static const int32_t synmatrix8[16][8] = {
          SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
 };
 
-/* Uncomment the following line to enable high precision build of SBC encoder */
-
-/* #define SBC_HIGH_PRECISION */
-
 #ifdef SBC_HIGH_PRECISION
 #define FIXED_A int64_t /* data type for fixed point accumulator */
 #define FIXED_T int32_t /* data type for fixed point constants */