Squashed commit of the following:
commit a2cc77cb2744a2cb0551b9bfdf06b97457b6d449
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Thu Nov 4 13:11:21 2010 -0400
Adding a switch to enable the post-filter (off by default)
commit 8e860dc0dfbe57e59fcbd5352588c5edff020e27
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Thu Nov 4 11:57:12 2010 -0400
Allowing pitches up to 3000 Hz
commit 837412d37bbca32bb34bfb5941e132ff4b0a568c
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Wed Nov 3 20:47:11 2010 -0400
Pitch estimation tuning to prevent some cases of pitch halving
commit 34e20f24c85b40fffd1a15c5b632f2f78b26f081
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Nov 3 16:31:51 2010 -0400
Resynthesis now purely a compile-time option with RESYNTH
commit d83fb5a9cc2ec4b6cce938662997643da1c5ed0d
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Nov 3 16:28:25 2010 -0400
Fixes a divide by zero in remove_doubling()
commit bb91e05b7f8f91fd15a8a0daae3d8cb6bd8d81db
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Nov 3 15:55:48 2010 -0400
Bring back resynthesis with RESYNTH macro
commit 31fe6f6b4997af0a46b8c62f523fe2dfdb7f56ae
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Tue Nov 2 17:55:04 2010 -0400
Tuning the allocation tilt to give more bits to higher frequencies.
Especially useful now that the post-filter can reduce low freq noise.
commit 919ba48f0369a87885334756cdfac2a448ce52d0
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Nov 1 17:27:19 2010 -0400
C89 fix
commit ee0dbb1855a82ee8c132ddaffcab4d072bb3455e
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Nov 1 11:45:10 2010 -0400
Complete fixed-point port of the pitch code (I think).
commit 4c7b3fd12a8f7469607b5ac57c85301a5de9fa81
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Nov 1 10:55:43 2010 -0400
More fixed-point pitch gain work
commit 26f1412188900199b63e187fcb0bd04db53c898a
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Nov 1 10:39:25 2010 -0400
Fixed-point version of the pitch gain calculation code
commit 27c73d008e9f50d282c3ad08e2f05f7006013ae1
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Sun Oct 31 16:50:26 2010 -0400
Some more fixed-point work in remove_doubling()
commit 59354672cb3af794a0e46c0b2097d6441c75cdd1
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Sun Oct 31 09:57:36 2010 -0400
Fixed a stupid fixed-point pf bug in the gain handling
commit be9e7dabf6c8b32bc049da260b58ff6085dc1ac3
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Sat Oct 30 01:52:09 2010 -0400
Fixed-point: fixed frac_div32() that was broken a few commits ago.
commit 5b06270afc41a88915252cea14411be43650e704
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 17:45:44 2010 -0400
This fixes VBR when encoding the pitch period with raw bits
commit 10e0488458ae558aa80d0b30cce70841ad081f73
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 16:50:31 2010 -0400
Pitch period is now encoder with equal probability for each octave (rather than each lag).
Max pitch gain allowed is now 0.625.
commit ca19396c1c1511c0e208b400efb51384fc7c200d
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 16:00:01 2010 -0400
More fixed-point post-filter work
commit f3e42fde1b575bc587b2557b8b31a6085421a99c
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 14:39:23 2010 -0400
More fixed-point work for the prefilter/postfilter
commit db945132d12b25ff25acc0701b91a1d8a81417d5
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 14:14:02 2010 -0400
Making the pitch estimation work in fixed-point
Even if there's still lots of float operations left.
commit acb3f96e04802ac4601295f83bef1f32593e261a
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Fri Oct 29 10:57:39 2010 -0400
Making the PLC code consistent with the prefilter/postfilter
commit 8f64f5974ac846b8c35d0b692e0472f279206cf0
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Thu Oct 28 00:33:53 2010 -0400
More tuning for remove_doubling()
commit 0c08f2ee9dcc135dd222fef30f5ad93e95e0d364
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 17:48:02 2010 -0400
Doing an interpolation step to improve the accuracy of the pitch estimate
Also increasing the gain slightly.
commit 23d303e992f1fdc3d2668652603ae6311d3b91c5
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 16:56:42 2010 -0400
Implements a fixed 3-tap prefilter/postfilter to make the gain roll off with frequency
commit 881c5928adc1af9eb75c4b68e9eba94ab1d65adc
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 14:47:30 2010 -0400
Partially whitening the down-sampled signal before the pitch search
commit 4a8687deea8587007f14051cb966f6fd748893a1
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 14:27:47 2010 -0400
pitch_search() no longer computes the gain
commit a7f85bb6b10d9c509caec521ca444efb3f27df05
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 14:00:53 2010 -0400
remove_doubling() now works on the down-sampled signal
commit 06cb70e876873f79fed214ebbca35cb4c5057ec8
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 11:28:53 2010 -0400
Simplification to the pitch continuity code
commit 5201927c284a424eb8f21f63d358844b3de8c285
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Wed Oct 27 11:04:02 2010 -0400
Some more pitch doubling prevention code
commit 7ef63fbe1f78f79e1923bc42e06fbdf1ec28ffd3
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Wed Oct 27 06:49:28 2010 -0400
Minor fix
commit eb37eaab32e7df074a7ddf0ae4781e57f827c4ad
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Tue Oct 26 18:32:25 2010 -0400
Enforcing some pitch continuity
commit 751ef6edf2ee7721252cedb264bdf9b3f6244a9d
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Tue Oct 26 17:29:47 2010 -0400
Code for preventing pitch doubling/halving
commit c12647ecb55b645005efbeede91880db72936f8d
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Tue Oct 26 00:04:34 2010 -0400
Finally getting perfect reconstruction when pitch changes
Post-filter now delays the filter coefs by the overlap so that the pre-filter
and post-filter are synchronised.
commit f854311d945bb375039a4a4a4fea782b648581f8
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Oct 25 14:59:13 2010 -0400
Very simple/inefficient signalling of the prefilter period/gain
commit b4e1215432e3d89a29c998639a6d8b07e28c5a2a
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Oct 25 14:09:17 2010 -0400
using the actual pitch gain
commit e7cd4f07bb073b6955a001e56c0bbf16156f4195
Author: Jean-Marc Valin <jean-marc.valin@octasic.com>
Date: Mon Oct 25 12:16:11 2010 -0400
Adding some pitch prediction though side information still isn't coded
commit 77a03aa27c9b6ed2fe80c27a1196b460ccb5079e
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Mon Oct 25 00:12:48 2010 -0400
prefilter implemented as well
commit a3fd81b6ca213d4a9f8ddfa2883fd0e238d64d04
Author: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Date: Sun Oct 24 01:14:10 2010 -0400
Implementing Raymond Chen's comb filter idea
So far, only the post-filter is there.
diff --git a/libcelt/pitch.c b/libcelt/pitch.c
index 533f997..bff5c70 100644
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -46,7 +46,8 @@
#include "stack_alloc.h"
#include "mathops.h"
-static void find_best_pitch(celt_word32 *xcorr, celt_word32 maxcorr, celt_word16 *y, int yshift, int len, int max_pitch, int best_pitch[2])
+static void find_best_pitch(celt_word32 *xcorr, celt_word32 maxcorr, celt_word16 *y,
+ int yshift, int len, int max_pitch, int best_pitch[2])
{
int i, j;
celt_word32 Syy=1;
@@ -96,28 +97,65 @@
}
}
+#include "plc.h"
void pitch_downsample(celt_sig * restrict x[], celt_word16 * restrict x_lp, int len, int end, int _C, celt_sig * restrict xmem, celt_word16 * restrict filt_mem)
{
int i;
+ celt_word32 ac[5];
+ celt_word16 tmp=Q15ONE;
+ celt_word16 lpc[4], mem[4]={0,0,0,0};
const int C = CHANNELS(_C);
for (i=1;i<len>>1;i++)
- x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT);
- x_lp[0] = SHR32(HALF32(HALF32(*xmem+x[0][1])+x[0][0]), SIG_SHIFT);
+ x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+2);
+ x_lp[0] = SHR32(HALF32(HALF32(*xmem+x[0][1])+x[0][0]), SIG_SHIFT+2);
*xmem = x[0][end-1];
if (C==2)
{
for (i=1;i<len>>1;i++)
- x_lp[i] = SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT);
- x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT);
+ x_lp[i] = SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+2);
+ x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+2);
*xmem += x[1][end-1];
}
+
+ _celt_autocorr(x_lp, ac, NULL, 0,
+ 4, len>>1);
+
+ /* Noise floor -40 dB */
+#ifdef FIXED_POINT
+ ac[0] += SHR32(ac[0],13);
+#else
+ ac[0] *= 1.0001f;
+#endif
+ /* Lag windowing */
+ for (i=1;i<=4;i++)
+ {
+ /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
+#ifdef FIXED_POINT
+ ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
+#else
+ ac[i] -= ac[i]*(.008f*i)*(.008f*i);
+#endif
+ }
+
+ _celt_lpc(lpc, ac, 4);
+ for (i=0;i<4;i++)
+ {
+ tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);
+ lpc[i] = MULT16_16_Q15(lpc[i], tmp);
+ }
+ fir(x_lp, lpc, x_lp, len>>1, 4, mem);
+
+ mem[0]=0;
+ lpc[0]=QCONST16(.8,12);
+ fir(x_lp, lpc, x_lp, len>>1, 1, mem);
+
}
-void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_word16 * restrict y, int len, int max_pitch, int *pitch, celt_sig *xmem, int M)
+void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_word16 * restrict y,
+ int len, int max_pitch, int *pitch, celt_sig *xmem, int M)
{
int i, j;
- const int lag = MAX_PERIOD;
- const int N = M*m->shortMdctSize;
+ int lag;
int best_pitch[2]={0};
VARDECL(celt_word16, x_lp4);
VARDECL(celt_word16, y_lp4);
@@ -128,6 +166,8 @@
SAVE_STACK;
+ lag = len+max_pitch;
+
ALLOC(x_lp4, len>>2, celt_word16);
ALLOC(y_lp4, lag>>2, celt_word16);
ALLOC(xcorr, max_pitch>>1, celt_word32);
@@ -198,10 +238,135 @@
}
*pitch = 2*best_pitch[0]-offset;
- CELT_MOVE(y, y+(N>>1), (lag-N)>>1);
- CELT_MOVE(y+((lag-N)>>1), x_lp, N>>1);
-
RESTORE_STACK;
-
- /*printf ("%d\n", *pitch);*/
}
+
+#ifdef ENABLE_POSTFILTER
+static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
+celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
+ int N, int *_T0, int prev_period, celt_word16 prev_gain)
+{
+ int k, i, T, T0, k0;
+ celt_word16 g, g0;
+ celt_word16 pg;
+ celt_word32 xy,xx,yy;
+ celt_word32 xcorr[3];
+ celt_word32 best_xy, best_yy;
+ int offset;
+
+ maxperiod /= 2;
+ minperiod /= 2;
+ *_T0 /= 2;
+ prev_period /= 2;
+ N /= 2;
+ x += maxperiod;
+ if (*_T0>=maxperiod)
+ *_T0=maxperiod-1;
+
+ T = T0 = *_T0;
+ xx=xy=yy=0;
+ for (i=0;i<N;i++)
+ {
+ xy = MAC16_16(xy, x[i], x[i-T0]);
+ xx = MAC16_16(xx, x[i], x[i]);
+ yy = MAC16_16(yy, x[i-T0],x[i-T0]);
+ }
+ best_xy = xy;
+ best_yy = yy;
+#ifdef FIXED_POINT
+ {
+ celt_word32 x2y2;
+ int sh, t;
+ x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
+ sh = celt_ilog2(x2y2)>>1;
+ t = VSHR32(x2y2, 2*(sh-7));
+ g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
+ }
+#else
+ g = g0 = xy/sqrt(1+xx*yy);
+#endif
+ k0 = 1;
+ /* Look for any pitch at T/k */
+ for (k=2;k<=15;k++)
+ {
+ int T1, T1b;
+ celt_word16 g1;
+ celt_word16 cont=0;
+ T1 = (2*T0+k)/(2*k);
+ if (T1 < minperiod)
+ break;
+ /* Look for another strong correlation at T1b */
+ if (k==2)
+ {
+ if (T1+T0>maxperiod)
+ T1b = T0;
+ else
+ T1b = T0+T1;
+ } else
+ {
+ T1b = (2*second_check[k]*T0+k)/(2*k);
+ }
+ xy=yy=0;
+ for (i=0;i<N;i++)
+ {
+ xy = MAC16_16(xy, x[i], x[i-T1]);
+ yy = MAC16_16(yy, x[i-T1], x[i-T1]);
+
+ xy = MAC16_16(xy, x[i], x[i-T1b]);
+ yy = MAC16_16(yy, x[i-T1b], x[i-T1b]);
+ }
+#ifdef FIXED_POINT
+ {
+ celt_word32 x2y2;
+ int sh, t;
+ x2y2 = 1+MULT32_32_Q31(xx,yy);
+ sh = celt_ilog2(x2y2)>>1;
+ t = VSHR32(x2y2, 2*(sh-7));
+ g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
+ }
+#else
+ g1 = xy/sqrt(1+2.f*xx*1.f*yy);
+#endif
+ if (abs(T1-prev_period)<=1)
+ cont = prev_gain;
+ else if (abs(T1-prev_period)<=2 && 5*k*k < T0)
+ cont = HALF32(prev_gain);
+ else
+ cont = 0;
+ if (g1 > QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont)
+ {
+ best_xy = xy;
+ best_yy = yy;
+ T = T1;
+ g = g1;
+ }
+ }
+ if (best_yy <= best_xy)
+ pg = Q15ONE;
+ else
+ pg = SHR32(frac_div32(best_xy,best_yy+1),16);
+
+ for (k=0;k<3;k++)
+ {
+ int T1 = T+k-1;
+ xy = 0;
+ for (i=0;i<N;i++)
+ xy = MAC16_16(xy, x[i], x[i-T1]);
+ xcorr[k] = xy;
+ }
+ if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0]))
+ offset = 1;
+ else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2]))
+ offset = -1;
+ else
+ offset = 0;
+ if (pg > g)
+ pg = g;
+ *_T0 = 2*T+offset;
+
+ if (*_T0<2*minperiod)
+ *_T0=2*minperiod;
+ return pg;
+}
+
+#endif /* ENABLE_POSTFILTER */