Skip to content
......@@ -34,10 +34,10 @@
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <math.h>
#include "ivas_lcld_prot.h"
#include "ivas_lcld_rom_tables.h"
#include "isar_lcld_prot.h"
#include "isar_rom_lcld_tables.h"
#include "prot.h"
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "wmc_auto.h"
......@@ -66,6 +66,14 @@ static void deactivate_bit(
( *state ) &= ( ~( 1 << bit_id ) );
}
void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder )
{
if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets )
{
psPredictionEncoder->iSubSetId = 0;
}
}
/*-------------------------------------------------------------------*
* Function CreatePredictionEncoder()
*
......@@ -92,16 +100,6 @@ ivas_error CreatePredictionEncoder(
psPredictionEncoder->iSubSetId = 0;
psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands;
psPredictionEncoder->iNumSubSets = iNumSubSets;
if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * LCLD_PRED_WIN_LEN ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
}
for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ )
{
psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) LCLD_PRED_WIN_LEN );
}
if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL )
{
......@@ -115,7 +113,7 @@ ivas_error CreatePredictionEncoder(
for ( n = 0; n < psPredictionEncoder->iChannels; n++ )
{
psPredictionEncoder->piPredChanEnable[n] = 0;
psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly
psPredictionEncoder->piNumPredBands[n] = 40;
}
if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL )
......@@ -271,9 +269,6 @@ void DeletePredictionEncoder(
PredictionEncoder *psPredictionEncoder )
{
int32_t n;
free( psPredictionEncoder->pfWindow );
for ( n = 0; n < psPredictionEncoder->iChannels; n++ )
{
int32_t k;
......@@ -367,8 +362,7 @@ void ComputePredictors(
for ( c = 0; c < psPredictionEncoder->iChannels; c++ )
{
int32_t b;
psPredictionEncoder->piNumPredBands[c] = min( 50, psPredictionEncoder->iMaxNumPredBands );
for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += bstep )
for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
{
int32_t n;
float fGain = 0.0;
......@@ -418,7 +412,7 @@ void ComputePredictors(
/* compute these before quant */
/* Compute est coding gain based on quantized filter coefficients */
fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag );
fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1)
fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS );
fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag );
fA1Mag = fMagScale * asinf( fA1Mag );
iA1Mag = (int32_t) ( fA1Mag + 0.5f );
......@@ -430,14 +424,14 @@ void ComputePredictors(
fA1Phase = fPhaseScale * fA1Phase;
iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f );
iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN;
iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap?
iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX;
fA1Phase = fInvPhaseScale * (float) iA1Phase;
fA1Real = fA1Mag * cosf( fA1Phase );
fA1Imag = fA1Mag * sinf( fA1Phase );
fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag );
fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1)
fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS );
fGain = ( fGain < fGain2 ) ? fGain : fGain2;
fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2;
}
......@@ -447,11 +441,11 @@ void ComputePredictors(
fA1Imag = 0.0f;
iA1Mag = 0;
iA1Phase = 0;
fGain = -10.0f; // Fix this
fGain = -10.0f;
}
pfEstPredBitGain[b] = fBitGain;
psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable
psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f );
psPredictionEncoder->ppfA1Real[c][b] = fA1Real;
psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag;
psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag;
......@@ -467,8 +461,8 @@ void ComputePredictors(
fBestCost = 0.0;
iPredBands = 0;
fBitGain = -7.0;
for ( b = b0; b < 50; b += bstep )
{ // still getting this decision wrong!
for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
{
fBitGain -= 1.0;
if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 )
{
......@@ -491,15 +485,6 @@ void ComputePredictors(
activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep;
}
else if ( iPredBands > 0 )
{
for ( b = iPredBands; b < LCLD_BANDS; b += bstep )
{
psPredictionEncoder->ppiPredBandEnable[c][b] = 0;
}
activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
psPredictionEncoder->piNumPredBands[c] = iPredBands;
}
else
{
for ( b = b0; b < LCLD_BANDS; b += bstep )
......@@ -520,61 +505,6 @@ void ComputePredictors(
*
*-------------------------------------------------------------------*/
void ApplyForwardPredictors(
PredictionEncoder *psPredictionEncoder,
float ***pppfReal,
float ***pppfImag )
{
int32_t c;
for ( c = 0; c < psPredictionEncoder->iChannels; c++ )
{
int32_t b;
if ( psPredictionEncoder->piPredChanEnable[c] > 0 )
{
for ( b = 0; b < LCLD_BANDS; b++ )
{
if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 )
{
int32_t n;
float fOldReal = 0.0f;
float fOldImag = 0.0f;
float fA1Real;
float fA1Imag;
int32_t iSubset = b % psPredictionEncoder->iNumSubSets;
if ( iSubset != psPredictionEncoder->iSubSetId )
{
fOldReal = psPredictionEncoder->ppfInpPrevReal[c][b];
fOldImag = psPredictionEncoder->ppfInpPrevImag[c][b];
}
psPredictionEncoder->ppfInpPrevReal[c][b] = pppfReal[c][psPredictionEncoder->iNumBlocks - 1][b];
psPredictionEncoder->ppfInpPrevImag[c][b] = pppfImag[c][psPredictionEncoder->iNumBlocks - 1][b];
fA1Real = psPredictionEncoder->ppfA1Real[c][b];
fA1Imag = psPredictionEncoder->ppfA1Imag[c][b];
for ( n = 0; n < psPredictionEncoder->iNumBlocks; n++ )
{
float fReal;
float fImag;
fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag;
fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal;
fOldReal = pppfReal[c][n][b];
fOldImag = pppfImag[c][n][b];
pppfReal[c][n][b] = fReal;
pppfImag[c][n][b] = fImag;
}
}
}
}
}
return;
}
/*-------------------------------------------------------------------*
* Function WritePredictors()
*
......@@ -583,7 +513,7 @@ void ApplyForwardPredictors(
int32_t WritePredictors(
PredictionEncoder *psPredictionEncoder,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsWritten = 0;
int32_t c;
......@@ -593,13 +523,13 @@ int32_t WritePredictors(
const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 );
/* number of subsets */
ivas_split_rend_bitstream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */
iBitsWritten += iSubSetBits;
if ( iNumSubSets > 1 )
{
/* write current subset */
ivas_split_rend_bitstream_write_int32( pBits, iSubSetId, iSubSetBits );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits );
iBitsWritten += iSubSetBits;
iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 );
}
......@@ -609,19 +539,19 @@ int32_t WritePredictors(
int32_t b;
int32_t b0 = iSubSetId;
ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets );
iBitsWritten += iNumSubSets;
if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) )
{
int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets;
ivas_split_rend_bitstream_write_int32( pBits, iNumPredBands, iNumPredBandBits );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits );
iBitsWritten += iNumPredBandBits;
for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets )
{
ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 );
iBitsWritten += 1;
if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 )
......@@ -632,10 +562,10 @@ int32_t WritePredictors(
iA1Mag = psPredictionEncoder->ppiA1Mag[c][b];
iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN;
ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS );
iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS;
ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS );
iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS;
}
}
......
......@@ -30,16 +30,13 @@
*******************************************************************************************************/
/* Double check cost function calculation */
#include <stdlib.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <math.h>
#include "prot.h"
#include "ivas_prot_rend.h"
#include "ivas_lcld_prot.h"
#include "ivas_lcld_rom_tables.h"
#include "isar_lcld_prot.h"
#include "isar_rom_lcld_tables.h"
#include "wmc_auto.h"
......@@ -244,7 +241,7 @@ static void ComputeBandEnergy(
fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] );
iFBOffset++;
}
fEnergy /= (float) ( piBandwidths[b] ); // Correction removed normalization by 2
fEnergy /= (float) ( piBandwidths[b] ); /* Correction removed normalization by 2*/
ppfBandEnergy[k][iChanOffset + b] = fEnergy;
fWeight = 0.33f * powf( 10.0f, 0.0068f * ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) );
......@@ -309,7 +306,7 @@ static void ComputeMergeRMS(
fRMSEnvelope = log2f( fGroupEnergy );
iQRMSEnvelope = ( fRMSEnvelope > 0.0 ) ? (int32_t) ( fRMSEnvelope + 0.5 ) : (int32_t) ( fRMSEnvelope - 0.5 );
fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy;
fGroupEnergy = 10.0f * log10f( fGroupEnergy ); /* Note epsilon was added when computing BandEnergy;*/
pfMergedEnergydB[b] = fGroupEnergy;
piQRMSEnvelope[b] = iQRMSEnvelope;
......@@ -398,7 +395,7 @@ static float ComputeSNRPenalty(
fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b];
if ( fDeltadB < -9.0309f )
{
fSNRPenalty += 1e10f; // Some large number to prevent clipping
fSNRPenalty += 1e10f; /* Some large number to prevent clipping*/
}
else /*if(fDeltadB < 0.0)*/
{
......@@ -541,7 +538,7 @@ static void ComputeGreedyGroups3(
}
else
{
iDone++; // This only catches a problem
iDone++; /* This only catches a problem*/
}
}
......@@ -590,7 +587,7 @@ static void ComputeRMSEnvelope(
fGroupEnergy /= (float) piGroupLengths[k];
fGroupEnergy = log2f( fGroupEnergy );
pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 ); // Bug fix
pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 );
pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] > ENV_MIN ) ? pppiRMSEnvelope[n][k][b] : ENV_MIN;
pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] < ENV_MAX ) ? pppiRMSEnvelope[n][k][b] : ENV_MAX;
}
......@@ -668,7 +665,7 @@ void ComputeEnvelopeGrouping(
RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
const int32_t iChannels,
const int32_t iNumBands,
const int32_t *piBandwidths, // pass in absolute thresh
const int32_t *piBandwidths,
float ***pppfReal,
float ***pppfImag,
int32_t *piNumGroups,
......
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef ISAR_CNST_H
#define ISAR_CNST_H
#include <stdint.h>
#include "options.h"
/* clang-format off */
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*----------------------------------------------------------------------------------*
* Split Binaural Rendering Constants
*----------------------------------------------------------------------------------*/
typedef enum
{
PCM_INT16,
PCM_FLOAT32,
PCM_NOT_KNOW = 0xffff
} PCM_RESOLUTION;
typedef enum
{
ANY_YAW,
PITCH_ONLY,
ANY_ROLL,
PRED_ONLY,
PRED_ROLL_ONLY,
COM_GAIN_ONLY,
LR_GAIN_ONLY
} ISAR_SPLIT_REND_POSE_TYPE;
#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */
#define SPLIT_REND_MAX_YAW_ONLY_POSES 2
#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2
#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2
#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2
#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/
#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES )
#define MAX_SPLIT_REND_MD_BANDS 20
#define MAX_SPLIT_MD_SUBFRAMES 1
#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
#define COMPLEX_MD_BAND_THRESH_LOW 4
#define COMPLEX_MD_BAND_THRESH_HIGH 10
#else
#define COMPLEX_MD_BAND_THRESH_LOW 5
#endif
#define SPLIT_REND_RO_MD_BAND_THRESH 4
#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4
#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63
#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31
#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31
#define ISAR_SPLIT_REND_D_QUANT_PNTS 15
#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f
#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f
#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f
#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f
#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS
#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f
#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f
#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) )
#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
#define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) )
#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
#define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) )
#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) )
#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) )
#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) )
#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) )
#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9
#define ISAR_SPLIT_REND_DOF_BITS 2
#define ISAR_SPLIT_REND_HQ_MODE_BITS 1
#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3
#define ISAR_SPLIT_REND_RO_FLAG_BITS 1
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2
#endif
/*----------------------------------------------------------------------------------*
* Split rendering bitrate constants
*----------------------------------------------------------------------------------*/
#define SPLIT_REND_256k 256000
#define SPLIT_REND_320k 320000
#define SPLIT_REND_384k 384000
#define SPLIT_REND_512k 512000
#define SPLIT_REND_768k 768000
#endif /*SPLIT_REND_WITH_HEAD_ROT */
#endif /*ISAR_CNST_H */
/* clang-format on */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include "options.h"
#include "isar_lc3plus_common.h"
#include "ivas_error.h"
#include "lc3.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*-----------------------------------------------------------------------------------------*
* Function ISAR_LC3PLUS_LC3plusErrToIvasErr()
*
*
*-----------------------------------------------------------------------------------------*/
ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr(
const LC3PLUS_Error lc3PlusError )
{
switch ( lc3PlusError )
{
case LC3PLUS_OK:
return IVAS_ERR_OK;
case LC3PLUS_BITRATE_ERROR:
return IVAS_ERR_LC3PLUS_INVALID_BITRATE;
default:
break;
}
return IVAS_ERR_INTERNAL;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError )
{
switch ( lc3PlusRtpError )
{
case LC3PLUS_RTP_ERR_NO_ERROR:
return IVAS_ERR_OK;
case LC3PLUS_RTP_ERR_NULL_PTR:
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
case LC3PLUS_RTP_ERR_INVALID_PARAMETERS:
return IVAS_ERR_WRONG_PARAMS;
case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED:
return IVAS_ERR_NOT_IMPLEMENTED;
case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION:
return IVAS_ERR_INTERNAL;
case LC3PLUS_RTP_ERR_INVALID_BITSTREAM:
return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM;
case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE:
return IVAS_ERR_INVALID_BUFFER_SIZE;
case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED:
return IVAS_ERR_INTERNAL;
case LC3PLUS_RTP_ERR_GENERIC_ERROR:
default:
break;
}
return IVAS_ERR_UNKNOWN;
}
#endif
#endif
......@@ -30,28 +30,43 @@
*******************************************************************************************************/
#ifndef IVAS_LC3PLUS_COM_H
#define IVAS_LC3PLUS_COM_H
#ifndef ISAR_LC3PLUS_COM_H
#define ISAR_LC3PLUS_COM_H
#include <stdint.h>
#include "options.h"
#include "ivas_error.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "lc3.h"
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
#include "isar_lc3plus_payload.h"
#endif
/*! common configuration parameters between encoder and decoder */
typedef struct LC3PLUS_CONFIG
{
/*! frame duration in microseconds [10000, 5000, 2500] */
uint32_t lc3plus_frame_duration_us;
/*! ivas frame duration in microseconds [20000, 5000] */
uint32_t ivas_frame_duration_us;
int16_t lc3plus_frame_duration_us;
/*! isar frame duration in microseconds [20000, 10000, 5000] */
int16_t isar_frame_duration_us;
/*! sampling rate*/
uint32_t samplerate;
int32_t samplerate;
/*! number of channels */
uint16_t channels;
int16_t channels;
#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS || defined ISAR_BITSTREAM_UPDATE_LC3PLUS
/*! high resolution mode enabled (1) or disabled (0)*/
int16_t high_res_mode_enabled;
#endif
} LC3PLUS_CONFIG;
/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */
ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError );
ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError );
#endif /* IVAS_LC3PLUS_COM_H */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */
ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError );
#endif
#endif /* SPLIT_REND_WITH_HEAD_ROT */
#endif /* ISAR_LC3PLUS_COM_H */
......@@ -34,41 +34,80 @@
#include "options.h"
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_lc3plus_dec.h"
#include "ivas_lc3plus_common.h"
#include "isar_lc3plus_dec.h"
#include "isar_lc3plus_common.h"
#include "lc3.h"
#include "ivas_error_utils.h"
#include "wmc_auto.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_Open()
* isar_LC3PLUS_AllocateSubframeDecodingMatrix()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_Open(
static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix(
int16_t **subframeChannelMatrix )
{
for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
{
free( subframeChannelMatrix[i] );
}
free( subframeChannelMatrix );
return;
}
#endif
/*-------------------------------------------------------------------------
* ISAR_LC3PLUS_DEC_Open()
*
*
*------------------------------------------------------------------------*/
ivas_error ISAR_LC3PLUS_DEC_Open(
const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */
IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
)
{
LC3PLUS_Error err;
int32_t decoder_size;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int16_t i;
if ( 0 == config.lc3plus_frame_duration_us )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" );
}
#else
int16_t lc3plusFrameIdx;
int16_t numLC3plusFramesPerIvasFrame;
int16_t i;
#endif
if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS )
{
return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" );
}
#else
if ( 0 == config.lc3plus_frame_duration_us )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" );
}
numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us );
numLC3plusFramesPerIvasFrame = (int16_t) ( config.isar_frame_duration_us / config.lc3plus_frame_duration_us );
#endif
( *handle )->num_decs = 0;
......@@ -77,15 +116,15 @@ ivas_error IVAS_LC3PLUS_DEC_Open(
( *handle )->selective_decoding_states = NULL;
( *handle )->bitstream_caches = NULL;
if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL )
if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
......@@ -95,9 +134,9 @@ ivas_error IVAS_LC3PLUS_DEC_Open(
( *handle )->selective_decoding_states[i] = NULL;
}
if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL )
if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
for ( i = 0; i < config.channels; ++i )
......@@ -117,89 +156,103 @@ ivas_error IVAS_LC3PLUS_DEC_Open(
decoder_size = lc3plus_dec_get_size( config.samplerate, 1 );
if ( 0 == decoder_size )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" );
}
if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled );
#else
err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 );
#endif
if ( LC3PLUS_OK != err )
{
IVAS_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" );
}
err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
if ( LC3PLUS_OK != err )
{
IVAS_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" );
}
/* allocate and configure per LC3plus decoder skip state */
if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL )
if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
}
#endif
( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0;
( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE;
#else
for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ )
{
( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE;
}
#endif
/* allocate and configure per LC3plus decoder bitstream cache */
if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL )
if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/;
#else
( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame;
#endif
if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
}
( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0;
}
( *handle )->config = config;
if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" );
}
if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL )
{
IVAS_LC3PLUS_DEC_Close( handle );
ISAR_LC3PLUS_DEC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" );
}
return IVAS_ERR_OK;
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix()
* ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
int16_t ***subframeChannelMatrix,
const uint32_t num_decs )
{
......@@ -219,7 +272,7 @@ ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
{
if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL )
{
IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix );
isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" );
}
}
......@@ -229,44 +282,24 @@ ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix()
* ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix()
*
*
*------------------------------------------------------------------------*/
void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix(
int16_t **subframeChannelMatrix )
{
for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
{
free( subframeChannelMatrix[i] );
}
free( subframeChannelMatrix );
return;
}
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] )
{
int16_t numIvasSubFramesPerLC3frame;
uint32_t decIdx;
int16_t ivasSubframeIdx;
int16_t effectiveIvasSubframeDuration;
int16_t effectiveIsarSubframeDuration;
int16_t actual_num_spatial_subframes;
if ( NULL == handle )
{
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" );
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" );
}
if ( NULL == subframeChannelMatrix )
......@@ -274,14 +307,14 @@ ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" );
}
if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" );
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid isar_frame_duration_us/lc3plus_frame_duration_us values\n" );
}
effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us );
numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration;
actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration;
effectiveIsarSubframeDuration = (int16_t) ( handle->config.isar_frame_duration_us == 20000 ? handle->config.isar_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.isar_frame_duration_us );
numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIsarSubframeDuration;
actual_num_spatial_subframes = (int16_t) handle->config.isar_frame_duration_us / effectiveIsarSubframeDuration;
/* 0.5(0) = 10ms lc3plus, 5ms subframe */
if ( numIvasSubFramesPerLC3frame != 1 )
{
......@@ -360,16 +393,17 @@ ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_GetDelay()
* ISAR_LC3PLUS_DEC_GetDelay()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_GetDelay(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
ivas_error ISAR_LC3PLUS_DEC_GetDelay(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
int32_t *delayInSamples /* o : decoder delay in number of samples per channel */
)
{
......@@ -377,7 +411,7 @@ ivas_error IVAS_LC3PLUS_DEC_GetDelay(
if ( NULL == handle )
{
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" );
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" );
}
if ( NULL == delayInSamples )
{
......@@ -407,13 +441,13 @@ ivas_error IVAS_LC3PLUS_DEC_GetDelay(
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_Close()
* ISAR_LC3PLUS_DEC_Close()
*
*
*------------------------------------------------------------------------*/
void IVAS_LC3PLUS_DEC_Close(
IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */
void ISAR_LC3PLUS_DEC_Close(
ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */
)
{
if ( NULL == handle || NULL == *handle )
......@@ -430,7 +464,9 @@ void IVAS_LC3PLUS_DEC_Close(
if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] )
{
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
free( ( *handle )->selective_decoding_states[iDec]->frame_actions );
#endif
free( ( *handle )->selective_decoding_states[iDec] );
}
......@@ -487,7 +523,7 @@ static ivas_error decode_or_conceal_one_lc3plus_frame(
if ( err != LC3PLUS_OK )
{
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" );
}
return IVAS_ERR_OK;
......@@ -495,13 +531,13 @@ static ivas_error decode_or_conceal_one_lc3plus_frame(
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal()
* isar_LC3PLUS_DEC_Decode_or_Conceal_internal()
*
*
*------------------------------------------------------------------------*/
static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
uint8_t *bitstream_in, /* i : pointer to input bitstream */
int32_t bitstream_in_size, /* i : size of bitstream_in */
const int16_t badFrameIndicator, /* i : bad frame indicator. If set to 1, triggers concealment */
......@@ -509,13 +545,20 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
)
{
uint32_t iDec;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t config_num_media_times;
int32_t iMediaTime;
int32_t iFtd;
LC3PLUS_RTP_PAYLOAD payload;
#else
int32_t iLc3plusFrame;
int32_t lc3framesPerIvasFrame;
int32_t bitstreamOffsetPerCoder;
uint8_t *bitstream_in_iter = bitstream_in;
#endif
int32_t ivasSampleIndex;
int16_t numSamplesPerLC3plusChannel;
int32_t bitstreamOffsetPerCoder;
ivas_error err;
uint8_t *bitstream_in_iter = bitstream_in;
if ( NULL == handle )
{
......@@ -538,19 +581,59 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" );
}
if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
if ( !badFrameIndicator )
{
if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" );
}
if ( payload.sampling_rate_hz != handle->config.samplerate )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" );
}
if ( payload.num_channels != handle->config.channels )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" );
}
if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" );
}
if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" );
}
if ( payload.num_media_times != config_num_media_times )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" );
}
}
#endif
lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times );
for ( iDec = 0; iDec < handle->num_decs; iDec++ )
{
for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ )
{
iFtd = iDec + iMediaTime * handle->num_decs;
#else
lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame );
numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame );
bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame;
for ( iDec = 0; iDec < handle->num_decs; iDec++ )
{
for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ )
{
#endif
if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame )
{
if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size )
......@@ -572,8 +655,14 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
{
handle->bitstream_caches[iDec]->bitstream_cache_size = 0;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
switch ( handle->selective_decoding_states[iDec]->frame_action )
#else
switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] )
#endif
{
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
case DEC_ACTION_DECODE_AND_DROP:
{
err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator );
......@@ -584,8 +673,37 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
break;
}
#endif
case DEC_ACTION_DECODE_AND_USE:
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( badFrameIndicator )
{
err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator );
}
else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD )
{
return IVAS_ERR_NOT_IMPLEMENTED;
/* Untested therefore disabled. Would probably only need to call concealment,
* but the LC3plus API requires a non-NULL ptr for this which is not available here */
}
else
{
err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator );
}
if ( err != IVAS_ERR_OK )
{
return IVAS_ERROR( err, "lc3plus decoding failed\n" );
}
for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ )
{
ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel;
pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16];
}
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
break;
#else
err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator );
if ( err != IVAS_ERR_OK )
{
......@@ -599,15 +717,30 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
}
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
break;
#endif
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
case DEC_ACTION_SKIP:
{
/* log that this instance has skipped a frame and must decode twice once reactivated */
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
break;
}
#endif
case DEC_ACTION_CACHE:
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length )
{
return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" );
}
/* store bit rate of cached frame */
mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length );
handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length;
/* log that this instance has skipped a frame and must decode twice once reactivated */
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
break;
#else
if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder )
{
return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" );
......@@ -618,11 +751,18 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
/* log that this instance has skipped a frame and must decode twice once reactivated */
handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
break;
#endif
}
case DEC_ACTION_NUM_ENUMS:
default:
return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
} /* for each media time */
/* reset skipping state, must be set by the user before each decode call*/
handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE;
} /* for each dec/channel */
#else
bitstream_in_iter += bitstreamOffsetPerCoder;
}
......@@ -634,18 +774,19 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal(
}
}
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_Decode()
* ISAR_LC3PLUS_DEC_Decode()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_Decode(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
ivas_error ISAR_LC3PLUS_DEC_Decode(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
uint8_t *bitstream_in, /* i : pointer to input bitstream */
const int32_t bitstream_in_size, /* i : size of bitstream_in */
float **pcm_out /* o : decoded samples */
......@@ -667,18 +808,18 @@ ivas_error IVAS_LC3PLUS_DEC_Decode(
}
badFrameIndicator = 0;
return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out );
return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out );
}
/*-------------------------------------------------------------------------
* IVAS_LC3PLUS_DEC_Conceal()
* ISAR_LC3PLUS_DEC_Conceal()
*
*
*------------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_DEC_Conceal(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
ivas_error ISAR_LC3PLUS_DEC_Conceal(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
float **pcm_out /* o : concealed samples */
)
{
......@@ -698,6 +839,6 @@ ivas_error IVAS_LC3PLUS_DEC_Conceal(
/* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */
badFrameIndicator = 1;
return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out );
return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out );
}
#endif /* SPLIT_REND_WITH_HEAD_ROT */
......@@ -30,90 +30,106 @@
*******************************************************************************************************/
#ifndef IVAS_LC3PLUS_DEC_H
#define IVAS_LC3PLUS_DEC_H
#ifndef ISAR_LC3PLUS_DEC_H
#define ISAR_LC3PLUS_DEC_H
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "lc3.h"
#include "ivas_error.h"
#include "ivas_lc3plus_common.h"
#include "ivas_cnst.h"
#include "isar_lc3plus_common.h"
typedef enum
{
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
DEC_ACTION_DECODE_AND_DROP = 0,
#endif
DEC_ACTION_DECODE_AND_USE,
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
DEC_ACTION_SKIP,
#endif
DEC_ACTION_CACHE,
DEC_ACTION_NUM_ENUMS
} SelectiveDecAction;
typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE
typedef struct ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE
{
/*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */
int16_t has_skipped_a_frame;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*! action to execute for the next frame */
SelectiveDecAction frame_action;
#else
/*! if set to 1, decoder will skip decoding for the next frame */
SelectiveDecAction *frame_actions;
#endif
/*! if set to 1, decoder will decode the cache before decoding any of current frames */
int16_t shall_decode_cached_frame;
} IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE;
} ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE;
typedef struct IVAS_LC3PLUS_DEC_BITSTREAM_CACHE
typedef struct ISAR_LC3PLUS_DEC_BITSTREAM_CACHE
{
uint8_t *bitstream_cache;
int32_t bitstream_cache_capacity;
int32_t bitstream_cache_size;
} IVAS_LC3PLUS_DEC_BITSTREAM_CACHE;
} ISAR_LC3PLUS_DEC_BITSTREAM_CACHE;
/* decoder wrapper */
typedef struct IVAS_LC3PLUS_DEC_HANDLE
typedef struct ISAR_LC3PLUS_DEC_HANDLE
{
LC3PLUS_Dec **handles;
IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states;
IVAS_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches;
ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states;
ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches;
uint32_t num_decs;
int16_t *pcm_conversion_buffer;
LC3PLUS_CONFIG config;
} * IVAS_LC3PLUS_DEC_HANDLE;
} * ISAR_LC3PLUS_DEC_HANDLE;
ivas_error IVAS_LC3PLUS_DEC_Open(
ivas_error ISAR_LC3PLUS_DEC_Open(
const LC3PLUS_CONFIG config, /* i : decoder configuration */
IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
);
ivas_error IVAS_LC3PLUS_DEC_GetDelay(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
ivas_error ISAR_LC3PLUS_DEC_GetDelay(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */
);
void IVAS_LC3PLUS_DEC_Close(
IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */
void ISAR_LC3PLUS_DEC_Close(
ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */
);
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */
ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */
);
#endif
ivas_error IVAS_LC3PLUS_DEC_Decode(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
ivas_error ISAR_LC3PLUS_DEC_Decode(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
uint8_t *bitstream_in, /* i : pointer to input bitstream */
const int32_t bitstream_in_size, /* i : size of bitstream_in */
float **pcm_out /* o : decoded samples */
);
ivas_error IVAS_LC3PLUS_DEC_Conceal(
IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
ivas_error ISAR_LC3PLUS_DEC_Conceal(
ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
float **pcm_out /* o : concealed samples */
);
ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
int16_t ***subframeChannelMatrix,
const uint32_t num_decs );
void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix );
void ISAR_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix );
#endif
#endif /* IVAS_LC3PLUS_DEC_H */
#endif /* SPLIT_REND_WITH_HEAD_ROT */
#endif /* ISAR_LC3PLUS_DEC_H */
......@@ -30,27 +30,83 @@
*******************************************************************************************************/
#include "ivas_lc3plus_enc.h"
#include "ivas_lc3plus_common.h"
#include "isar_lc3plus_enc.h"
#include "isar_lc3plus_common.h"
#include "lc3.h"
#include "ivas_error_utils.h"
#include "prot.h"
#include "wmc_auto.h"
#include "options.h"
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA;
#endif
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config,
int32_t per_channel_bitrate )
{
if ( config.high_res_mode_enabled )
{
switch ( config.lc3plus_frame_duration_us )
{
case 10000:
return min( per_channel_bitrate, 500000 );
case 5000:
return min( per_channel_bitrate, 600000 );
case 2500:
return min( per_channel_bitrate, 672000 );
default:
assert( false && "unreachable" );
}
}
switch ( config.samplerate )
{
case 48000:
case 32000:
return min( per_channel_bitrate, 320000 );
case 24000:
return min( per_channel_bitrate, 314400 );
case 16000:
return min( per_channel_bitrate, 221600 );
case 8000:
return min( per_channel_bitrate, 114400 );
default:
assert( false && "unreachable" );
}
assert( false && "unreachable" );
return -1;
}
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_Open()
* Function ISAR_LC3PLUS_ENC_Open()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_ENC_Open(
ivas_error ISAR_LC3PLUS_ENC_Open(
const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */
const uint32_t bitsPerSecond, /* i : bit rate */
IVAS_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */
ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */
)
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t num_lc3plus_media_times_per_ivas_frame;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t lc3plus_num_bytes_per_frame;
#endif
bool is_last_media_time, is_last_channel;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error ivas_err;
#endif
#endif
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t bitsPerSecondPerChannel;
#endif
int32_t encoder_size;
LC3PLUS_Error err;
int32_t lfeChans[1];
......@@ -62,24 +118,39 @@ ivas_error IVAS_LC3PLUS_ENC_Open(
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" );
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
bitsPerSecondPerChannel = bitsPerSecond / config.channels;
#endif
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" );
}
if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" );
}
#endif
encoder_size = lc3plus_enc_get_size( config.samplerate, 1 );
if ( 0 == encoder_size )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" );
}
if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *handle )->config = config;
( *handle )->frame_type_descriptors = NULL;
#endif
( *handle )->pcm_conversion_buffer = NULL;
( *handle )->num_encs = 0;
if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
{
IVAS_LC3PLUS_ENC_Close( handle );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
}
......@@ -88,63 +159,243 @@ ivas_error IVAS_LC3PLUS_ENC_Open(
( *handle )->handles[i] = NULL;
}
( *handle )->num_encs = config.channels;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us;
( *handle )->fdl_request = s_fdl_request;
( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame;
( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) );
if ( NULL == ( *handle )->frame_type_descriptors )
{
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" );
}
#endif
for ( int32_t iCh = 0; iCh < config.channels; iCh++ )
{
if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL )
{
IVAS_LC3PLUS_ENC_Close( handle );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans );
#else
err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans );
#endif
if ( err != LC3PLUS_OK )
{
IVAS_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" );
}
err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
if ( err != LC3PLUS_OK )
{
IVAS_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" );
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel );
if ( err != LC3PLUS_OK )
{
IVAS_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" );
}
#endif
}
if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
{
IVAS_LC3PLUS_ENC_Close( handle );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" );
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *handle )->config = config;
#endif
( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 );
if ( NULL == ( *handle )->pcm_conversion_buffer )
{
IVAS_LC3PLUS_ENC_Close( handle );
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* update FDI fields */
for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime )
{
for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc )
{
int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */
#else
lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] );
if ( lc3plus_num_bytes_per_frame <= 0 )
{
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" );
}
( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame;
#endif
if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) )
{
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" );
}
if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) )
{
ISAR_LC3PLUS_ENC_Close( handle );
return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" );
}
( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY;
( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL;
/* The FTDs in the ToC are included in the following order:
* 1) First the FTD for the first channel of the first FDB (oldest frame)
* 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order
* 3) Then the FTD for the first channel of the second FDB
* 4) Then the FTDs for the remaining channels for the second FDB
* 5) Etc. to the last FDB */
is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime;
is_last_channel = ( *handle )->num_encs - 1 == iEnc;
if ( is_last_media_time && is_last_channel )
{
( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL;
}
else if ( !is_last_media_time && is_last_channel )
{
( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME;
}
else
{
( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL;
}
}
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond );
if ( ivas_err != IVAS_ERR_OK )
{
ISAR_LC3PLUS_ENC_Close( handle );
return ivas_err;
}
#endif
#endif
return IVAS_ERR_OK;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_SetBitrate()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_ENC_SetBitrate(
ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */
const uint32_t bitsPerSecond /* i : new target bit rate */
)
{
int32_t numLc3plusMediaTimesPerIvasFrame;
int32_t lc3plus_num_bytes_per_frame;
int32_t availableOctetsPerIsarFrame;
int32_t actualOctetsPerFrame;
LC3PLUS_Error err;
int32_t iFtd;
int32_t fdrLength;
int32_t lc3plusPacketRate;
int32_t numSubframes;
int32_t minPayloadOverhead;
int32_t targetLc3PlusBitratePerChannel;
int32_t targetLc3PlusOctetCount;
int32_t lc3plusFdlLength;
if ( NULL == handle )
{
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
}
availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8;
lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us;
numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels;
/* subtract minimum required payload bytes & calculate a first per-channel target bit rate */
if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" );
}
minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE );
targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( targetLc3PlusBitratePerChannel <= 0 )
{
return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" );
}
#endif
targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel );
targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate;
/* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */
if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" );
}
if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH )
{
/* reduce bitrate to allow for the required fdl field */
targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate;
}
for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ )
{
err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel );
if ( err != LC3PLUS_OK )
{
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" );
}
}
// update FTD settings after bitrate change
for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime )
{
for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc )
{
iFtd = iEnc + iMediaTime * handle->num_encs;
lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
if ( lc3plus_num_bytes_per_frame <= 0 )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" );
}
handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame;
}
}
// TODO: remove sanity checks?
if ( ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) != IVAS_ERR_OK )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "ISAR_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" );
}
if ( actualOctetsPerFrame > availableOctetsPerIsarFrame )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" );
}
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_GetDelay()
* Function ISAR_LC3PLUS_ENC_GetDelay()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_ENC_GetDelay(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
ivas_error ISAR_LC3PLUS_ENC_GetDelay(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
int32_t *delayInSamples /* o : encoder delay in number of samples per channel */
)
{
......@@ -181,17 +432,25 @@ ivas_error IVAS_LC3PLUS_ENC_GetDelay(
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_GetOutputBitstreamSize()
* Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
int32_t *bsSize /* o : size of each bitstream frame in bytes */
)
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
LC3PLUS_RTP_ERR rtp_err;
int32_t num_lc3plus_media_times_per_ivas_frame;
int32_t iMediaTime;
int32_t ftd_frame_data_length_size, lc3plus_frame_data_length;
int32_t ftd_index;
#else
int32_t bitstreamSizeMultiplier;
#endif
if ( NULL == handle )
{
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
......@@ -201,42 +460,90 @@ ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize(
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( 0 == handle->config.lc3plus_frame_duration_us )
{
return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" );
}
if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
}
num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
#endif
*bsSize = 0;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t fdl_request_length;
rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request );
if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" );
}
*bsSize += fdl_request_length;
#endif
for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ )
{
if ( NULL == handle->handles[iEnc] )
{
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime )
{
ftd_index = iEnc + iMediaTime * handle->num_encs;
if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" );
}
rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length );
if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" );
}
*bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL;
*bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length;
*bsSize += ftd_frame_data_length_size;
}
}
#else
*bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
}
if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
}
bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us;
bitstreamSizeMultiplier = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
*bsSize *= bitstreamSizeMultiplier;
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_Close()
* Function ISAR_LC3PLUS_ENC_Close()
*
*
*-------------------------------------------------------------------*/
void IVAS_LC3PLUS_ENC_Close(
IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
void ISAR_LC3PLUS_ENC_Close(
ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
)
{
if ( NULL == handle || NULL == *handle )
{
return;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( NULL != ( *handle )->frame_type_descriptors )
{
free( ( *handle )->frame_type_descriptors );
}
#endif
for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ )
{
if ( NULL != ( *handle )->handles[iEnc] )
......@@ -260,25 +567,36 @@ void IVAS_LC3PLUS_ENC_Close(
/*-------------------------------------------------------------------*
* Function IVAS_LC3PLUS_ENC_Encode()
* Function ISAR_LC3PLUS_ENC_Encode()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_LC3PLUS_ENC_Encode(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
ivas_error ISAR_LC3PLUS_ENC_Encode(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
float **pcm_in, /* i : pointer input samples */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
void *bitstream_out, /* o : pointer to bitstream frame */
const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */
#else
void *bitstream_out /* o : pointer to bitstream frame */
#endif
)
{
uint32_t numSamplesPerLC3plusChannel;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t ftdIndex;
LC3PLUS_RTP_ERR rtpErr;
uint32_t num_media_times;
#else
uint32_t lc3framesPerIvasFrame;
int32_t ivasSampleIndex;
uint8_t *bitstream_out_iter = bitstream_out;
#endif
uint32_t numSamplesPerLC3plusChannel;
int32_t ivasSampleIndex;
int32_t num_bytes = 0;
LC3PLUS_Error err;
push_wmops( "IVAS_LC3PLUS_ENC_Encode" );
push_wmops( "ISAR_LC3PLUS_ENC_Encode" );
if ( NULL == handle )
{
......@@ -293,37 +611,71 @@ ivas_error IVAS_LC3PLUS_ENC_Encode(
return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" );
}
if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times;
size_t actual_size;
rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds );
if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" );
}
lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us;
#else
lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame;
numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame;
#endif
for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ )
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ )
#else
for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ )
#endif
{
for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ )
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel;
#else
ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel;
#endif
handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ftdIndex = iMediaTime * handle->num_encs + iEnc;
#endif
num_bytes = 0;
push_wmops( "lc3plus_enc16" );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL );
#else
err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL );
#endif
pop_wmops();
if ( err != LC3PLUS_OK )
{
return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" );
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" );
}
if ( 0 == num_bytes )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" );
}
#else
bitstream_out_iter += num_bytes;
#endif
}
}
......
......@@ -30,47 +30,73 @@
*******************************************************************************************************/
#ifndef IVAS_LC3PLUS_ENC_H
#define IVAS_LC3PLUS_ENC_H
#ifndef ISAR_LC3PLUS_ENC_H
#define ISAR_LC3PLUS_ENC_H
#include <stdint.h>
#include "lc3.h"
#include "ivas_error.h"
#include "ivas_lc3plus_common.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "lc3.h"
#include "isar_lc3plus_common.h"
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
#include "isar_lc3plus_payload.h"
#endif
/* encoder wrapper */
typedef struct IVAS_LC3PLUS_ENC_HANDLE
typedef struct ISAR_LC3PLUS_ENC_HANDLE
{
LC3PLUS_CONFIG config;
LC3PLUS_Enc **handles;
uint32_t num_encs;
int16_t *pcm_conversion_buffer;
} * IVAS_LC3PLUS_ENC_HANDLE;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
LC3PLUS_RTP_FTD *frame_type_descriptors;
int32_t num_ftds;
LC3PLUS_RTP_FDL fdl_request;
#endif
} * ISAR_LC3PLUS_ENC_HANDLE;
ivas_error IVAS_LC3PLUS_ENC_Open(
ivas_error ISAR_LC3PLUS_ENC_Open(
const LC3PLUS_CONFIG config, /* i : encoder configuration */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const uint32_t initialBitsPerSecond, /* i : initial target bit rate */
#else
const uint32_t bitsPerSecond, /* i : bit rate */
IVAS_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */
#endif
ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */
);
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error IVAS_LC3PLUS_ENC_SetBitrate(
ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */
const uint32_t bitsPerSecond /* i : new target bit rate */
);
#endif
ivas_error IVAS_LC3PLUS_ENC_GetDelay(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
ivas_error ISAR_LC3PLUS_ENC_GetDelay(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */
);
ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
int32_t *bsSize /* o : size of each bitstream frame in bytes */
ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
int32_t *bsSize /* o : size of next bitstream frame in bytes */
);
void IVAS_LC3PLUS_ENC_Close(
IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
void ISAR_LC3PLUS_ENC_Close(
ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
);
ivas_error IVAS_LC3PLUS_ENC_Encode(
IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
ivas_error ISAR_LC3PLUS_ENC_Encode(
ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
float **pcm_in, /* i : pointer input samples */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
void *bitstream_out, /* o : pointer to bitstream frame */
const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */
#else
void *bitstream_out /* o : pointer to bitstream frame */
#endif
);
#endif
#endif /* IVAS_LC3PLUS_ENC_H */
#endif /* ISAR_LC3PLUS_ENC_H */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include "isar_lc3plus_payload.h"
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi )
{
if ( NULL == frame_duration_us )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
switch ( fdi )
{
case LC3PLUS_RTP_FTD_FDI_2500_US:
*frame_duration_us = 2500;
break;
case LC3PLUS_RTP_FTD_FDI_5000_US:
*frame_duration_us = 5000;
break;
case LC3PLUS_RTP_FTD_FDI_10000_US:
*frame_duration_us = 10000;
break;
case LC3PLUS_RTP_FTD_FDI_RESERVED:
default:
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr )
{
if ( NULL == sample_rate_hz )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
switch ( bwr )
{
case LC3PLUS_RTP_FTD_BWR_NB:
*sample_rate_hz = 8000;
break;
case LC3PLUS_RTP_FTD_BWR_WB:
*sample_rate_hz = 16000;
break;
case LC3PLUS_RTP_FTD_BWR_SSWB:
*sample_rate_hz = 24000;
break;
case LC3PLUS_RTP_FTD_BWR_SWB:
*sample_rate_hz = 32000;
break;
case LC3PLUS_RTP_FTD_BWR_FBCD:
*sample_rate_hz = 44100;
break;
case LC3PLUS_RTP_FTD_BWR_FB:
*sample_rate_hz = 48000;
break;
case LC3PLUS_RTP_FTD_BWR_FBHR:
*sample_rate_hz = 48000;
break;
case LC3PLUS_RTP_FTD_BWR_UBHR:
*sample_rate_hz = 96000;
break;
default:
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr )
{
if ( NULL == high_resolution_flag )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
switch ( bwr )
{
case LC3PLUS_RTP_FTD_BWR_NB:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_WB:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_SSWB:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_SWB:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_FBCD:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_FB:
*high_resolution_flag = 0;
break;
case LC3PLUS_RTP_FTD_BWR_FBHR:
*high_resolution_flag = 1;
break;
case LC3PLUS_RTP_FTD_BWR_UBHR:
*high_resolution_flag = 1;
break;
default:
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue )
{
if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID )
{
*length = 1;
}
else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX )
{
*length = 1;
}
else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX )
{
*length = 2;
}
else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
{
*length = 3;
}
else
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst )
{
int32_t frame_data_length_size;
LC3PLUS_RTP_ERR err;
if ( NULL == dst )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue );
if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
{
return err;
}
if ( 1 == frame_data_length_size )
{
*dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
}
else if ( 2 == frame_data_length_size )
{
const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE;
*dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
*dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
}
else if ( 3 == frame_data_length_size )
{
const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE );
*dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
*dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
*dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl )
{
if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
{
return fdl;
}
return 0;
}
static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl )
{
if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD )
{
return true;
}
return false;
}
static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request )
{
/* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */
if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) )
{
return true;
}
return false;
}
static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity )
{
int32_t frame_data_length_size;
LC3PLUS_RTP_ERR err;
if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) )
{
*frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
}
else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src )
{
*frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
}
else if ( remaining_capacity > 0 )
{
*frame_data_length_value = *src << 0;
}
else
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
/* sanity check */
err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value );
if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
{
return err;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity )
{
int32_t frame_data_block_size;
LC3PLUS_RTP_FDL fdl;
LC3PLUS_RTP_ERR err;
if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
*num_bytes_read = 0;
receiver_ftd->fc = 0;
receiver_ftd->fdi = 0;
receiver_ftd->bwr = 0;
receiver_ftd->h = 0;
receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK;
receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK );
receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK );
receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK );
p_read++;
*num_bytes_read = 1;
err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
frame_data_block_size = s_get_size_from_fdl( fdl );
receiver_ftd->frame_data_length = frame_data_block_size;
int32_t length_field_size;
err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
*num_bytes_read += length_field_size;
return LC3PLUS_RTP_ERR_NO_ERROR;
}
LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize(
uint8_t *serialized_buffer,
const size_t serialized_buffer_capacity,
size_t *packed_buffer_actual_size,
const LC3PLUS_RTP_FDL fdl_request,
LC3PLUS_RTP_FTD *sender_ftds,
const size_t sender_ftds_num )
{
LC3PLUS_RTP_ERR err;
uint8_t *p_write = serialized_buffer;
uint32_t i;
int32_t bytes_written = 0;
int32_t lc3plus_frame_size_sum;
uint8_t *p_frame_data;
int32_t fdl_request_length;
if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
*packed_buffer_actual_size = 0;
err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( !s_fdl_value_is_valid_request( fdl_request ) )
{
return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
}
if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
err = s_frame_data_length_pack( fdl_request, p_write );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
bytes_written += fdl_request_length;
p_write += bytes_written;
for ( i = 0; i < sender_ftds_num; ++i )
{
/* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
/* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
*p_write = 0x00;
*p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc;
*p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi;
*p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr;
*p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h;
p_write++;
bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL;
int32_t fdl_length;
err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
p_write += fdl_length;
bytes_written += fdl_length;
}
lc3plus_frame_size_sum = 0;
p_frame_data = serialized_buffer + bytes_written;
for ( i = 0; i < sender_ftds_num; ++i )
{
sender_ftds[i].frame_data = p_frame_data;
p_frame_data += sender_ftds[i].frame_data_length;
lc3plus_frame_size_sum += sender_ftds[i].frame_data_length;
}
*packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum;
assert( *packed_buffer_actual_size <= serialized_buffer_capacity );
return LC3PLUS_RTP_ERR_NO_ERROR;
}
static LC3PLUS_RTP_ERR s_ftds_parse(
LC3PLUS_RTP_FTD *receiver_ftds,
const int32_t receiver_ftds_num_max,
int16_t *receiver_ftds_num,
uint8_t *serialized_buffer,
const size_t serialized_buffer_size )
{
int32_t diff;
uint8_t *p_read;
uint32_t ftds_offset_sum = 0;
int16_t i;
LC3PLUS_RTP_ERR error;
int32_t frame_offset_counter;
int32_t size;
p_read = serialized_buffer;
if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
if ( 0 == serialized_buffer_size )
{
return LC3PLUS_RTP_ERR_EMPTY_TOC;
}
if ( receiver_ftds_num_max <= 0 )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
{
int32_t num_bytes_read_sum = 0;
const int32_t min_num_bytes_per_ftd = 2;
int16_t receiver_ftds_index = 0;
bool another_ftd = true;
int32_t num_bytes_read_per_ftd;
while ( another_ftd )
{
if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
num_bytes_read_per_ftd = 0;
error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum );
if ( LC3PLUS_RTP_ERR_NO_ERROR != error )
{
return error;
}
p_read += num_bytes_read_per_ftd;
num_bytes_read_sum += num_bytes_read_per_ftd;
if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
}
else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL )
{
another_ftd = false;
}
if ( another_ftd )
{
if ( receiver_ftds_index >= receiver_ftds_num_max )
{
return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED;
}
( receiver_ftds_index )++;
}
}
*receiver_ftds_num = receiver_ftds_index + 1;
}
/* set frame-data pointers into serialized_buffer */
for ( i = 0; i < *receiver_ftds_num; ++i )
{
error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length );
if ( error != LC3PLUS_RTP_ERR_NO_ERROR )
{
return error;
}
ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size;
}
frame_offset_counter = 0;
for ( i = 0; i < *receiver_ftds_num; ++i )
{
if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) )
{
receiver_ftds[i].frame_data = NULL;
}
else
{
receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter;
frame_offset_counter += receiver_ftds[i].frame_data_length;
}
}
if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size )
{
/* parsed content & size n bytes of input buffer do not line up */
/* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */
diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter );
if ( diff < 0 )
{
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
}
/* verify that all bytes are zero */
p_read += frame_offset_counter;
for ( i = 0; i < diff; ++i )
{
if ( *p_read != 0 )
{
/* non-zero byte in padding region */
return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES;
}
p_read++;
}
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize(
LC3PLUS_RTP_PAYLOAD *payload,
uint8_t *serialized_buffer,
const size_t serialized_buffer_size )
{
int32_t new_frame_duration_us;
int32_t new_sampling_rate_hz;
int16_t new_high_resolution_flag;
int16_t i = 0;
int16_t channel_id = 0;
int16_t media_time_id = 0;
const int16_t invalid_value = -1;
int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS];
int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES];
LC3PLUS_RTP_ERR err;
if ( NULL == payload || NULL == serialized_buffer )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
if ( 0 == serialized_buffer_size )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id )
{
channels_per_media_time[media_time_id] = invalid_value;
}
media_time_id = 0;
for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id )
{
media_times_per_channel[channel_id] = invalid_value;
}
channel_id = 0;
err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
int32_t fdl_request_length;
err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( !s_fdl_value_is_valid_request( payload->fdl_request ) )
{
return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
}
err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( 0 == payload->num_ftds )
{
return LC3PLUS_RTP_ERR_GENERIC_ERROR;
}
/* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */
/* initialize on the first FTD, use this as reference */
err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
payload->num_channels = 0;
payload->num_media_times = 0;
for ( i = 0; i < payload->num_ftds; ++i )
{
if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY )
{
/* not implemented */
return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
}
err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( payload->frame_duration_us != new_frame_duration_us )
{
/* mixed frame durations not supported */
return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
}
err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( payload->sampling_rate_hz != new_sampling_rate_hz )
{
/* mixed sampling frequencies not supported */
return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
}
err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr );
if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
{
return err;
}
if ( payload->high_resolution_enabled != new_high_resolution_flag )
{
/* mixed high resolution mode not supported */
return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
}
switch ( payload->ftds[i].fc )
{
case LC3PLUS_RTP_FTD_FC_LAST_OVERALL:
channels_per_media_time[media_time_id]++;
media_times_per_channel[channel_id]++;
channel_id = 0;
media_time_id = 0;
break;
case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL:
media_times_per_channel[channel_id]++;
channels_per_media_time[media_time_id]++;
channel_id++;
break;
case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME:
media_times_per_channel[channel_id]++;
channels_per_media_time[media_time_id]++;
channel_id = 0;
media_time_id++;
break;
case LC3PLUS_RTP_FTD_FC_RESERVED:
default:
return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
}
}
{
int32_t valid_num_media_times_per_channel;
int32_t iCh;
/* check whether all channels exist for each media time */
if ( media_times_per_channel[0] == invalid_value )
{
return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
}
valid_num_media_times_per_channel = media_times_per_channel[0];
for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh )
{
if ( media_times_per_channel[iCh] == invalid_value )
{
break;
}
if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] )
{
return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
}
}
}
{
/* whether all media times exist for each channel */
int32_t iMediaTime;
int32_t valid_num_channels_per_media_time;
if ( channels_per_media_time[0] == invalid_value )
{
return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
}
valid_num_channels_per_media_time = channels_per_media_time[0];
for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime )
{
if ( channels_per_media_time[iMediaTime] == invalid_value )
{
break;
}
if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] )
{
return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
}
}
}
/* convert zero-index to count */
payload->num_channels = channels_per_media_time[0] + 1;
payload->num_media_times = media_times_per_channel[0] + 1;
/* verify that all media times have the same number of channels, partial packets are not supported */
if ( payload->num_ftds != payload->num_channels * payload->num_media_times )
{
return LC3PLUS_RTP_ERR_GENERIC_ERROR;
}
return LC3PLUS_RTP_ERR_NO_ERROR;
}
LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled )
{
if ( NULL == bwr )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
switch ( sampling_rate )
{
case 8000:
if ( high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_NB;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 16000:
if ( high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_WB;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 24000:
if ( high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_SSWB;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 32000:
if ( high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_SWB;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 44100:
if ( high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_FBCD;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 48000:
if ( 0 == high_res_enabled )
{
*bwr = LC3PLUS_RTP_FTD_BWR_FB;
return LC3PLUS_RTP_ERR_NO_ERROR;
}
else
{
*bwr = LC3PLUS_RTP_FTD_BWR_FBHR;
return LC3PLUS_RTP_ERR_NO_ERROR;
}
case 96000:
if ( 0 == high_res_enabled )
{
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
*bwr = LC3PLUS_RTP_FTD_BWR_UBHR;
return LC3PLUS_RTP_ERR_NO_ERROR;
default:
break;
}
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us )
{
if ( NULL == fdi )
{
return LC3PLUS_RTP_ERR_NULL_PTR;
}
switch ( frame_duration_us )
{
case 2500:
*fdi = LC3PLUS_RTP_FTD_FDI_2500_US;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 5000:
*fdi = LC3PLUS_RTP_FTD_FDI_5000_US;
return LC3PLUS_RTP_ERR_NO_ERROR;
case 10000:
*fdi = LC3PLUS_RTP_FTD_FDI_10000_US;
return LC3PLUS_RTP_ERR_NO_ERROR;
default:
break;
}
return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
}
#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */
#endif /* SPLIT_REND_WITH_HEAD_ROT */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef ISAR_LC3PLUS_PAYLOAD_H
#define ISAR_LC3PLUS_PAYLOAD_H
#include <stdint.h>
#include <stddef.h>
#include "lc3.h"
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format
* for LC3plus as specified in ETSI TS 103 634. */
typedef enum LC3PLUS_RTP_ERR
{
LC3PLUS_RTP_ERR_NO_ERROR,
LC3PLUS_RTP_ERR_NULL_PTR,
LC3PLUS_RTP_ERR_INVALID_PARAMETERS,
LC3PLUS_RTP_ERR_EMPTY_TOC,
LC3PLUS_RTP_ERR_NOT_IMPLEMENTED,
LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION,
LC3PLUS_RTP_ERR_INVALID_BITSTREAM,
LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE,
LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED,
LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST,
LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES,
LC3PLUS_RTP_ERR_GENERIC_ERROR
} LC3PLUS_RTP_ERR;
/*
* The content of the FTD is shown in Figure B.6.
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/* FC (2 bits):
* Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC
* indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments
* of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent
* FTD (if available). */
typedef enum LC3PLUS_RTP_FTD_FC
{
LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */
LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */
LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */
LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */
} LC3PLUS_RTP_FTD_FC;
#define LC3PLUS_RTP_FTD_FC_MASK 0x03
/* FDI (2 bits):
* Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given
* payload type during the session. The FDI also dictates the TSI, needed for deriving the media
* time in case of more than one frame in the payload. */
typedef enum LC3PLUS_RTP_FTD_FDI
{
LC3PLUS_RTP_FTD_FDI_2500_US = 0x00,
LC3PLUS_RTP_FTD_FDI_5000_US = 0x04,
LC3PLUS_RTP_FTD_FDI_10000_US = 0x08,
LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C,
} LC3PLUS_RTP_FTD_FDI;
#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C
LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us );
/* BWR (3 bits):
* Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and
* resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is
* defined in Table B.4. The BWR index shall be static for a given payload type during the session. */
typedef enum LC3PLUS_RTP_FTD_BWR
{
LC3PLUS_RTP_FTD_BWR_NB = 0x00,
LC3PLUS_RTP_FTD_BWR_WB = 0x10,
LC3PLUS_RTP_FTD_BWR_SSWB = 0x20,
LC3PLUS_RTP_FTD_BWR_SWB = 0x30,
LC3PLUS_RTP_FTD_BWR_FBCD = 0x40,
LC3PLUS_RTP_FTD_BWR_FB = 0x50,
LC3PLUS_RTP_FTD_BWR_FBHR = 0x60,
LC3PLUS_RTP_FTD_BWR_UBHR = 0x70,
} LC3PLUS_RTP_FTD_BWR;
#define LC3PLUS_RTP_FTD_BWR_MASK 0x70
LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled );
/* H (1 bit):
* Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame
* (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */
typedef enum LC3PLUS_RTP_FTD_H
{
LC3PLUS_RTP_FTD_H_PRIMARY = 0x00,
LC3PLUS_RTP_FTD_H_SECONDARY = 0x80,
} LC3PLUS_RTP_FTD_H;
#define LC3PLUS_RTP_FTD_H_MASK 0x80
typedef enum LC3PLUS_RTP_FDL
{
LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0,
LC3PLUS_RTP_FDL_SPEECH_BAD = 1,
LC3PLUS_RTP_FDL_SPEECH_SID = 2,
LC3PLUS_RTP_FDL_RESERVED_MIN = 3,
LC3PLUS_RTP_FDL_RESERVED_MAX = 19,
LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20,
LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254,
LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255,
LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509,
LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510,
LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765
} LC3PLUS_RTP_FDL;
/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */
#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF
typedef struct LC3PLUS_RTP_FTD
{
LC3PLUS_RTP_FTD_FC fc;
LC3PLUS_RTP_FTD_FDI fdi;
LC3PLUS_RTP_FTD_BWR bwr;
LC3PLUS_RTP_FTD_H h;
uint8_t *frame_data;
LC3PLUS_RTP_FDL frame_data_length;
} LC3PLUS_RTP_FTD;
#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1
#define LC3PLUS_RTP_FDL_MIN_LENGTH 1
#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH )
/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer
* @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to
* @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes
* @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity)
* @param[in] fdl_request frame data length request
* @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in
* the packed_buffer (so it can subsequently be used as input for the LC3plus encode call)
* @param[in] sender_ftds_num number of sender_ftds
* @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize(
uint8_t *serialized_buffer,
const size_t serialized_buffer_capacity,
size_t *packed_buffer_actual_size,
const LC3PLUS_RTP_FDL fdl_request,
LC3PLUS_RTP_FTD *sender_ftds,
const size_t sender_ftds_num );
/*! Get size of the frame data length field for a certain frame data length value in bytes.
* @param[out] length size of the frame data length field in bytes [1,2,3]
* @param[in] frameDataLengthValue frame data length value
* @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue );
#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16
#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */
#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES
typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG
{
/* frame duration in us shared among all FTDs */
int32_t frame_duration_us;
/* high resolution flag shared among all FTDs */
int16_t high_resolution_enabled;
/* sampling frequency shared among all FTDs */
int32_t sampling_rate_hz;
/* number of individual channels in the payload */
int16_t num_channels;
/* number of individual media times in the payload */
int16_t num_media_times;
/* frame data length request */
LC3PLUS_RTP_FDL fdl_request;
/* FTD data with pointer to raw frame data */
LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS];
/* actual number of ftds */
int16_t num_ftds;
} LC3PLUS_RTP_PAYLOAD;
/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct
* @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer.
* @param serialized_buffer pointer to the start of the serialized input buffer
* @param serialized_buffer_size size of the serialized input buffer in bytes
* @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize(
LC3PLUS_RTP_PAYLOAD *payload,
uint8_t *serialized_buffer,
const size_t serialized_buffer_size );
#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */
#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */
#endif /* ISAR_LC3PLUS_PAYLOAD_H */
......@@ -33,11 +33,11 @@
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "ivas_lcld_prot.h"
#include "ivas_lcld_rom_tables.h"
#include "isar_lcld_prot.h"
#include "isar_rom_lcld_tables.h"
#include "prot.h"
#include <assert.h>
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "wmc_auto.h"
......@@ -93,6 +93,7 @@ struct LCLD_DECODER
int32_t ***pppiAlloc;
int32_t iAllocOffset;
int32_t iRealOnlyOut;
int32_t ***pppiLCLDSignReal;
int32_t ***pppiLCLDSignImag;
......@@ -105,14 +106,14 @@ struct LCLD_DECODER
NoiseGen *psNoiseGen;
};
static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables );
static TableNode *CreateTableList( int32_t iReadLength );
static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables );
static TableNode *CreateTableList( const int32_t iReadLength );
static void DeleteTableList( TableList *ptable_list, int32_t iTables );
static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated );
static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables );
static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated );
static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated );
static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables );
static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated );
static TableNode *CreateTableList( int32_t iReadLength )
static TableNode *CreateTableList( const int32_t iReadLength )
{
int32_t n;
int32_t iMaxTables;
......@@ -172,7 +173,7 @@ static void DeleteTableList( TableList *ptable_list, int32_t iTables )
free( ptable_list );
}
}
static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated )
static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated )
{
TableNode *poNextNode;
......@@ -193,7 +194,7 @@ static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode
return poNextNode;
}
static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated )
static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated )
{
int32_t iMaxTables;
......@@ -202,7 +203,7 @@ static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *pt
iMaxTables = 1 << iReadLength;
psLCLDDecoder->c_apauiHuffDecTable_RAM[n] =
malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) );
malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) );
poNode = ptable_list->poOrderedTop;
for ( j = 0; j < iTablesCreated; j++ )
......@@ -222,7 +223,7 @@ static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *pt
poNode = poNode->poOrderedNext;
}
}
static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables )
static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables )
{
int32_t iDifference;
int32_t iMask;
......@@ -257,7 +258,7 @@ static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t i
}
}
static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables )
static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables )
{
int32_t n;
uint32_t **ppsort_enc_table;
......@@ -345,7 +346,8 @@ ivas_error CreateLCLDDecoder(
LCLDDecoder **psLCLDDecoder_out,
const int32_t iSampleRate,
const int32_t iChannels,
const int32_t iNumBlocks )
const int32_t iNumBlocks,
const int32_t iRealOnlyOut )
{
int32_t n;
int32_t read_length;
......@@ -360,9 +362,16 @@ ivas_error CreateLCLDDecoder(
}
psLCLDDecoder->iSampleRate = iSampleRate;
psLCLDDecoder->iChannels = iChannels;
psLCLDDecoder->iNumBlocks = iNumBlocks;
psLCLDDecoder->iAllocOffset = 0;
psLCLDDecoder->iRealOnlyOut = iRealOnlyOut;
if ( iRealOnlyOut == 1 )
{
psLCLDDecoder->iNumBlocks = iNumBlocks / 2;
}
else
{
psLCLDDecoder->iNumBlocks = iNumBlocks;
}
psLCLDDecoder->iNumBands = 0; /* read from bitstream*/
psLCLDDecoder->piBandwidths = c_aiBandwidths48;
......@@ -702,23 +711,108 @@ static void InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGrou
static void InvMSCoding( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag );
static int32_t ReadHeaderInformation( int32_t *piNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadHeaderInformation( int32_t *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ReadAllocInformation( int32_t *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t
ReadLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] );
ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiDecodingUnresolved, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] );
static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiSMR, const int32_t iAllocOffset, int32_t ***pppiAlloc );
void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder )
{
int32_t n, ch;
PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
{
for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
{
psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1;
psPredictionDecoder->ppiDecodingFailed[ch][n] = 1;
psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1;
}
}
}
int32_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder )
{
int32_t n, ch;
PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
{
for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
{
if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 )
{
return 1;
}
}
}
return 0;
}
int32_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder )
{
int32_t n, ch;
PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
{
for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
{
if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 )
{
return 1;
}
}
}
return 0;
}
int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder )
{
return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed;
}
int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder )
{
return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets;
}
int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder )
{
return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev;
}
static void UnpackReal(
const int32_t iChannels,
const int32_t iNumBlocks,
float ***pppfReal,
float ***pppfImag )
{
int32_t ch, b, n;
for ( ch = 0; ch < iChannels; ch++ )
{
for ( b = 0; b < LCLD_BANDS; b++ )
{
int32_t iRealBlock = iNumBlocks - 1;
for ( n = iNumBlocks / 2 - 1; n >= 0; n-- )
{
pppfReal[ch][iRealBlock][b] = pppfImag[ch][n][b] * 2.0f;
pppfReal[ch][iRealBlock - 1][b] = pppfReal[ch][n][b] * 2.0f;
pppfImag[ch][iRealBlock][b] = 0.0f;
pppfImag[ch][iRealBlock - 1][b] = 0.0f;
iRealBlock -= 2;
}
}
}
}
/*------------------------------------------------------------------------------------------*
* Function DecodeLCLDFrame()
......@@ -728,7 +822,7 @@ static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGrou
int32_t DecodeLCLDFrame(
LCLDDecoder *psLCLDDecoder,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
float ***pppfLCLDReal,
float ***pppfLCLDImag )
{
......@@ -742,6 +836,8 @@ int32_t DecodeLCLDFrame(
}
ReadPredictors( psLCLDDecoder->psPredictionDecoder, pBits );
UpdateDecodingUnresolved( psLCLDDecoder->psPredictionDecoder );
UpdateDecodingFailedStatus( psLCLDDecoder->psPredictionDecoder );
ReadGroupInformation( psLCLDDecoder->iChannels, psLCLDDecoder->iNumBlocks, &psLCLDDecoder->iCommonGrouping, psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, pBits );
......@@ -776,20 +872,23 @@ int32_t DecodeLCLDFrame(
ComputeAllocation( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc );
for ( n = 0; n < psLCLDDecoder->iChannels; n++ )
{
ReadLCLDData(
psLCLDDecoder->piNumGroups[n],
(const int32_t *) psLCLDDecoder->ppiGroupLengths[n],
psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths,
(const int32_t *)
psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n],
psLCLDDecoder->pppiAlloc[n],
psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n],
psLCLDDecoder->pppiQLCLDReal[n], psLCLDDecoder->pppiQLCLDImag[n],
psLCLDDecoder->piNumGroups,
psLCLDDecoder->ppiGroupLengths,
psLCLDDecoder->iNumBands,
psLCLDDecoder->iChannels,
psLCLDDecoder->psPredictionDecoder->ppiDecodingUnresolved,
psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable,
psLCLDDecoder->psPredictionDecoder->iNumSubSets,
psLCLDDecoder->psPredictionDecoder->iSubSetId,
psLCLDDecoder->pppiAlloc,
psLCLDDecoder->pppiLCLDSignReal,
psLCLDDecoder->pppiLCLDSignImag,
psLCLDDecoder->pppiQLCLDReal,
psLCLDDecoder->pppiQLCLDImag,
psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed,
pBits,
psLCLDDecoder->c_apauiHuffDecTable_RAM );
}
for ( n = 0; n < psLCLDDecoder->iChannels; n++ )
{
......@@ -843,7 +942,15 @@ int32_t DecodeLCLDFrame(
pppfLCLDReal, pppfLCLDImag );
}
return 0;
if ( psLCLDDecoder->iRealOnlyOut == 1 )
{
UnpackReal( psLCLDDecoder->iChannels,
psLCLDDecoder->iNumBlocks * 2,
pppfLCLDReal,
pppfLCLDImag );
}
return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder );
}
......@@ -1051,7 +1158,7 @@ static void InvMSCoding(
if ( iMSMode == 3 )
{
cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] );
cplxmult_lcld( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] );
}
pppfReal[0][k][iFBOffset] = fLeftReal;
......@@ -1077,12 +1184,12 @@ static void InvMSCoding(
/* Currently only the number of bands in frame */
static int32_t ReadHeaderInformation(
int32_t *piNumBands,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsRead;
iBitsRead = 0;
*piNumBands = ivas_split_rend_bitstream_read_int32( pBits, 5 );
*piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 );
iBitsRead += 5;
return iBitsRead;
......@@ -1095,12 +1202,12 @@ static int32_t ReadMSInformation(
int32_t *piMSFlags,
int32_t *piLRPhaseDiffs,
int32_t *piMSPredCoefs,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsRead;
iBitsRead = 0;
*piMSMode = ivas_split_rend_bitstream_read_int32( pBits, 2 );
*piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 );
iBitsRead += 2;
if ( *piMSMode == 0 )
......@@ -1124,7 +1231,7 @@ static int32_t ReadMSInformation(
int32_t n;
for ( n = 0; n < iNumBands; n++ )
{
piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 );
piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
}
}
......@@ -1134,7 +1241,7 @@ static int32_t ReadMSInformation(
int32_t iMSPredAll;
int32_t iNumMSPredBands = 0;
int32_t anyNonZero;
iMSPredAll = ivas_split_rend_bitstream_read_int32( pBits, 1 );
iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( iMSPredAll )
{
......@@ -1148,7 +1255,7 @@ static int32_t ReadMSInformation(
{
for ( n = 0; n < iNumBands; n++ )
{
piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 );
piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( piMSFlags[n] )
{
......@@ -1156,10 +1263,10 @@ static int32_t ReadMSInformation(
}
}
}
anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 );
anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
if ( anyNonZero )
{
piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS );
piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS );
piLRPhaseDiffs[0] += PHASE_MIN_VAL;
iBitsRead += PHASE_BAND0_BITS;
for ( n = 1; n < iNumMSPredBands; n++ )
......@@ -1177,10 +1284,10 @@ static int32_t ReadMSInformation(
piLRPhaseDiffs[n] = 0;
}
}
anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 );
anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
if ( anyNonZero )
{
piMSPredCoefs[0] = ivas_split_rend_bitstream_read_int32( pBits, PRED_BAND0_BITS );
piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS );
piMSPredCoefs[0] += PRED_MIN_VAL;
iBitsRead += PRED_BAND0_BITS;
for ( n = 1; n < iNumMSPredBands; n++ )
......@@ -1221,14 +1328,14 @@ static int32_t ReadGroupInformation(
int32_t *piCommonGrouping,
int32_t *piNumGroups,
int32_t **ppiGroupLengths,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t c, k, iBitsRead;
iBitsRead = 0;
if ( iChannels == 2 )
{
*piCommonGrouping = ivas_split_rend_bitstream_read_int32( pBits, 1 );
*piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( *piCommonGrouping == 1 )
......@@ -1239,7 +1346,7 @@ static int32_t ReadGroupInformation(
{
int32_t iGroupStart;
iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 );
iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( iGroupStart == 1 )
......@@ -1270,7 +1377,7 @@ static int32_t ReadGroupInformation(
{
int32_t iGroupStart;
iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 );
iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( iGroupStart == 1 )
......@@ -1297,7 +1404,7 @@ static int32_t ReadGroupInformation(
{
int32_t iGroupStart;
iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 );
iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
if ( iGroupStart == 1 )
......@@ -1319,7 +1426,7 @@ static int32_t ReadGroupInformation(
static int32_t BSForceBack(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
int32_t iValue,
int32_t iBitCount )
{
......@@ -1332,7 +1439,7 @@ static int32_t BSForceBack(
static int32_t ReadHuff(
const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE],
int32_t *piSymbol,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsRead;
int32_t iSymbol;
......@@ -1345,7 +1452,7 @@ static int32_t ReadHuff(
iBitsRead = 0;
while ( iSymbol == 0xFFFF )
{
iIndex = ivas_split_rend_bitstream_read_int32( pBits, HUFF_READ_SIZE );
iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE );
iBitsRead += HUFF_READ_SIZE;
iIndex = pauiHuffDecTable[iVal][iIndex];
......@@ -1371,7 +1478,7 @@ static int32_t ReadRMSEnvelope(
const int32_t *piNumGroups,
const int32_t iNumBands,
int32_t ***pppiRMSEnvelope,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t b, k, n;
int32_t iBitsRead, iLastRMSVal;
......@@ -1381,7 +1488,7 @@ static int32_t ReadRMSEnvelope(
{
for ( k = 0; k < piNumGroups[n]; k++ )
{
iLastRMSVal = ivas_split_rend_bitstream_read_int32( pBits, ENV0_BITS );
iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS );
iBitsRead += ENV0_BITS;
iLastRMSVal += ENV_MIN;
......@@ -1405,12 +1512,12 @@ static int32_t ReadRMSEnvelope(
static int32_t ReadAllocInformation(
int32_t *piAllocOffset,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsRead;
iBitsRead = 0;
*piAllocOffset = ivas_split_rend_bitstream_read_int32( pBits, ALLOC_OFFSET_BITS );
*piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS );
*piAllocOffset += MIN_ALLOC_OFFSET;
iBitsRead += ALLOC_OFFSET_BITS;
......@@ -1418,67 +1525,102 @@ static int32_t ReadAllocInformation(
}
static int32_t ReadLCLDData(
const int32_t iNumGroups,
const int32_t *piGroupLengths,
const int32_t *piNumGroups,
int32_t **ppiGroupLengths,
const int32_t iNumBands,
const int32_t *piBandwidths,
const int32_t *piPredEnable,
int32_t **ppiAlloc,
int32_t **ppiSignReal,
int32_t **ppiSignImag,
int32_t **ppiQReal,
int32_t **ppiQImag,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
const int32_t iNumChannels,
int32_t **ppiDecodingUnresolved,
int32_t **ppiPredEnable,
const int32_t iNumSubSets,
const int32_t iSubSetId,
int32_t ***pppiAlloc,
int32_t ***pppiSignReal,
int32_t ***pppiSignImag,
int32_t ***pppiQReal,
int32_t ***pppiQImag,
int32_t **ppiDecodingFailed,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] )
{
int32_t b, k, m, n;
int32_t iBitsRead, iBlockOffest, iFBOffset;
int32_t iAlloc, iHuffDim, iHuffMod;
int32_t iBitsRead;
int32_t iDecodingStopped = 0;
int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1];
int32_t s;
int32_t iSet = iSubSetId;
iBitsRead = 0;
for ( s = 0; s < iNumSubSets; s++, iSet-- )
{
int32_t ch;
if ( iSet < 0 )
{
iSet = iNumSubSets - 1;
}
for ( ch = 0; ch < iNumChannels; ch++ )
{
int32_t n;
int32_t iBlockOffest;
if ( ppiDecodingUnresolved[ch][iSet] == 1 )
{
iDecodingStopped = 1;
ppiDecodingFailed[ch][iSet] = 1; /* mark as not decoded (is also initialized like that when a frame is lost */
}
else
{
ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */
}
iBlockOffest = 0;
for ( n = 0; n < iNumGroups; n++ )
for ( n = 0; n < piNumGroups[ch]; n++ )
{
for ( k = 0; k < piGroupLengths[n]; k++ )
int32_t k;
for ( k = 0; k < ppiGroupLengths[ch][n]; k++ )
{
iFBOffset = 0;
for ( b = 0; b < iNumBands; b++ )
int32_t iFBOffset;
for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets )
{
iAlloc = ppiAlloc[n][b];
int32_t b;
int32_t iAlloc;
int32_t iHuffDim;
int32_t iHuffMod;
b = c_aiBandIdPerLcldBand[iFBOffset];
iAlloc = pppiAlloc[ch][n][b];
iHuffDim = c_aiHuffmanDim[iAlloc];
iHuffMod = c_aiHuffmanMod[iAlloc];
if ( iAlloc > 0 )
if ( iDecodingStopped == 1 )
{
pppiQReal[ch][iBlockOffest][iFBOffset] = 0;
pppiQImag[ch][iBlockOffest][iFBOffset] = 0;
pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
}
else if ( iAlloc > 0 )
{
const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL;
const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL;
#ifdef USE_DEMOD_TABLES
const int32_t( *paiDemodTable )[2] = NULL;
#endif
int32_t iQuantValue1 = 0;
int32_t iQuantValue2 = 0;
pauiHuffmanTable = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc];
pauiHuffmanTableDPCM = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc];
#ifdef USE_DEMOD_TABLES
paiDemodTable = c_apaiDemodTables[iAlloc];
#ifdef LCLD_HANDLE_PRED_START_SAMPLE
if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) )
#else
if ( ppiPredEnable[ch][iFBOffset] == 1 )
#endif
for ( m = 0; m < piBandwidths[b]; m++ )
{
int32_t iQuantValue1 = 0;
int32_t iQuantValue2 = 0;
if ( piPredEnable[iFBOffset] == 1 )
{
if ( iHuffDim == 2 )
{
int32_t iSymbol;
iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits );
#ifdef USE_DEMOD_TABLES
iQuantValue1 = paiDemodTable[iSymbol][0];
iQuantValue2 = paiDemodTable[iSymbol][1];
#else
iQuantValue1 = iSymbol / iHuffMod;
iQuantValue2 = iSymbol % iHuffMod;
#endif
}
else
{
......@@ -1493,13 +1635,8 @@ static int32_t ReadLCLDData(
int32_t iSymbol;
iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits );
#ifdef USE_DEMOD_TABLES
iQuantValue1 = paiDemodTable[iSymbol][0];
iQuantValue2 = paiDemodTable[iSymbol][1];
#else
iQuantValue1 = iSymbol / iHuffMod;
iQuantValue2 = iSymbol % iHuffMod;
#endif
}
else
{
......@@ -1508,50 +1645,43 @@ static int32_t ReadLCLDData(
}
}
ppiQReal[iBlockOffest][iFBOffset] = iQuantValue1;
ppiQImag[iBlockOffest][iFBOffset] = iQuantValue2;
pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1;
pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2;
if ( iQuantValue1 > 0 )
{
ppiSignReal[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 );
pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
}
else
{
ppiSignReal[iBlockOffest][iFBOffset] = 0;
pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
}
if ( iQuantValue2 > 0 )
{
ppiSignImag[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 );
pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
iBitsRead += 1;
}
else
{
ppiSignImag[iBlockOffest][iFBOffset] = 0;
}
iFBOffset++;
pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
}
}
else
{
for ( m = 0; m < piBandwidths[b]; m++ )
{
ppiSignReal[iBlockOffest][iFBOffset] = 0;
ppiSignImag[iBlockOffest][iFBOffset] = 0;
iFBOffset++;
}
pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
}
}
iBlockOffest++;
}
}
}
}
return iBitsRead;
}
static void ComputeAllocation(
const int32_t iChannels,
const int32_t *piNumGroups,
......
......@@ -35,10 +35,8 @@
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <math.h>
#include <assert.h>
#include "ivas_lcld_prot.h"
#include "ivas_lcld_rom_tables.h"
#include "prot.h"
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "wmc_auto.h"
/*------------------------------------------------------------------------------------------*
......@@ -62,6 +60,7 @@ struct LCLD_ENCODER
int32_t piLRPhaseDiffs[MAX_BANDS];
int32_t iAllowSidePred;
int32_t iRealOnlyOut;
RMSEnvelopeGrouping *psRMSEnvelopeGrouping;
......@@ -136,6 +135,28 @@ static float UnQuantize(
return fVal;
}
static void PackReal(
const int32_t iChannels,
const int32_t iNumBlocks,
float ***pppfReal,
float ***pppfImag )
{
int32_t ch, b, n;
for ( ch = 0; ch < iChannels; ch++ )
{
for ( b = 0; b < LCLD_BANDS; b++ )
{
int32_t iRealBlock = 0;
for ( n = 0; n < iNumBlocks; n += 2 )
{
pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b];
pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b];
iRealBlock++;
}
}
}
}
/*------------------------------------------------------------------------------------------*
* Function CreateLCLDEncoder()
*
......@@ -149,14 +170,15 @@ ivas_error CreateLCLDEncoder(
const int32_t iTargetBitRate,
const int32_t iAllowSidePred,
const int16_t iNumBlocks,
const int16_t iNumSubSets )
const int16_t iNumSubSets,
const int32_t iRealOnlyOut )
{
int32_t n;
LCLDEncoder *psLCLDEncoder;
ivas_error error;
int32_t iMaxNumPredBands = 0;
assert( iSampleRate == 48000 ); // Fix
assert( iSampleRate == 48000 );
assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 );
assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS );
......@@ -167,19 +189,24 @@ ivas_error CreateLCLDEncoder(
psLCLDEncoder->iSampleRate = iSampleRate;
psLCLDEncoder->iChannels = iChannels;
psLCLDEncoder->iNumBlocks = (int32_t) iNumBlocks;
psLCLDEncoder->iRealOnlyOut = iRealOnlyOut;
psLCLDEncoder->iAllocOffset = 0;
psLCLDEncoder->iTargetBitRate = iTargetBitRate;
psLCLDEncoder->piBandwidths = c_aiBandwidths48;
psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */
for ( n = 0; n < psLCLDEncoder->iNumBands; n++ )
iMaxNumPredBands = min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 );
if ( iRealOnlyOut == 1 )
{
iMaxNumPredBands += psLCLDEncoder->piBandwidths[n];
iMaxNumPredBands = 0;
assert( iNumSubSets == 1 );
psLCLDEncoder->iNumBlocks = iNumBlocks / 2;
}
else
{
psLCLDEncoder->iNumBlocks = iNumBlocks;
}
psLCLDEncoder->iMSMode = 0;
if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL )
{
......@@ -192,10 +219,9 @@ ivas_error CreateLCLDEncoder(
psLCLDEncoder->piMSPredCoefs[n] = 0;
}
psLCLDEncoder->iAllowSidePred = iAllowSidePred;
psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks );
psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */
psLCLDEncoder->iCommonGrouping = 1; /*Common grouping always on only impacts stereo */
if ( ( psLCLDEncoder->piNumGroups = (int32_t *) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
......@@ -505,23 +531,23 @@ void DeleteLCLDEncoder(
* Local function declarations
*------------------------------------------------------------------------------------------*/
static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, int32_t *piMSFlags );
static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, const int32_t iRealOnlyOut, int32_t *piMSFlags );
static void RemoveRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag );
static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag );
static int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteHeaderInformation( const int32_t iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteAllocInformation( const int32_t iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits );
static int32_t WriteLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits );
static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder );
......@@ -537,15 +563,22 @@ int32_t EncodeLCLDFrame(
float ***pppfLCLDImag,
int32_t *piBitsWritten,
const int32_t available_bits,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t n;
int32_t iAvailableBits, iBitsWritten;
int32_t iNumMSBands = 0;
iAvailableBits = available_bits; // HCBR for now
int32_t iAudioBitsWritten;
iAvailableBits = available_bits; /* HCBR for now*/
iBitsWritten = 0;
assert( available_bits <= pBits->buf_len * 8 );
if ( psLCLDEncoder->iRealOnlyOut == 1 )
{
PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal, pppfLCLDImag );
}
/* Do MS calc here */
if ( psLCLDEncoder->iChannels == 2 )
{
......@@ -558,11 +591,12 @@ int32_t EncodeLCLDFrame(
psLCLDEncoder->piLRPhaseDiffs,
psLCLDEncoder->piMSPredCoefs,
psLCLDEncoder->iAllowSidePred,
psLCLDEncoder->iRealOnlyOut,
psLCLDEncoder->piMSFlags );
if ( psLCLDEncoder->iMSMode > 0 )
{
psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use
psLCLDEncoder->iCommonGrouping = 1; /* Make sure common grouping is enabled when MS is in use */
}
}
......@@ -699,36 +733,26 @@ int32_t EncodeLCLDFrame(
iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset,
pBits );
for ( n = 0; n < psLCLDEncoder->iChannels; n++ )
{
iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups[n],
(const int32_t *) psLCLDEncoder->ppiGroupLengths[n],
iAudioBitsWritten = iBitsWritten;
iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups,
psLCLDEncoder->ppiGroupLengths,
psLCLDEncoder->iNumBands,
psLCLDEncoder->piBandwidths,
(const int32_t *) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n],
psLCLDEncoder->pppiAlloc[n],
psLCLDEncoder->pppiLCLDSignReal[n],
psLCLDEncoder->pppiLCLDSignImag[n],
psLCLDEncoder->pppiQLCLDReal[n],
psLCLDEncoder->pppiQLCLDImag[n],
psLCLDEncoder->iChannels,
psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable,
psLCLDEncoder->psPredictionEncoder->iNumSubSets,
psLCLDEncoder->psPredictionEncoder->iSubSetId,
psLCLDEncoder->pppiAlloc,
psLCLDEncoder->pppiLCLDSignReal,
psLCLDEncoder->pppiLCLDSignImag,
psLCLDEncoder->pppiQLCLDReal,
psLCLDEncoder->pppiQLCLDImag,
pBits );
}
*piBitsWritten = iBitsWritten;
iAudioBitsWritten = iBitsWritten - iAudioBitsWritten;
return 0;
}
UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder );
/*------------------------------------------------------------------------------------------*
* Function GetNumGroups()
*
*
*------------------------------------------------------------------------------------------*/
int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder )
{
return psLCLDEncoder->piNumGroups[0];
return 0;
}
......@@ -763,6 +787,7 @@ static int32_t MSModeCalculation(
int32_t *piLRPhaseDiffs,
int32_t *piMSPredCoefs,
const int32_t iAllowSidePred,
const int32_t iRealOnlyOut,
int32_t *piMSFlags )
{
int32_t b;
......@@ -770,25 +795,39 @@ static int32_t MSModeCalculation(
int32_t iNumMSBands;
int32_t iMSPredType;
float fMSBitGain = 0.0f;
float pfMSPredBitGain[3] = { 0.0f };
float pfMSPredBitGain[3];
float fPred;
int32_t piMSPredFlags0[MAX_BANDS] = { 0 };
int32_t piMSPredFlags1[MAX_BANDS] = { 0 };
int32_t piMSPredFlags2[MAX_BANDS] = { 0 };
int32_t piMSPredFlags0[MAX_BANDS];
int32_t piMSPredFlags1[MAX_BANDS];
int32_t piMSPredFlags2[MAX_BANDS];
int32_t *ppiMSPredFlags[3];
int32_t piMSPredCoefs0[MAX_BANDS] = { 0 };
int32_t piMSPredCoefs1[MAX_BANDS] = { 0 };
int32_t piMSPredCoefs2[MAX_BANDS] = { 0 };
int32_t piMSPredCoefs0[MAX_BANDS];
int32_t piMSPredCoefs1[MAX_BANDS];
int32_t piMSPredCoefs2[MAX_BANDS];
int32_t *ppiMSPredCoefs[3];
int32_t piMSPredPhase0[MAX_BANDS] = { 0 };
int32_t piMSPredPhase1[MAX_BANDS] = { 0 };
int32_t piMSPredPhase2[MAX_BANDS] = { 0 };
int32_t piMSPredPhase0[MAX_BANDS];
int32_t piMSPredPhase1[MAX_BANDS];
int32_t piMSPredPhase2[MAX_BANDS];
int32_t *ppiMSPredPhase[3];
int32_t iMsInfoBits;
int32_t piMsPredInfoBits[3] = { 0 };
int32_t piMsPredInfoBits[3];
const float feps = 1e-12f;
float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */
set_zero( pfMSPredBitGain, 3 );
set_l( piMsPredInfoBits, 0, 3 );
set_l( piMSPredFlags0, 0, MAX_BANDS );
set_l( piMSPredFlags1, 0, MAX_BANDS );
set_l( piMSPredFlags2, 0, MAX_BANDS );
set_l( piMSPredCoefs0, 0, MAX_BANDS );
set_l( piMSPredCoefs1, 0, MAX_BANDS );
set_l( piMSPredCoefs2, 0, MAX_BANDS );
set_l( piMSPredPhase0, 0, MAX_BANDS );
set_l( piMSPredPhase1, 0, MAX_BANDS );
set_l( piMSPredPhase2, 0, MAX_BANDS );
if ( iNumBlocks < LCLD_BLOCKS_PER_FRAME )
{
fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */
......@@ -826,7 +865,7 @@ static int32_t MSModeCalculation(
int32_t iPhase;
int32_t iPred;
int32_t tabIdx = 0;
float fNumLines = (float) ( iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */
float fNumLines = (float) ( iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */
float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */
fLeftEnergy = 0.0f;
fRightEnergy = 0.0f;
......@@ -880,7 +919,7 @@ static int32_t MSModeCalculation(
/* adjust covariance */
tabIdx = iPhase - PHASE_MIN_VAL;
cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] );
cplxmult_lcld( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] );
/* compute MS prediction coefficient based on adjusted covariance */
fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal );
......@@ -942,9 +981,16 @@ static int32_t MSModeCalculation(
}
/* find the best M/S Pred type */
if ( iRealOnlyOut == 1 )
{
iMSPredType = MS_PRED_ONLY;
}
else
{
iMSPredType = MS_PHASE_AND_PRED;
iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType );
iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType );
}
/* plain M/S */
iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL );
......@@ -1013,7 +1059,7 @@ static int32_t MSModeCalculation(
if ( *piMSMode == MS_PRED )
{
cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] );
cplxmult_lcld( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] );
}
fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] );
......@@ -1120,9 +1166,9 @@ static void QuantizeSpectrumDPCM_Opt(
int32_t **ppiQImag,
int32_t **ppiSignReal,
int32_t **ppiSignImag,
int32_t iNumSubSets,
int32_t iSubSetId,
int32_t *piPredEnable,
const int32_t iNumSubSets,
const int32_t iSubSetId,
const int32_t *piPredEnable,
float *pfA1Real,
float *pfA1Imag,
float *pfPredStateReal,
......@@ -1314,12 +1360,12 @@ static int32_t CountLCLDBits(
/* Currently only the number of bands in frame */
static int32_t WriteHeaderInformation(
const int32_t iNumBands,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsWritten;
iBitsWritten = 0;
ivas_split_rend_bitstream_write_int32( pBits, iNumBands, 5 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 );
iBitsWritten += 5;
return iBitsWritten;
......@@ -1333,7 +1379,7 @@ static int32_t WriteMSInformation(
const int32_t *piLRPhaseDiff,
const int32_t *piMSPredCoef,
int32_t iNumMSPredBands,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsWritten;
int32_t iMSPredAll = ( iNumMSPredBands == iNumBands );
......@@ -1341,12 +1387,12 @@ static int32_t WriteMSInformation(
int32_t iBitsWrittenTmp = 0;
#endif
iBitsWritten = 0;
ivas_split_rend_bitstream_write_int32( pBits, iMSMode, 2 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 );
iBitsWritten += 2;
if ( iMSMode == 3 )
{
ivas_split_rend_bitstream_write_int32( pBits, iMSPredAll, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 );
iBitsWritten += 1;
}
......@@ -1355,7 +1401,7 @@ static int32_t WriteMSInformation(
int32_t n;
for ( n = 0; n < iNumBands; n++ )
{
ivas_split_rend_bitstream_write_int32( pBits, piMSFlags[n], 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 );
iBitsWritten += 1;
}
}
......@@ -1376,17 +1422,17 @@ static int32_t WriteMSInformation(
break;
}
}
ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
iBitsWritten++;
if ( anyNonZero )
{
ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS );
iBitsWritten += PHASE_BAND0_BITS;
for ( b = 1; b < iNumMSPredBands; b++ )
{
int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN;
ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0];
}
}
......@@ -1401,17 +1447,17 @@ static int32_t WriteMSInformation(
}
}
ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
iBitsWritten++;
if ( anyNonZero )
{
ivas_split_rend_bitstream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS );
iBitsWritten += PRED_BAND0_BITS;
for ( b = 1; b < iNumMSPredBands; b++ )
{
int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN;
ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0];
}
}
......@@ -1436,33 +1482,33 @@ static int32_t WriteGroupInformation(
const int32_t iCommonGrouping,
const int32_t *piNumGroups,
int32_t **ppiGroupLengths,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t c, k, n, iBitsWritten;
iBitsWritten = 0;
if ( iChannels == 2 && iCommonGrouping == 1 )
{
ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
iBitsWritten += 1;
for ( n = 0; n < piNumGroups[0]; n++ )
{
for ( k = 1; k < ppiGroupLengths[0][n]; k++ )
{
ivas_split_rend_bitstream_write_int32( pBits, 0, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
iBitsWritten += 1;
}
if ( n < ( piNumGroups[0] - 1 ) )
{
ivas_split_rend_bitstream_write_int32( pBits, 1, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
iBitsWritten += 1;
}
}
}
else if ( iChannels == 2 )
{
ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
iBitsWritten += 1;
for ( c = 0; c < iChannels; c++ )
......@@ -1471,12 +1517,12 @@ static int32_t WriteGroupInformation(
{
for ( k = 1; k < ppiGroupLengths[c][n]; k++ )
{
ivas_split_rend_bitstream_write_int32( pBits, 0, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
iBitsWritten += 1;
}
if ( n < ( piNumGroups[c] - 1 ) )
{
ivas_split_rend_bitstream_write_int32( pBits, 1, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
iBitsWritten += 1;
}
}
......@@ -1490,13 +1536,13 @@ static int32_t WriteGroupInformation(
{
for ( k = 1; k < ppiGroupLengths[c][n]; k++ )
{
ivas_split_rend_bitstream_write_int32( pBits, 0, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
iBitsWritten += 1;
}
if ( n < ( piNumGroups[c] - 1 ) )
{
ivas_split_rend_bitstream_write_int32( pBits, 1, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
iBitsWritten += 1;
}
}
......@@ -1512,7 +1558,7 @@ static int32_t WriteRMSEnvelope(
const int32_t *piNumGroups,
const int32_t iNumBands,
int32_t ***pppiRMSEnvelope,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t k, n;
int32_t iBitsWritten;
......@@ -1528,7 +1574,7 @@ static int32_t WriteRMSEnvelope(
iLastRMSVal = pppiRMSEnvelope[n][k][0];
iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN;
iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX;
ivas_split_rend_bitstream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS );
iBitsWritten += ENV0_BITS;
for ( b = 1; b < iNumBands; b++ )
......@@ -1539,7 +1585,7 @@ static int32_t WriteRMSEnvelope(
iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN;
iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX;
iDelta -= ENV_DELTA_MIN;
ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] );
iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0];
iLastRMSVal = pppiRMSEnvelope[n][k][b];
......@@ -1553,7 +1599,7 @@ static int32_t WriteRMSEnvelope(
static int32_t WriteAllocInformation(
const int32_t iAllocOffset,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsWritten;
......@@ -1564,50 +1610,61 @@ static int32_t WriteAllocInformation(
printf( "Serious error\n" );
}
ivas_split_rend_bitstream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS );
iBitsWritten += ALLOC_OFFSET_BITS;
return iBitsWritten;
}
static int32_t WriteLCLDData(
const int32_t iNumGroups,
const int32_t *piGroupLengths,
const int32_t *piNumGroups,
int32_t **ppiGroupLengths,
const int32_t iNumBands,
const int32_t *piBandwidths,
const int32_t *piPredEnable,
int32_t **ppiAlloc,
int32_t **ppiSignReal,
int32_t **ppiSignImag,
int32_t **ppiQReal,
int32_t **ppiQImag,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
const int32_t iNumChannels,
int32_t **ppiPredEnable,
const int32_t iNumSubSets,
const int32_t iSubSetId,
int32_t ***pppiAlloc,
int32_t ***pppiSignReal,
int32_t ***pppiSignImag,
int32_t ***pppiQReal,
int32_t ***pppiQImag,
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t n;
int32_t iBitsWritten;
int32_t iBlockOffest;
int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1];
int32_t s;
int32_t iSet = iSubSetId;
iBitsWritten = 0;
iBlockOffest = 0;
for ( s = 0; s < iNumSubSets; s++, iSet-- )
{
int32_t ch;
if ( iSet < 0 )
{
iSet = iNumSubSets - 1;
}
for ( n = 0; n < iNumGroups; n++ )
for ( ch = 0; ch < iNumChannels; ch++ )
{
int32_t iBlockOffest = 0;
int32_t n;
for ( n = 0; n < piNumGroups[ch]; n++ )
{
int32_t k;
for ( k = 0; k < piGroupLengths[n]; k++ )
for ( k = 0; k < ppiGroupLengths[ch][n]; k++ )
{
int32_t b;
int32_t iFBOffset;
iFBOffset = 0;
for ( b = 0; b < iNumBands; b++ )
for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets )
{
int32_t m;
int32_t b;
int32_t iAlloc;
int32_t iHuffDim;
int32_t iHuffMod;
iAlloc = ppiAlloc[n][b];
b = c_aiBandIdPerLcldBand[iFBOffset];
iAlloc = pppiAlloc[ch][n][b];
iHuffDim = c_aiHuffmanDim[iAlloc];
iHuffMod = c_aiHuffmanMod[iAlloc];
......@@ -1616,17 +1673,18 @@ static int32_t WriteLCLDData(
{
const uint16_t( *pauiHuffmanTable )[2] = NULL;
const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL;
pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
for ( m = 0; m < piBandwidths[b]; m++ )
{
int32_t iQuantValue1;
int32_t iQuantValue2;
pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset];
iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset];
if ( piPredEnable[iFBOffset] == 1 )
iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset];
iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset];
#ifdef LCLD_HANDLE_PRED_START_SAMPLE
if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) )
#else
if ( ppiPredEnable[ch][iFBOffset] == 1 )
#endif
{
if ( iHuffDim == 2 )
{
......@@ -1634,15 +1692,15 @@ static int32_t WriteLCLDData(
iSymbol = iQuantValue1;
iSymbol *= iHuffMod;
iSymbol += iQuantValue2;
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] );
iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0];
}
else
{
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] );
iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0];
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] );
iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0];
}
}
......@@ -1654,47 +1712,40 @@ static int32_t WriteLCLDData(
iSymbol = iQuantValue1;
iSymbol *= iHuffMod;
iSymbol += iQuantValue2;
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] );
iBitsWritten += pauiHuffmanTable[iSymbol][0];
}
else
{
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] );
iBitsWritten += pauiHuffmanTable[iQuantValue1][0];
ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] );
iBitsWritten += pauiHuffmanTable[iQuantValue2][0];
}
}
if ( iQuantValue1 > 0 )
{
ivas_split_rend_bitstream_write_int32( pBits, ppiSignReal[iBlockOffest][iFBOffset], 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 );
iBitsWritten += 1;
}
if ( iQuantValue2 > 0 )
{
ivas_split_rend_bitstream_write_int32( pBits, ppiSignImag[iBlockOffest][iFBOffset], 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 );
iBitsWritten += 1;
}
iFBOffset++;
}
}
else
{
iFBOffset += piBandwidths[b];
iBlockOffest++;
}
}
iBlockOffest++;
}
}
return iBitsWritten;
}
static int32_t ComputeAllocation(
const int32_t iChannels,
const int32_t *piNumGroups,
......@@ -1785,7 +1836,7 @@ static int32_t ComputeAllocation(
#ifdef DEBUG_VERBOSE
printf( "Frame can not be coded with the number of bits available\n" );
#endif
// iLastError = ENC_ERROR_STREAM_FAILURE;
/* iLastError = ENC_ERROR_STREAM_FAILURE;*/
return -1;
}
else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits )
......@@ -1828,16 +1879,14 @@ static int32_t ComputeAllocation(
mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS );
mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS );
}
if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets )
{
psPredictionEncoder->iSubSetId = 0;
}
}
// printf("%d\n",*piAllocOffset);
// printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]);
/*
printf("%d\n",*piAllocOffset);
printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]);
// printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed);
printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed);
*/
return iBitsUsed;
}
......
......@@ -30,13 +30,13 @@
*******************************************************************************************************/
#ifndef _IVAS_LCLD_ENCODER_H_
#define _IVAS_LCLD_ENCODER_H_
#ifndef ISAR_LCLD_PROT_H
#define ISAR_LCLD_PROT_H
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "lib_rend.h"
#include "ivas_lcld_rom_tables.h"
#include "common_api_types.h"
#include "isar_rom_lcld_tables.h"
/* clang-format off */
......@@ -49,7 +49,9 @@ ivas_error CreateLCLDEncoder(
const int32_t iTargetBitRate,
const int32_t iAllowSidePred,
const int16_t iNumBlocks,
const int16_t iNumSubSets );
const int16_t iNumSubSets,
const int32_t iRealOnlyOut
);
void DeleteLCLDEncoder(
LCLDEncoder *psLCLDEncoder
......@@ -61,11 +63,7 @@ int32_t EncodeLCLDFrame(
float ***pppfLCLDImag,
int32_t *piNumiBites,
const int32_t available_bits,
IVAS_SPLIT_REND_BITS_HANDLE pBits );
int32_t GetNumGroups(
LCLDEncoder *psLCLDEncoder
);
ISAR_SPLIT_REND_BITS_HANDLE pBits );
typedef struct LCLD_DECODER LCLDDecoder;
......@@ -74,7 +72,8 @@ ivas_error CreateLCLDDecoder(
LCLDDecoder **psLCLDDecoder_out,
const int32_t iSampleRate,
const int32_t iChannels,
const int32_t iNumBlocks );
const int32_t iNumBlocks,
const int32_t iRealOnlyOut);
void DeleteLCLDDecoder(
LCLDDecoder *psLCLDDecoder
......@@ -82,7 +81,7 @@ void DeleteLCLDDecoder(
int32_t DecodeLCLDFrame(
LCLDDecoder *psLCLDDecoder,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
float ***pppfLCLDReal,
float ***pppfLCLDImag
);
......@@ -96,11 +95,11 @@ int32_t quantPhase(
float phase
);
void cplxmult(
void cplxmult_lcld(
float *pr1,
float *pi1,
float r2,
float i2
const float r2,
const float i2
);
......@@ -238,8 +237,6 @@ typedef struct PREDICTION_ENCODER
float **ppfPredStateImagTmp;
float **ppfInpPrevReal; /* channels, bands */
float **ppfInpPrevImag;
float *pfWindow;
float pfRxxReal[2];
float pfRxxImag[2];
......@@ -272,15 +269,10 @@ void ComputePredictors(
float ***pppfImag
);
void ApplyForwardPredictors(
PredictionEncoder *psPredictionEncoder,
float ***pppfReal,
float ***pppfImag
);
int32_t WritePredictors(
PredictionEncoder *psPredictionEncoder,
IVAS_SPLIT_REND_BITS_HANDLE pBits
ISAR_SPLIT_REND_BITS_HANDLE pBits
);
typedef struct PREDICTION_DECODER
......@@ -295,6 +287,11 @@ typedef struct PREDICTION_DECODER
int32_t *piPredChanEnable;
int32_t **ppiPredBandEnable;
/* PLC_IMPROVEMENT */
int32_t **ppiDecodingUnresolved;
int32_t **ppiDecodingFailed;
int32_t **ppiDecodingFailedPrev;
float **ppfA1Real;
float **ppfA1Imag;
......@@ -319,9 +316,43 @@ void DeletePredictionDecoder(
int32_t ReadPredictors(
PredictionDecoder *psPredictionDecoder,
IVAS_SPLIT_REND_BITS_HANDLE pBits
ISAR_SPLIT_REND_BITS_HANDLE pBits
);
/* PLC_IMPROVEMENT */
void UpdatePredictionSubSetId(
PredictionEncoder *psPredictionEncoder);
void SetDecodingUnresolved(
LCLDDecoder *psLCLDDecoder);
int32_t AnyDecodingFailedPrev(
LCLDDecoder *psLCLDDecoder);
int32_t AnyDecodingFailed(
LCLDDecoder *psLCLDDecoder);
int32_t **GetDecodingFailedStatus(
LCLDDecoder *psLCLDDecoder);
int16_t GetNumSubSets(
LCLDDecoder *psLCLDDecoder);
int32_t **GetDecodingFailedPrevStatus(
LCLDDecoder *psLCLDDecoder);
void SetDecodingPassed(
PredictionDecoder *psPredictionDecoder);
void UpdateDecodingUnresolved(
PredictionDecoder *psPredictionDecoder);
void UpdateDecodingFailedStatus(
PredictionDecoder *psPredictionDecoder);
int32_t AnyDecodingUnresolved(
PredictionDecoder *psPredictionDecoder);
void ApplyInversePredictors(
PredictionDecoder *psPredictionDecoder,
float ***pppfReal,
......
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef ISAR_PROT_H
#define ISAR_PROT_H
#include "isar_stat.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <stdint.h>
#include "options.h"
#include "ivas_error.h"
#include "lib_isar_post_rend.h"
ivas_error isar_splitBinPreRendOpen(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
const int32_t output_Fs
#endif
);
ivas_error split_renderer_open_lc3plus(
SPLIT_REND_WRAPPER *hSplitRendWrapper,
const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int32_t OutSampleRate,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const IVAS_RENDER_FRAMESIZE ivas_frame_size
#else
const int16_t num_subframes
#endif
);
void isar_splitBinPreRendClose(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend );
void lc3plusTimeAlignCldfbPoseCorr(
SPLIT_REND_WRAPPER *hSplitBin,
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] );
ivas_error splitRendLc3plusEncodeAndWrite(
SPLIT_REND_WRAPPER *hSplitBin,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int32_t available_bits,
#else
const int32_t SplitRendBitRate,
#endif
float *in[] );
int32_t ISAR_SPLIT_REND_BITStream_read_int32(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t bits );
void ISAR_SPLIT_REND_BITStream_write_int32(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t val,
const int32_t bits );
ivas_error isar_splitBinLCLDEncOpen(
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
const int32_t iSampleRate,
const int16_t iChannels,
const int32_t iDataRate,
const int16_t iNumBlocks,
const int16_t iNumIterations );
ivas_error isar_splitBinRendPLCOpen(
ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC,
const int16_t iNumSubSets );
void isar_splitBinRendPLCClose(
ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC );
ivas_error isar_splitBinLCLDDecOpen(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
const int32_t iSampleRate,
const int16_t iChannels,
const int16_t iNumBlocks,
const int16_t iNumIterations );
void isar_splitBinLCLDDecClose(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec );
void isar_splitBinRendPLCsaveState(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations );
void isar_splitBinRendPLC_xf(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations,
int32_t **ppiDecodingFailed,
int32_t **ppiDecodingFailedPrev );
void isar_splitBinRendPLC(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations,
int32_t **ppiDecodingFailed );
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
void isar_log_cldfb2wav_data(
float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
HANDLE_CLDFB_FILTER_BANK *cldfbSyn,
const int16_t num_chs,
const int16_t num_freq_bands,
const int32_t output_Fs,
const int16_t start_slot_idx,
const int16_t md_band_idx,
const char *filename );
#endif
void isar_splitBinLCLDDecProcess(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t bfi );
void set_fix_rotation_mat(
float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
void isar_splitBinLCLDEncClose(
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc );
void isar_splitBinLCLDEncProcess(
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int32_t available_bits,
ISAR_SPLIT_REND_BITS_HANDLE pBits );
void set_pose_types(
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
void isar_split_rend_init_huff_cfg(
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg );
ivas_error isar_splitBinPostRendOpen(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int32_t output_Fs );
void isar_splitBinPostRendClose(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend );
void isar_SplitRenderer_getdiagdiff(
int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
const int16_t sign,
const int16_t min_val,
const int16_t max_val );
void isar_split_rend_get_quant_params(
const int16_t num_md_bands,
int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
const int16_t ro_flag,
#endif
int16_t *num_quant_strats
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
,
int16_t *num_complex_bands
#endif
);
void isar_splitBinPostRendMdDec(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend
#else
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
#endif
);
void Quat2EulerDegree(
const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
float *yaw, /* o : yaw */
float *pitch, /* o : pitch */
float *roll /* o : roll */
);
void isar_mat_mult_2by2_complex(
float in_re1[2][2],
float in_im1[2][2],
float in_re2[2][2],
float in_im2[2][2],
float out_re2[2][2],
float out_im2[2][2] );
void isar_rend_CldfbSplitPostRendProcess(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const IVAS_QUATERNION QuaternionPost,
float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
float output[][L_FRAME48k],
const int16_t cldfb_in_flag );
void isar_rend_CldfbSplitPreRendProcess(
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
const IVAS_QUATERNION headPosition,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t target_md_bits,
const int16_t low_res_pre_rend_rot,
const int16_t ro_md_flag );
ivas_error isar_renderMultiTDBinToSplitBinaural(
SPLIT_REND_WRAPPER *hSplitBin,
const IVAS_QUATERNION headPosition,
const int32_t SplitRendBitRate,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int16_t isar_frame_size_ms,
#endif
const int16_t codec_frame_size_ms,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int16_t max_bands,
float *in[],
const int16_t low_res_pre_rend_rot,
const int16_t pcm_out_flag,
const int16_t ro_md_flag );
void isar_init_multi_bin_pose_data(
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
void isar_renderSplitGetMultiBinPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const ISAR_SPLIT_REND_ROT_AXIS rot_axis );
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
int16_t isar_renderSplitGetRot_axisNumBits(
const int16_t dof );
ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
const int16_t dof,
const int16_t code );
int16_t isar_renderSplitGetCodeFromRot_axis(
const int16_t dof,
const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
int16_t *num_bits );
#endif
void isar_init_split_post_rend_handles(
ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper );
void isar_set_split_rend_ht_setup(
SPLIT_REND_WRAPPER *hSplitrend,
IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] );
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t isar_get_lc3plus_bitrate(
const int32_t SplitRendBitRate,
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms );
#endif
ivas_error isar_split_rend_validate_config(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int16_t pcm_out_flag );
int32_t isar_get_lcld_bitrate(
const int32_t SplitRendBitRate,
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode );
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
int8_t isar_get_lc3plus_bitrate_id(
const int32_t SplitRendBitRate );
#endif
int32_t isar_get_split_rend_md_target_brate(
const int32_t SplitRendBitRate,
const int16_t pcm_out_flag );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error isar_framesize_to_ms(
const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
int16_t *ms /* o : frame size in ms */
);
#endif
ivas_error isar_split_rend_choose_default_codec(
ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */
#endif
int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */
const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */
const int16_t pcm_out_flag, /* i : flag to indicate PCM output */
const int16_t num_subframes /* i : number of subframes */
);
void ISAR_SPLIT_REND_BITStream_init(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t buf_len_bytes,
uint8_t *pbuf );
void isar_split_rend_huffman_dec_init_min_max_len(
isar_split_rend_huffman_cfg_t *p_huff_cfg );
int16_t wrap_a(
int16_t val,
const int16_t min_val,
const int16_t max_val );
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t isar_get_lc3plus_size_from_id(
const int8_t SplitRendBitRateId,
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms );
#endif
void isar_renderSplitUpdateNoCorrectionPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
int32_t get_bit(
const int32_t state,
const int32_t bit_id );
ISAR_POST_REND_AudioConfigType isar_getAudioConfigType(
const IVAS_AUDIO_CONFIG config );
void isar_init_split_rend_handles(
SPLIT_REND_WRAPPER *hSplitRendWrapper );
#endif
/* clang-format on */
#endif /* ISAR_PROT_H */
......@@ -30,15 +30,22 @@
*******************************************************************************************************/
#include "ivas_lcld_rom_tables.h"
#include "isar_rom_lcld_tables.h"
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "wmc_auto.h"
#include "prot.h"
#include "ivas_lcld_prot.h"
#include "isar_lcld_prot.h"
/* clang-format off */
const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60
};
const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18,
18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22
};
/* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */
const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] =
......@@ -70,7 +77,6 @@ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] =
{ -1.00000000f, 0.00000000f }
};
/* Move this to perceptual model ? */
const int32_t c_aiBandwidths48[MAX_BANDS_48] =
{
1,
......@@ -10934,7763 +10940,6 @@ const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36,
100, 169, 196, 289, 324, 400, 576, 729, 729, 28,
29, 32, 37, 39, 46, 55, 65, 77, 91, 109,
129, 153, 181 };
#ifdef USE_DEMOD_TABLES
const int32_t c_aaiHuffDemod1[16][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
1,
0,
1,
1,
1,
2,
1,
3,
2,
0,
2,
1,
2,
2,
2,
3,
3,
0,
3,
1,
3,
2,
3,
3,
};
const int32_t c_aaiHuffDemod2[16][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
1,
0,
1,
1,
1,
2,
1,
3,
2,
0,
2,
1,
2,
2,
2,
3,
3,
0,
3,
1,
3,
2,
3,
3,
};
const int32_t c_aaiHuffDemod3[25][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
};
const int32_t c_aaiHuffDemod4[36][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
};
const int32_t c_aaiHuffDemod5[36][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
};
const int32_t c_aaiHuffDemod6[49][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
};
const int32_t c_aaiHuffDemod7[64][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
};
const int32_t c_aaiHuffDemod8[81][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
};
const int32_t c_aaiHuffDemod9[100][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
};
const int32_t c_aaiHuffDemod10[169][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
};
const int32_t c_aaiHuffDemod11[196][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
};
const int32_t c_aaiHuffDemod12[289][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
};
const int32_t c_aaiHuffDemod13[324][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
0,
17,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
1,
17,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
2,
17,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
3,
17,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
4,
17,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
5,
17,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
6,
17,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
7,
17,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
8,
17,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
9,
17,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
10,
17,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
11,
17,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
12,
17,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
13,
17,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
14,
17,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
15,
17,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
16,
17,
17,
0,
17,
1,
17,
2,
17,
3,
17,
4,
17,
5,
17,
6,
17,
7,
17,
8,
17,
9,
17,
10,
17,
11,
17,
12,
17,
13,
17,
14,
17,
15,
17,
16,
17,
17,
};
const int32_t c_aaiHuffDemod14[400][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
0,
17,
0,
18,
0,
19,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
1,
17,
1,
18,
1,
19,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
2,
17,
2,
18,
2,
19,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
3,
17,
3,
18,
3,
19,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
4,
17,
4,
18,
4,
19,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
5,
17,
5,
18,
5,
19,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
6,
17,
6,
18,
6,
19,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
7,
17,
7,
18,
7,
19,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
8,
17,
8,
18,
8,
19,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
9,
17,
9,
18,
9,
19,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
10,
17,
10,
18,
10,
19,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
11,
17,
11,
18,
11,
19,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
12,
17,
12,
18,
12,
19,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
13,
17,
13,
18,
13,
19,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
14,
17,
14,
18,
14,
19,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
15,
17,
15,
18,
15,
19,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
16,
17,
16,
18,
16,
19,
17,
0,
17,
1,
17,
2,
17,
3,
17,
4,
17,
5,
17,
6,
17,
7,
17,
8,
17,
9,
17,
10,
17,
11,
17,
12,
17,
13,
17,
14,
17,
15,
17,
16,
17,
17,
17,
18,
17,
19,
18,
0,
18,
1,
18,
2,
18,
3,
18,
4,
18,
5,
18,
6,
18,
7,
18,
8,
18,
9,
18,
10,
18,
11,
18,
12,
18,
13,
18,
14,
18,
15,
18,
16,
18,
17,
18,
18,
18,
19,
19,
0,
19,
1,
19,
2,
19,
3,
19,
4,
19,
5,
19,
6,
19,
7,
19,
8,
19,
9,
19,
10,
19,
11,
19,
12,
19,
13,
19,
14,
19,
15,
19,
16,
19,
17,
19,
18,
19,
19,
};
const int32_t c_aaiHuffDemod15[576][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
0,
17,
0,
18,
0,
19,
0,
20,
0,
21,
0,
22,
0,
23,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
1,
17,
1,
18,
1,
19,
1,
20,
1,
21,
1,
22,
1,
23,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
2,
17,
2,
18,
2,
19,
2,
20,
2,
21,
2,
22,
2,
23,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
3,
17,
3,
18,
3,
19,
3,
20,
3,
21,
3,
22,
3,
23,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
4,
17,
4,
18,
4,
19,
4,
20,
4,
21,
4,
22,
4,
23,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
5,
17,
5,
18,
5,
19,
5,
20,
5,
21,
5,
22,
5,
23,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
6,
17,
6,
18,
6,
19,
6,
20,
6,
21,
6,
22,
6,
23,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
7,
17,
7,
18,
7,
19,
7,
20,
7,
21,
7,
22,
7,
23,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
8,
17,
8,
18,
8,
19,
8,
20,
8,
21,
8,
22,
8,
23,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
9,
17,
9,
18,
9,
19,
9,
20,
9,
21,
9,
22,
9,
23,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
10,
17,
10,
18,
10,
19,
10,
20,
10,
21,
10,
22,
10,
23,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
11,
17,
11,
18,
11,
19,
11,
20,
11,
21,
11,
22,
11,
23,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
12,
17,
12,
18,
12,
19,
12,
20,
12,
21,
12,
22,
12,
23,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
13,
17,
13,
18,
13,
19,
13,
20,
13,
21,
13,
22,
13,
23,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
14,
17,
14,
18,
14,
19,
14,
20,
14,
21,
14,
22,
14,
23,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
15,
17,
15,
18,
15,
19,
15,
20,
15,
21,
15,
22,
15,
23,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
16,
17,
16,
18,
16,
19,
16,
20,
16,
21,
16,
22,
16,
23,
17,
0,
17,
1,
17,
2,
17,
3,
17,
4,
17,
5,
17,
6,
17,
7,
17,
8,
17,
9,
17,
10,
17,
11,
17,
12,
17,
13,
17,
14,
17,
15,
17,
16,
17,
17,
17,
18,
17,
19,
17,
20,
17,
21,
17,
22,
17,
23,
18,
0,
18,
1,
18,
2,
18,
3,
18,
4,
18,
5,
18,
6,
18,
7,
18,
8,
18,
9,
18,
10,
18,
11,
18,
12,
18,
13,
18,
14,
18,
15,
18,
16,
18,
17,
18,
18,
18,
19,
18,
20,
18,
21,
18,
22,
18,
23,
19,
0,
19,
1,
19,
2,
19,
3,
19,
4,
19,
5,
19,
6,
19,
7,
19,
8,
19,
9,
19,
10,
19,
11,
19,
12,
19,
13,
19,
14,
19,
15,
19,
16,
19,
17,
19,
18,
19,
19,
19,
20,
19,
21,
19,
22,
19,
23,
20,
0,
20,
1,
20,
2,
20,
3,
20,
4,
20,
5,
20,
6,
20,
7,
20,
8,
20,
9,
20,
10,
20,
11,
20,
12,
20,
13,
20,
14,
20,
15,
20,
16,
20,
17,
20,
18,
20,
19,
20,
20,
20,
21,
20,
22,
20,
23,
21,
0,
21,
1,
21,
2,
21,
3,
21,
4,
21,
5,
21,
6,
21,
7,
21,
8,
21,
9,
21,
10,
21,
11,
21,
12,
21,
13,
21,
14,
21,
15,
21,
16,
21,
17,
21,
18,
21,
19,
21,
20,
21,
21,
21,
22,
21,
23,
22,
0,
22,
1,
22,
2,
22,
3,
22,
4,
22,
5,
22,
6,
22,
7,
22,
8,
22,
9,
22,
10,
22,
11,
22,
12,
22,
13,
22,
14,
22,
15,
22,
16,
22,
17,
22,
18,
22,
19,
22,
20,
22,
21,
22,
22,
22,
23,
23,
0,
23,
1,
23,
2,
23,
3,
23,
4,
23,
5,
23,
6,
23,
7,
23,
8,
23,
9,
23,
10,
23,
11,
23,
12,
23,
13,
23,
14,
23,
15,
23,
16,
23,
17,
23,
18,
23,
19,
23,
20,
23,
21,
23,
22,
23,
23,
};
const int32_t c_aaiHuffDemod16[729][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
0,
17,
0,
18,
0,
19,
0,
20,
0,
21,
0,
22,
0,
23,
0,
24,
0,
25,
0,
26,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
1,
17,
1,
18,
1,
19,
1,
20,
1,
21,
1,
22,
1,
23,
1,
24,
1,
25,
1,
26,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
2,
17,
2,
18,
2,
19,
2,
20,
2,
21,
2,
22,
2,
23,
2,
24,
2,
25,
2,
26,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
3,
17,
3,
18,
3,
19,
3,
20,
3,
21,
3,
22,
3,
23,
3,
24,
3,
25,
3,
26,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
4,
17,
4,
18,
4,
19,
4,
20,
4,
21,
4,
22,
4,
23,
4,
24,
4,
25,
4,
26,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
5,
17,
5,
18,
5,
19,
5,
20,
5,
21,
5,
22,
5,
23,
5,
24,
5,
25,
5,
26,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
6,
17,
6,
18,
6,
19,
6,
20,
6,
21,
6,
22,
6,
23,
6,
24,
6,
25,
6,
26,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
7,
17,
7,
18,
7,
19,
7,
20,
7,
21,
7,
22,
7,
23,
7,
24,
7,
25,
7,
26,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
8,
17,
8,
18,
8,
19,
8,
20,
8,
21,
8,
22,
8,
23,
8,
24,
8,
25,
8,
26,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
9,
17,
9,
18,
9,
19,
9,
20,
9,
21,
9,
22,
9,
23,
9,
24,
9,
25,
9,
26,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
10,
17,
10,
18,
10,
19,
10,
20,
10,
21,
10,
22,
10,
23,
10,
24,
10,
25,
10,
26,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
11,
17,
11,
18,
11,
19,
11,
20,
11,
21,
11,
22,
11,
23,
11,
24,
11,
25,
11,
26,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
12,
17,
12,
18,
12,
19,
12,
20,
12,
21,
12,
22,
12,
23,
12,
24,
12,
25,
12,
26,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
13,
17,
13,
18,
13,
19,
13,
20,
13,
21,
13,
22,
13,
23,
13,
24,
13,
25,
13,
26,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
14,
17,
14,
18,
14,
19,
14,
20,
14,
21,
14,
22,
14,
23,
14,
24,
14,
25,
14,
26,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
15,
17,
15,
18,
15,
19,
15,
20,
15,
21,
15,
22,
15,
23,
15,
24,
15,
25,
15,
26,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
16,
17,
16,
18,
16,
19,
16,
20,
16,
21,
16,
22,
16,
23,
16,
24,
16,
25,
16,
26,
17,
0,
17,
1,
17,
2,
17,
3,
17,
4,
17,
5,
17,
6,
17,
7,
17,
8,
17,
9,
17,
10,
17,
11,
17,
12,
17,
13,
17,
14,
17,
15,
17,
16,
17,
17,
17,
18,
17,
19,
17,
20,
17,
21,
17,
22,
17,
23,
17,
24,
17,
25,
17,
26,
18,
0,
18,
1,
18,
2,
18,
3,
18,
4,
18,
5,
18,
6,
18,
7,
18,
8,
18,
9,
18,
10,
18,
11,
18,
12,
18,
13,
18,
14,
18,
15,
18,
16,
18,
17,
18,
18,
18,
19,
18,
20,
18,
21,
18,
22,
18,
23,
18,
24,
18,
25,
18,
26,
19,
0,
19,
1,
19,
2,
19,
3,
19,
4,
19,
5,
19,
6,
19,
7,
19,
8,
19,
9,
19,
10,
19,
11,
19,
12,
19,
13,
19,
14,
19,
15,
19,
16,
19,
17,
19,
18,
19,
19,
19,
20,
19,
21,
19,
22,
19,
23,
19,
24,
19,
25,
19,
26,
20,
0,
20,
1,
20,
2,
20,
3,
20,
4,
20,
5,
20,
6,
20,
7,
20,
8,
20,
9,
20,
10,
20,
11,
20,
12,
20,
13,
20,
14,
20,
15,
20,
16,
20,
17,
20,
18,
20,
19,
20,
20,
20,
21,
20,
22,
20,
23,
20,
24,
20,
25,
20,
26,
21,
0,
21,
1,
21,
2,
21,
3,
21,
4,
21,
5,
21,
6,
21,
7,
21,
8,
21,
9,
21,
10,
21,
11,
21,
12,
21,
13,
21,
14,
21,
15,
21,
16,
21,
17,
21,
18,
21,
19,
21,
20,
21,
21,
21,
22,
21,
23,
21,
24,
21,
25,
21,
26,
22,
0,
22,
1,
22,
2,
22,
3,
22,
4,
22,
5,
22,
6,
22,
7,
22,
8,
22,
9,
22,
10,
22,
11,
22,
12,
22,
13,
22,
14,
22,
15,
22,
16,
22,
17,
22,
18,
22,
19,
22,
20,
22,
21,
22,
22,
22,
23,
22,
24,
22,
25,
22,
26,
23,
0,
23,
1,
23,
2,
23,
3,
23,
4,
23,
5,
23,
6,
23,
7,
23,
8,
23,
9,
23,
10,
23,
11,
23,
12,
23,
13,
23,
14,
23,
15,
23,
16,
23,
17,
23,
18,
23,
19,
23,
20,
23,
21,
23,
22,
23,
23,
23,
24,
23,
25,
23,
26,
24,
0,
24,
1,
24,
2,
24,
3,
24,
4,
24,
5,
24,
6,
24,
7,
24,
8,
24,
9,
24,
10,
24,
11,
24,
12,
24,
13,
24,
14,
24,
15,
24,
16,
24,
17,
24,
18,
24,
19,
24,
20,
24,
21,
24,
22,
24,
23,
24,
24,
24,
25,
24,
26,
25,
0,
25,
1,
25,
2,
25,
3,
25,
4,
25,
5,
25,
6,
25,
7,
25,
8,
25,
9,
25,
10,
25,
11,
25,
12,
25,
13,
25,
14,
25,
15,
25,
16,
25,
17,
25,
18,
25,
19,
25,
20,
25,
21,
25,
22,
25,
23,
25,
24,
25,
25,
25,
26,
26,
0,
26,
1,
26,
2,
26,
3,
26,
4,
26,
5,
26,
6,
26,
7,
26,
8,
26,
9,
26,
10,
26,
11,
26,
12,
26,
13,
26,
14,
26,
15,
26,
16,
26,
17,
26,
18,
26,
19,
26,
20,
26,
21,
26,
22,
26,
23,
26,
24,
26,
25,
26,
26,
};
const int32_t c_aaiHuffDemod17[729][2] = {
0,
0,
0,
1,
0,
2,
0,
3,
0,
4,
0,
5,
0,
6,
0,
7,
0,
8,
0,
9,
0,
10,
0,
11,
0,
12,
0,
13,
0,
14,
0,
15,
0,
16,
0,
17,
0,
18,
0,
19,
0,
20,
0,
21,
0,
22,
0,
23,
0,
24,
0,
25,
0,
26,
1,
0,
1,
1,
1,
2,
1,
3,
1,
4,
1,
5,
1,
6,
1,
7,
1,
8,
1,
9,
1,
10,
1,
11,
1,
12,
1,
13,
1,
14,
1,
15,
1,
16,
1,
17,
1,
18,
1,
19,
1,
20,
1,
21,
1,
22,
1,
23,
1,
24,
1,
25,
1,
26,
2,
0,
2,
1,
2,
2,
2,
3,
2,
4,
2,
5,
2,
6,
2,
7,
2,
8,
2,
9,
2,
10,
2,
11,
2,
12,
2,
13,
2,
14,
2,
15,
2,
16,
2,
17,
2,
18,
2,
19,
2,
20,
2,
21,
2,
22,
2,
23,
2,
24,
2,
25,
2,
26,
3,
0,
3,
1,
3,
2,
3,
3,
3,
4,
3,
5,
3,
6,
3,
7,
3,
8,
3,
9,
3,
10,
3,
11,
3,
12,
3,
13,
3,
14,
3,
15,
3,
16,
3,
17,
3,
18,
3,
19,
3,
20,
3,
21,
3,
22,
3,
23,
3,
24,
3,
25,
3,
26,
4,
0,
4,
1,
4,
2,
4,
3,
4,
4,
4,
5,
4,
6,
4,
7,
4,
8,
4,
9,
4,
10,
4,
11,
4,
12,
4,
13,
4,
14,
4,
15,
4,
16,
4,
17,
4,
18,
4,
19,
4,
20,
4,
21,
4,
22,
4,
23,
4,
24,
4,
25,
4,
26,
5,
0,
5,
1,
5,
2,
5,
3,
5,
4,
5,
5,
5,
6,
5,
7,
5,
8,
5,
9,
5,
10,
5,
11,
5,
12,
5,
13,
5,
14,
5,
15,
5,
16,
5,
17,
5,
18,
5,
19,
5,
20,
5,
21,
5,
22,
5,
23,
5,
24,
5,
25,
5,
26,
6,
0,
6,
1,
6,
2,
6,
3,
6,
4,
6,
5,
6,
6,
6,
7,
6,
8,
6,
9,
6,
10,
6,
11,
6,
12,
6,
13,
6,
14,
6,
15,
6,
16,
6,
17,
6,
18,
6,
19,
6,
20,
6,
21,
6,
22,
6,
23,
6,
24,
6,
25,
6,
26,
7,
0,
7,
1,
7,
2,
7,
3,
7,
4,
7,
5,
7,
6,
7,
7,
7,
8,
7,
9,
7,
10,
7,
11,
7,
12,
7,
13,
7,
14,
7,
15,
7,
16,
7,
17,
7,
18,
7,
19,
7,
20,
7,
21,
7,
22,
7,
23,
7,
24,
7,
25,
7,
26,
8,
0,
8,
1,
8,
2,
8,
3,
8,
4,
8,
5,
8,
6,
8,
7,
8,
8,
8,
9,
8,
10,
8,
11,
8,
12,
8,
13,
8,
14,
8,
15,
8,
16,
8,
17,
8,
18,
8,
19,
8,
20,
8,
21,
8,
22,
8,
23,
8,
24,
8,
25,
8,
26,
9,
0,
9,
1,
9,
2,
9,
3,
9,
4,
9,
5,
9,
6,
9,
7,
9,
8,
9,
9,
9,
10,
9,
11,
9,
12,
9,
13,
9,
14,
9,
15,
9,
16,
9,
17,
9,
18,
9,
19,
9,
20,
9,
21,
9,
22,
9,
23,
9,
24,
9,
25,
9,
26,
10,
0,
10,
1,
10,
2,
10,
3,
10,
4,
10,
5,
10,
6,
10,
7,
10,
8,
10,
9,
10,
10,
10,
11,
10,
12,
10,
13,
10,
14,
10,
15,
10,
16,
10,
17,
10,
18,
10,
19,
10,
20,
10,
21,
10,
22,
10,
23,
10,
24,
10,
25,
10,
26,
11,
0,
11,
1,
11,
2,
11,
3,
11,
4,
11,
5,
11,
6,
11,
7,
11,
8,
11,
9,
11,
10,
11,
11,
11,
12,
11,
13,
11,
14,
11,
15,
11,
16,
11,
17,
11,
18,
11,
19,
11,
20,
11,
21,
11,
22,
11,
23,
11,
24,
11,
25,
11,
26,
12,
0,
12,
1,
12,
2,
12,
3,
12,
4,
12,
5,
12,
6,
12,
7,
12,
8,
12,
9,
12,
10,
12,
11,
12,
12,
12,
13,
12,
14,
12,
15,
12,
16,
12,
17,
12,
18,
12,
19,
12,
20,
12,
21,
12,
22,
12,
23,
12,
24,
12,
25,
12,
26,
13,
0,
13,
1,
13,
2,
13,
3,
13,
4,
13,
5,
13,
6,
13,
7,
13,
8,
13,
9,
13,
10,
13,
11,
13,
12,
13,
13,
13,
14,
13,
15,
13,
16,
13,
17,
13,
18,
13,
19,
13,
20,
13,
21,
13,
22,
13,
23,
13,
24,
13,
25,
13,
26,
14,
0,
14,
1,
14,
2,
14,
3,
14,
4,
14,
5,
14,
6,
14,
7,
14,
8,
14,
9,
14,
10,
14,
11,
14,
12,
14,
13,
14,
14,
14,
15,
14,
16,
14,
17,
14,
18,
14,
19,
14,
20,
14,
21,
14,
22,
14,
23,
14,
24,
14,
25,
14,
26,
15,
0,
15,
1,
15,
2,
15,
3,
15,
4,
15,
5,
15,
6,
15,
7,
15,
8,
15,
9,
15,
10,
15,
11,
15,
12,
15,
13,
15,
14,
15,
15,
15,
16,
15,
17,
15,
18,
15,
19,
15,
20,
15,
21,
15,
22,
15,
23,
15,
24,
15,
25,
15,
26,
16,
0,
16,
1,
16,
2,
16,
3,
16,
4,
16,
5,
16,
6,
16,
7,
16,
8,
16,
9,
16,
10,
16,
11,
16,
12,
16,
13,
16,
14,
16,
15,
16,
16,
16,
17,
16,
18,
16,
19,
16,
20,
16,
21,
16,
22,
16,
23,
16,
24,
16,
25,
16,
26,
17,
0,
17,
1,
17,
2,
17,
3,
17,
4,
17,
5,
17,
6,
17,
7,
17,
8,
17,
9,
17,
10,
17,
11,
17,
12,
17,
13,
17,
14,
17,
15,
17,
16,
17,
17,
17,
18,
17,
19,
17,
20,
17,
21,
17,
22,
17,
23,
17,
24,
17,
25,
17,
26,
18,
0,
18,
1,
18,
2,
18,
3,
18,
4,
18,
5,
18,
6,
18,
7,
18,
8,
18,
9,
18,
10,
18,
11,
18,
12,
18,
13,
18,
14,
18,
15,
18,
16,
18,
17,
18,
18,
18,
19,
18,
20,
18,
21,
18,
22,
18,
23,
18,
24,
18,
25,
18,
26,
19,
0,
19,
1,
19,
2,
19,
3,
19,
4,
19,
5,
19,
6,
19,
7,
19,
8,
19,
9,
19,
10,
19,
11,
19,
12,
19,
13,
19,
14,
19,
15,
19,
16,
19,
17,
19,
18,
19,
19,
19,
20,
19,
21,
19,
22,
19,
23,
19,
24,
19,
25,
19,
26,
20,
0,
20,
1,
20,
2,
20,
3,
20,
4,
20,
5,
20,
6,
20,
7,
20,
8,
20,
9,
20,
10,
20,
11,
20,
12,
20,
13,
20,
14,
20,
15,
20,
16,
20,
17,
20,
18,
20,
19,
20,
20,
20,
21,
20,
22,
20,
23,
20,
24,
20,
25,
20,
26,
21,
0,
21,
1,
21,
2,
21,
3,
21,
4,
21,
5,
21,
6,
21,
7,
21,
8,
21,
9,
21,
10,
21,
11,
21,
12,
21,
13,
21,
14,
21,
15,
21,
16,
21,
17,
21,
18,
21,
19,
21,
20,
21,
21,
21,
22,
21,
23,
21,
24,
21,
25,
21,
26,
22,
0,
22,
1,
22,
2,
22,
3,
22,
4,
22,
5,
22,
6,
22,
7,
22,
8,
22,
9,
22,
10,
22,
11,
22,
12,
22,
13,
22,
14,
22,
15,
22,
16,
22,
17,
22,
18,
22,
19,
22,
20,
22,
21,
22,
22,
22,
23,
22,
24,
22,
25,
22,
26,
23,
0,
23,
1,
23,
2,
23,
3,
23,
4,
23,
5,
23,
6,
23,
7,
23,
8,
23,
9,
23,
10,
23,
11,
23,
12,
23,
13,
23,
14,
23,
15,
23,
16,
23,
17,
23,
18,
23,
19,
23,
20,
23,
21,
23,
22,
23,
23,
23,
24,
23,
25,
23,
26,
24,
0,
24,
1,
24,
2,
24,
3,
24,
4,
24,
5,
24,
6,
24,
7,
24,
8,
24,
9,
24,
10,
24,
11,
24,
12,
24,
13,
24,
14,
24,
15,
24,
16,
24,
17,
24,
18,
24,
19,
24,
20,
24,
21,
24,
22,
24,
23,
24,
24,
24,
25,
24,
26,
25,
0,
25,
1,
25,
2,
25,
3,
25,
4,
25,
5,
25,
6,
25,
7,
25,
8,
25,
9,
25,
10,
25,
11,
25,
12,
25,
13,
25,
14,
25,
15,
25,
16,
25,
17,
25,
18,
25,
19,
25,
20,
25,
21,
25,
22,
25,
23,
25,
24,
25,
25,
25,
26,
26,
0,
26,
1,
26,
2,
26,
3,
26,
4,
26,
5,
26,
6,
26,
7,
26,
8,
26,
9,
26,
10,
26,
11,
26,
12,
26,
13,
26,
14,
26,
15,
26,
16,
26,
17,
26,
18,
26,
19,
26,
20,
26,
21,
26,
22,
26,
23,
26,
24,
26,
25,
26,
26,
};
const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = {
NULL,
c_aaiHuffDemod1,
c_aaiHuffDemod2,
c_aaiHuffDemod3,
c_aaiHuffDemod4,
c_aaiHuffDemod5,
c_aaiHuffDemod6,
c_aaiHuffDemod7,
c_aaiHuffDemod8,
c_aaiHuffDemod9,
c_aaiHuffDemod10,
c_aaiHuffDemod11,
c_aaiHuffDemod12,
c_aaiHuffDemod13,
c_aaiHuffDemod14,
c_aaiHuffDemod15,
c_aaiHuffDemod16,
c_aaiHuffDemod17,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
#endif
const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = {
0x40,
......
......@@ -30,15 +30,16 @@
*******************************************************************************************************/
#ifndef _IVAS_TABLES_H_
#define _IVAS_TABLES_H_
#ifndef ISAR_ROM_LCLD_TABLES_H
#define ISAR_ROM_LCLD_TABLES_H
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI
#define M_PI 3.14159265358979323846264338327950288f
#endif
......@@ -47,7 +48,6 @@
#define LCLD_BANDS ( 60 )
#define LCLD_PRED_WIN_LEN ( 16 )
#define LCLD_MAX_NUM_PRED_SUBSETS ( 8 )
#define MAX_BANDS ( 23 )
#define MAX_BANDS_48 ( 23 )
#define DEF_BANDS_48 ( 22 )
......@@ -93,10 +93,10 @@
#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 )
//#define USE_DEMOD_TABLES
#define HUFF_DEC_TABLE_SIZE ( 16 )
extern const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48];
extern const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS];
extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2];
extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48];
......@@ -190,30 +190,8 @@ extern const uint16_t c_aauiLCLDHuffEnc62[153][2];
extern const uint16_t c_aauiLCLDHuffEnc63[181][2];
extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2];
extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE];
#ifdef USE_DEMOD_TABLES
extern const int32_t c_aaiHuffDemod1[16][2];
extern const int32_t c_aaiHuffDemod2[16][2];
extern const int32_t c_aaiHuffDemod3[25][2];
extern const int32_t c_aaiHuffDemod4[36][2];
extern const int32_t c_aaiHuffDemod5[36][2];
extern const int32_t c_aaiHuffDemod6[49][2];
extern const int32_t c_aaiHuffDemod7[64][2];
extern const int32_t c_aaiHuffDemod8[81][2];
extern const int32_t c_aaiHuffDemod9[100][2];
extern const int32_t c_aaiHuffDemod10[169][2];
extern const int32_t c_aaiHuffDemod11[196][2];
extern const int32_t c_aaiHuffDemod12[289][2];
extern const int32_t c_aaiHuffDemod13[324][2];
extern const int32_t c_aaiHuffDemod14[400][2];
extern const int32_t c_aaiHuffDemod15[576][2];
extern const int32_t c_aaiHuffDemod16[729][2];
extern const int32_t c_aaiHuffDemod17[729][2];
extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2];
#endif
extern const uint32_t c_aaiRMSEnvHuffEnc[64][2];
extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE];
#endif /*SPLIT_REND_WITH_HEAD_ROT*/
#endif /* _TABLES_H_ */
#endif /* ISAR_ROM_LCLD_TABLES_H_ */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include <stdint.h>
#include "options.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
#include "isar_cnst.h"
#include "wmc_auto.h"
/* clang-format off */
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*----------------------------------------------------------------------*
* Binuaral split rendering ROM tables
*-----------------------------------------------------------------------*/
/* rotations in this array are relative to ref rotation */
const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f};
const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f};
const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f};
const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f};
const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f};
const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f};
const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f};
const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f};
const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60
};
const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
{
{0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12},
{6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61},
{12,7,125},{13,8,254},{14,8,255}
};
const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
{
{ 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 },
{ 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 },
{ 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 },
{ 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 }
};
const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
{
{ 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 },
{ 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 },
{ 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 },
{ 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 }
};
const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] =
{
{-31,11,2040},
{-30,11,2041},
{-29,11,2042},
{-28,11,2043},
{-27,10,1012},
{-26,10,1013},
{-25,10,1014},
{-24,10,1015},
{-23,9,498},
{-22,9,499},
{-21,9,500},
{-20,9,501},
{-19,8,242},
{-18,8,243},
{-17,8,244},
{-16,8,245},
{-15,7,112},
{-14,7,113},
{-13,7,114},
{-12,7,115},
{-11,6,48},
{-10,6,49},
{-9,6,50},
{-8,6,51},
{-7,5,16},
{-6,5,17},
{-5,5,18},
{-4,5,19},
{-3,4,2},
{-2,4,3},
{-1,4,4},
{0,3,0},
{1,4,5},
{2,4,6},
{3,4,7},
{4,5,20},
{5,5,21},
{6,5,22},
{7,5,23},
{8,6,52},
{9,6,53},
{10,6,54},
{11,6,55},
{12,7,116},
{13,7,117},
{14,7,118},
{15,7,119},
{16,7,120},
{17,8,246},
{18,8,247},
{19,8,248},
{20,9,502},
{21,9,503},
{22,9,504},
{23,9,505},
{24,10,1016},
{25,10,1017},
{26,10,1018},
{27,10,1019},
{28,11,2044},
{29,11,2045},
{30,11,2046},
{31,11,2047},
};
const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] =
{
{-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507},
{-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121},
{-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8},
{-2,4,9},{-1,3,2},{0,2,0},{1,3,3},
{2,4,10},{3,4,11},{4,5,26},{5,5,27},
{6,6,58},{7,6,59},{8,7,122},{9,7,123},
{10,7,124},{11,8,252},{12,9,508},{13,9,509},
{14,10,1022},{15,10,1023},
};
const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] =
{
{-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507},
{-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121},
{-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8},
{-2,4,9},{-1,3,2},{0,2,0},{1,3,3},
{2,4,10},{3,4,11},{4,5,26},{5,5,27},
{6,6,58},{7,6,59},{8,7,122},{9,7,123},
{10,7,124},{11,8,252},{12,9,508},{13,9,509},
{14,10,1022},{15,10,1023},
};
#endif
/* clang-format on */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef ISAR_ROM_POST_REND_H
#define ISAR_ROM_POST_REND_H
#include <stdint.h>
#include "options.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
#include "isar_cnst.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*----------------------------------------------------------------------*
* Binuaral split rendering ROM tables
*-----------------------------------------------------------------------*/
extern const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES];
extern const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES];
extern const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES];
extern const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES];
extern const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES];
extern const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES];
extern const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES];
extern const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES];
extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3];
extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1];
extern const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
extern const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3];
extern const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3];
extern const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3];
extern const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
extern const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
#endif
#endif
......@@ -33,7 +33,7 @@
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "ivas_prot.h"
#include "prot.h"
#ifdef DEBUGGING
......@@ -43,23 +43,23 @@
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDDecOpen()
* Function isar_splitBinLCLDDecOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_splitBinLCLDDecOpen(
BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
ivas_error isar_splitBinLCLDDecOpen(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
const int32_t iSampleRate,
const int16_t iChannels,
const int16_t iNumBlocks,
const int16_t iNumIterations )
{
int16_t n;
BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec;
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec;
ivas_error error;
if ( ( splitBinLCLDDec = (BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL )
if ( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
}
......@@ -68,7 +68,7 @@ ivas_error ivas_splitBinLCLDDecOpen(
splitBinLCLDDec->iChannels = iChannels;
if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks ) ) != IVAS_ERR_OK )
if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -107,7 +107,7 @@ ivas_error ivas_splitBinLCLDDecOpen(
fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut );
#endif
if ( ( error = ivas_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC ) ) != IVAS_ERR_OK )
if ( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -121,13 +121,13 @@ ivas_error ivas_splitBinLCLDDecOpen(
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDDecClose()
* Function isar_splitBinLCLDDecClose()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinLCLDDecClose(
BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec )
void isar_splitBinLCLDDecClose(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec )
{
int16_t n;
......@@ -152,7 +152,7 @@ void ivas_splitBinLCLDDecClose(
fclose( ( *hSplitBinLCLDDec )->cldfbOut );
}
#endif
ivas_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC );
isar_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC );
free( *hSplitBinLCLDDec );
*hSplitBinLCLDDec = NULL;
......@@ -163,21 +163,21 @@ void ivas_splitBinLCLDDecClose(
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDDecProcess()
* Function isar_splitBinLCLDDecProcess()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinLCLDDecProcess(
BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
void isar_splitBinLCLDDecProcess(
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t bfi )
{
int16_t k, n;
int16_t itr;
push_wmops( "ivas_splitBinLCLDDecProcess" );
push_wmops( "isar_splitBinLCLDDecProcess" );
assert( hSplitBinLCLDDec != NULL );
assert( Cldfb_Out_Real != NULL );
......@@ -224,21 +224,32 @@ void ivas_splitBinLCLDDecProcess(
}
}
#endif
if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 )
if ( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) )
{
/* continue concealing */
isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks,
hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) );
}
if ( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) )
{
/* cross-fade recovered frame into good frame */
ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations );
isar_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks,
hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ) );
}
}
}
else
{
/* set states in decoder */
SetDecodingUnresolved( hSplitBinLCLDDec->psLCLDDecoder );
/* do PLC for lost split renderer frame */
ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations );
isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks,
hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) );
}
/* save PLC state */
ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations );
isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations );
pop_wmops();
......