📄 sunplus_cdxafx_enc_2_0_3.cpp
字号:
/*=============================================================================
//
// Copyright 2007, Sunplus Technology Co., LTD.
// ALL RIGHTS RESERVED
//
//-----------------------------------------------------------------------------
// Sunplus algorighm standard library
//-----------------------------------------------------------------------------
//
// Part : Speech Coding
// Function: ADPCM cdxa fixed point Encoder
// Author : phhsieh
// Date : 2007/11/06
//
//=============================================================================
//
// File Name : sunplus_cdxaFx_enc_2_0_3.c
// Function Name : sunplus_cdxaFx_enc_v203
//
//=============================================================================*/
/* generic header */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/* system header */
#include "sunplus_cdxa.h"
enum {
CDXA_FRAME = 32, /* one frame contains 32 samples */
CDXA_SHIFT_FACTOR = 16, /* number of shiftfactor type */
CDXA_HEADER_SIZE = 48, /* include ID, Version, Reserved, Data size, Sampling freqency */
CDXA_FIX_MN = 6, /* fixed point m.n, n=CDXA_FIX_MN */
CDXA_FILTER_MAX_SIZE = 32, /* max number of adpcm predictor */
CDXA_FILTER_MAX_ORDER = 10, /* max number of predictor order */
CDXA_MAX_RESOLUTION = 8, /* max bits CDXA compress */
CDXA_FILTER_SIZE = 30, /* number of adpcm predictor */
CDXA_FILTER_ORDER = 2, /* number of predictor order */
CDXA_RESOLUTION = 4 /* one 16-bit sample compress to CDXA_RESOLUTION bit */
};
/*********************************************************************************************************************************************/
/* Function : findPredict1 */
/* void findPredict1(short *frame, int *enErr, int *predictNr, int *shiftFactor, int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps) */
/* Purpose : find the best predictNr and shiftFactor */
/* frame : one frame samples */
/* enErr : quantization error */
/* predictNr : the best filter type in this frame */
/* shiftFactor: coding quantization error parameter */
/* T_ENCODE[][CDXA_FILTER_ORDER] : encode table */
/* ps : all pole model */
/*********************************************************************************************************************************************/
static void findPredict1( short *frame, int *enErr, int *predictNr, int *shiftFactor,
int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps)
{
int i, j;
int buffer[CDXA_FRAME][CDXA_FILTER_MAX_SIZE];
int min = 99999999;
int max[CDXA_FILTER_MAX_SIZE];
int ds;
int shift_mask;
int sample;
int s[CDXA_FILTER_MAX_ORDER];
for ( i = 0; i < CDXA_FILTER_SIZE; ++i ) {
max[i] = 0;
s[0] = ps[0];
s[1] = ps[1];
for ( j = 0; j < CDXA_FRAME; ++j ) {
sample = (int)frame[j]; /* s[t-0] */
if ( sample > 30719 ) sample = 30719; /* 30719=0x77FF */
if ( sample < -30720 ) sample = -30720; /* -30720=0x8800 */
ds = sample - ((s[0] * T_ENCODE[i][0] + s[1] * T_ENCODE[i][1] + 32)>>6);
if (ds > 32767) ds = 32767;
if (ds < -32768) ds = -32768;
buffer[j][i] = ds;
if ( abs( ds ) > max[i] )
max[i] = abs( ds );
s[1] = s[0];
s[0] = sample;
}
if ( max[i] < min ) {
min = max[i];
*predictNr = i;
}
}
/* store s[t-2] and s[t-1] etc... */
/* these than used in the next function call */
ps[0] = s[0];
ps[1] = s[1];
for (i = 0; i < CDXA_FRAME; ++i)
enErr[i] = buffer[i][*predictNr];
shift_mask = 0x4000;
*shiftFactor = 0;
/* note: min is postive number */
while( *shiftFactor < (16-CDXA_RESOLUTION) ) {
if ( shift_mask & ( min + ( shift_mask >> (CDXA_RESOLUTION-1) ) ) )
break;
(*shiftFactor)++;
shift_mask = shift_mask >> 1;
}
}
/*********************************************************************************************************************************/
/* Function : findPredict2 */
/* void findPredict2(short *frame, int *predictNr, int *shiftFactor, int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps) */
/* Purpose : find the best predictNr and shiftFactor */
/* frame : one frame samples */
/* predictNr : the best filter type in this frame */
/* shiftFactor: coding quantization error parameter */
/* T_ENCODE[][CDXA_FILTER_ORDER] : encode table */
/* ps : all pole model */
/*********************************************************************************************************************************/
static void findPredict2( short *frame, int *predictNr, int estShiftFactor, int *shiftFactor,
int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps)
{
int h, i, j, x;
int shiftFactorMinError;
int filterMinError;
int sampleMaxError;
int dataMinError;
int ds;
int data;
int sample, error;
int s[CDXA_FILTER_MAX_ORDER];
int predictor, sn, filter, preData;
int shiftStart, shiftEnd;
shiftStart = estShiftFactor - 2;
shiftEnd = estShiftFactor + 2;
if (shiftStart < 0 || shiftEnd > CDXA_SHIFT_FACTOR-4) {
if (shiftStart < 0) {
shiftStart = 0;
shiftEnd = 5;
}
if (shiftEnd > CDXA_SHIFT_FACTOR-4) {
shiftStart = CDXA_SHIFT_FACTOR-9;
shiftEnd = CDXA_SHIFT_FACTOR-4;
}
}
shiftFactorMinError = 0x7fffffff;
for ( h = shiftStart; h < shiftEnd; ++h) {
filterMinError = 0x7fffffff;
for ( i = 0; i < CDXA_FILTER_SIZE; ++i ) {
sampleMaxError = 0;
s[0] = ps[0];
s[1] = ps[1];
for ( j = 0; j < CDXA_FRAME; ++j ) {
dataMinError = 0x7fffffff;
for ( x = 0; x < 16; ++x ) {
error = x << 12;
if ( error & 0x00008000 ) error |= 0xFFFF0000;
/* F32 filter architecture */
sn = abs( s[0] );
filter = abs( T_ENCODE[i][0] );
preData = (sn * filter) >> 6;
if ( (s[0]<0 && T_ENCODE[i][0]>0) || (s[0]>0 && T_ENCODE[i][0]<0) )
preData = -1 * preData;
sample = (error >> h) + preData;
sn = abs ( s[1] );
filter = abs( T_ENCODE[i][1] );
preData = (sn * filter) >> 6;
if ( (s[1]<0 && T_ENCODE[i][1]>0) || (s[1]>0 && T_ENCODE[i][1]<0) )
preData = -1 * preData;
sample += preData;
/* error */
ds = abs( (int)frame[j] - sample );
if ( ds < dataMinError ){
dataMinError = ds;
data = x;
}
}
error = data << 12;
if ( error & 0x00008000 ) error |= 0xFFFF0000;
/* F32 filter architecture */
sn = abs( s[0] );
filter = abs( T_ENCODE[i][0] );
preData = (sn * filter) >> 6;
if ( (s[0]<0 && T_ENCODE[i][0]>0) || (s[0]>0 && T_ENCODE[i][0]<0) )
preData = -1 * preData;
sample = (error >> h) + preData;
sn = abs( s[1] );
filter = abs( T_ENCODE[i][1] );
preData = (sn * filter) >> 6;
if ( (s[1]<0 && T_ENCODE[i][1]>0) || (s[1]>0 && T_ENCODE[i][1]<0) )
preData = -1 * preData;
sample += preData;
s[1] = s[0];
s[0] = sample;
sampleMaxError += dataMinError;
}
if (sampleMaxError < filterMinError) {
filterMinError = sampleMaxError;
predictor = i;
}
}
if (filterMinError < shiftFactorMinError) {
shiftFactorMinError = filterMinError;
*predictNr = predictor;
*shiftFactor = h;
}
}
}
/***************************************************************************************************************************************************/
/* Function : pack1 */
/* void pack1(int *enErr, int *errSum1, int *fourBit, int predictNr, int shiftFactor, int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ks */
/* Purpose : coding quantization error */
/* enErr : quantization error */
/* errSum1 : sum of enErr */
/* fourBit : result of coding quantization error */
/* predictNr : the best filter type in this frame */
/* shiftFactor : coding quantization error parameter */
/* T_ENCODE[][CDXA_FILTER_ORDER] : encode table */
/* ks : all pole model */
/***************************************************************************************************************************************************/
static void pack1( int *enErr, int *errSum1, int *fourBit, int predictNr, int shiftFactor ,
int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ks)
{
int di, ds;
int s0;
int i;
*errSum1 = 0;
for ( i = 0; i < CDXA_FRAME; i++ ) {
s0 = enErr[i] - ((ks[0]*T_ENCODE[predictNr][0] + ks[1]*T_ENCODE[predictNr][1] + 32)>>6);
ds = s0 * ( 1 << shiftFactor );
di = ( ds + 0x00000800 ) & 0xfffff000;
if ( di > 32767 ) di = 32767;
if ( di < -32768 ) di = -32768;
fourBit[i] = (short) di;
di = di >> shiftFactor;
ks[1] = ks[0];
ks[0] = di - s0;
*errSum1 += abs( enErr[i] );
}
}
/***************************************************************************************************************************************************************/
/* Function : pack2 */
/* void pack2(short *frame, int *enErr, int *errSum2, int *fourBit, int predictNr, int shiftFactor, int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps) */
/* Purpose : coding quantization error */
/* enErr : quantization error */
/* errSum2 : sum of enErr */
/* fourBit : result of coding quantization error */
/* predictNr : the best filter type in this frame */
/* shiftFactor : coding quantization error parameter */
/* T_ENCODE[][CDXA_FILTER_ORDER] : encode table */
/* ps : all pole model */
/***************************************************************************************************************************************************************/
static void pack2( short *frame, int *enErr, int *errSum2, int *fourBit, int predictNr, int shiftFactor ,
int T_ENCODE[][CDXA_FILTER_MAX_ORDER], int *ps)
{
int i, x;
int sample, error;
int data;
int sampleMinError;
int ds;
int predictionGain, preData, sn, filter;
*errSum2 = 0;
for ( i = 0; i < CDXA_FRAME; ++i ) {
/* F32 architecture */
sn = abs( ps[0] );
filter = abs( T_ENCODE[predictNr][0] );
preData = (sn * filter) >> 6;
if ( (ps[0]<0 && T_ENCODE[predictNr][0]>0) || (ps[0]>0 && T_ENCODE[predictNr][0]<0) )
preData = -1 * preData;
predictionGain = preData;
sn = abs( ps[1] );
filter = abs( T_ENCODE[predictNr][1] );
preData = (sn * filter) >> 6;
if ( (ps[1]<0 && T_ENCODE[predictNr][1]>0) || (ps[1]>0 && T_ENCODE[predictNr][1]<0) )
preData = -1 * preData;
predictionGain += preData;
sampleMinError = 0x7fffffff;
for ( x = 0; x < 16; ++x ) {
error = x << 12;
if (error & 0x00008000) error |= 0xFFFF0000;
sample = (error >> shiftFactor) + predictionGain;
ds = abs(sample - (int)frame[i]);
if (sampleMinError > ds){
sampleMinError = ds;
data = x;
}
}
error = data << (16 - CDXA_RESOLUTION);
if (error & 0x00008000) error |= 0xFFFF0000;
ps[1] = ps[0];
ps[0] = (error >> shiftFactor) + predictionGain;
fourBit[i] = data;
enErr[i] = (int)frame[i] - ps[0];
*errSum2 += abs( enErr[i] );
}
}
/************************************************************************************/
/* Function : sunplus_cdxaFx_enc_v203 */
/* int sunplus_cdxaFx_enc_v203(double *y, double *x, int size) */
/* Purpose : using ADPCM algorithm compress speech data */
/* y : pointer of output bitstream */
/* x : pointer of speech data */
/* size : total speech length */
/* return : bitstream length */
/************************************************************************************/
int sunplus_cdxaFx_enc_v203(double *y, double *x, int size)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -