Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a80d0f65 authored by William Escande's avatar William Escande Committed by Gerrit Code Review
Browse files

Merge "Add encoder for aptX and encoder for aptX HD source code."

parents 3ea4d290 62649d83
Loading
Loading
Loading
Loading
+52 −0
Original line number Original line Diff line number Diff line
/*------------------------------------------------------------------------------
 *
 *  This file exposes a public interface to allow clients to invoke aptX
 *  encoding on 4 new PCM samples, generating 2 new codeword (one for the
 *  left channel and one for the right channel).
 *
 *----------------------------------------------------------------------------*/

#ifndef APTXBTENC_H
#define APTXBTENC_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _DLLEXPORT
#define APTXBTENCEXPORT __declspec(dllexport)
#else
#define APTXBTENCEXPORT
#endif

/* SizeofAptxbtenc returns the size (in byte) of the memory
 * allocation required to store the state of the encoder */
APTXBTENCEXPORT int SizeofAptxbtenc(void);

/* aptxbtenc_version can be used to extract the version number
 * of the aptX encoder */
APTXBTENCEXPORT const char* aptxbtenc_version(void);

/* aptxbtenc_init is used to initialise the encoder structure.
 * _state should be a pointer to the encoder structure (stereo).
 * endian represent the endianness of the output data
 * (0=little endian. Big endian otherwise)
 * The function returns 1 if an error occurred during the initialisation.
 * The function returns 0 if no error occurred during the initialisation. */
APTXBTENCEXPORT int aptxbtenc_init(void* _state, short endian);

/* aptxbtenc_setsync_mode is used to initialise the sync mode in the encoder state structure.
 * _state should be a pointer to the encoder structure (stereo, though strictly-speaking it is dual channel).
 * 'sync_mode' is an enumerated type  {stereo=0, dualmono=1, no_sync=2}
 * The function returns 0 if no error occurred during the initialisation. */
APTXBTENCEXPORT int aptxbtenc_setsync_mode(void* _state, int32_t sync_mode);

/* StereoEncode will take 8 audio samples (16-bit per sample)
 * and generate one 32-bit codeword with autosync inserted. */
APTXBTENCEXPORT int aptxbtenc_encodestereo(void* _state, void* _pcmL, void* _pcmR, void* _buffer);

#ifdef __cplusplus
} //  /extern "C"
#endif

#endif //APTXBTENC_H
+80 −0
Original line number Original line Diff line number Diff line
/*------------------------------------------------------------------------------
 *
 *  All declarations relevant for aptxEncode. This function allows clients
 *  to invoke bt-aptX encoding on 4 new PCM samples,
 *  generating 4 new quantised codes. A separate function allows the
 *  packing of the 4 codes into a 16-bit word.
 *
 *----------------------------------------------------------------------------*/

#ifndef APTXENCODER_H
#define APTXENCODER_H
#ifdef _GCC
  #pragma GCC visibility push(hidden)
#endif

#include "AptxParameters.h"
#include "DitherGenerator.h"
#include "Quantiser.h"
#include "SubbandFunctionsCommon.h"
#include "Qmf.h"


 /* Function to carry out a single-channel aptX encode on 4 new PCM samples */
XBT_INLINE_ void aptxEncode(int32_t pcm[4], Qmf_storage* Qmf_St, Encoder_data* EncoderDataPt)
{
   int32_t predVals[4];
   int32_t qCodes[4];
   int32_t aqmfOutputs[4];

   /* Extract the previous predicted values and quantised codes into arrays */
   for (int i = 0; i < 4; i++)
   {
      predVals[i] = EncoderDataPt->m_SubbandData[i].m_predData.m_predVal;
      qCodes[i] = EncoderDataPt->m_qdata[i].qCode;
   }

   /* Update codeword history, then generate new dither values. */
   EncoderDataPt->m_codewordHistory = xbtEncupdateCodewordHistory(qCodes, EncoderDataPt->m_codewordHistory);
   EncoderDataPt->m_dithSyncRandBit = xbtEncgenerateDither(EncoderDataPt->m_codewordHistory, EncoderDataPt->m_ditherOutputs);

   /* Run the analysis QMF */
   QmfAnalysisFilter(pcm, Qmf_St, predVals, aqmfOutputs);

   /* Run the quantiser for each subband */
   quantiseDifferenceLL(aqmfOutputs[0], EncoderDataPt->m_ditherOutputs[0], EncoderDataPt->m_SubbandData[0].m_iqdata.delta, &EncoderDataPt->m_qdata[0]);
   quantiseDifferenceLH(aqmfOutputs[1], EncoderDataPt->m_ditherOutputs[1], EncoderDataPt->m_SubbandData[1].m_iqdata.delta, &EncoderDataPt->m_qdata[1]);
   quantiseDifferenceHL(aqmfOutputs[2], EncoderDataPt->m_ditherOutputs[2], EncoderDataPt->m_SubbandData[2].m_iqdata.delta, &EncoderDataPt->m_qdata[2]);
   quantiseDifferenceHH(aqmfOutputs[3], EncoderDataPt->m_ditherOutputs[3], EncoderDataPt->m_SubbandData[3].m_iqdata.delta, &EncoderDataPt->m_qdata[3]);
}

