⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cook_float.h

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 H
字号:
 /*
  * COOK compatible decoder, floating point implementation.
  * Copyright (c) 2003 Sascha Sommer
  * Copyright (c) 2005 Benjamin Larsson
  *
  */
 
 /**
  * @file cook_float.h
  *
  * Cook AKA RealAudio G2 floating point functions.
  */
 
 
/**
  * Initialise floating point implementation:
  * lookup tables, mdct and associated window.
  *
  * @param q                     pointer to the COOKContext
  */
static inline int init_cook_math(COOKContext *q)
{
     int gain_size_factor = q->samples_per_channel/8;
     int mlt_size = q->samples_per_channel;
     int i;
     float alpha;
 
     /* Table of pow(2, [-63:63]) */
     q->math.pow2tab[63] = 1.0;
     for (i=1 ; i<64 ; i++){
         q->math.pow2tab[63+i]=(float)((uint64_t)1<<i);
         q->math.pow2tab[63-i]=1.0/(float)((uint64_t)1<<i);
     }
 
     /* Table of pow(2, [-63..63]/2) */
     q->math.rootpow2tab[63] = 1.0;
     for (i=1 ; i<64 ; i++){
         q->math.rootpow2tab[63+i]=sqrt((float)((uint64_t)1<<i));
         q->math.rootpow2tab[63-i]=sqrt(1.0/(float)((uint64_t)1<<i));
     }
 
     /* Table of pow(2, [-11..11]/(samples_per_channel/8)) */
     for (i=0 ; i<23 ; i++) {
         q->math.gain_table[i] = pow((double)q->math.pow2tab[i+52],
                                     1.0/(double)gain_size_factor);
     }
 
     /* Initialize the MLT window: simple sine window. */
     if ((q->math.mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0)
         return -1;
 
     alpha = M_PI / (2.0 * (float)mlt_size);
     for(i=0 ; i<mlt_size ; i++) {
         q->math.mlt_window[i] =
           sin((i + 0.5) * alpha) * sqrt(2.0 / q->samples_per_channel);
     }
 
     /* Initialize the MDCT. */
     if (ff_mdct_init(&q->math.mdct_ctx, av_log2(mlt_size)+1, 1)) {
         av_free(q->math.mlt_window);
         return -1;
     }
     av_log(NULL,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n",
            av_log2(mlt_size)+1);
     return 0;
 }
 
 
 /**
  * Free resources used by floating point implementation.
  *
  * @param q                     pointer to the COOKContext
  */
static inline void free_cook_math(COOKContext *q)
 {
     /* Free allocated memory buffers. */
     av_free(q->math.mlt_window);
     /* Free the transform. */
     ff_mdct_end(&q->math.mdct_ctx);
 }
 
 
 /**
  * The real requantization of the mltcoefs
  *
  * @param q                     pointer to the COOKContext
  * @param subband_coef_sign     signs of coefficients
  * @param mlt_p                 pointer into the mlt buffer
  */
static void scalar_dequant_math(COOKContext *q, int index, int quant_index,
                                 int* subband_coef_index,
                                 int* subband_coef_sign, float* mlt_p){
     int i;
     float f1;
 
             f1 = dither_tab[index];
             if (av_random(&q->random_state) < 0x80000000) f1 = -f1;
         }
         mlt_p[i] = f1 * q->math.rootpow2tab[quant_index+63];
     }
 }
 
 
 /**
  * @param gain_index        index for the block multiplier
  * @param gain_index_next   index for the next block multiplier
  */
static inline void interpolate_math(COOKContext *q, float* buffer,
                                    int gain_index, int gain_index_next){
    int gain_size_factor = q->samples_per_channel/8;
     int i;
     float fc1, fc2;

     fc1 = q->math.pow2tab[gain_index+63];
 
     if(gain_index == gain_index_next){              //static gain
         for(i=0 ; i<gain_size_factor ; i++){
             buffer[i]*=fc1;
         }
     } else {                                        //smooth gain
         fc2 = q->math.gain_table[11 + (gain_index_next-gain_index)];
         for(i=0 ; i<gain_size_factor ; i++){
             buffer[i]*=fc1;
             fc1*=fc2;
         }
     }
 }
 
 /**
  * The modulated lapped transform, this takes transform coefficients
  * and transforms them into timedomain samples.
  * Applies transform window and overlaps buffers.
  *
  * @param q                 pointer to the COOKContext
  * @param inbuffer          pointer to the mltcoefficients
  * @param gain0             gain difference now/previous buffers
  * @param previous_buffer   pointer to the previous buffer to be used for overlapping
  */
 
static void imlt_math(COOKContext *q, float *inbuffer,
                      int gain0, float* previous_buffer)
 {
     const float fc = q->math.pow2tab[gain0 + 63];
     float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
     int i;
 
     /* Inverse modified discrete cosine transform */
     q->math.mdct_ctx.fft.imdct_calc(&q->math.mdct_ctx, q->mono_mdct_output,
                                     inbuffer, q->math.mdct_tmp);
 
     /* The weird thing here, is that the two halves of the time domain
      * buffer are swapped. Also, the newest data, that we save away for 
      *Apply window and overlap */
     for(i = 0; i < q->samples_per_channel; i++){
         buffer1[i] = buffer1[i] * fc * q->math.mlt_window[i] -
         previous_buffer[i] * q->math.mlt_window[q->samples_per_channel - 1 - i];
     }
 }
 
 
 /**
  * Decoupling calculation for joint stereo coefficients.
  *
  * @param x                 mono coefficient
  * @param table             number of decoupling table
  * @param i                 table index
  */
static inline float cplscale_math(float x, int table, int i)
 {
  return x * cplscales[table-2][i];
 }
 

 /**
  * Final converion from floating point values to
  * signed, 16 bit sound samples. Round and clip.
  *
  * @param q                 pointer to the COOKContext
  * @param out               pointer to the output buffer
  * @param chan              0: left or single channel, 1: right channel
  */
static inline void output_math(COOKContext *q, int16_t *out, int chan)
 {
     float *output = q->mono_mdct_output + q->samples_per_channel;
     int j;
 
    /* FIXME: Should use DSPContext.float_to_int16() here.
      */
     for (j = 0; j < q->samples_per_channel; j++) {
         out[chan + q->nb_channels * j] =
           av_clip(lrintf(output[j]), -32768, 32767);
     }
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -