]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/opus_celt.c
avcodec/nvenc: migrate to new encode API
[ffmpeg] / libavcodec / opus_celt.c
index aee8ddc616d3077e8f863766d2eef4b2cdd50c1f..84d484753b361fe9292d3941a2510a0f771ace51 100644 (file)
 #include "opustab.h"
 #include "opus_pvq.h"
 
+/* Use the 2D z-transform to apply prediction in both the time domain (alpha)
+ * and the frequency domain (beta) */
 static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
 {
     int i, j;
-    float prev[2] = {0};
-    float alpha, beta;
-    const uint8_t *model;
-
-    /* use the 2D z-transform to apply prediction in both */
-    /* the time domain (alpha) and the frequency domain (beta) */
-
-    if (opus_rc_tell(rc)+3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
-        /* intra frame */
-        alpha = 0;
-        beta  = 1.0f - 4915.0f/32768.0f;
+    float prev[2] = { 0 };
+    float alpha = ff_celt_alpha_coef[f->size];
+    float beta  = ff_celt_beta_coef[f->size];
+    const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0];
+
+    /* intra frame */
+    if (opus_rc_tell(rc) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
+        alpha = 0.0f;
+        beta  = 1.0f - (4915.0f/32768.0f);
         model = ff_celt_coarse_energy_dist[f->size][1];
-    } else {
-        alpha = ff_celt_alpha_coef[f->size];
-        beta  = 1.0f - ff_celt_beta_coef[f->size];
-        model = ff_celt_coarse_energy_dist[f->size][0];
     }
 
     for (i = 0; i < CELT_MAX_BANDS; i++) {
@@ -485,7 +481,7 @@ static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data)
 
     for (i = f->start_band; i < f->end_band; i++) {
         float *dst = data + (ff_celt_freq_bands[i] << f->size);
-        float norm = exp2(block->energy[i] + ff_celt_mean_energy[i]);
+        float norm = exp2f(block->energy[i] + ff_celt_mean_energy[i]);
 
         for (j = 0; j < ff_celt_freq_range[i] << f->size; j++)
             dst[j] *= norm;
@@ -594,11 +590,6 @@ static void celt_postfilter(CeltFrame *f, CeltBlock *block)
 
 static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
 {
-    static const float postfilter_taps[3][3] = {
-        { 0.3066406250f, 0.2170410156f, 0.1296386719f },
-        { 0.4638671875f, 0.2680664062f, 0.0           },
-        { 0.7998046875f, 0.1000976562f, 0.0           }
-    };
     int i;
 
     memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new));
@@ -620,9 +611,9 @@ static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
                 CeltBlock *block = &f->block[i];
 
                 block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
-                block->pf_gains_new[0] = gain * postfilter_taps[tapset][0];
-                block->pf_gains_new[1] = gain * postfilter_taps[tapset][1];
-                block->pf_gains_new[2] = gain * postfilter_taps[tapset][2];
+                block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
+                block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
+                block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
             }
         }
 
@@ -664,7 +655,7 @@ static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
 
         /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
         short blocks don't have the same energy as long */
-        r = exp2(1 - Ediff);
+        r = exp2f(1 - Ediff);
         if (f->size == 3)
             r *= M_SQRT2;
         r = FFMIN(thresh, r) * sqrt_1;
@@ -753,15 +744,15 @@ static void celt_decode_bands(CeltFrame *f, OpusRangeCoder *rc)
         }
 
         if (f->dual_stereo) {
-            cm[0] = ff_celt_decode_band(f, rc, i, X, NULL, band_size, b / 2, f->blocks,
+            cm[0] = f->pvq->decode_band(f->pvq, f, rc, i, X, NULL, band_size, b / 2, f->blocks,
                                         effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
                                         norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]);
 
-            cm[1] = ff_celt_decode_band(f, rc, i, Y, NULL, band_size, b/2, f->blocks,
+            cm[1] = f->pvq->decode_band(f->pvq, f, rc, i, Y, NULL, band_size, b/2, f->blocks,
                                         effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL, f->size,
                                         norm2 + band_offset, 0, 1.0f, lowband_scratch, cm[1]);
         } else {
-            cm[0] = ff_celt_decode_band(f, rc, i, X, Y, band_size, b, f->blocks,
+            cm[0] = f->pvq->decode_band(f->pvq, f, rc, i, X, Y, band_size, b, f->blocks,
                                         effective_lowband != -1 ? norm + (effective_lowband << f->size) : NULL, f->size,
                                         norm + band_offset, 0, 1.0f, lowband_scratch, cm[0]|cm[1]);
             cm[1] = cm[0];
@@ -780,10 +771,9 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
                          float **output, int channels, int frame_size,
                          int start_band,  int end_band)
 {
-    int i, j;
+    int i, j, downmix = 0;
     int consumed;           // bits of entropy consumed thus far for this frame
     MDCT15Context *imdct;
-    float imdct_scale = 1.0;
 
     if (channels != 1 && channels != 2) {
         av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
@@ -875,7 +865,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
     /* stereo -> mono downmix */
     if (f->output_channels < f->channels) {
         f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16));
-        imdct_scale = 0.5;
+        downmix = 1;
     } else if (f->output_channels > f->channels)
         memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float));
 
@@ -900,20 +890,24 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
             float *dst  = block->buf + 1024 + j * f->blocksize;
 
             imdct->imdct_half(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j,
-                              f->blocks, imdct_scale);
+                              f->blocks);
             f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
                                        ff_celt_window, CELT_OVERLAP / 2);
         }
 
+        if (downmix)
+            f->dsp->vector_fmul_scalar(&block->buf[1024], &block->buf[1024], 0.5f, frame_size);
+
         /* postfilter */
         celt_postfilter(f, block);
 
         /* deemphasis and output scaling */
         for (j = 0; j < frame_size; j++) {
-            float tmp = block->buf[1024 - frame_size + j] + m;
+            const float tmp = block->buf[1024 - frame_size + j] + m;
             m = tmp * CELT_EMPH_COEFF;
-            output[i][j] = tmp / 32768.;
+            output[i][j] = tmp;
         }
+
         block->emph_coeff = m;
     }
 
@@ -984,6 +978,8 @@ void ff_celt_free(CeltFrame **f)
     for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++)
         ff_mdct15_uninit(&frm->imdct[i]);
 
+    ff_celt_pvq_uninit(&frm->pvq);
+
     av_freep(&frm->dsp);
     av_freep(f);
 }
@@ -1006,11 +1002,12 @@ int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels)
     frm->avctx           = avctx;
     frm->output_channels = output_channels;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++) {
-        ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f);
-        if (ret < 0)
+    for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++)
+        if ((ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f/32768)) < 0)
             goto fail;
-    }
+
+    if ((ret = ff_celt_pvq_init(&frm->pvq)) < 0)
+        goto fail;
 
     frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
     if (!frm->dsp) {