XBT_INLINE_ void aptxPostEncode(Encoder_data* EncoderDataPt)
{
   /* Run the remaining subband processing for each subband */
   /* Manual inlining on the 4 subband */
   processSubbandLL(EncoderDataPt->m_qdata[0].qCode,
      EncoderDataPt->m_ditherOutputs[0],
      &EncoderDataPt->m_SubbandData[0],
      &EncoderDataPt->m_SubbandData[0].m_iqdata);

   processSubband(EncoderDataPt->m_qdata[1].qCode,
      EncoderDataPt->m_ditherOutputs[1],
      &EncoderDataPt->m_SubbandData[1],
      &EncoderDataPt->m_SubbandData[1].m_iqdata);

   processSubbandHL(EncoderDataPt->m_qdata[2].qCode,
      EncoderDataPt->m_ditherOutputs[2],
      &EncoderDataPt->m_SubbandData[2],
      &EncoderDataPt->m_SubbandData[2].m_iqdata);

   processSubband(EncoderDataPt->m_qdata[3].qCode,
      EncoderDataPt->m_ditherOutputs[3],
      &EncoderDataPt->m_SubbandData[3],
      &EncoderDataPt->m_SubbandData[3].m_iqdata);
}


#ifdef _GCC
  #pragma GCC visibility pop
#endif
#endif //APTXENCODER_H
+247 −0
Original line number Original line Diff line number Diff line
/*------------------------------------------------------------------------------
 *
 *  General shared aptX parameters.
 *
 *----------------------------------------------------------------------------*/

#ifndef APTXPARAMETERS_H
#define APTXPARAMETERS_H
#ifdef _GCC
  #pragma GCC visibility push(hidden)
#endif


#include <stdint.h>
#include "CBStruct.h"

#if defined _MSC_VER
   #define XBT_INLINE_ inline
   #define _STDQMFOUTERCOEFF 1
#elif defined  __clang__
   #define XBT_INLINE_ static inline
   #define _STDQMFOUTERCOEFF 1
#elif defined __GNUC__
   #define XBT_INLINE_ inline
   #define _STDQMFOUTERCOEFF 1
#else
   #define XBT_INLINE_ static
   #define _STDQMFOUTERCOEFF 1
#endif


/* Signed saturate to a 24bit value */
XBT_INLINE_ int32_t ssat24(int32_t val)
{
   if (val > 8388607)  val = 8388607;
   if (val < -8388608) val = -8388608;
   return val;
}

typedef union u_reg64
{
   uint64_t u64;
   int64_t s64;
   struct s_u32
   {
#ifdef __BIGENDIAN
      uint32_t h;
      uint32_t l;
#else
      uint32_t l;
      uint32_t h;
#endif
   } u32;

   struct s_s32
   {
#ifdef __BIGENDIAN
      int32_t h;
      int32_t l;
#else
      int32_t l;
      int32_t h;
#endif
   } s32;
} reg64_t;

typedef union u_reg32
{
   uint32_t u32;
   int32_t s32;

   struct s_u16
   {
#ifdef __BIGENDIAN
      uint16_t h;
      uint16_t l;
#else
      uint16_t l;
      uint16_t h;
#endif
   } u16;
   struct s_s16
   {
#ifdef __BIGENDIAN
      int16_t h;
      int16_t l;
#else
      int16_t l;
      int16_t h;
#endif
   } s16;
} reg32_t;

