Index: celt/celt_encoder.c |
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c |
index ffff0775dfd6181aa0bf0d899dddfffdd0efee44..86a3fbb5731ed574c91ebc5318259bdaf2395d7f 100644 |
--- a/celt/celt_encoder.c |
+++ b/celt/celt_encoder.c |
@@ -57,7 +57,6 @@ |
*/ |
struct OpusCustomEncoder { |
const OpusCustomMode *mode; /**< Mode used by the encoder */ |
- int overlap; |
int channels; |
int stream_channels; |
@@ -173,7 +172,6 @@ static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode, |
OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); |
st->mode = mode; |
- st->overlap = mode->overlap; |
st->stream_channels = st->channels = channels; |
st->upsample = 1; |
@@ -276,8 +274,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int |
} |
/*printf("\n");*/ |
/* First few samples are bad because we don't propagate the memory */ |
- for (i=0;i<12;i++) |
- tmp[i] = 0; |
+ OPUS_CLEAR(tmp, 12); |
#ifdef FIXED_POINT |
/* Normalize tmp to max range */ |
@@ -366,7 +363,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int |
/* Arbitrary metric for VBR boost */ |
tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); |
/* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ |
- *tf_estimate = celt_sqrt(MAX16(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); |
+ *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); |
/*printf("%d %f\n", tf_max, mask_metric);*/ |
RESTORE_STACK; |
#ifdef FUZZING |
@@ -419,7 +416,7 @@ int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands, |
static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, |
celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample) |
{ |
- const int overlap = OVERLAP(mode); |
+ const int overlap = mode->overlap; |
int N; |
int B; |
int shift; |
@@ -453,8 +450,7 @@ static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS |
int bound = B*N/upsample; |
for (i=0;i<bound;i++) |
out[c*B*N+i] *= upsample; |
- for (;i<B*N;i++) |
- out[c*B*N+i] = 0; |
+ OPUS_CLEAR(&out[c*B*N+bound], B*N-bound); |
} while (++c<C); |
} |
} |
@@ -469,26 +465,30 @@ void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RES |
int Nu; |
coef0 = coef[0]; |
+ m = *mem; |
+ /* Fast path for the normal 48kHz case and no clipping */ |
+ if (coef[1] == 0 && upsample == 1 && !clip) |
+ { |
+ for (i=0;i<N;i++) |
+ { |
+ opus_val16 x; |
+ x = SCALEIN(pcmp[CC*i]); |
+ /* Apply pre-emphasis */ |
+ inp[i] = SHL32(x, SIG_SHIFT) - m; |
+ m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT); |
+ } |
+ *mem = m; |
+ return; |
+ } |
Nu = N/upsample; |
if (upsample!=1) |
{ |
- for (i=0;i<N;i++) |
- inp[i] = 0; |
+ OPUS_CLEAR(inp, N); |
} |
for (i=0;i<Nu;i++) |
- { |
- celt_sig x; |
- |
- x = SCALEIN(pcmp[CC*i]); |
-#ifndef FIXED_POINT |
- /* Replace NaNs with zeros */ |
- if (!(x==x)) |
- x = 0; |
-#endif |
- inp[i*upsample] = x; |
- } |
+ inp[i*upsample] = SCALEIN(pcmp[CC*i]); |
#ifndef FIXED_POINT |
if (clip) |
@@ -500,7 +500,6 @@ void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RES |
#else |
(void)clip; /* Avoids a warning about clip being unused. */ |
#endif |
- m = *mem; |
#ifdef CUSTOM_MODES |
if (coef[1] != 0) |
{ |
@@ -520,11 +519,11 @@ void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RES |
{ |
for (i=0;i<N;i++) |
{ |
- celt_sig x; |
- x = SHL32(inp[i], SIG_SHIFT); |
+ opus_val16 x; |
+ x = inp[i]; |
/* Apply pre-emphasis */ |
- inp[i] = x + m; |
- m = - MULT16_32_Q15(coef0, x); |
+ inp[i] = SHL32(x, SIG_SHIFT) - m; |
+ m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT); |
} |
} |
*mem = m; |
@@ -575,15 +574,14 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient, |
*tf_sum = 0; |
for (i=0;i<len;i++) |
{ |
- int j, k, N; |
+ int k, N; |
int narrow; |
opus_val32 L1, best_L1; |
int best_level=0; |
N = (m->eBands[i+1]-m->eBands[i])<<LM; |
/* band is too narrow to be split down to LM=-1 */ |
narrow = (m->eBands[i+1]-m->eBands[i])==1; |
- for (j=0;j<N;j++) |
- tmp[j] = X[tf_chan*N0 + j+(m->eBands[i]<<LM)]; |
+ OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<<LM)], N); |
/* Just add the right channel if we're in stereo */ |
/*if (C==2) |
for (j=0;j<N;j++) |
@@ -593,8 +591,7 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient, |
/* Check the -1 case for transients */ |
if (isTransient && !narrow) |
{ |
- for (j=0;j<N;j++) |
- tmp_1[j] = tmp[j]; |
+ OPUS_COPY(tmp_1, tmp, N); |
haar1(tmp_1, N>>LM, 1<<LM); |
L1 = l1_metric(tmp_1, N, LM+1, bias); |
if (L1<best_L1) |
@@ -754,12 +751,12 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, |
static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
const opus_val16 *bandLogE, int end, int LM, int C, int N0, |
AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate, |
- int intensity, opus_val16 surround_trim) |
+ int intensity, opus_val16 surround_trim, int arch) |
{ |
int i; |
opus_val32 diff=0; |
int c; |
- int trim_index = 5; |
+ int trim_index; |
opus_val16 trim = QCONST16(5.f, 8); |
opus_val16 logXC, logXC2; |
if (C==2) |
@@ -769,10 +766,9 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
/* Compute inter-channel correlation for low frequencies */ |
for (i=0;i<8;i++) |
{ |
- int j; |
- opus_val32 partial = 0; |
- for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++) |
- partial = MAC16_16(partial, X[j], X[N0+j]); |
+ opus_val32 partial; |
+ partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)], |
+ (m->eBands[i+1]-m->eBands[i])<<LM, arch); |
sum = ADD16(sum, EXTRACT16(SHR32(partial, 18))); |
} |
sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum); |
@@ -780,22 +776,13 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
minXC = sum; |
for (i=8;i<intensity;i++) |
{ |
- int j; |
- opus_val32 partial = 0; |
- for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++) |
- partial = MAC16_16(partial, X[j], X[N0+j]); |
+ opus_val32 partial; |
+ partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)], |
+ (m->eBands[i+1]-m->eBands[i])<<LM, arch); |
minXC = MIN16(minXC, ABS16(EXTRACT16(SHR32(partial, 18)))); |
} |
minXC = MIN16(QCONST16(1.f, 10), ABS16(minXC)); |
/*printf ("%f\n", sum);*/ |
- if (sum > QCONST16(.995f,10)) |
- trim_index-=4; |
- else if (sum > QCONST16(.92f,10)) |
- trim_index-=3; |
- else if (sum > QCONST16(.85f,10)) |
- trim_index-=2; |
- else if (sum > QCONST16(.8f,10)) |
- trim_index-=1; |
/* mid-side savings estimations based on the LF average*/ |
logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum)); |
/* mid-side savings estimations based on min correlation */ |
@@ -819,14 +806,6 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
} while (++c<C); |
diff /= C*(end-1); |
/*printf("%f\n", diff);*/ |
- if (diff > QCONST16(2.f, DB_SHIFT)) |
- trim_index--; |
- if (diff > QCONST16(8.f, DB_SHIFT)) |
- trim_index--; |
- if (diff < -QCONST16(4.f, DB_SHIFT)) |
- trim_index++; |
- if (diff < -QCONST16(10.f, DB_SHIFT)) |
- trim_index++; |
trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 )); |
trim -= SHR16(surround_trim, DB_SHIFT-8); |
trim -= 2*SHR16(tf_estimate, 14-8); |
@@ -836,6 +815,8 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), |
(opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f)))); |
} |
+#else |
+ (void)analysis; |
#endif |
#ifdef FIXED_POINT |
@@ -843,10 +824,7 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, |
#else |
trim_index = (int)floor(.5f+trim); |
#endif |
- if (trim_index<0) |
- trim_index = 0; |
- if (trim_index>10) |
- trim_index = 10; |
+ trim_index = IMAX(0, IMIN(10, trim_index)); |
/*printf("%d\n", trim_index);*/ |
#ifdef FUZZING |
trim_index = rand()%11; |
@@ -886,6 +864,66 @@ static int stereo_analysis(const CELTMode *m, const celt_norm *X, |
> MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); |
} |
+#define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0) |
+static opus_val16 median_of_5(const opus_val16 *x) |
+{ |
+ opus_val16 t0, t1, t2, t3, t4; |
+ t2 = x[2]; |
+ if (x[0] > x[1]) |
+ { |
+ t0 = x[1]; |
+ t1 = x[0]; |
+ } else { |
+ t0 = x[0]; |
+ t1 = x[1]; |
+ } |
+ if (x[3] > x[4]) |
+ { |
+ t3 = x[4]; |
+ t4 = x[3]; |
+ } else { |
+ t3 = x[3]; |
+ t4 = x[4]; |
+ } |
+ if (t0 > t3) |
+ { |
+ MSWAP(t0, t3); |
+ MSWAP(t1, t4); |
+ } |
+ if (t2 > t1) |
+ { |
+ if (t1 < t3) |
+ return MIN16(t2, t3); |
+ else |
+ return MIN16(t4, t1); |
+ } else { |
+ if (t2 < t3) |
+ return MIN16(t1, t3); |
+ else |
+ return MIN16(t2, t4); |
+ } |
+} |
+ |
+static opus_val16 median_of_3(const opus_val16 *x) |
+{ |
+ opus_val16 t0, t1, t2; |
+ if (x[0] > x[1]) |
+ { |
+ t0 = x[1]; |
+ t1 = x[0]; |
+ } else { |
+ t0 = x[0]; |
+ t1 = x[1]; |
+ } |
+ t2 = x[2]; |
+ if (t1 < t2) |
+ return t1; |
+ else if (t0 < t2) |
+ return t2; |
+ else |
+ return t0; |
+} |
+ |
static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2, |
int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN, |
int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM, |
@@ -899,8 +937,7 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 |
SAVE_STACK; |
ALLOC(follower, C*nbEBands, opus_val16); |
ALLOC(noise_floor, C*nbEBands, opus_val16); |
- for (i=0;i<nbEBands;i++) |
- offsets[i] = 0; |
+ OPUS_CLEAR(offsets, nbEBands); |
/* Dynamic allocation code */ |
maxDepth=-QCONST16(31.9f, DB_SHIFT); |
for (i=0;i<end;i++) |
@@ -922,7 +959,11 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 |
int last=0; |
c=0;do |
{ |
- follower[c*nbEBands] = bandLogE2[c*nbEBands]; |
+ opus_val16 offset; |
+ opus_val16 tmp; |
+ opus_val16 *f; |
+ f = &follower[c*nbEBands]; |
+ f[0] = bandLogE2[c*nbEBands]; |
for (i=1;i<end;i++) |
{ |
/* The last band to be at least 3 dB higher than the previous one |
@@ -930,12 +971,26 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 |
bandlimited signals. */ |
if (bandLogE2[c*nbEBands+i] > bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT)) |
last=i; |
- follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); |
+ f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); |
} |
for (i=last-1;i>=0;i--) |
- follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i], MIN16(follower[c*nbEBands+i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); |
+ f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); |
+ |
+ /* Combine with a median filter to avoid dynalloc triggering unnecessarily. |
+ The "offset" value controls how conservative we are -- a higher offset |
+ reduces the impact of the median filter and makes dynalloc use more bits. */ |
+ offset = QCONST16(1.f, DB_SHIFT); |
+ for (i=2;i<end-2;i++) |
+ f[i] = MAX16(f[i], median_of_5(&bandLogE2[c*nbEBands+i-2])-offset); |
+ tmp = median_of_3(&bandLogE2[c*nbEBands])-offset; |
+ f[0] = MAX16(f[0], tmp); |
+ f[1] = MAX16(f[1], tmp); |
+ tmp = median_of_3(&bandLogE2[c*nbEBands+end-3])-offset; |
+ f[end-2] = MAX16(f[end-2], tmp); |
+ f[end-1] = MAX16(f[end-1], tmp); |
+ |
for (i=0;i<end;i++) |
- follower[c*nbEBands+i] = MAX16(follower[c*nbEBands+i], noise_floor[i]); |
+ f[i] = MAX16(f[i], noise_floor[i]); |
} while (++c<C); |
if (C==2) |
{ |
@@ -1016,9 +1071,11 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, |
opus_val16 pf_threshold; |
int pf_on; |
int qg; |
+ int overlap; |
SAVE_STACK; |
mode = st->mode; |
+ overlap = mode->overlap; |
ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); |
pre[0] = _pre; |
@@ -1027,7 +1084,7 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, |
c=0; do { |
OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); |
- OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); |
+ OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N); |
} while (++c<CC); |
if (enabled) |
@@ -1044,7 +1101,7 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, |
pitch_index = COMBFILTER_MAXPERIOD-pitch_index; |
gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, |
- N, &pitch_index, st->prefilter_period, st->prefilter_gain); |
+ N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch); |
if (pitch_index > COMBFILTER_MAXPERIOD-2) |
pitch_index = COMBFILTER_MAXPERIOD-2; |
gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); |
@@ -1100,18 +1157,18 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, |
/*printf("%d %f\n", pitch_index, gain1);*/ |
c=0; do { |
- int offset = mode->shortMdctSize-st->overlap; |
+ int offset = mode->shortMdctSize-overlap; |
st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); |
- OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap); |
+ OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap); |
if (offset) |
- comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD, |
+ comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD, |
st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, |
st->prefilter_tapset, st->prefilter_tapset, NULL, 0); |
- comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, |
+ comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, |
st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, |
- st->prefilter_tapset, prefilter_tapset, mode->window, st->overlap); |
- OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap); |
+ st->prefilter_tapset, prefilter_tapset, mode->window, overlap); |
+ OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap); |
if (N>COMBFILTER_MAXPERIOD) |
{ |
@@ -1196,6 +1253,9 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32 |
/*printf("%f %f ", analysis->tonality, tonal);*/ |
target = tonal_target; |
} |
+#else |
+ (void)analysis; |
+ (void)pitch_change; |
#endif |
if (has_surround_mask&&!lfe) |
@@ -1273,6 +1333,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
int LM, M; |
int tf_select; |
int nbFilledBytes, nbAvailableBytes; |
+ int start; |
+ int end; |
int effEnd; |
int codedBands; |
int tf_sum; |
@@ -1316,6 +1378,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
nbEBands = mode->nbEBands; |
overlap = mode->overlap; |
eBands = mode->eBands; |
+ start = st->start; |
+ end = st->end; |
tf_estimate = 0; |
if (nbCompressedBytes<2 || pcm==NULL) |
{ |
@@ -1335,8 +1399,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
M=1<<LM; |
N = M*mode->shortMdctSize; |
- prefilter_mem = st->in_mem+CC*(st->overlap); |
- oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD)); |
+ prefilter_mem = st->in_mem+CC*(overlap); |
+ oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD)); |
oldLogE = oldBandE + CC*nbEBands; |
oldLogE2 = oldLogE + CC*nbEBands; |
@@ -1352,8 +1416,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
#ifdef CUSTOM_MODES |
if (st->signalling && enc==NULL) |
{ |
- int tmp = (mode->effEBands-st->end)>>1; |
- st->end = IMAX(1, mode->effEBands-tmp); |
+ int tmp = (mode->effEBands-end)>>1; |
+ end = st->end = IMAX(1, mode->effEBands-tmp); |
compressed[0] = tmp<<5; |
compressed[0] |= LM<<3; |
compressed[0] |= (C==2)<<2; |
@@ -1436,11 +1500,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
} |
total_bits = nbCompressedBytes*8; |
- effEnd = st->end; |
+ effEnd = end; |
if (effEnd > mode->effEBands) |
effEnd = mode->effEBands; |
- ALLOC(in, CC*(N+st->overlap), celt_sig); |
+ ALLOC(in, CC*(N+overlap), celt_sig); |
sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample)); |
st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample); |
@@ -1474,8 +1538,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
enc->nbits_total+=tell-ec_tell(enc); |
} |
c=0; do { |
- celt_preemphasis(pcm+c, in+c*(N+st->overlap)+st->overlap, N, CC, st->upsample, |
- mode->preemph, st->preemph_memE+c, st->clip); |
+ int need_clip=0; |
+#ifndef FIXED_POINT |
+ need_clip = st->clip && sample_max>65536.f; |
+#endif |
+ celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample, |
+ mode->preemph, st->preemph_memE+c, need_clip); |
} while (++c<CC); |
@@ -1484,7 +1552,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
{ |
int enabled; |
int qg; |
- enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && st->start==0 && !silence && !st->disable_pf |
+ enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && start==0 && !silence && !st->disable_pf |
&& st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE); |
prefilter_tapset = st->tapset_decision; |
@@ -1494,7 +1562,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
pitch_change = 1; |
if (pf_on==0) |
{ |
- if(st->start==0 && tell+16<=total_bits) |
+ if(start==0 && tell+16<=total_bits) |
ec_enc_bit_logp(enc, 0, 1); |
} else { |
/*This block is not gated by a total bits check only because |
@@ -1515,7 +1583,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
shortBlocks = 0; |
if (st->complexity >= 1 && !st->lfe) |
{ |
- isTransient = transient_analysis(in, N+st->overlap, CC, |
+ isTransient = transient_analysis(in, N+overlap, CC, |
&tf_estimate, &tf_chan); |
} |
if (LM>0 && ec_tell(enc)+3<=total_bits) |
@@ -1536,8 +1604,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
if (secondMdct) |
{ |
compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample); |
- compute_band_energies(mode, freq, bandE, effEnd, C, M); |
- amp2Log2(mode, effEnd, st->end, bandE, bandLogE2, C); |
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM); |
+ amp2Log2(mode, effEnd, end, bandE, bandLogE2, C); |
for (i=0;i<C*nbEBands;i++) |
bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT)); |
} |
@@ -1545,23 +1613,22 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample); |
if (CC==2&&C==1) |
tf_chan = 0; |
- compute_band_energies(mode, freq, bandE, effEnd, C, M); |
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM); |
if (st->lfe) |
{ |
- for (i=2;i<st->end;i++) |
+ for (i=2;i<end;i++) |
{ |
bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0])); |
bandE[i] = MAX32(bandE[i], EPSILON); |
} |
} |
- amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); |
+ amp2Log2(mode, effEnd, end, bandE, bandLogE, C); |
ALLOC(surround_dynalloc, C*nbEBands, opus_val16); |
- for(i=0;i<st->end;i++) |
- surround_dynalloc[i] = 0; |
+ OPUS_CLEAR(surround_dynalloc, end); |
/* This computes how much masking takes place between surround channels */ |
- if (st->start==0&&st->energy_mask&&!st->lfe) |
+ if (start==0&&st->energy_mask&&!st->lfe) |
{ |
int mask_end; |
int midband; |
@@ -1584,6 +1651,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
diff += MULT16_16(mask, 1+2*i-mask_end); |
} |
} |
+ celt_assert(count>0); |
mask_avg = DIV32_16(mask_avg,count); |
mask_avg += QCONST16(.2f, DB_SHIFT); |
diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end); |
@@ -1621,8 +1689,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
disabling masking. */ |
mask_avg = 0; |
diff = 0; |
- for(i=0;i<mask_end;i++) |
- surround_dynalloc[i] = 0; |
+ OPUS_CLEAR(surround_dynalloc, mask_end); |
} else { |
for(i=0;i<mask_end;i++) |
surround_dynalloc[i] = MAX16(0, surround_dynalloc[i]-QCONST16(.25f, DB_SHIFT)); |
@@ -1640,14 +1707,14 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
opus_val16 follow=-QCONST16(10.0f,DB_SHIFT); |
opus_val32 frame_avg=0; |
opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; |
- for(i=st->start;i<st->end;i++) |
+ for(i=start;i<end;i++) |
{ |
follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset); |
if (C==2) |
follow = MAX16(follow, bandLogE[i+nbEBands]-offset); |
frame_avg += follow; |
} |
- frame_avg /= (st->end-st->start); |
+ frame_avg /= (end-start); |
temporal_vbr = SUB16(frame_avg,st->spec_avg); |
temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); |
st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); |
@@ -1658,21 +1725,20 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
if (!secondMdct) |
{ |
- for (i=0;i<C*nbEBands;i++) |
- bandLogE2[i] = bandLogE[i]; |
+ OPUS_COPY(bandLogE2, bandLogE, C*nbEBands); |
} |
/* Last chance to catch any transient we might have missed in the |
time-domain analysis */ |
if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe) |
{ |
- if (patch_transient_decision(bandLogE, oldBandE, nbEBands, st->end, C)) |
+ if (patch_transient_decision(bandLogE, oldBandE, nbEBands, end, C)) |
{ |
isTransient = 1; |
shortBlocks = M; |
compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample); |
- compute_band_energies(mode, freq, bandE, effEnd, C, M); |
- amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); |
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM); |
+ amp2Log2(mode, effEnd, end, bandE, bandLogE, C); |
/* Compensate for the scaling of short vs long mdcts */ |
for (i=0;i<C*nbEBands;i++) |
bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT)); |
@@ -1690,7 +1756,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
ALLOC(tf_res, nbEBands, int); |
/* Disable variable tf resolution for hybrid and at very low bitrate */ |
- if (effectiveBytes>=15*C && st->start==0 && st->complexity>=2 && !st->lfe) |
+ if (effectiveBytes>=15*C && start==0 && st->complexity>=2 && !st->lfe) |
{ |
int lambda; |
if (effectiveBytes<40) |
@@ -1703,22 +1769,22 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
lambda = 3; |
lambda*=2; |
tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan); |
- for (i=effEnd;i<st->end;i++) |
+ for (i=effEnd;i<end;i++) |
tf_res[i] = tf_res[effEnd-1]; |
} else { |
tf_sum = 0; |
- for (i=0;i<st->end;i++) |
+ for (i=0;i<end;i++) |
tf_res[i] = isTransient; |
tf_select=0; |
} |
ALLOC(error, C*nbEBands, opus_val16); |
- quant_coarse_energy(mode, st->start, st->end, effEnd, bandLogE, |
+ quant_coarse_energy(mode, start, end, effEnd, bandLogE, |
oldBandE, total_bits, error, enc, |
C, LM, nbAvailableBytes, st->force_intra, |
&st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); |
- tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc); |
+ tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc); |
if (ec_tell(enc)+4<=total_bits) |
{ |
@@ -1726,7 +1792,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
{ |
st->tapset_decision = 0; |
st->spread_decision = SPREAD_NORMAL; |
- } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || st->start != 0) |
+ } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || start != 0) |
{ |
if (st->complexity == 0) |
st->spread_decision = SPREAD_NONE; |
@@ -1760,7 +1826,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
ALLOC(offsets, nbEBands, int); |
- maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, st->start, st->end, C, offsets, |
+ maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets, |
st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr, |
eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc); |
/* For LFE, everything interesting is in the first band */ |
@@ -1773,7 +1839,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
total_bits<<=BITRES; |
total_boost = 0; |
tell = ec_tell_frac(enc); |
- for (i=st->start;i<st->end;i++) |
+ for (i=start;i<end;i++) |
{ |
int width, quanta; |
int dynalloc_loop_logp; |
@@ -1818,7 +1884,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
st->intensity = hysteresis_decision((opus_val16)(equiv_rate/1000), |
intensity_thresholds, intensity_histeresis, 21, st->intensity); |
- st->intensity = IMIN(st->end,IMAX(st->start, st->intensity)); |
+ st->intensity = IMIN(end,IMAX(start, st->intensity)); |
} |
alloc_trim = 5; |
@@ -1828,7 +1894,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
alloc_trim = 5; |
else |
alloc_trim = alloc_trim_analysis(mode, X, bandLogE, |
- st->end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, st->intensity, surround_trim); |
+ end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, |
+ st->intensity, surround_trim, st->arch); |
ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); |
tell = ec_tell_frac(enc); |
} |
@@ -1930,7 +1997,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1; |
anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0; |
bits -= anti_collapse_rsv; |
- signalBandwidth = st->end-1; |
+ signalBandwidth = end-1; |
#ifndef DISABLE_FLOAT_API |
if (st->analysis.valid) |
{ |
@@ -1950,7 +2017,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
#endif |
if (st->lfe) |
signalBandwidth = 1; |
- codedBands = compute_allocation(mode, st->start, st->end, offsets, cap, |
+ codedBands = compute_allocation(mode, start, end, offsets, cap, |
alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses, |
fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth); |
if (st->lastCodedBands) |
@@ -1958,13 +2025,14 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
else |
st->lastCodedBands = codedBands; |
- quant_fine_energy(mode, st->start, st->end, oldBandE, error, fine_quant, enc, C); |
+ quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C); |
/* Residual quantisation */ |
ALLOC(collapse_masks, C*nbEBands, unsigned char); |
- quant_all_bands(1, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, |
- bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, st->intensity, tf_res, |
- nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng); |
+ quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, |
+ bandE, pulses, shortBlocks, st->spread_decision, |
+ dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, |
+ balance, enc, LM, codedBands, &st->rng, st->arch); |
if (anti_collapse_rsv > 0) |
{ |
@@ -1974,7 +2042,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
#endif |
ec_enc_bits(enc, anti_collapse_on, 1); |
} |
- quant_energy_finalise(mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); |
+ quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); |
if (silence) |
{ |
@@ -1990,40 +2058,25 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
if (anti_collapse_on) |
{ |
anti_collapse(mode, X, collapse_masks, LM, C, N, |
- st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); |
- } |
- |
- if (silence) |
- { |
- for (i=0;i<C*N;i++) |
- freq[i] = 0; |
- } else { |
- /* Synthesis */ |
- denormalise_bands(mode, X, freq, oldBandE, st->start, effEnd, C, M); |
+ start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); |
} |
c=0; do { |
OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2); |
} while (++c<CC); |
- if (CC==2&&C==1) |
- { |
- for (i=0;i<N;i++) |
- freq[N+i] = freq[i]; |
- } |
- |
c=0; do { |
out_mem[c] = st->syn_mem[c]+2*MAX_PERIOD-N; |
} while (++c<CC); |
- compute_inv_mdcts(mode, shortBlocks, freq, out_mem, CC, LM); |
+ celt_synthesis(mode, X, out_mem, oldBandE, start, effEnd, C, CC, isTransient, LM, st->upsample, silence); |
c=0; do { |
st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); |
st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); |
comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize, |
st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, |
- mode->window, st->overlap); |
+ mode->window, overlap); |
if (LM!=0) |
comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize, |
st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, |
@@ -2031,7 +2084,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
} while (++c<CC); |
/* We reuse freq[] as scratch space for the de-emphasis */ |
- deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, mode->preemph, st->preemph_memD, freq); |
+ deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, mode->preemph, st->preemph_memD); |
st->prefilter_period_old = st->prefilter_period; |
st->prefilter_gain_old = st->prefilter_gain; |
st->prefilter_tapset_old = st->prefilter_tapset; |
@@ -2051,16 +2104,13 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
#endif |
if (CC==2&&C==1) { |
- for (i=0;i<nbEBands;i++) |
- oldBandE[nbEBands+i]=oldBandE[i]; |
+ OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); |
} |
if (!isTransient) |
{ |
- for (i=0;i<CC*nbEBands;i++) |
- oldLogE2[i] = oldLogE[i]; |
- for (i=0;i<CC*nbEBands;i++) |
- oldLogE[i] = oldBandE[i]; |
+ OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands); |
+ OPUS_COPY(oldLogE, oldBandE, CC*nbEBands); |
} else { |
for (i=0;i<CC*nbEBands;i++) |
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); |
@@ -2068,12 +2118,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, |
/* In case start or end were to change */ |
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); |
@@ -2274,7 +2324,7 @@ int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...) |
{ |
int i; |
opus_val16 *oldBandE, *oldLogE, *oldLogE2; |
- oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->overlap+COMBFILTER_MAXPERIOD)); |
+ oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD)); |
oldLogE = oldBandE + st->channels*st->mode->nbEBands; |
oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; |
OPUS_CLEAR((char*)&st->ENCODER_RESET_START, |