Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * common functions for the ATRAC family of decoders
  3.  *
  4.  * Copyright (c) 2006-2013 Maxim Poliakovski
  5.  * Copyright (c) 2006-2008 Benjamin Larsson
  6.  *
  7.  * This file is part of FFmpeg.
  8.  *
  9.  * FFmpeg is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Lesser General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2.1 of the License, or (at your option) any later version.
  13.  *
  14.  * FFmpeg is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Lesser General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Lesser General Public
  20.  * License along with FFmpeg; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22.  */
  23.  
  24. /**
  25.  * @file
  26.  */
  27.  
  28. #include <math.h>
  29. #include <stddef.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #include "avcodec.h"
  34. #include "atrac.h"
  35.  
  36. float ff_atrac_sf_table[64];
  37. static float qmf_window[48];
  38.  
  39. static const float qmf_48tap_half[24] = {
  40.    -0.00001461907, -0.00009205479,-0.000056157569,0.00030117269,
  41.     0.0002422519,  -0.00085293897,-0.0005205574,  0.0020340169,
  42.     0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944,
  43.    -0.000061169922,-0.01344162,    0.0024626821,  0.021736089,
  44.    -0.007801671,   -0.034090221,   0.01880949,    0.054326009,
  45.    -0.043596379,   -0.099384367,   0.13207909,    0.46424159
  46. };
  47.  
  48. av_cold void ff_atrac_generate_tables(void)
  49. {
  50.     int i;
  51.     float s;
  52.  
  53.     /* Generate scale factors */
  54.     if (!ff_atrac_sf_table[63])
  55.         for (i=0 ; i<64 ; i++)
  56.             ff_atrac_sf_table[i] = pow(2.0, (i - 15) / 3.0);
  57.  
  58.     /* Generate the QMF window. */
  59.     if (!qmf_window[47])
  60.         for (i=0 ; i<24; i++) {
  61.             s = qmf_48tap_half[i] * 2.0;
  62.             qmf_window[i] = qmf_window[47 - i] = s;
  63.         }
  64. }
  65.  
  66. av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset,
  67.                                              int loc_scale)
  68. {
  69.     int i;
  70.  
  71.     gctx->loc_scale     = loc_scale;
  72.     gctx->loc_size      = 1 << loc_scale;
  73.     gctx->id2exp_offset = id2exp_offset;
  74.  
  75.     /* Generate gain level table. */
  76.     for (i = 0; i < 16; i++)
  77.         gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i);
  78.  
  79.     /* Generate gain interpolation table. */
  80.     for (i = -15; i < 16; i++)
  81.         gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i);
  82. }
  83.  
  84. void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev,
  85.                                 AtracGainInfo *gc_now, AtracGainInfo *gc_next,
  86.                                 int num_samples, float *out)
  87. {
  88.     float lev, gc_scale, gain_inc;
  89.     int i, pos, lastpos;
  90.  
  91.     gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]]
  92.                                    : 1.0f;
  93.  
  94.     if (!gc_now->num_points) {
  95.         for (pos = 0; pos < num_samples; pos++)
  96.             out[pos] = in[pos] * gc_scale + prev[pos];
  97.     } else {
  98.         pos = 0;
  99.  
  100.         for (i = 0; i < gc_now->num_points; i++) {
  101.             lastpos = gc_now->loc_code[i] << gctx->loc_scale;
  102.  
  103.             lev = gctx->gain_tab1[gc_now->lev_code[i]];
  104.             gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1]
  105.                                                                    : gctx->id2exp_offset) -
  106.                                        gc_now->lev_code[i] + 15];
  107.  
  108.             /* apply constant gain level and overlap */
  109.             for (; pos < lastpos; pos++)
  110.                 out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
  111.  
  112.             /* interpolate between two different gain levels */
  113.             for (; pos < lastpos + gctx->loc_size; pos++) {
  114.                 out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
  115.                 lev *= gain_inc;
  116.             }
  117.         }
  118.  
  119.         for (; pos < num_samples; pos++)
  120.             out[pos] = in[pos] * gc_scale + prev[pos];
  121.     }
  122.  
  123.     /* copy the overlapping part into the delay buffer */
  124.     memcpy(prev, &in[num_samples], num_samples * sizeof(float));
  125. }
  126.  
  127. void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut,
  128.                    float *delayBuf, float *temp)
  129. {
  130.     int   i, j;
  131.     float   *p1, *p3;
  132.  
  133.     memcpy(temp, delayBuf, 46*sizeof(float));
  134.  
  135.     p3 = temp + 46;
  136.  
  137.     /* loop1 */
  138.     for(i=0; i<nIn; i+=2){
  139.         p3[2*i+0] = inlo[i  ] + inhi[i  ];
  140.         p3[2*i+1] = inlo[i  ] - inhi[i  ];
  141.         p3[2*i+2] = inlo[i+1] + inhi[i+1];
  142.         p3[2*i+3] = inlo[i+1] - inhi[i+1];
  143.     }
  144.  
  145.     /* loop2 */
  146.     p1 = temp;
  147.     for (j = nIn; j != 0; j--) {
  148.         float s1 = 0.0;
  149.         float s2 = 0.0;
  150.  
  151.         for (i = 0; i < 48; i += 2) {
  152.             s1 += p1[i] * qmf_window[i];
  153.             s2 += p1[i+1] * qmf_window[i+1];
  154.         }
  155.  
  156.         pOut[0] = s2;
  157.         pOut[1] = s1;
  158.  
  159.         p1 += 2;
  160.         pOut += 2;
  161.     }
  162.  
  163.     /* Update the delay buffer. */
  164.     memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));
  165. }
  166.