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

libavcodec/ra144.c

Go to the documentation of this file.
00001 /*
00002  * Real Audio 1.0 (14.4K)
00003  *
00004  * Copyright (c) 2008 Vitor Sessak
00005  * Copyright (c) 2003 Nick Kurshev
00006  *     Based on public domain decoder at http://www.honeypot.net/audio
00007  *
00008  * This file is part of FFmpeg.
00009  *
00010  * FFmpeg is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * FFmpeg is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with FFmpeg; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00023  */
00024 
00025 #include "libavutil/intmath.h"
00026 #include "avcodec.h"
00027 #include "get_bits.h"
00028 #include "ra144.h"
00029 #include "celp_filters.h"
00030 
00031 #define NBLOCKS         4       ///< number of subblocks within a block
00032 #define BLOCKSIZE       40      ///< subblock size in 16-bit words
00033 #define BUFFERSIZE      146     ///< the size of the adaptive codebook
00034 
00035 
00036 typedef struct {
00037     AVCodecContext *avctx;
00038 
00039     unsigned int     old_energy;        
00040 
00041     unsigned int     lpc_tables[2][10];
00042 
00045     unsigned int    *lpc_coef[2];
00046 
00047     unsigned int     lpc_refl_rms[2];
00048 
00050     int16_t curr_sblock[50];
00051 
00054     uint16_t adapt_cb[146+2];
00055 } RA144Context;
00056 
00057 static av_cold int ra144_decode_init(AVCodecContext * avctx)
00058 {
00059     RA144Context *ractx = avctx->priv_data;
00060 
00061     ractx->avctx = avctx;
00062 
00063     ractx->lpc_coef[0] = ractx->lpc_tables[0];
00064     ractx->lpc_coef[1] = ractx->lpc_tables[1];
00065 
00066     avctx->sample_fmt = SAMPLE_FMT_S16;
00067     return 0;
00068 }
00069 
00074 static int t_sqrt(unsigned int x)
00075 {
00076     int s = 2;
00077     while (x > 0xfff) {
00078         s++;
00079         x >>= 2;
00080     }
00081 
00082     return ff_sqrt(x << 20) << s;
00083 }
00084 
00089 static void eval_coefs(int *coefs, const int *refl)
00090 {
00091     int buffer[10];
00092     int *b1 = buffer;
00093     int *b2 = coefs;
00094     int i, j;
00095 
00096     for (i=0; i < 10; i++) {
00097         b1[i] = refl[i] << 4;
00098 
00099         for (j=0; j < i; j++)
00100             b1[j] = ((refl[i] * b2[i-j-1]) >> 12) + b2[j];
00101 
00102         FFSWAP(int *, b1, b2);
00103     }
00104 
00105     for (i=0; i < 10; i++)
00106         coefs[i] >>= 4;
00107 }
00108 
00113 static void copy_and_dup(int16_t *target, const int16_t *source, int offset)
00114 {
00115     source += BUFFERSIZE - offset;
00116 
00117     memcpy(target, source, FFMIN(BLOCKSIZE, offset)*sizeof(*target));
00118     if (offset < BLOCKSIZE)
00119         memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target));
00120 }
00121 
00123 static int irms(const int16_t *data)
00124 {
00125     unsigned int i, sum = 0;
00126 
00127     for (i=0; i < BLOCKSIZE; i++)
00128         sum += data[i] * data[i];
00129 
00130     if (sum == 0)
00131         return 0; /* OOPS - division by zero */
00132 
00133     return 0x20000000 / (t_sqrt(sum) >> 8);
00134 }
00135 
00136 static void add_wav(int16_t *dest, int n, int skip_first, int *m,
00137                     const int16_t *s1, const int8_t *s2, const int8_t *s3)
00138 {
00139     int i;
00140     int v[3];
00141 
00142     v[0] = 0;
00143     for (i=!skip_first; i<3; i++)
00144         v[i] = (gain_val_tab[n][i] * m[i]) >> gain_exp_tab[n];
00145 
00146     if (v[0]) {
00147         for (i=0; i < BLOCKSIZE; i++)
00148             dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12;
00149     } else {
00150         for (i=0; i < BLOCKSIZE; i++)
00151             dest[i] = (             s2[i]*v[1] + s3[i]*v[2]) >> 12;
00152     }
00153 }
00154 
00155 static unsigned int rescale_rms(unsigned int rms, unsigned int energy)
00156 {
00157     return (rms * energy) >> 10;
00158 }
00159 
00160 static unsigned int rms(const int *data)
00161 {
00162     int i;
00163     unsigned int res = 0x10000;
00164     int b = 10;
00165 
00166     for (i=0; i < 10; i++) {
00167         res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
00168 
00169         if (res == 0)
00170             return 0;
00171 
00172         while (res <= 0x3fff) {
00173             b++;
00174             res <<= 2;
00175         }
00176     }
00177 
00178     return t_sqrt(res) >> b;
00179 }
00180 
00181 static void do_output_subblock(RA144Context *ractx, const uint16_t  *lpc_coefs,
00182                                int gval, GetBitContext *gb)
00183 {
00184     uint16_t buffer_a[40];
00185     uint16_t *block;
00186     int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none
00187     int gain    = get_bits(gb, 8);
00188     int cb1_idx = get_bits(gb, 7);
00189     int cb2_idx = get_bits(gb, 7);
00190     int m[3];
00191 
00192     if (cba_idx) {
00193         cba_idx += BLOCKSIZE/2 - 1;
00194         copy_and_dup(buffer_a, ractx->adapt_cb, cba_idx);
00195         m[0] = (irms(buffer_a) * gval) >> 12;
00196     } else {
00197         m[0] = 0;
00198     }
00199 
00200     m[1] = (cb1_base[cb1_idx] * gval) >> 8;
00201     m[2] = (cb2_base[cb2_idx] * gval) >> 8;
00202 
00203     memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,
00204             (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));
00205 
00206     block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
00207 
00208     add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
00209             cb1_vects[cb1_idx], cb2_vects[cb2_idx]);
00210 
00211     memcpy(ractx->curr_sblock, ractx->curr_sblock + 40,
00212            10*sizeof(*ractx->curr_sblock));
00213 
00214     if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs,
00215                                     block, BLOCKSIZE, 10, 1, 0xfff))
00216         memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock));
00217 }
00218 
00219 static void int_to_int16(int16_t *out, const int *inp)
00220 {
00221     int i;
00222 
00223     for (i=0; i < 10; i++)
00224         *out++ = *inp++;
00225 }
00226 
00234 static int eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
00235 {
00236     int b, i, j;
00237     int buffer1[10];
00238     int buffer2[10];
00239     int *bp1 = buffer1;
00240     int *bp2 = buffer2;
00241 
00242     for (i=0; i < 10; i++)
00243         buffer2[i] = coefs[i];
00244 
00245     refl[9] = bp2[9];
00246 
00247     if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {
00248         av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
00249         return 1;
00250     }
00251 
00252     for (i=8; i >= 0; i--) {
00253         b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
00254 
00255         if (!b)
00256             b = -2;
00257 
00258         for (j=0; j <= i; j++)
00259             bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12;
00260 
00261         if ((unsigned) bp1[i] + 0x1000 > 0x1fff)
00262             return 1;
00263 
00264         refl[i] = bp1[i];
00265 
00266         FFSWAP(int *, bp1, bp2);
00267     }
00268     return 0;
00269 }
00270 
00271 static int interp(RA144Context *ractx, int16_t *out, int a,
00272                   int copyold, int energy)
00273 {
00274     int work[10];
00275     int b = NBLOCKS - a;
00276     int i;
00277 
00278     // Interpolate block coefficients from the this frame's forth block and
00279     // last frame's forth block.
00280     for (i=0; i<10; i++)
00281         out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
00282 
00283     if (eval_refl(work, out, ractx->avctx)) {
00284         // The interpolated coefficients are unstable, copy either new or old
00285         // coefficients.
00286         int_to_int16(out, ractx->lpc_coef[copyold]);
00287         return rescale_rms(ractx->lpc_refl_rms[copyold], energy);
00288     } else {
00289         return rescale_rms(rms(work), energy);
00290     }
00291 }
00292 
00294 static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
00295                               int *data_size, AVPacket *avpkt)
00296 {
00297     const uint8_t *buf = avpkt->data;
00298     int buf_size = avpkt->size;
00299     static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
00300     unsigned int refl_rms[4];    // RMS of the reflection coefficients
00301     uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block
00302     unsigned int lpc_refl[10];   // LPC reflection coefficients of the frame
00303     int i, j;
00304     int16_t *data = vdata;
00305     unsigned int energy;
00306 
00307     RA144Context *ractx = avctx->priv_data;
00308     GetBitContext gb;
00309 
00310     if (*data_size < 2*160)
00311         return -1;
00312 
00313     if(buf_size < 20) {
00314         av_log(avctx, AV_LOG_ERROR,
00315                "Frame too small (%d bytes). Truncated file?\n", buf_size);
00316         *data_size = 0;
00317         return buf_size;
00318     }
00319     init_get_bits(&gb, buf, 20 * 8);
00320 
00321     for (i=0; i<10; i++)
00322         lpc_refl[i] = lpc_refl_cb[i][get_bits(&gb, sizes[i])];
00323 
00324     eval_coefs(ractx->lpc_coef[0], lpc_refl);
00325     ractx->lpc_refl_rms[0] = rms(lpc_refl);
00326 
00327     energy = energy_tab[get_bits(&gb, 5)];
00328 
00329     refl_rms[0] = interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
00330     refl_rms[1] = interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy,
00331                     t_sqrt(energy*ractx->old_energy) >> 12);
00332     refl_rms[2] = interp(ractx, block_coefs[2], 3, 0, energy);
00333     refl_rms[3] = rescale_rms(ractx->lpc_refl_rms[0], energy);
00334 
00335     int_to_int16(block_coefs[3], ractx->lpc_coef[0]);
00336 
00337     for (i=0; i < 4; i++) {
00338         do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb);
00339 
00340         for (j=0; j < BLOCKSIZE; j++)
00341             *data++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2);
00342     }
00343 
00344     ractx->old_energy = energy;
00345     ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
00346 
00347     FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
00348 
00349     *data_size = 2*160;
00350     return 20;
00351 }
00352 
00353 AVCodec ra_144_decoder =
00354 {
00355     "real_144",
00356     AVMEDIA_TYPE_AUDIO,
00357     CODEC_ID_RA_144,
00358     sizeof(RA144Context),
00359     ra144_decode_init,
00360     NULL,
00361     NULL,
00362     ra144_decode_frame,
00363     .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
00364 };

Generated on Fri Sep 16 2011 17:17:42 for FFmpeg by  doxygen 1.7.1