ref: 798ab38b27e362c58108011f098e5b1b1a040c6b
parent: 0719f6fc25d6ab376f674cd204cf4f4ae2d57e21
author: Jean-Marc Valin <[email protected]>
date: Sun Jul 12 16:41:29 EDT 2009
Using normalised M/S stereo data for folding and use separate folding gains for M and S.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -458,7 +458,7 @@
/* If pitch isn't available, use intra-frame prediction */
if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
{
- intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], q, norm, P+eBands[i], eBands[i], B);
+ intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], &q, norm, P+eBands[i], eBands[i], B);
} else if (pitch_used && eBands[i] < m->pitchEnd) {
for (j=eBands[i];j<eBands[i+1];j++)
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
@@ -502,6 +502,7 @@
balance = 0;
for (i=0;i<m->nbEBands;i++)
{
+ int c;
int tell;
int q1, q2;
celt_word16_t n;
@@ -618,7 +619,8 @@
/* If pitch isn't available, use intra-frame prediction */
if ((eBands[i] >= m->pitchEnd && fold) || (q1+q2)<=0)
{
- intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q1+q2, norm, P+C*eBands[i], eBands[i], B);
+ int K[2] = {q1, q2};
+ intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], K, norm, P+C*eBands[i], eBands[i], B);
deinterleave(P+C*eBands[i], C*N);
} else if (pitch_used && eBands[i] < m->pitchEnd) {
stereo_band_mix(m, P, bandE, qb==0, i, 1);
@@ -650,6 +652,10 @@
mid = (1./32768)*imid;
side = (1./32768)*iside;
#endif
+ for (c=0;c<C;c++)
+ for (j=0;j<N;j++)
+ norm[C*(eBands[i]+j)+c] = MULT16_16_Q15(n,X[C*eBands[i]+c*N+j]);
+
for (j=0;j<N;j++)
X[C*eBands[i]+j] = MULT16_16_Q15(X[C*eBands[i]+j], mid);
for (j=0;j<N;j++)
@@ -656,8 +662,6 @@
X[C*eBands[i]+N+j] = MULT16_16_Q15(X[C*eBands[i]+N+j], side);
interleave(X+C*eBands[i], C*N);
- for (j=0;j<C*N;j++)
- norm[C*eBands[i]+j] = MULT16_16_Q15(n,X[C*eBands[i]+j]);
stereo_band_mix(m, X, bandE, 0, i, -1);
@@ -738,7 +742,7 @@
/* If pitch isn't available, use intra-frame prediction */
if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
{
- intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], q, norm, P+eBands[i], eBands[i], B);
+ intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], &q, norm, P+eBands[i], eBands[i], B);
} else if (pitch_used && eBands[i] < m->pitchEnd) {
for (j=eBands[i];j<eBands[i+1];j++)
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
@@ -782,6 +786,7 @@
balance = 0;
for (i=0;i<m->nbEBands;i++)
{
+ int c;
int tell;
int q1, q2;
celt_word16_t n;
@@ -885,7 +890,8 @@
/* If pitch isn't available, use intra-frame prediction */
if ((eBands[i] >= m->pitchEnd && fold) || (q1+q2)<=0)
{
- intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q1+q2, norm, P+C*eBands[i], eBands[i], B);
+ int K[2] = {q1, q2};
+ intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], K, norm, P+C*eBands[i], eBands[i], B);
deinterleave(P+C*eBands[i], C*N);
} else if (pitch_used && eBands[i] < m->pitchEnd) {
stereo_band_mix(m, P, bandE, qb==0, i, 1);
@@ -918,15 +924,16 @@
mid = (1./32768)*imid;
side = (1./32768)*iside;
#endif
+ for (c=0;c<C;c++)
+ for (j=0;j<N;j++)
+ norm[C*(eBands[i]+j)+c] = MULT16_16_Q15(n,X[C*eBands[i]+c*N+j]);
+
for (j=0;j<N;j++)
X[C*eBands[i]+j] = MULT16_16_Q15(X[C*eBands[i]+j], mid);
for (j=0;j<N;j++)
X[C*eBands[i]+N+j] = MULT16_16_Q15(X[C*eBands[i]+N+j], side);
-
- interleave(X+C*eBands[i], C*N);
- for (j=0;j<C*N;j++)
- norm[C*eBands[i]+j] = MULT16_16_Q15(n,X[C*eBands[i]+j]);
+ interleave(X+C*eBands[i], C*N);
stereo_band_mix(m, X, bandE, 0, i, -1);
renormalise_vector(X+C*eBands[i], Q15ONE, N, C);
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -39,7 +39,7 @@
#include "psy.h"
#include "pitch.h"
-#define CELT_BITSTREAM_VERSION 0x80000008
+#define CELT_BITSTREAM_VERSION 0x80000009
#ifdef STATIC_MODES
#include "static_modes.h"
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -370,17 +370,22 @@
P[j] = Y[id++];
}
-void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
+void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int *pulses, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
{
+ int c;
celt_word16_t pred_gain;
const int C = CHANNELS(m);
- if (K==0)
- pred_gain = Q15ONE;
- else
- pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+2*K*(K+1)));
-
fold(m, N, Y, P, N0, B);
- renormalise_vector(P, pred_gain, C*N, 1);
+ c=0;
+ do {
+ int K = pulses[c];
+ if (K==0)
+ pred_gain = Q15ONE;
+ else
+ pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+2*K*(K+1)));
+
+ renormalise_vector(P+c, pred_gain, N, C);
+ } while (++c < C);
}
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -74,6 +74,6 @@
* @param B Stride (number of channels multiplied by the number of MDCTs per frame)
* @param N0 Number of valid offsets
*/
-void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B);
+void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int *pulses, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B);
#endif /* VQ_H */