libavcodec/opus_celt.h
e538108c
 /*
  * Opus decoder/demuxer common functions
  * Copyright (c) 2012 Andrew D'Addesio
  * Copyright (c) 2013-2014 Mozilla Corporation
  * Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
  *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AVCODEC_OPUS_CELT_H
 #define AVCODEC_OPUS_CELT_H
 
07b78340
 #include <float.h>
 
e538108c
 #include "opus.h"
8e7e74df
 #include "opus_pvq.h"
e538108c
 
 #include "mdct15.h"
 #include "libavutil/float_dsp.h"
 #include "libavutil/libm.h"
 
 #define CELT_VECTORS                 11
 #define CELT_ALLOC_STEPS             6
 #define CELT_FINE_OFFSET             21
 #define CELT_MAX_FINE_BITS           8
 #define CELT_NORM_SCALE              16384
 #define CELT_QTHETA_OFFSET           4
 #define CELT_QTHETA_OFFSET_TWOPHASE  16
07b78340
 #define CELT_EMPH_COEFF              0.85000610f
e538108c
 #define CELT_POSTFILTER_MINPERIOD    15
 #define CELT_ENERGY_SILENCE          (-28.0f)
 
8e7e74df
 typedef struct CeltPVQ CeltPVQ;
 
e538108c
 enum CeltSpread {
     CELT_SPREAD_NONE,
     CELT_SPREAD_LIGHT,
     CELT_SPREAD_NORMAL,
     CELT_SPREAD_AGGRESSIVE
 };
 
07b78340
 enum CeltBlockSize {
     CELT_BLOCK_120,
     CELT_BLOCK_240,
     CELT_BLOCK_480,
     CELT_BLOCK_960,
 
     CELT_BLOCK_NB
 };
 
 typedef struct CeltBlock {
e538108c
     float energy[CELT_MAX_BANDS];
5f47c85e
     float lin_energy[CELT_MAX_BANDS];
     float error_energy[CELT_MAX_BANDS];
e538108c
     float prev_energy[2][CELT_MAX_BANDS];
 
     uint8_t collapse_masks[CELT_MAX_BANDS];
 
     /* buffer for mdct output + postfilter */
     DECLARE_ALIGNED(32, float, buf)[2048];
07b78340
     DECLARE_ALIGNED(32, float, coeffs)[CELT_MAX_FRAME_SIZE];
e538108c
 
5f47c85e
     /* Used by the encoder */
035c755b
     DECLARE_ALIGNED(32, float, overlap)[FFALIGN(CELT_OVERLAP, 16)];
     DECLARE_ALIGNED(32, float, samples)[FFALIGN(CELT_MAX_FRAME_SIZE, 16)];
5f47c85e
 
e538108c
     /* postfilter parameters */
07b78340
     int   pf_period_new;
e538108c
     float pf_gains_new[3];
07b78340
     int   pf_period;
e538108c
     float pf_gains[3];
07b78340
     int   pf_period_old;
e538108c
     float pf_gains_old[3];
 
07b78340
     float emph_coeff;
 } CeltBlock;
e538108c
 
07b78340
 struct CeltFrame {
e538108c
     // constant values that do not change during context lifetime
07b78340
     AVCodecContext      *avctx;
     MDCT15Context       *imdct[4];
     AVFloatDSPContext   *dsp;
     CeltBlock           block[2];
8e7e74df
     CeltPVQ             *pvq;
07b78340
     int channels;
e538108c
     int output_channels;
 
07b78340
     enum CeltBlockSize size;
     int start_band;
     int end_band;
     int coded_bands;
     int transient;
5f47c85e
     int pfilter;
     int skip_band_floor;
     int tf_select;
     int alloc_trim;
     int alloc_boost[CELT_MAX_BANDS];
07b78340
     int blocks;        /* number of iMDCT blocks in the frame, depends on transient */
     int blocksize;     /* size of each block */
     int silence;       /* Frame is filled with silence */
     int anticollapse_needed; /* Whether to expect an anticollapse bit */
     int anticollapse;  /* Encoded anticollapse bit */
     int intensity_stereo;
     int dual_stereo;
e538108c
     int flushed;
07b78340
     uint32_t seed;
e538108c
     enum CeltSpread spread;
 
2ad1768c
     /* Encoder PF coeffs */
     int pf_octave;
     int pf_period;
     int pf_tapset;
     float pf_gain;
 
07b78340
     /* Bit allocation */
     int framebits;
e538108c
     int remaining;
     int remaining2;
5f47c85e
     int caps         [CELT_MAX_BANDS];
e538108c
     int fine_bits    [CELT_MAX_BANDS];
     int fine_priority[CELT_MAX_BANDS];
     int pulses       [CELT_MAX_BANDS];
     int tf_change    [CELT_MAX_BANDS];
 };
 
 /* LCG for noise generation */
07b78340
 static av_always_inline uint32_t celt_rng(CeltFrame *f)
e538108c
 {
07b78340
     f->seed = 1664525 * f->seed + 1013904223;
     return f->seed;
e538108c
 }
 
 static av_always_inline void celt_renormalize_vector(float *X, int N, float gain)
 {
     int i;
     float g = 1e-15f;
     for (i = 0; i < N; i++)
         g += X[i] * X[i];
     g = gain / sqrtf(g);
 
     for (i = 0; i < N; i++)
         X[i] *= g;
 }
 
07b78340
 int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels);
 
 void ff_celt_free(CeltFrame **f);
 
 void ff_celt_flush(CeltFrame *f);
 
 int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output,
                          int coded_channels, int frame_size, int startband, int endband);
 
e538108c
 #endif /* AVCODEC_OPUS_CELT_H */