/* Each aptX enc/dec round consumes/produces 4 PCM samples */
static const uint32_t numPcmSamples = 4;

/* Symbolic constants for PCM data indicies. */
enum {FirstPcm=0, SecondPcm=1, ThirdPcm=2, FourthPcm=3};

/* Symbolic constants for sync modes. */
enum {stereo=0, dualmono=1, no_sync=2};

/* Number of subbands is fixed at 4 */
#define NUMSUBBANDS 4

/* Symbolic constants for subband identification. */
typedef enum {LL=0, LH=1, HL=2, HH=3}  bands;

/* Structure declaration to bind a set of subband parameters */
typedef struct
{
  const int32_t* threshTable;
  const int32_t* threshTable_sl1;
  const int32_t* dithTable;
  const int32_t* dithTable_sh1;
  const int32_t* minusLambdaDTable;
  const int32_t* incrTable;
  int32_t numBits;
  int32_t maxLogDelta;
  int32_t minLogDelta;
  int32_t numZeros;
} SubbandParameters;

/* Struct required for the polecoeffcalculator function of bt-aptX encoder and decoder*/
/* Size of structure: 16 Bytes */
typedef struct
{
   /* 2-tap delay line for previous sgn values */
   reg32_t m_poleAdaptDelayLine;
   /* 2 pole filter coeffs */
   int32_t m_poleCoeff[2];
} PoleCoeff_data;

/* Struct required for the zerocoeffcalculator function of bt-aptX encoder and decoder*/
/* Size of structure: 100 Bytes */
typedef struct
{
   /* The zero filter length for this subband */
   int32_t m_numZeros;
   /* Maximum number of zeros for any subband is 24. */
   /* 24 zero filter coeffs */
   int32_t m_zeroCoeff[24];
} ZeroCoeff_data;

/* Struct required for the prediction filtering function of bt-aptX encoder and decoder*/
/* Size of structure: 200+20=220 Bytes */
typedef struct
{
   /* Number of zeros associated with this subband */
   int32_t m_numZeros;
   /* Zero data delay line (circular) */
   circularBuffer m_zeroDelayLine;
   /* 2-tap pole data delay line */
   int32_t m_poleDelayLine[2];
   /* Output from zero filter */
   int32_t m_zeroVal;
   /* Output from overall ARMA filter */
   int32_t m_predVal;
} Predictor_data;

/* Struct required for the Quantisation function of bt-aptX encoder and decoder*/
/* Size of structure: 24 Bytes */
typedef struct
{
   /* Number of bits in the quantised code for this subband */
   int32_t codeBits;
   /* Pointer to threshold table */
   const int32_t* thresholdTablePtr;
   const int32_t* thresholdTablePtr_sl1;
   /* Pointer to dither table */
   const int32_t* ditherTablePtr;
   /* Pointer to minus Lambda table */
   const int32_t* minusLambdaDTable;
   /* Output quantised code */
   int32_t qCode;
   /* Alternative quantised code for sync purposes */
   int32_t altQcode;
   /* Penalty associated with choosing alternative code */
   int32_t distPenalty;
} Quantiser_data;

/* Struct required for the inverse Quantisation function of bt-aptX encoder and decoder*/
/* Size of structure: 32 Bytes */
typedef struct
{
   /* Pointer to threshold table */
   const int32_t* thresholdTablePtr;
   const int32_t* thresholdTablePtr_sl1;
   /* Pointer to dither table */
   const int32_t* ditherTablePtr_sf1;
   /* Pointer to increment table */
   const int32_t* incrTablePtr;
   /* Upper and lower bounds for logDelta */
   int32_t maxLogDelta;
   int32_t minLogDelta;
   /* Delta (quantisation step size */
   int32_t delta;
   /* Delta, expressed as a log base 2 */
   uint16_t logDelta;
   /* Output dequantised signal */
   int32_t invQ;
   /* pointer to IQuant_tableLogT */
   const int32_t* iquantTableLogPtr;
} IQuantiser_data;

/* Subband data structure bt-aptX encoder*/
/* Size of structure: 116+220+32= 368 Bytes */
typedef struct
{
   /* Subband processing consists of inverse quantisation, predictor
    * coefficient update, and predictor filtering. */
   ZeroCoeff_data m_ZeroCoeffData;
   PoleCoeff_data m_PoleCoeffData;
   /* structure holding the data associated with the predictor */
   Predictor_data m_predData;
   /* iqdata holds the data associated with the instance of inverse quantiser */
   IQuantiser_data m_iqdata;
} Subband_data;

