[FFmpeg-soc] [soc]: r719 - in qcelp: README doc/TODO qcelpdec.c
reynaldo
subversion at mplayerhq.hu
Sun Aug 12 10:45:02 CEST 2007
Author: reynaldo
Date: Sun Aug 12 10:45:01 2007
New Revision: 719
Log:
- Fixes nan/-inf/+inf conditions on qcelp_do_pitch_filter :)
- Some reestructuration work on qcelp_do_pitchfilter.
- Implements pitch filter / pitch pre filter memory (draft)
- Adds several debug messages that are not going to stay longer
- GOT SOUND :-) (but not even close to the input yet)
Modified:
qcelp/README
qcelp/doc/TODO
qcelp/qcelpdec.c
Modified: qcelp/README
==============================================================================
--- qcelp/README (original)
+++ qcelp/README Sun Aug 12 10:45:01 2007
@@ -2,6 +2,7 @@ Testing instructions ;)
1.- svn update
2.- From this dir run ./srcprepare.sh /path/to/clean/FFmpeg/repo
- (a new dir with ffmpeg sources is created here, your repo stays untouched)
+ (a new dir with ffmpeg sources is created here before being patched, your
+ repo stays untouched)
3.- cd trunk
4.- ./configure ; make
Modified: qcelp/doc/TODO
==============================================================================
--- qcelp/doc/TODO (original)
+++ qcelp/doc/TODO Sun Aug 12 10:45:01 2007
@@ -3,6 +3,8 @@ Clear
- Make it work / Sample smashing
- Code and Hook adaptive postfilter using qcelp_apply_gain_ctrl()
- Rework IFQ handling & decoding glue code in general.
+- Stop calling hammsinc a zillion times, make a table and fill it at init
+ instead.
End goals:
Modified: qcelp/qcelpdec.c
==============================================================================
--- qcelp/qcelpdec.c (original)
+++ qcelp/qcelpdec.c Sun Aug 12 10:45:01 2007
@@ -48,6 +48,8 @@ typedef struct {
uint8_t erasure_count;
uint8_t ifq_count;
float prev_lspf[10];
+ float pitchf_mem[144];
+ float ppitchf_mem[144];
} QCELPContext;
static int qcelp_decode_init(AVCodecContext *avctx);
@@ -56,6 +58,15 @@ static int qcelp_decode_frame(AVCodecCon
static int qcelp_decode_close(AVCodecContext *avctx);
+static void qcelp_update_pitchf_mem(float *pitchf_mem, float last)
+{
+ float tmp[144];
+
+ memcpy(tmp, pitchf_mem+1, 143*sizeof(float));
+ pitchf_mem[143]=last;
+ memcpy(pitchf_mem, tmp, 143*sizeof(float));
+}
+
static int qcelp_decode_init(AVCodecContext *avctx)
{
QCELPContext *q = (QCELPContext *) avctx->priv_data;
@@ -73,6 +84,9 @@ static int qcelp_decode_init(AVCodecCont
for(i=0; i<10; i++)
q->prev_lspf[i]=0.0;
+ for(i=0; i<144; i++)
+ q->pitchf_mem[i]=q->ppitchf_mem[i]=0.0;
+
return 0;
}
@@ -284,7 +298,7 @@ static int qcelp_compute_svector(qcelp_p
/**
* Computes hammsinc(x), this will be replaced by a lookup table
*/
-static float qcelp_hammsinc(int i)
+static float qcelp_hammsinc(float i)
{
return (sin(M_PI*i)/(M_PI*i))*(0.5+0.46*cos(M_PI*i/4));
}
@@ -348,11 +362,12 @@ static void qcelp_apply_gain_ctrl(int do
*
* WIP (but should work)
*/
-static int qcelp_do_pitchfilter(QCELPFrame *frame, float *pv, float *ppv)
+static int qcelp_do_pitchfilter(QCELPFrame *frame, float *pitchf_mem,
+ float *ppitchf_mem, float *pv, float *ppv)
{
- int i,j;
+ int i, j, tmp;
uint8_t *pgain, *plag, *pfrac;
- float gain1, gain2, lag;
+ float gain1[4], gain2[4], lag[4], lagged_out;
switch(frame->rate)
{
@@ -363,38 +378,71 @@ static int qcelp_do_pitchfilter(QCELPFra
plag =frame->data+QCELP_PLAG0_POS;
pfrac=frame->data+QCELP_PFRAC0_POS;
- for(i=0; i<160; i++)
+ /**
+ * Compute Gain & Lag
+ */
+
+ for(i=0; i<4; i++)
{
- gain1=plag[i/40]? (pgain[i/40]+1)/4.0 : 0.0;
- gain2=0.5*FFMIN(gain1,1.0);
- lag=plag[i/40]+16+0.5*pfrac[i/40];
+ gain1[i]=plag[i]? (pgain[i]+1)/4.0 : 0.0;
+ gain2[i]=0.5*FFMIN(gain1[i],1.0);
+ lag[i] =plag[i]+16;
- if(lag == 140.5 || lag == 141.5 || lag == 142.5)
+ if(pfrac[i])
+ lag[i]+=0.5;
+
+
+ if(lag[i] == 140.5 || lag[i] == 141.5 || lag[i] == 142.5)
return -1;
+ }
- if(pfrac[i/40]==1) /* if is a fractional lag... */
+ /**
+ * Apply pitch and pre pitch filters in tandem
+ */
+
+ for(i=0; i<160; i++)
+ {
+ ppv[i]=pv[i];
+
+ if(pfrac[i/40]) /* if is a fractional lag... */
{
for(j=-4; j<4; j++)
{
- if(i + j - lag + 0.5 < 0)
- break; /*XXX may be unneded */
+ tmp = i+j+0.5-lag[i/40];
- /* WIP this will get simpler soon */
- pv [i]+=gain1*qcelp_hammsinc(j+0.5)*
- pv [i + j - (int)(lag + 0.5)];
- ppv[i]+=gain2*qcelp_hammsinc(j+0.5)*
- ppv[i + j - (int)(lag + 0.5)];
+ if(tmp < 0)
+ {
+ pv [i]+=gain1[i/40]*qcelp_hammsinc(j+0.5)
+ * pitchf_mem[144+tmp];
+ ppv[i]+=gain2[i/40]*qcelp_hammsinc(j+0.5)
+ *ppitchf_mem[144+tmp];
+ }else
+ {
+ pv [i]+=gain1[i/40]*qcelp_hammsinc(j+0.5)*pv [tmp];
+ ppv[i]+=gain2[i/40]*qcelp_hammsinc(j+0.5)*ppv[tmp];
+ }
}
- if(j<4) break;
- }else if(i >= lag) /*XXX may be unneded*/
- {
- pv [i]+=gain1*pv [i - (int)lag];
- ppv[i]+=gain2*ppv[i - (int)lag];
}else
- break; /* shouldn't happen */
+ {
+ tmp=i-lag[i/40];
+
+ if(tmp < 0)
+ {
+ pv [i]+=gain1[i/40]* pitchf_mem[144+tmp];
+ ppv[i]+=gain2[i/40]*ppitchf_mem[144+tmp];
+ }else
+ {
+ pv [i]+=gain1[i/40]*pv [i - lrintf(lag[i/40])];
+ ppv[i]+=gain2[i/40]*ppv[i - lrintf(lag[i/40])];
+ }
+
+
+ }
+
+ qcelp_update_pitchf_mem( pitchf_mem, pv[i]);
+ qcelp_update_pitchf_mem(ppitchf_mem, ppv[i]);
}
- if(i < 160) return i;
break;
case RATE_QUARTER:
@@ -719,8 +767,17 @@ static int qcelp_decode_frame(AVCodecCon
if(!is_ifq)
{
qcelp_compute_svector(q->frame->rate, gain, index, cbseed, cdn_vector);
+
+ av_log(avctx, AV_LOG_DEBUG, "-------- Pre pitch filters --------\n");
+ av_log(avctx, AV_LOG_DEBUG, "[CDN_VECTOR]:\n");
+ for(i=0; i<160; i++)
+ {
+ av_log(avctx, AV_LOG_DEBUG, " %f", cdn_vector[i]);
+ }
/* pitch filter */
- if((is_ifq = qcelp_do_pitchfilter(q->frame, cdn_vector, ppf_vector)))
+ if((is_ifq = qcelp_do_pitchfilter(q->frame, q->pitchf_mem,
+ q->ppitchf_mem, cdn_vector,
+ ppf_vector)))
{
av_log(avctx, AV_LOG_ERROR, "Error can't pitch cdn_vector[%d]\n",
is_ifq);
@@ -728,21 +785,55 @@ static int qcelp_decode_frame(AVCodecCon
}
}
+ av_log(avctx, AV_LOG_DEBUG, "-------- Post pitch filters --------\n");
+ av_log(avctx, AV_LOG_DEBUG, "[CDN_VECTOR]:\n");
+ for(i=0; i<160; i++)
+ {
+ av_log(avctx, AV_LOG_DEBUG, " %f", cdn_vector[i]);
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "[PPF_VECTOR]:\n");
+ for(i=0; i<160; i++)
+ {
+ av_log(avctx, AV_LOG_DEBUG, " %f", ppf_vector[i]);
+ }
+ av_log(avctx, AV_LOG_DEBUG, "\n");
+
/* pitch gain control */
qcelp_apply_gain_ctrl(0, cdn_vector, ppf_vector);
+
+ av_log(avctx, AV_LOG_DEBUG, "-------- Post Gain control --------\n");
+ av_log(avctx, AV_LOG_DEBUG, "[CDN_VECTOR]:\n");
+ for(i=0; i<160; i++)
+ {
+ av_log(avctx, AV_LOG_DEBUG, " %f", cdn_vector[i]);
+ }
+ av_log(avctx, AV_LOG_DEBUG, "\n");
+
+ av_log(avctx, AV_LOG_DEBUG, "[PPF_VECTOR]:\n");
+ for(i=0; i<160; i++)
+ {
+ av_log(avctx, AV_LOG_DEBUG, " %f", ppf_vector[i]);
+ }
+ av_log(avctx, AV_LOG_DEBUG, "\n");
+
/* lsp freq interpolation */
qcelp_do_interpolate_lspf(q->frame->rate, q->prev_lspf, qtzd_lspf);
/* get lpc coeficients */
qcelp_lsp2lpc(avctx, qtzd_lspf, lpc);
/* Apply formant synthesis filter over the pitch prefilter output. */
+ av_log(avctx, AV_LOG_DEBUG, "-------- Output --------\n");
for(i=0; i<160; i++)
{
ppf_vector[i]=1.0/qcelp_prede_filter(lpc, ppf_vector[i]);
+ av_log(avctx, AV_LOG_DEBUG, " %f/", ppf_vector[i]);
/* WIP adaptive postfilter here */
/* output stage */
outbuffer[i]=av_clip(lrintf(ppf_vector[i]), -32768, 32767);
+ av_log(avctx, AV_LOG_DEBUG, "%d", outbuffer[i]);
}
+ av_log(avctx, AV_LOG_DEBUG, "\n");
if(is_ifq)
{
More information about the FFmpeg-soc
mailing list