FFmpeg
synth_filter.c
Go to the documentation of this file.
1 /*
2  * copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (C) 2016 foo86
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "fft.h"
23 #include "dcadct.h"
24 #include "dcamath.h"
25 #include "synth_filter.h"
26 
27 static void synth_filter_float(FFTContext *imdct,
28  float *synth_buf_ptr, int *synth_buf_offset,
29  float synth_buf2[32], const float window[512],
30  float out[32], const float in[32], float scale)
31 {
32  float *synth_buf = synth_buf_ptr + *synth_buf_offset;
33  int i, j;
34 
35  imdct->imdct_half(imdct, synth_buf, in);
36 
37  for (i = 0; i < 16; i++) {
38  float a = synth_buf2[i ];
39  float b = synth_buf2[i + 16];
40  float c = 0;
41  float d = 0;
42  for (j = 0; j < 512 - *synth_buf_offset; j += 64) {
43  a += window[i + j ] * (-synth_buf[15 - i + j ]);
44  b += window[i + j + 16] * ( synth_buf[ i + j ]);
45  c += window[i + j + 32] * ( synth_buf[16 + i + j ]);
46  d += window[i + j + 48] * ( synth_buf[31 - i + j ]);
47  }
48  for ( ; j < 512; j += 64) {
49  a += window[i + j ] * (-synth_buf[15 - i + j - 512]);
50  b += window[i + j + 16] * ( synth_buf[ i + j - 512]);
51  c += window[i + j + 32] * ( synth_buf[16 + i + j - 512]);
52  d += window[i + j + 48] * ( synth_buf[31 - i + j - 512]);
53  }
54  out[i ] = a * scale;
55  out[i + 16] = b * scale;
56  synth_buf2[i ] = c;
57  synth_buf2[i + 16] = d;
58  }
59 
60  *synth_buf_offset = (*synth_buf_offset - 32) & 511;
61 }
62 
63 static void synth_filter_float_64(FFTContext *imdct,
64  float *synth_buf_ptr, int *synth_buf_offset,
65  float synth_buf2[64], const float window[1024],
66  float out[64], const float in[64], float scale)
67 {
68  float *synth_buf = synth_buf_ptr + *synth_buf_offset;
69  int i, j;
70 
71  imdct->imdct_half(imdct, synth_buf, in);
72 
73  for (i = 0; i < 32; i++) {
74  float a = synth_buf2[i ];
75  float b = synth_buf2[i + 32];
76  float c = 0;
77  float d = 0;
78  for (j = 0; j < 1024 - *synth_buf_offset; j += 128) {
79  a += window[i + j ] * (-synth_buf[31 - i + j ]);
80  b += window[i + j + 32] * ( synth_buf[ i + j ]);
81  c += window[i + j + 64] * ( synth_buf[32 + i + j ]);
82  d += window[i + j + 96] * ( synth_buf[63 - i + j ]);
83  }
84  for ( ; j < 1024; j += 128) {
85  a += window[i + j ] * (-synth_buf[31 - i + j - 1024]);
86  b += window[i + j + 32] * ( synth_buf[ i + j - 1024]);
87  c += window[i + j + 64] * ( synth_buf[32 + i + j - 1024]);
88  d += window[i + j + 96] * ( synth_buf[63 - i + j - 1024]);
89  }
90  out[i ] = a * scale;
91  out[i + 32] = b * scale;
92  synth_buf2[i ] = c;
93  synth_buf2[i + 32] = d;
94  }
95 
96  *synth_buf_offset = (*synth_buf_offset - 64) & 1023;
97 }
98 
99 static void synth_filter_fixed(DCADCTContext *imdct,
100  int32_t *synth_buf_ptr, int *synth_buf_offset,
101  int32_t synth_buf2[32], const int32_t window[512],
102  int32_t out[32], const int32_t in[32])
103 {
104  int32_t *synth_buf = synth_buf_ptr + *synth_buf_offset;
105  int i, j;
106 
107  imdct->imdct_half[0](synth_buf, in);
108 
109  for (i = 0; i < 16; i++) {
110  int64_t a = synth_buf2[i ] * (INT64_C(1) << 21);
111  int64_t b = synth_buf2[i + 16] * (INT64_C(1) << 21);
112  int64_t c = 0;
113  int64_t d = 0;
114  for (j = 0; j < 512 - *synth_buf_offset; j += 64) {
115  a += (int64_t)window[i + j ] * synth_buf[ i + j ];
116  b += (int64_t)window[i + j + 16] * synth_buf[15 - i + j ];
117  c += (int64_t)window[i + j + 32] * synth_buf[16 + i + j ];
118  d += (int64_t)window[i + j + 48] * synth_buf[31 - i + j ];
119  }
120  for ( ; j < 512; j += 64) {
121  a += (int64_t)window[i + j ] * synth_buf[ i + j - 512];
122  b += (int64_t)window[i + j + 16] * synth_buf[15 - i + j - 512];
123  c += (int64_t)window[i + j + 32] * synth_buf[16 + i + j - 512];
124  d += (int64_t)window[i + j + 48] * synth_buf[31 - i + j - 512];
125  }
126  out[i ] = clip23(norm21(a));
127  out[i + 16] = clip23(norm21(b));
128  synth_buf2[i ] = norm21(c);
129  synth_buf2[i + 16] = norm21(d);
130  }
131 
132  *synth_buf_offset = (*synth_buf_offset - 32) & 511;
133 }
134 
136  int32_t *synth_buf_ptr, int *synth_buf_offset,
137  int32_t synth_buf2[64], const int32_t window[1024],
138  int32_t out[64], const int32_t in[64])
139 {
140  int32_t *synth_buf = synth_buf_ptr + *synth_buf_offset;
141  int i, j;
142 
143  imdct->imdct_half[1](synth_buf, in);
144 
145  for (i = 0; i < 32; i++) {
146  int64_t a = synth_buf2[i ] * (INT64_C(1) << 20);
147  int64_t b = synth_buf2[i + 32] * (INT64_C(1) << 20);
148  int64_t c = 0;
149  int64_t d = 0;
150  for (j = 0; j < 1024 - *synth_buf_offset; j += 128) {
151  a += (int64_t)window[i + j ] * synth_buf[ i + j ];
152  b += (int64_t)window[i + j + 32] * synth_buf[31 - i + j ];
153  c += (int64_t)window[i + j + 64] * synth_buf[32 + i + j ];
154  d += (int64_t)window[i + j + 96] * synth_buf[63 - i + j ];
155  }
156  for ( ; j < 1024; j += 128) {
157  a += (int64_t)window[i + j ] * synth_buf[ i + j - 1024];
158  b += (int64_t)window[i + j + 32] * synth_buf[31 - i + j - 1024];
159  c += (int64_t)window[i + j + 64] * synth_buf[32 + i + j - 1024];
160  d += (int64_t)window[i + j + 96] * synth_buf[63 - i + j - 1024];
161  }
162  out[i ] = clip23(norm20(a));
163  out[i + 32] = clip23(norm20(b));
164  synth_buf2[i ] = norm20(c);
165  synth_buf2[i + 32] = norm20(d);
166  }
167 
168  *synth_buf_offset = (*synth_buf_offset - 64) & 1023;
169 }
170 
172 {
173  c->synth_filter_float = synth_filter_float;
174  c->synth_filter_float_64 = synth_filter_float_64;
175  c->synth_filter_fixed = synth_filter_fixed;
176  c->synth_filter_fixed_64 = synth_filter_fixed_64;
177 
178  if (ARCH_AARCH64)
180  if (ARCH_ARM)
182  if (ARCH_X86)
184 }
dcamath.h
out
FILE * out
Definition: movenc.c:54
synth_filter.h
dcadct.h
b
#define b
Definition: input.c:41
ff_synth_filter_init_aarch64
av_cold void ff_synth_filter_init_aarch64(SynthFilterContext *s)
Definition: synth_filter_init.c:41
synth_filter_float_64
static void synth_filter_float_64(FFTContext *imdct, float *synth_buf_ptr, int *synth_buf_offset, float synth_buf2[64], const float window[1024], float out[64], const float in[64], float scale)
Definition: synth_filter.c:63
synth_filter_fixed_64
static void synth_filter_fixed_64(DCADCTContext *imdct, int32_t *synth_buf_ptr, int *synth_buf_offset, int32_t synth_buf2[64], const int32_t window[1024], int32_t out[64], const int32_t in[64])
Definition: synth_filter.c:135
norm20
static int32_t norm20(int64_t a)
Definition: dcamath.h:42
ff_synth_filter_init
av_cold void ff_synth_filter_init(SynthFilterContext *c)
Definition: synth_filter.c:171
window
static SDL_Window * window
Definition: ffplay.c:366
SynthFilterContext
Definition: synth_filter.h:27
clip23
static int32_t clip23(int32_t a)
Definition: dcamath.h:54
synth_filter_float
static void synth_filter_float(FFTContext *imdct, float *synth_buf_ptr, int *synth_buf_offset, float synth_buf2[32], const float window[512], float out[32], const float in[32], float scale)
Definition: synth_filter.c:27
av_cold
#define av_cold
Definition: attributes.h:90
DCADCTContext
Definition: dcadct.h:26
int32_t
int32_t
Definition: audio_convert.c:194
c
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
Definition: undefined.txt:32
FFTContext::imdct_half
void(* imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.h:103
ff_synth_filter_init_arm
av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
Definition: synth_filter_init_arm.c:41
DCADCTContext::imdct_half
void(* imdct_half[2])(int32_t *output, const int32_t *input)
Definition: dcadct.h:27
a
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
Definition: undefined.txt:41
in
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
Definition: audio_convert.c:326
FFTContext
Definition: fft.h:83
i
int i
Definition: input.c:407
norm21
static int32_t norm21(int64_t a)
Definition: dcamath.h:43
synth_filter_fixed
static void synth_filter_fixed(DCADCTContext *imdct, int32_t *synth_buf_ptr, int *synth_buf_offset, int32_t synth_buf2[32], const int32_t window[512], int32_t out[32], const int32_t in[32])
Definition: synth_filter.c:99
fft.h
ff_synth_filter_init_x86
void ff_synth_filter_init_x86(SynthFilterContext *c)
Definition: synth_filter_init.c:54