/* Encoder data structure bt-aptX encoder*/
/* Size of structure: 368*4+24+4*24 = 1592 Bytes */
typedef struct
{
   /* Subband processing consists of inverse quantisation, predictor
    * coefficient update, and predictor filtering. */
   Subband_data m_SubbandData[4];
   int32_t m_codewordHistory;
   int32_t m_dithSyncRandBit;
   int32_t m_ditherOutputs[4];
   /* structure holding data values for this quantiser */
   Quantiser_data m_qdata[4];
} Encoder_data;

/* Number of predictor pole filter coefficients is fixed at 2 for all subbands */
static const uint32_t numPoleFilterCoeffs = 2;

/* Subband-specific number of predictor zero filter coefficients. */
static const uint32_t numZeroFilterCoeffs[4] = {24, 12, 6, 12};

/* Delta is scaled by 4 positions within the quantiser and inverse quantiser. */
static const uint32_t deltaScale = 4;


#ifdef _GCC
  #pragma GCC visibility pop
#endif
#endif //APTXPARAMETERS_H
+424 −0
Original line number Original line Diff line number Diff line
/*------------------------------------------------------------------------------
 *
 *  All table definitions used for the quantizer.
 *
 *----------------------------------------------------------------------------*/

#ifndef APTXTABLES_H
#define APTXTABLES_H


#include "AptxParameters.h"


/* Quantisation threshold, logDelta increment and dither tables for 2-bit codes */
static const int32_t dq2bit16_sl1[3] =
{
   -194080,
   194080,
   890562,
};

static const int32_t q2incr16[3] =
{
   0,
   -33,
   136,
};

static const int32_t dq2dith16_sf1[3] =
{
   194080,
   194080,
   502402,
};

static const int32_t dq2mLamb16[2] =
{
   0,
   -77081,
};

/* Quantisation threshold, logDelta increment and dither tables for 3-bit codes */
static const int32_t dq3bit16_sl1[5] =
{
   -163006,
   163006,
   542708,
   1120554,
   2669238,
};

static const int32_t q3incr16[5] =
{
   0,
   -8,
   33,
   95,
   262,
};

static const int32_t dq3dith16_sf1[5] =
{
   163006,
   163006,
   216698,
   361148,
   1187538,
};

static const int32_t dq3mLamb16[4] =
{
   0,
   -13423,
   -36113,
   -206598,
};

/* Quantisation threshold, logDelta increment and dither tables for 4-bit codes */
static const int32_t dq4bit16_sl1[9] =
{
   -89806,
   89806,
   278502,
   494338,
   759442,
   1113112,
   1652322,
   2720256,
   5190186,
};

static const int32_t q4incr16[9] =
{
   0,
   -14,
   6,
   29,
   58,
   96,
   154,
   270,
   521,
};

static const int32_t dq4dith16_sf1[9] =
{
   89806,
   89806,
   98890,
   116946,
   148158,
   205512,
   333698,
   734236,
   1735696,
};

static const int32_t dq4mLamb16[8] =
{
   0,
   -2271,
   -4514,
   -7803,
   -14339,
   -32047,
   -100135,
   -250365,
};

/* Quantisation threshold, logDelta increment and dither tables for 7-bit codes */
static const int32_t dq7bit16_sl1[65] =
{
   -9948,
   9948,
   29860,
   49808,
   69822,
   89926,
   110144,
   130502,
   151026,
   171738,
   192666,
   213832,
   235264,
   256982,
   279014,
   301384,
   324118,
   347244,
   370790,
   394782,
   419250,
   444226,
   469742,
   495832,
   522536,
   549890,
   577936,
   606720,
   636290,
   666700,
   698006,
   730270,
   763562,
   797958,
   833538,
   870398,
   908640,
   948376,
   989740,
   1032874,
   1077948,
   1125150,
   1174700,
   1226850,
   1281900,
   1340196,
   1402156,
   1468282,
   1539182,
   1615610,
   1698514,
   1789098,
   1888944,
   2000168,
   2125700,
   2269750,
   2438670,
   2642660,
   2899462,
   3243240,
   3746078,
   4535138,
   5664098,
   7102424,
   8897462,
};

