[FFmpeg-soc] [soc]: r1161 - qcelp/qcelpdec.c
reynaldo
subversion at mplayerhq.hu
Wed Aug 22 21:18:09 CEST 2007
Author: reynaldo
Date: Wed Aug 22 21:18:09 2007
New Revision: 1161
Log:
- Corrected some spec-not-clear-enough issues. Pitch filter/pre-filter
need to be applyed on pitch-subframe steps. With this fixes we get RI
compliant results but with an small (order 10^-5) drift when hammsinc
gets used.
Modified:
qcelp/qcelpdec.c
Modified: qcelp/qcelpdec.c
==============================================================================
--- qcelp/qcelpdec.c (original)
+++ qcelp/qcelpdec.c Wed Aug 22 21:18:09 2007
@@ -46,8 +46,8 @@ typedef struct {
uint8_t erasure_count;
uint8_t ifq_count;
float prev_lspf[10];
- float pitchf_mem[144];
- float pitchp_mem[144];
+ float pitchf_mem[150];
+ float pitchp_mem[150];
float hammsinc_table[8];
int frame_num;
} QCELPContext;
@@ -60,16 +60,16 @@ static int qcelp_decode_close(AVCodecCon
static float qcelp_hammsinc(float i)
{
- return (sin(M_PI*i)/(M_PI*i))*(0.5+0.46*cos(M_PI*i/4));
+ return (sin(M_PI*i)/(M_PI*i))*(0.5+0.46*cos(M_PI*i/4.0));
}
-static void qcelp_update_pitchf_mem(float *pitchf_mem, float last)
+static void qcelp_update_pitchf_mem(float *pitchf_mem, float *last)
{
- float tmp[144];
+ float tmp[150];
- memcpy(tmp, pitchf_mem+1, 143*sizeof(float));
- pitchf_mem[143]=last;
- memcpy(pitchf_mem, tmp, 143*sizeof(float));
+ memcpy(tmp, pitchf_mem+40, 110*sizeof(float));
+ memcpy(tmp+110, last, 40*sizeof(float));
+ memcpy(pitchf_mem, tmp, 150*sizeof(float));
}
static int qcelp_decode_init(AVCodecContext *avctx)
@@ -405,9 +405,9 @@ static void qcelp_apply_gain_ctrl(int do
static int qcelp_do_pitchfilter(QCELPFrame *frame, float *pitch_mem, int step,
float *pv, float *hammsinc_table)
{
- int i, j, tmp;
+ int i, j, k, tmp;
uint8_t *pgain, *plag, *pfrac;
- float gain[4], lag[4];
+ float gain[4], lag[4], hamm_tmp;
if(step != 1 && step != 2)
return -1;
@@ -422,7 +422,7 @@ static int qcelp_do_pitchfilter(QCELPFra
pfrac=frame->data+QCELP_PFRAC0_POS;
/**
- * Compute Gain & Lag
+ * Compute Gain & Lag for the whole frame
*/
for(i=0; i<4; i++)
@@ -432,7 +432,7 @@ static int qcelp_do_pitchfilter(QCELPFra
if(step == 2) /* become pitch pre-filter */
gain[i]=0.5*FFMIN(gain[i],1.0);
- lag[i] =plag[i]+16;
+ lag[i]=plag[i]+16;
if(pfrac[i])
lag[i]+=0.5;
@@ -443,35 +443,54 @@ static int qcelp_do_pitchfilter(QCELPFra
/**
* Apply filter
+ *
+ * TIA/EIA/IS-733 2.4.5.2-2/3 equations aren't clear enough to assume
+ * this filter had to be applied in pitch-subframe steps. Experimentation
+ * was needed.
*/
+ k=0;
for(i=0; i<160; i++)
{
if(pfrac[i/40]) /* if is a fractional lag... */
{
+ hamm_tmp=0.0;
+
for(j=-4; j<4; j++)
{
- tmp = i+j+0.5-lag[i/40];
+ tmp = k+j+0.5-lag[i/40];
if(tmp < 0)
- pv[i]+=gain[i/40]*hammsinc_table[j+4]
- * pitch_mem[144+tmp];
+ hamm_tmp+=hammsinc_table[j+4]
+ * pitch_mem[150+tmp];
else
- pv[i]+=gain[i/40]*hammsinc_table[j+4]
+ hamm_tmp+=hammsinc_table[j+4]
* pv [tmp];
}
+ pv[i]+=gain[i/40]*hamm_tmp;
+
}else
{
- tmp=i-lag[i/40];
+ tmp=k-lag[i/40];
if(tmp < 0)
- pv[i]+=gain[i/40]*pitch_mem[144+tmp];
+ pv[i]+=lrintf(gain[i/40]*pitch_mem[150+tmp]);
else
- pv[i]+=gain[i/40]*pv[i - lrintf(lag[i/40])];
+ pv[i]+=lrintf(gain[i/40]*pv[i - lrintf(lag[i/40])]);
}
- qcelp_update_pitchf_mem(pitch_mem, pv[i]);
+ /**
+ * If we are done with the pitch subframe we have to
+ * update the filter memory.
+ */
+
+ if(k==39)
+ {
+ qcelp_update_pitchf_mem(pitch_mem, &pv[i-k]);
+ }
+
+ k=(k<39)? k+1:0;
}
break;
More information about the FFmpeg-soc
mailing list