| Index: celt/celt_encoder.c
|
| diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c
|
| index 59dcc5c61eabca745030b6fa89f3369b842912a5..ffff0775dfd6181aa0bf0d899dddfffdd0efee44 100644
|
| --- a/celt/celt_encoder.c
|
| +++ b/celt/celt_encoder.c
|
| @@ -161,17 +161,8 @@ CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int
|
| }
|
| #endif /* CUSTOM_MODES */
|
|
|
| -int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels)
|
| -{
|
| - int ret;
|
| - ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
|
| - if (ret != OPUS_OK)
|
| - return ret;
|
| - st->upsample = resampling_factor(sampling_rate);
|
| - return OPUS_OK;
|
| -}
|
| -
|
| -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
|
| +static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode,
|
| + int channels, int arch)
|
| {
|
| if (channels < 0 || channels > 2)
|
| return OPUS_BAD_ARG;
|
| @@ -190,7 +181,7 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMod
|
| st->end = st->mode->effEBands;
|
| st->signalling = 1;
|
|
|
| - st->arch = opus_select_arch();
|
| + st->arch = arch;
|
|
|
| st->constrained_vbr = 1;
|
| st->clip = 1;
|
| @@ -207,6 +198,25 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMod
|
| }
|
|
|
| #ifdef CUSTOM_MODES
|
| +int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
|
| +{
|
| + return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch());
|
| +}
|
| +#endif
|
| +
|
| +int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
|
| + int arch)
|
| +{
|
| + int ret;
|
| + ret = opus_custom_encoder_init_arch(st,
|
| + opus_custom_mode_create(48000, 960, NULL), channels, arch);
|
| + if (ret != OPUS_OK)
|
| + return ret;
|
| + st->upsample = resampling_factor(sampling_rate);
|
| + return OPUS_OK;
|
| +}
|
| +
|
| +#ifdef CUSTOM_MODES
|
| void opus_custom_encoder_destroy(CELTEncoder *st)
|
| {
|
| opus_free(st);
|
| @@ -240,7 +250,6 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
|
| ALLOC(tmp, len, opus_val16);
|
|
|
| len2=len/2;
|
| - tf_max = 0;
|
| for (c=0;c<C;c++)
|
| {
|
| opus_val32 mean;
|
| @@ -451,7 +460,7 @@ static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS
|
| }
|
|
|
|
|
| -void preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
|
| +void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
|
| int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip)
|
| {
|
| int i;
|
| @@ -488,6 +497,8 @@ void preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT
|
| for (i=0;i<Nu;i++)
|
| inp[i*upsample] = MAX32(-65536.f, MIN32(65536.f,inp[i*upsample]));
|
| }
|
| +#else
|
| + (void)clip; /* Avoids a warning about clip being unused. */
|
| #endif
|
| m = *mem;
|
| #ifdef CUSTOM_MODES
|
| @@ -497,7 +508,7 @@ void preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT
|
| opus_val16 coef2 = coef[2];
|
| for (i=0;i<N;i++)
|
| {
|
| - opus_val16 x, tmp;
|
| + celt_sig x, tmp;
|
| x = inp[i];
|
| /* Apply pre-emphasis */
|
| tmp = MULT16_16(coef2, x);
|
| @@ -822,7 +833,8 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
|
| #ifndef DISABLE_FLOAT_API
|
| if (analysis->valid)
|
| {
|
| - trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), QCONST16(2.f, 8)*(analysis->tonality_slope+.05f)));
|
| + trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8),
|
| + (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f))));
|
| }
|
| #endif
|
|
|
| @@ -1023,11 +1035,12 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem,
|
| VARDECL(opus_val16, pitch_buf);
|
| ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
|
|
|
| - pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
|
| + pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch);
|
| /* Don't search for the fir last 1.5 octave of the range because
|
| there's too many false-positives due to short-term correlation */
|
| pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
|
| - COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index);
|
| + COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index,
|
| + st->arch);
|
| pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
|
|
|
| gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
|
| @@ -1156,6 +1169,7 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
|
| coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands;
|
| /* Maximum fraction of the bits we can save if the signal is mono. */
|
| max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins);
|
| + stereo_saving = MIN16(stereo_saving, QCONST16(1.f, 8));
|
| /*printf("%d %d %d ", coded_stereo_dof, coded_bins, tot_boost);*/
|
| target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target),
|
| SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));
|
| @@ -1294,6 +1308,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| opus_val16 surround_masking=0;
|
| opus_val16 temporal_vbr=0;
|
| opus_val16 surround_trim = 0;
|
| + opus_int32 equiv_rate = 510000;
|
| VARDECL(opus_val16, surround_dynalloc);
|
| ALLOC_STACK;
|
|
|
| @@ -1303,14 +1318,20 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| eBands = mode->eBands;
|
| tf_estimate = 0;
|
| if (nbCompressedBytes<2 || pcm==NULL)
|
| - return OPUS_BAD_ARG;
|
| + {
|
| + RESTORE_STACK;
|
| + return OPUS_BAD_ARG;
|
| + }
|
|
|
| frame_size *= st->upsample;
|
| for (LM=0;LM<=mode->maxLM;LM++)
|
| if (mode->shortMdctSize<<LM==frame_size)
|
| break;
|
| if (LM>mode->maxLM)
|
| + {
|
| + RESTORE_STACK;
|
| return OPUS_BAD_ARG;
|
| + }
|
| M=1<<LM;
|
| N = M*mode->shortMdctSize;
|
|
|
| @@ -1341,7 +1362,10 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| {
|
| int c0 = toOpus(compressed[0]);
|
| if (c0<0)
|
| + {
|
| + RESTORE_STACK;
|
| return OPUS_BAD_ARG;
|
| + }
|
| compressed[0] = c0;
|
| }
|
| compressed++;
|
| @@ -1375,6 +1399,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
|
| effectiveBytes = nbCompressedBytes;
|
| }
|
| + if (st->bitrate != OPUS_BITRATE_MAX)
|
| + equiv_rate = st->bitrate - (40*C+20)*((400>>LM) - 50);
|
|
|
| if (enc==NULL)
|
| {
|
| @@ -1448,7 +1474,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| enc->nbits_total+=tell-ec_tell(enc);
|
| }
|
| c=0; do {
|
| - preemphasis(pcm+c, in+c*(N+st->overlap)+st->overlap, N, CC, st->upsample,
|
| + celt_preemphasis(pcm+c, in+c*(N+st->overlap)+st->overlap, N, CC, st->upsample,
|
| mode->preemph, st->preemph_memE+c, st->clip);
|
| } while (++c<CC);
|
|
|
| @@ -1458,7 +1484,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| {
|
| int enabled;
|
| int qg;
|
| - enabled = (st->lfe || nbAvailableBytes>12*C) && st->start==0 && !silence && !st->disable_pf
|
| + enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && st->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;
|
| @@ -1612,7 +1638,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| if (!st->lfe)
|
| {
|
| opus_val16 follow=-QCONST16(10.0f,DB_SHIFT);
|
| - float frame_avg=0;
|
| + opus_val32 frame_avg=0;
|
| opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0;
|
| for(i=st->start;i<st->end;i++)
|
| {
|
| @@ -1710,7 +1736,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| /* Disable new spreading+tapset estimator until we can show it works
|
| better than the old one. So far it seems like spreading_decision()
|
| works best. */
|
| - if (0&&st->analysis.valid)
|
| +#if 0
|
| + if (st->analysis.valid)
|
| {
|
| static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)};
|
| static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)};
|
| @@ -1718,7 +1745,9 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)};
|
| st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision);
|
| st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision);
|
| - } else {
|
| + } else
|
| +#endif
|
| + {
|
| st->spread_decision = spreading_decision(mode, X,
|
| &st->tonal_average, st->spread_decision, &st->hf_average,
|
| &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
|
| @@ -1777,25 +1806,18 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
|
|
| if (C==2)
|
| {
|
| - int effectiveRate;
|
| -
|
| static const opus_val16 intensity_thresholds[21]=
|
| /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 off*/
|
| - { 16,21,23,25,27,29,31,33,35,38,42,46,50,54,58,63,68,75,84,102,130};
|
| + { 1, 2, 3, 4, 5, 6, 7, 8,16,24,36,44,50,56,62,67,72,79,88,106,134};
|
| static const opus_val16 intensity_histeresis[21]=
|
| - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 8, 12};
|
| + { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 8, 8};
|
|
|
| /* Always use MS for 2.5 ms frames until we can do a better analysis */
|
| if (LM!=0)
|
| dual_stereo = stereo_analysis(mode, X, LM, N);
|
|
|
| - /* Account for coarse energy */
|
| - effectiveRate = (8*effectiveBytes - 80)>>LM;
|
| -
|
| - /* effectiveRate in kb/s */
|
| - effectiveRate = 2*effectiveRate/5;
|
| -
|
| - st->intensity = hysteresis_decision((opus_val16)effectiveRate, intensity_thresholds, intensity_histeresis, 21, st->intensity);
|
| + 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));
|
| }
|
|
|
| @@ -1829,7 +1851,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| if (st->constrained_vbr)
|
| base_target += (st->vbr_offset>>lm_diff);
|
|
|
| - target = compute_vbr(mode, &st->analysis, base_target, LM, st->bitrate,
|
| + target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
|
| st->lastCodedBands, C, st->intensity, st->constrained_vbr,
|
| st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,
|
| st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking,
|
| @@ -1913,13 +1935,13 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
|
| if (st->analysis.valid)
|
| {
|
| int min_bandwidth;
|
| - if (st->bitrate < (opus_int32)32000*C)
|
| + if (equiv_rate < (opus_int32)32000*C)
|
| min_bandwidth = 13;
|
| - else if (st->bitrate < (opus_int32)48000*C)
|
| + else if (equiv_rate < (opus_int32)48000*C)
|
| min_bandwidth = 16;
|
| - else if (st->bitrate < (opus_int32)60000*C)
|
| + else if (equiv_rate < (opus_int32)60000*C)
|
| min_bandwidth = 18;
|
| - else if (st->bitrate < (opus_int32)80000*C)
|
| + else if (equiv_rate < (opus_int32)80000*C)
|
| min_bandwidth = 19;
|
| else
|
| min_bandwidth = 20;
|
|
|