static const int32_t q7incr16[65] =
{
   0,
   -21,
   -19,
   -17,
   -15,
   -12,
   -10,
   -8,
   -6,
   -4,
   -1,
   1,
   3,
   6,
   8,
   10,
   13,
   15,
   18,
   20,
   23,
   26,
   29,
   31,
   34,
   37,
   40,
   43,
   47,
   50,
   53,
   57,
   60,
   64,
   68,
   72,
   76,
   80,
   85,
   89,
   94,
   99,
   105,
   110,
   116,
   123,
   129,
   136,
   144,
   152,
   161,
   171,
   182,
   194,
   207,
   223,
   241,
   263,
   291,
   328,
   382,
   467,
   522,
   522,
   522,
};

static const int32_t dq7dith16_sf1[65] =
{
   9948,
   9948,
   9962,
   9988,
   10026,
   10078,
   10142,
   10218,
   10306,
   10408,
   10520,
   10646,
   10784,
   10934,
   11098,
   11274,
   11462,
   11664,
   11880,
   12112,
   12358,
   12618,
   12898,
   13194,
   13510,
   13844,
   14202,
   14582,
   14988,
   15422,
   15884,
   16380,
   16912,
   17484,
   18098,
   18762,
   19480,
   20258,
   21106,
   22030,
   23044,
   24158,
   25390,
   26760,
   28290,
   30008,
   31954,
   34172,
   36728,
   39700,
   43202,
   47382,
   52462,
   58762,
   66770,
   77280,
   91642,
   112348,
   144452,
   199326,
   303512,
   485546,
   643414,
   794914,
   1000124,
};

static const int32_t dq7mLamb16[65] =
{
   0,
   -4,
   -7,
   -10,
   -13,
   -16,
   -19,
   -22,
   -26,
   -28,
   -32,
   -35,
   -38,
   -41,
   -44,
   -47,
   -51,
   -54,
   -58,
   -62,
   -65,
   -70,
   -74,
   -79,
   -84,
   -90,
   -95,
   -102,
   -109,
   -116,
   -124,
   -133,
   -143,
   -154,
   -166,
   -180,
   -195,
   -212,
   -231,
   -254,
   -279,
   -308,
   -343,
   -383,
   -430,
   -487,
   -555,
   -639,
   -743,
   -876,
   -1045,
   -1270,
   -1575,
   -2002,
   -2628,
   -3591,
   -5177,
   -8026,
   -13719,
   -26047,
   -45509,
   -39467,
   -37875,
   -51303,
   0,
};

/* Array of structures containing subband parameters. */
static const SubbandParameters subbandParameters[NUMSUBBANDS] =
{
  /* LL band */
  { 0, dq7bit16_sl1, 0, dq7dith16_sf1, dq7mLamb16, q7incr16, 7, (18*256)-1, -20, 24 },

  /* LH band */
  { 0, dq4bit16_sl1, 0, dq4dith16_sf1, dq4mLamb16, q4incr16, 4, (21*256)-1, -23, 12 },

  /* HL band */
  { 0, dq2bit16_sl1, 0, dq2dith16_sf1, dq2mLamb16, q2incr16, 2, (23*256)-1, -25, 6 },

  /* HH band */
  { 0, dq3bit16_sl1, 0, dq3dith16_sf1, dq3mLamb16, q3incr16, 3, (22*256)-1, -24, 12 }
};


#endif //APTXTABLES_H
+28 −0
Original line number Original line Diff line number Diff line
/*------------------------------------------------------------------------------
 *
 *  Structure required to implement a circular buffer.
 *
 *----------------------------------------------------------------------------*/

#ifndef CBSTRUCT_H
#define CBSTRUCT_H
#ifdef _GCC
  #pragma GCC visibility push(hidden)
#endif


typedef struct circularBuffer_t
{
   /* Buffer storage */
   int32_t buffer[48];
   /* Pointer to current buffer location */
   uint32_t pointer;
   /* Modulo length of circular buffer */
   uint32_t modulo;
}circularBuffer;


#ifdef _GCC
  #pragma GCC visibility pop
#endif
#endif //CBSTRUCT_H
 No newline at end of file
Loading