summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2014-01-19 16:31:59 +0100
committerNils Wallménius <nils@rockbox.org>2014-07-13 11:12:40 +0200
commit9b7ec42403073ee887efc531c153e6b1b6c15bab (patch)
tree07e72fe9d817c65a6fede22955344a870842d5e6 /lib/rbcodec/codecs/libopus/celt/celt_decoder.c
parente557951c94c1efa769900257e466900f0ffeb53b (diff)
downloadrockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.zip
rockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.tar.gz
rockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.tar.bz2
rockbox-9b7ec42403073ee887efc531c153e6b1b6c15bab.tar.xz
Sync to upstream libopus
Sync to commit bb4b6885a139644cf3ac14e7deda9f633ec2d93c This brings in a bunch of optimizations to decode speed and memory usage. Allocations are switched from using the pseudostack to using the real stack. Enabled hacks to reduce stack usage. This should fix crashes on sansa clip, although some files will not play due to failing allocations in the codec buffer. Speeds up decoding of the following test files: H300 (cf) C200 (arm7tdmi) ipod classic (arm9e) 16 kbps (silk) 14.28 MHz 4.00 MHz 2.61 MHz 64 kbps (celt) 4.09 MHz 8.08 MHz 6.24 MHz 128 kbps (celt) 1.93 MHz 8.83 MHz 6.53 MHz Change-Id: I851733a8a5824b61feb363a173091bc7e6629b58
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/celt_decoder.c')
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_decoder.c325
1 files changed, 180 insertions, 145 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
index 77fa2d0..8af96b7 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
@@ -51,6 +51,9 @@
#include "celt_lpc.h"
#include "vq.h"
+#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
+#define NORM_ALIASING_HACK
+#endif
/**********************************************************************/
/* */
/* DECODER */
@@ -175,28 +178,24 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
}
#endif /* CUSTOM_MODES */
-static OPUS_INLINE opus_val16 SIG2WORD16(celt_sig x)
-{
-#ifdef FIXED_POINT
- x = PSHR32(x, SIG_SHIFT);
- x = MAX32(x, -32768);
- x = MIN32(x, 32767);
- return EXTRACT16(x);
-#else
- return (opus_val16)x;
-#endif
-}
#ifndef RESYNTH
static
#endif
-void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch)
+void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef,
+ celt_sig *mem, int accum)
{
int c;
int Nd;
int apply_downsampling=0;
opus_val16 coef0;
-
+ VARDECL(celt_sig, scratch);
+ SAVE_STACK;
+#ifndef FIXED_POINT
+ (void)accum;
+ celt_assert(accum==0);
+#endif
+ ALLOC(scratch, N, celt_sig);
coef0 = coef[0];
Nd = N/downsample;
c=0; do {
@@ -234,11 +233,24 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
apply_downsampling=1;
} else {
/* Shortcut for the standard (non-custom modes) case */
- for (j=0;j<N;j++)
+#ifdef FIXED_POINT
+ if (accum)
{
- celt_sig tmp = x[j] + m + VERY_SMALL;
- m = MULT16_32_Q15(coef0, tmp);
- y[j*C] = SCALEOUT(SIG2WORD16(tmp));
+ for (j=0;j<N;j++)
+ {
+ celt_sig tmp = x[j] + m + VERY_SMALL;
+ m = MULT16_32_Q15(coef0, tmp);
+ y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));
+ }
+ } else
+#endif
+ {
+ for (j=0;j<N;j++)
+ {
+ celt_sig tmp = x[j] + m + VERY_SMALL;
+ m = MULT16_32_Q15(coef0, tmp);
+ y[j*C] = SCALEOUT(SIG2WORD16(tmp));
+ }
}
}
mem[c] = m;
@@ -246,41 +258,94 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
if (apply_downsampling)
{
/* Perform down-sampling */
- for (j=0;j<Nd;j++)
- y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));
+#ifdef FIXED_POINT
+ if (accum)
+ {
+ for (j=0;j<Nd;j++)
+ y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample]))));
+ } else
+#endif
+ {
+ for (j=0;j<Nd;j++)
+ y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));
+ }
}
} while (++c<C);
+ RESTORE_STACK;
}
-/** Compute the IMDCT and apply window for all sub-frames and
- all channels in a frame */
#ifndef RESYNTH
static
#endif
-void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
- celt_sig * OPUS_RESTRICT out_mem[], int C, int LM)
+void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
+ opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient,
+ int LM, int downsample, int silence)
{
- int b, c;
+ int c, i;
+ int M;
+ int b;
int B;
- int N;
+ int N, NB;
int shift;
- const int overlap = OVERLAP(mode);
+ int nbEBands;
+ int overlap;
+ VARDECL(celt_sig, freq);
+ SAVE_STACK;
- if (shortBlocks)
+ overlap = mode->overlap;
+ nbEBands = mode->nbEBands;
+ N = mode->shortMdctSize<<LM;
+ ALLOC(freq, N, celt_sig); /**< Interleaved signal MDCTs */
+ M = 1<<LM;
+
+ if (isTransient)
{
- B = shortBlocks;
- N = mode->shortMdctSize;
+ B = M;
+ NB = mode->shortMdctSize;
shift = mode->maxLM;
} else {
B = 1;
- N = mode->shortMdctSize<<LM;
+ NB = mode->shortMdctSize<<LM;
shift = mode->maxLM-LM;
}
- c=0; do {
- /* IMDCT on the interleaved the sub-frames, overlap-add is performed by the IMDCT */
+
+ if (CC==2&&C==1)
+ {
+ /* Copying a mono streams to two channels */
+ celt_sig *freq2;
+ denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
+ downsample, silence);
+ /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */
+ freq2 = out_syn[1]+overlap/2;
+ OPUS_COPY(freq2, freq, N);
for (b=0;b<B;b++)
- clt_mdct_backward(&mode->mdct, &X[b+c*N*B], out_mem[c]+N*b, mode->window, overlap, shift, B);
- } while (++c<C);
+ clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B);
+ for (b=0;b<B;b++)
+ clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B);
+ } else if (CC==1&&C==2)
+ {
+ /* Downmixing a stereo stream to mono */
+ celt_sig *freq2;
+ freq2 = out_syn[0]+overlap/2;
+ denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
+ downsample, silence);
+ /* Use the output buffer as temp array before downmixing. */
+ denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
+ downsample, silence);
+ for (i=0;i<N;i++)
+ freq[i] = HALF32(ADD32(freq[i],freq2[i]));
+ for (b=0;b<B;b++)
+ clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B);
+ } else {
+ /* Normal case (mono or stereo) */
+ c=0; do {
+ denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
+ downsample, silence);
+ for (b=0;b<B;b++)
+ clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B);
+ } while (++c<CC);
+ }
+ RESTORE_STACK;
}
static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)
@@ -330,7 +395,23 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
pitch of 480 Hz. */
#define PLC_PITCH_LAG_MIN (100)
-static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_RESTRICT pcm, int N, int LM)
+static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
+{
+ int pitch_index;
+ VARDECL( opus_val16, lp_pitch_buf );
+ SAVE_STACK;
+ ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
+ pitch_downsample(decode_mem, lp_pitch_buf,
+ DECODE_BUFFER_SIZE, C, arch);
+ pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
+ DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,
+ PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);
+ pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
+ RESTORE_STACK;
+ return pitch_index;
+}
+
+static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
{
int c;
int i;
@@ -343,11 +424,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
int nbEBands;
int overlap;
int start;
- int downsample;
int loss_count;
int noise_based;
const opus_int16 *eBands;
- VARDECL(celt_sig, scratch);
SAVE_STACK;
mode = st->mode;
@@ -367,14 +446,15 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
loss_count = st->loss_count;
start = st->start;
- downsample = st->downsample;
noise_based = loss_count >= 5 || start != 0;
- ALLOC(scratch, noise_based?N*C:N, celt_sig);
if (noise_based)
{
/* Noise-based PLC/CNG */
- celt_sig *freq;
+#ifdef NORM_ALIASING_HACK
+ celt_norm *X;
+#else
VARDECL(celt_norm, X);
+#endif
opus_uint32 seed;
opus_val16 *plcLogE;
int end;
@@ -383,10 +463,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
end = st->end;
effEnd = IMAX(start, IMIN(end, mode->effEBands));
- /* Share the interleaved signal MDCT coefficient buffer with the
- deemphasis scratch buffer. */
- freq = scratch;
+#ifdef NORM_ALIASING_HACK
+ /* This is an ugly hack that breaks aliasing rules and would be easily broken,
+ but it saves almost 4kB of stack. */
+ X = (celt_norm*)(out_syn[C-1]+overlap/2);
+#else
ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+#endif
if (loss_count >= 5)
plcLogE = backgroundLogE;
@@ -421,20 +504,12 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
}
st->rng = seed;
- denormalise_bands(mode, X, freq, plcLogE, start, effEnd, C, 1<<LM);
-
- c=0; do {
- int bound = eBands[effEnd]<<LM;
- if (downsample!=1)
- bound = IMIN(bound, N/downsample);
- for (i=bound;i<N;i++)
- freq[c*N+i] = 0;
- } while (++c<C);
c=0; do {
OPUS_MOVE(decode_mem[c], decode_mem[c]+N,
DECODE_BUFFER_SIZE-N+(overlap>>1));
} while (++c<C);
- compute_inv_mdcts(mode, 0, freq, out_syn, C, LM);
+
+ celt_synthesis(mode, X, out_syn, plcLogE, start, effEnd, C, C, 0, LM, st->downsample, 0);
} else {
/* Pitch-based PLC */
const opus_val16 *window;
@@ -445,15 +520,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
if (loss_count == 0)
{
- VARDECL( opus_val16, lp_pitch_buf );
- ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
- pitch_downsample(decode_mem, lp_pitch_buf,
- DECODE_BUFFER_SIZE, C, st->arch);
- pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
- DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,
- PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, st->arch);
- pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
- st->last_pitch_index = pitch_index;
+ st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch);
} else {
pitch_index = st->last_pitch_index;
fade = QCONST16(.8f,15);
@@ -644,25 +711,23 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
} while (++c<C);
}
- deemphasis(out_syn, pcm, N, C, downsample,
- mode->preemph, st->preemph_memD, scratch);
-
st->loss_count = loss_count+1;
RESTORE_STACK;
}
-#define FREQ_X_BUF_SIZE (2*8*120) /* stereo * nbShortMdcts * shortMdctSize */
-static celt_sig s_freq[FREQ_X_BUF_SIZE] IBSS_ATTR MEM_ALIGN_ATTR; /* 7680 byte */
-static celt_norm s_X[FREQ_X_BUF_SIZE] IBSS_ATTR MEM_ALIGN_ATTR; /* 3840 byte */
-int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec)
+int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
+ int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
{
int c, i, N;
int spread_decision;
opus_int32 bits;
ec_dec _dec;
- VARDECL(celt_sig, freq);
+#ifdef NORM_ALIASING_HACK
+ celt_norm *X;
+#else
VARDECL(celt_norm, X);
+#endif
VARDECL(int, fine_quant);
VARDECL(int, pulses);
VARDECL(int, cap);
@@ -680,6 +745,8 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
int intra_ener;
const int CC = st->channels;
int LM, M;
+ int start;
+ int end;
int effEnd;
int codedBands;
int alloc_trim;
@@ -706,11 +773,10 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
nbEBands = mode->nbEBands;
overlap = mode->overlap;
eBands = mode->eBands;
+ start = st->start;
+ end = st->end;
frame_size *= st->downsample;
- c=0; do {
- decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
- } while (++c<CC);
lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);
oldBandE = lpc+CC*LPC_ORDER;
oldLogE = oldBandE + 2*nbEBands;
@@ -728,7 +794,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
if (data0<0)
return OPUS_INVALID_PACKET;
}
- st->end = IMAX(1, mode->effEBands-2*(data0>>5));
+ st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));
LM = (data0>>3)&0x3;
C = 1 + ((data0>>2)&0x1);
data++;
@@ -755,14 +821,19 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
return OPUS_BAD_ARG;
N = M*mode->shortMdctSize;
+ c=0; do {
+ decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
+ out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
+ } while (++c<CC);
- effEnd = st->end;
+ effEnd = end;
if (effEnd > mode->effEBands)
effEnd = mode->effEBands;
if (data == NULL || len<=1)
{
- celt_decode_lost(st, pcm, N, LM);
+ celt_decode_lost(st, N, LM);
+ deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
RESTORE_STACK;
return frame_size/st->downsample;
}
@@ -798,7 +869,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
postfilter_gain = 0;
postfilter_pitch = 0;
postfilter_tapset = 0;
- if (st->start==0 && tell+16 <= total_bits)
+ if (start==0 && tell+16 <= total_bits)
{
if(ec_dec_bit_logp(dec, 1))
{
@@ -829,11 +900,11 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
/* Decode the global flags (first symbols in the stream) */
intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
/* Get band energies */
- unquant_coarse_energy(mode, st->start, st->end, oldBandE,
+ unquant_coarse_energy(mode, start, end, oldBandE,
intra_ener, dec, C, LM);
ALLOC(tf_res, nbEBands, int);
- tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
+ tf_decode(start, end, isTransient, tf_res, LM, dec);
tell = ec_tell(dec);
spread_decision = SPREAD_NORMAL;
@@ -849,7 +920,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
dynalloc_logp = 6;
total_bits<<=BITRES;
tell = ec_tell_frac(dec);
- for (i=st->start;i<st->end;i++)
+ for (i=start;i<end;i++)
{
int width, quanta;
int dynalloc_loop_logp;
@@ -888,21 +959,28 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
ALLOC(pulses, nbEBands, int);
ALLOC(fine_priority, nbEBands, int);
- codedBands = compute_allocation(mode, st->start, st->end, offsets, cap,
+ codedBands = compute_allocation(mode, start, end, offsets, cap,
alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
- unquant_fine_energy(mode, st->start, st->end, oldBandE, fine_quant, dec, C);
+ unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C);
+
+ c=0; do {
+ OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);
+ } while (++c<CC);
/* Decode fixed codebook */
ALLOC(collapse_masks, C*nbEBands, unsigned char);
- /**< Interleaved normalised MDCTs */
- if (FREQ_X_BUF_SIZE >= C*N)
- X = s_X;
- else
- ALLOC(X, C*N, celt_norm);
- quant_all_bands(0, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
+#ifdef NORM_ALIASING_HACK
+ /* This is an ugly hack that breaks aliasing rules and would be easily broken,
+ but it saves almost 4kB of stack. */
+ X = (celt_norm*)(out_syn[CC-1]+overlap/2);
+#else
+ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+#endif
+
+ quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
@@ -911,58 +989,20 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
anti_collapse_on = ec_dec_bits(dec, 1);
}
- unquant_energy_finalise(mode, st->start, st->end, oldBandE,
+ unquant_energy_finalise(mode, start, end, oldBandE,
fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
if (anti_collapse_on)
anti_collapse(mode, X, collapse_masks, LM, C, N,
- st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
-
- /**< Interleaved signal MDCTs */
- if (FREQ_X_BUF_SIZE >= IMAX(CC,C)*N)
- freq = s_freq;
- else
- ALLOC(freq, IMAX(CC,C)*N, celt_sig);
+ start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
if (silence)
{
for (i=0;i<C*nbEBands;i++)
oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
- for (i=0;i<C*N;i++)
- freq[i] = 0;
- } else {
- /* Synthesis */
- denormalise_bands(mode, X, freq, oldBandE, st->start, effEnd, C, M);
}
- c=0; do {
- OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);
- } while (++c<CC);
- c=0; do {
- int bound = M*eBands[effEnd];
- if (st->downsample!=1)
- bound = IMIN(bound, N/st->downsample);
- for (i=bound;i<N;i++)
- freq[c*N+i] = 0;
- } while (++c<C);
-
- c=0; do {
- out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
- } while (++c<CC);
-
- if (CC==2&&C==1)
- {
- for (i=0;i<N;i++)
- freq[N+i] = freq[i];
- }
- if (CC==1&&C==2)
- {
- for (i=0;i<N;i++)
- freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
- }
-
- /* Compute inverse MDCTs */
- compute_inv_mdcts(mode, shortBlocks, freq, out_syn, CC, LM);
+ celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, CC, isTransient, LM, st->downsample, silence);
c=0; do {
st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
@@ -989,18 +1029,14 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
st->postfilter_tapset_old = st->postfilter_tapset;
}
- if (C==1) {
- for (i=0;i<nbEBands;i++)
- oldBandE[nbEBands+i]=oldBandE[i];
- }
+ if (C==1)
+ OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
/* In case start or end were to change */
if (!isTransient)
{
- for (i=0;i<2*nbEBands;i++)
- oldLogE2[i] = oldLogE[i];
- for (i=0;i<2*nbEBands;i++)
- oldLogE[i] = oldBandE[i];
+ OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
+ OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
for (i=0;i<2*nbEBands;i++)
backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
} else {
@@ -1009,12 +1045,12 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
}
c=0; do
{
- for (i=0;i<st->start;i++)
+ for (i=0;i<start;i++)
{
oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
}
- for (i=st->end;i<nbEBands;i++)
+ for (i=end;i<nbEBands;i++)
{
oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
@@ -1022,8 +1058,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
} while (++c<2);
st->rng = dec->rng;
- /* We reuse freq[] as scratch space for the de-emphasis */
- deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, freq);
+ deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
st->loss_count = 0;
RESTORE_STACK;
if (ec_tell(dec) > 8*len)
@@ -1039,7 +1074,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
#ifdef FIXED_POINT
int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
{
- return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
+ return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
}
#ifndef DISABLE_FLOAT_API
@@ -1056,7 +1091,7 @@ int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char
N = frame_size;
ALLOC(out, C*N, opus_int16);
- ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
+ ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)
pcm[j]=out[j]*(1.f/32768.f);
@@ -1070,7 +1105,7 @@ int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char
int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
{
- return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
+ return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
}
int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
@@ -1086,7 +1121,7 @@ int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data
N = frame_size;
ALLOC(out, C*N, celt_sig);
- ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
+ ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)