patch by Kenan Gillet, kenan.gillet gmail com Originally committed as revision 15680 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -156,7 +156,7 @@ OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o | |||
| OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o | |||
| OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o | |||
| OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o | |||
| OBJS-$(CONFIG_RA_144_DECODER) += ra144.o acelp_filters.o | |||
| OBJS-$(CONFIG_RA_144_DECODER) += ra144.o celp_filters.o | |||
| OBJS-$(CONFIG_RA_288_DECODER) += ra288.o | |||
| OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o | |||
| OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o | |||
| @@ -81,65 +81,6 @@ void ff_acelp_interpolate( | |||
| } | |||
| } | |||
| void ff_acelp_convolve_circ( | |||
| int16_t* fc_out, | |||
| const int16_t* fc_in, | |||
| const int16_t* filter, | |||
| int len) | |||
| { | |||
| int i, k; | |||
| memset(fc_out, 0, len * sizeof(int16_t)); | |||
| /* Since there are few pulses over an entire subframe (i.e. almost | |||
| all fc_in[i] are zero) it is faster to loop over fc_in first. */ | |||
| for(i=0; i<len; i++) | |||
| { | |||
| if(fc_in[i]) | |||
| { | |||
| for(k=0; k<i; k++) | |||
| fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15; | |||
| for(k=i; k<len; k++) | |||
| fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15; | |||
| } | |||
| } | |||
| } | |||
| int ff_acelp_lp_synthesis_filter( | |||
| int16_t *out, | |||
| const int16_t* filter_coeffs, | |||
| const int16_t* in, | |||
| int buffer_length, | |||
| int filter_length, | |||
| int stop_on_overflow, | |||
| int rounder) | |||
| { | |||
| int i,n; | |||
| // These two lines are to avoid a -1 subtraction in the main loop | |||
| filter_length++; | |||
| filter_coeffs--; | |||
| for(n=0; n<buffer_length; n++) | |||
| { | |||
| int sum = rounder; | |||
| for(i=1; i<filter_length; i++) | |||
| sum -= filter_coeffs[i] * out[n-i]; | |||
| sum = (sum >> 12) + in[n]; | |||
| if(sum + 0x8000 > 0xFFFFU) | |||
| { | |||
| if(stop_on_overflow) | |||
| return 1; | |||
| sum = (sum >> 31) ^ 32767; | |||
| } | |||
| out[n] = sum; | |||
| } | |||
| return 0; | |||
| } | |||
| void ff_acelp_high_pass_filter( | |||
| int16_t* out, | |||
| @@ -60,50 +60,6 @@ void ff_acelp_interpolate( | |||
| int filter_length, | |||
| int length); | |||
| /** | |||
| * Circularly convolve fixed vector with a phase dispersion impulse | |||
| * response filter (D.6.2 of G.729 and 6.1.5 of AMR). | |||
| * @param fc_out vector with filter applied | |||
| * @param fc_in source vector | |||
| * @param filter phase filter coefficients | |||
| * | |||
| * fc_out[n] = sum(i,0,len-1){ fc_in[i] * filter[(len + n - i)%len] } | |||
| * | |||
| * \note fc_in and fc_out should not overlap! | |||
| */ | |||
| void ff_acelp_convolve_circ( | |||
| int16_t* fc_out, | |||
| const int16_t* fc_in, | |||
| const int16_t* filter, | |||
| int len); | |||
| /** | |||
| * LP synthesis filter. | |||
| * @param out [out] pointer to output buffer | |||
| * @param filter_coeffs filter coefficients (-0x8000 <= (3.12) < 0x8000) | |||
| * @param in input signal | |||
| * @param buffer_length amount of data to process | |||
| * @param filter_length filter length (10 for 10th order LP filter) | |||
| * @param stop_on_overflow 1 - return immediately if overflow occurs | |||
| * 0 - ignore overflows | |||
| * @param rounder the amount to add for rounding (usually 0x800 or 0xfff) | |||
| * | |||
| * @return 1 if overflow occurred, 0 - otherwise | |||
| * | |||
| * @note Output buffer must contain 10 samples of past | |||
| * speech data before pointer. | |||
| * | |||
| * Routine applies 1/A(z) filter to given speech data. | |||
| */ | |||
| int ff_acelp_lp_synthesis_filter( | |||
| int16_t *out, | |||
| const int16_t* filter_coeffs, | |||
| const int16_t* in, | |||
| int buffer_length, | |||
| int filter_length, | |||
| int stop_on_overflow, | |||
| int rounder); | |||
| /** | |||
| * high-pass filtering and upscaling (4.2.5 of G.729). | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| * various filters for ACELP-based codecs | |||
| * | |||
| * Copyright (c) 2008 Vladimir Voroshilov | |||
| * | |||
| * 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 | |||
| */ | |||
| #include <inttypes.h> | |||
| #include "avcodec.h" | |||
| #include "celp_filters.h" | |||
| void ff_celp_convolve_circ( | |||
| int16_t* fc_out, | |||
| const int16_t* fc_in, | |||
| const int16_t* filter, | |||
| int len) | |||
| { | |||
| int i, k; | |||
| memset(fc_out, 0, len * sizeof(int16_t)); | |||
| /* Since there are few pulses over an entire subframe (i.e. almost | |||
| all fc_in[i] are zero) it is faster to loop over fc_in first. */ | |||
| for(i=0; i<len; i++) | |||
| { | |||
| if(fc_in[i]) | |||
| { | |||
| for(k=0; k<i; k++) | |||
| fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15; | |||
| for(k=i; k<len; k++) | |||
| fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15; | |||
| } | |||
| } | |||
| } | |||
| int ff_celp_lp_synthesis_filter( | |||
| int16_t *out, | |||
| const int16_t* filter_coeffs, | |||
| const int16_t* in, | |||
| int buffer_length, | |||
| int filter_length, | |||
| int stop_on_overflow, | |||
| int rounder) | |||
| { | |||
| int i,n; | |||
| // These two lines are to avoid a -1 subtraction in the main loop | |||
| filter_length++; | |||
| filter_coeffs--; | |||
| for(n=0; n<buffer_length; n++) | |||
| { | |||
| int sum = rounder; | |||
| for(i=1; i<filter_length; i++) | |||
| sum -= filter_coeffs[i] * out[n-i]; | |||
| sum = (sum >> 12) + in[n]; | |||
| if(sum + 0x8000 > 0xFFFFU) | |||
| { | |||
| if(stop_on_overflow) | |||
| return 1; | |||
| sum = (sum >> 31) ^ 32767; | |||
| } | |||
| out[n] = sum; | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -0,0 +1,72 @@ | |||
| /* | |||
| * various filters for CELP-based codecs | |||
| * | |||
| * Copyright (c) 2008 Vladimir Voroshilov | |||
| * | |||
| * 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_CELP_FILTERS_H | |||
| #define AVCODEC_CELP_FILTERS_H | |||
| #include <stdint.h> | |||
| /** | |||
| * Circularly convolve fixed vector with a phase dispersion impulse | |||
| * response filter (D.6.2 of G.729 and 6.1.5 of AMR). | |||
| * @param fc_out vector with filter applied | |||
| * @param fc_in source vector | |||
| * @param filter phase filter coefficients | |||
| * | |||
| * fc_out[n] = sum(i,0,len-1){ fc_in[i] * filter[(len + n - i)%len] } | |||
| * | |||
| * \note fc_in and fc_out should not overlap! | |||
| */ | |||
| void ff_celp_convolve_circ( | |||
| int16_t* fc_out, | |||
| const int16_t* fc_in, | |||
| const int16_t* filter, | |||
| int len); | |||
| /** | |||
| * LP synthesis filter. | |||
| * @param out [out] pointer to output buffer | |||
| * @param filter_coeffs filter coefficients (-0x8000 <= (3.12) < 0x8000) | |||
| * @param in input signal | |||
| * @param buffer_length amount of data to process | |||
| * @param filter_length filter length (10 for 10th order LP filter) | |||
| * @param stop_on_overflow 1 - return immediately if overflow occurs | |||
| * 0 - ignore overflows | |||
| * @param rounder the amount to add for rounding (usually 0x800 or 0xfff) | |||
| * | |||
| * @return 1 if overflow occurred, 0 - otherwise | |||
| * | |||
| * @note Output buffer must contain 10 samples of past | |||
| * speech data before pointer. | |||
| * | |||
| * Routine applies 1/A(z) filter to given speech data. | |||
| */ | |||
| int ff_celp_lp_synthesis_filter( | |||
| int16_t *out, | |||
| const int16_t* filter_coeffs, | |||
| const int16_t* in, | |||
| int buffer_length, | |||
| int filter_length, | |||
| int stop_on_overflow, | |||
| int rounder); | |||
| #endif /* AVCODEC_CELP_FILTERS_H */ | |||
| @@ -25,7 +25,7 @@ | |||
| #include "avcodec.h" | |||
| #include "bitstream.h" | |||
| #include "ra144.h" | |||
| #include "acelp_filters.h" | |||
| #include "celp_filters.h" | |||
| #define NBLOCKS 4 ///< number of subblocks within a block | |||
| #define BLOCKSIZE 40 ///< subblock size in 16-bit words | |||
| @@ -201,8 +201,8 @@ static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, | |||
| memcpy(ractx->curr_sblock, ractx->curr_sblock + 40, | |||
| 10*sizeof(*ractx->curr_sblock)); | |||
| if (ff_acelp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs, | |||
| block, BLOCKSIZE, 10, 1, 0xfff)) | |||
| if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs, | |||
| block, BLOCKSIZE, 10, 1, 0xfff)) | |||
| memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock)); | |||
| } | |||