• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/g722.c

Go to the documentation of this file.
00001 /*
00002  * G.722 ADPCM audio encoder/decoder
00003  *
00004  * Copyright (c) CMU 1993 Computer Science, Speech Group
00005  *                        Chengxiang Lu and Alex Hauptmann
00006  * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
00007  * Copyright (c) 2009 Kenan Gillet
00008  * Copyright (c) 2010 Martin Storsjo
00009  *
00010  * This file is part of Libav.
00011  *
00012  * Libav is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * Libav is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with Libav; if not, write to the Free Software
00024  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00025  */
00026 
00039 #include "mathops.h"
00040 #include "g722.h"
00041 
00042 static const int8_t sign_lookup[2] = { -1, 1 };
00043 
00044 static const int16_t inv_log2_table[32] = {
00045     2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383,
00046     2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834,
00047     2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371,
00048     3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008
00049 };
00050 static const int16_t high_log_factor_step[2] = { 798, -214 };
00051 const int16_t ff_g722_high_inv_quant[4] = { -926, -202, 926, 202 };
00055 static const int16_t low_log_factor_step[16] = {
00056      -60, 3042, 1198, 538, 334, 172,  58, -30,
00057     3042, 1198,  538, 334, 172,  58, -30, -60
00058 };
00059 const int16_t ff_g722_low_inv_quant4[16] = {
00060        0, -2557, -1612, -1121,  -786,  -530,  -323,  -150,
00061     2557,  1612,  1121,   786,   530,   323,   150,     0
00062 };
00063 const int16_t ff_g722_low_inv_quant6[64] = {
00064      -17,   -17,   -17,   -17, -3101, -2738, -2376, -2088,
00065    -1873, -1689, -1535, -1399, -1279, -1170, -1072,  -982,
00066     -899,  -822,  -750,  -682,  -618,  -558,  -501,  -447,
00067     -396,  -347,  -300,  -254,  -211,  -170,  -130,   -91,
00068     3101,  2738,  2376,  2088,  1873,  1689,  1535,  1399,
00069     1279,  1170,  1072,   982,   899,   822,   750,   682,
00070      618,   558,   501,   447,   396,   347,   300,   254,
00071      211,   170,   130,    91,    54,    17,   -54,   -17
00072 };
00073 
00079 static const int16_t qmf_coeffs[12] = {
00080     3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
00081 };
00082 
00083 
00090 static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)
00091 {
00092     int sg[2], limit, i, cur_qtzd_reconst;
00093 
00094     const int cur_part_reconst = band->s_zero + cur_diff < 0;
00095 
00096     sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];
00097     sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];
00098     band->part_reconst_mem[1] = band->part_reconst_mem[0];
00099     band->part_reconst_mem[0] = cur_part_reconst;
00100 
00101     band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +
00102                                 (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);
00103 
00104     limit = 15360 - band->pole_mem[1];
00105     band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);
00106 
00107 
00108     if (cur_diff) {
00109         for (i = 0; i < 6; i++)
00110             band->zero_mem[i] = ((band->zero_mem[i]*255) >> 8) +
00111                                 ((band->diff_mem[i]^cur_diff) < 0 ? -128 : 128);
00112     } else
00113         for (i = 0; i < 6; i++)
00114             band->zero_mem[i] = (band->zero_mem[i]*255) >> 8;
00115 
00116     for (i = 5; i > 0; i--)
00117         band->diff_mem[i] = band->diff_mem[i-1];
00118     band->diff_mem[0] = av_clip_int16(cur_diff << 1);
00119 
00120     band->s_zero = 0;
00121     for (i = 5; i >= 0; i--)
00122         band->s_zero += (band->zero_mem[i]*band->diff_mem[i]) >> 15;
00123 
00124 
00125     cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1);
00126     band->s_predictor = av_clip_int16(band->s_zero +
00127                                       (band->pole_mem[0] * cur_qtzd_reconst >> 15) +
00128                                       (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));
00129     band->prev_qtzd_reconst = cur_qtzd_reconst;
00130 }
00131 
00132 static inline int linear_scale_factor(const int log_factor)
00133 {
00134     const int wd1 = inv_log2_table[(log_factor >> 6) & 31];
00135     const int shift = log_factor >> 11;
00136     return shift < 0 ? wd1 >> -shift : wd1 << shift;
00137 }
00138 
00139 void ff_g722_update_low_predictor(struct G722Band *band, const int ilow)
00140 {
00141     do_adaptive_prediction(band,
00142                            band->scale_factor * ff_g722_low_inv_quant4[ilow] >> 10);
00143 
00144     // quantizer adaptation
00145     band->log_factor   = av_clip((band->log_factor * 127 >> 7) +
00146                                  low_log_factor_step[ilow], 0, 18432);
00147     band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11));
00148 }
00149 
00150 void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh,
00151                                   const int ihigh)
00152 {
00153     do_adaptive_prediction(band, dhigh);
00154 
00155     // quantizer adaptation
00156     band->log_factor   = av_clip((band->log_factor * 127 >> 7) +
00157                                  high_log_factor_step[ihigh&1], 0, 22528);
00158     band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11));
00159 }
00160 
00161 void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2)
00162 {
00163     int i;
00164 
00165     *xout1 = 0;
00166     *xout2 = 0;
00167     for (i = 0; i < 12; i++) {
00168         MAC16(*xout2, prev_samples[2*i  ], qmf_coeffs[i   ]);
00169         MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]);
00170     }
00171 }
Generated on Thu Jul 11 2013 15:38:19 for Libav by doxygen 1.7.1