35 memset(fc_out, 0, len *
sizeof(int16_t));
39 for (i = 0; i <
len; i++) {
41 for (k = 0; k <
i; k++)
42 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
44 for (k = i; k <
len; k++)
45 fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
51 const float *lagged,
int lag,
float fac,
int n)
54 for (k = 0; k < lag; k++)
55 out[k] = in[k] + fac * lagged[n + k - lag];
57 out[k] = in[k] + fac * lagged[ k - lag];
61 const int16_t *
in,
int buffer_length,
62 int filter_length,
int stop_on_overflow,
63 int shift,
int rounder)
67 for (n = 0; n < buffer_length; n++) {
68 int sum = rounder, sum1;
69 for (i = 1; i <= filter_length; i++)
70 sum -= (
unsigned)(filter_coeffs[i-1] * out[n-
i]);
72 sum1 = ((sum >> 12) + in[n]) >>
shift;
75 if (stop_on_overflow && sum != sum1)
85 const float*
in,
int buffer_length,
90 #if 0 // Unoptimized code path for improved readability 91 for (n = 0; n < buffer_length; n++) {
93 for (i = 1; i <= filter_length; i++)
94 out[n] -= filter_coeffs[i-1] * out[n-i];
97 float out0, out1, out2, out3;
98 float old_out0, old_out1, old_out2, old_out3;
101 a = filter_coeffs[0];
102 b = filter_coeffs[1];
103 c = filter_coeffs[2];
104 b -= filter_coeffs[0] * filter_coeffs[0];
105 c -= filter_coeffs[1] * filter_coeffs[0];
106 c -= filter_coeffs[0] *
b;
108 av_assert2((filter_length&1)==0 && filter_length>=4);
114 for (n = 0; n <= buffer_length - 4; n+=4) {
115 float tmp0,tmp1,tmp2;
123 out0 -= filter_coeffs[2] * old_out1;
124 out1 -= filter_coeffs[2] * old_out2;
125 out2 -= filter_coeffs[2] * old_out3;
127 out0 -= filter_coeffs[1] * old_out2;
128 out1 -= filter_coeffs[1] * old_out3;
130 out0 -= filter_coeffs[0] * old_out3;
132 val = filter_coeffs[3];
134 out0 -= val * old_out0;
135 out1 -= val * old_out1;
136 out2 -= val * old_out2;
137 out3 -= val * old_out3;
139 for (i = 5; i < filter_length; i += 2) {
141 val = filter_coeffs[i-1];
143 out0 -= val * old_out3;
144 out1 -= val * old_out0;
145 out2 -= val * old_out1;
146 out3 -= val * old_out2;
148 old_out2 = out[-i-1];
150 val = filter_coeffs[
i];
152 out0 -= val * old_out2;
153 out1 -= val * old_out3;
154 out2 -= val * old_out0;
155 out3 -= val * old_out1;
157 FFSWAP(
float, old_out0, old_out2);
191 for (; n < buffer_length; n++) {
193 for (i = 1; i <= filter_length; i++)
194 out[n] -= filter_coeffs[i-1] * out[n-i];
200 const float *
in,
int buffer_length,
205 for (n = 0; n < buffer_length; n++) {
207 for (i = 1; i <= filter_length; i++)
208 out[n] += filter_coeffs[i-1] * in[n-i];
void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, const float *in, int buffer_length, int filter_length)
LP synthesis filter.
static int shift(int a, int b)
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 shift, int rounder)
LP synthesis filter.
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
void(* celp_lp_zero_synthesis_filterf)(float *out, const float *filter_coeffs, const float *in, int buffer_length, int filter_length)
LP zero synthesis filter.
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
void(* celp_lp_synthesis_filterf)(float *out, const float *filter_coeffs, const float *in, int buffer_length, int filter_length)
LP synthesis filter.
simple assert() macros that are a bit more flexible than ISO C assert().
void ff_celp_convolve_circ(int16_t *fc_out, const int16_t *fc_in, const int16_t *filter, int len)
Circularly convolve fixed vector with a phase dispersion impulse response filter (D.6.2 of G.729 and 6.1.5 of AMR).
Libavcodec external API header.
void ff_celp_circ_addf(float *out, const float *in, const float *lagged, int lag, float fac, int n)
Add an array to a rotated array.
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
void ff_celp_filter_init(CELPFContext *c)
Initialize CELPFContext.
void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs, const float *in, int buffer_length, int filter_length)
LP zero synthesis filter.
common internal and external API header
#define FFSWAP(type, a, b)
static double val(void *priv, double ch)
void ff_celp_filter_init_mips(CELPFContext *c)