FFmpeg
Loading...
Searching...
No Matches
resample_template.c
Go to the documentation of this file.
1/*
2 * audio resampling
3 * Copyright (c) 2004-2012 Michael Niedermayer <michaelni@gmx.at>
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/**
23 * @file
24 * audio resampling
25 * @author Michael Niedermayer <michaelni@gmx.at>
26 */
27
28// FELEM2U, a variant of FELEM2 which does not produce undefined overflow
29
30#if defined(TEMPLATE_RESAMPLE_DBL)
31
32# define RENAME(N) N ## _double
33# define FILTER_SHIFT 0
34# define DELEM double
35# define FELEM double
36# define FELEM2 double
37# define FELEM2U double
38# define FOFFSET 0
39# define OUT(d, v) d = v
40
41#elif defined(TEMPLATE_RESAMPLE_FLT)
42
43# define RENAME(N) N ## _float
44# define FILTER_SHIFT 0
45# define DELEM float
46# define FELEM float
47# define FELEM2 float
48# define FELEM2U float
49# define FOFFSET 0
50# define OUT(d, v) d = v
51
52#elif defined(TEMPLATE_RESAMPLE_S32)
53
54# define RENAME(N) N ## _int32
55# define FILTER_SHIFT 30
56# define DELEM int32_t
57# define FELEM int32_t
58# define FELEM2 int64_t
59# define FELEM2U uint64_t
60# define FELEM_MAX INT32_MAX
61# define FELEM_MIN INT32_MIN
62# define FOFFSET (1<<(FILTER_SHIFT-1))
63# define OUT(d, v) (d) = av_clipl_int32((v)>>FILTER_SHIFT)
64
65#elif defined(TEMPLATE_RESAMPLE_S16)
66
67# define RENAME(N) N ## _int16
68# define FILTER_SHIFT 15
69# define DELEM int16_t
70# define FELEM int16_t
71# define FELEM2 int32_t
72# define FELEM2U uint32_t
73# define FELEML int64_t
74# define FELEM_MAX INT16_MAX
75# define FELEM_MIN INT16_MIN
76# define FOFFSET (1<<(FILTER_SHIFT-1))
77# define OUT(d, v) (d) = av_clip_int16((v)>>FILTER_SHIFT)
78
79#endif
80
81static void RENAME(resample_one)(void *dest, const void *source,
82 int dst_size, int64_t index2, int64_t incr)
83{
84 DELEM *dst = dest;
85 const DELEM *src = source;
86 int dst_index;
87
88 for (dst_index = 0; dst_index < dst_size; dst_index++) {
89 dst[dst_index] = src[index2 >> 32];
90 index2 += incr;
91 }
92}
93
94static int RENAME(resample_common)(ResampleContext *c,
95 void *dest, const void *source,
96 int n, int update_ctx)
97{
98 DELEM *dst = dest;
99 const DELEM *src = source;
100 int dst_index;
101 int index= c->index;
102 int frac= c->frac;
103 int sample_index = 0;
104
105 while (index >= c->phase_count) {
106 sample_index++;
107 index -= c->phase_count;
108 }
109
110 for (dst_index = 0; dst_index < n; dst_index++) {
111 FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
112
113 FELEM2 val = FOFFSET;
114 FELEM2 val2= 0;
115 int i;
116 for (i = 0; i + 1 < c->filter_length; i+=2) {
117 val += src[sample_index + i ] * (FELEM2)filter[i ];
118 val2 += src[sample_index + i + 1] * (FELEM2)filter[i + 1];
119 }
120 if (i < c->filter_length)
121 val += src[sample_index + i ] * (FELEM2)filter[i ];
122#ifdef FELEML
123 OUT(dst[dst_index], val + (FELEML)val2);
124#else
125 OUT(dst[dst_index], val + val2);
126#endif
127
128 frac += c->dst_incr_mod;
129 index += c->dst_incr_div;
130 if (frac >= c->src_incr) {
131 frac -= c->src_incr;
132 index++;
133 }
134
135 while (index >= c->phase_count) {
136 sample_index++;
137 index -= c->phase_count;
138 }
139 }
140
141 if(update_ctx){
142 c->frac= frac;
143 c->index= index;
144 }
145
146 return sample_index;
147}
148
150 void *dest, const void *source,
151 int n, int update_ctx)
152{
153 DELEM *dst = dest;
154 const DELEM *src = source;
155 int dst_index;
156 int index= c->index;
157 int frac= c->frac;
158 int sample_index = 0;
159#if FILTER_SHIFT == 0
160 double inv_src_incr = 1.0 / c->src_incr;
161#endif
162
163 while (index >= c->phase_count) {
164 sample_index++;
165 index -= c->phase_count;
166 }
167
168 for (dst_index = 0; dst_index < n; dst_index++) {
169 FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
170 FELEM2U val = FOFFSET, v2 = FOFFSET;
171
172 int i;
173 for (i = 0; i < c->filter_length; i++) {
174 val += src[sample_index + i] * (FELEM2)filter[i];
175 v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
176 }
177#ifdef FELEML
178 val += (FELEM2)(v2 - val) * (FELEML) frac / c->src_incr;
179#else
180# if FILTER_SHIFT == 0
181 val += (FELEM2)(v2 - val) * inv_src_incr * frac;
182# else
183 val += (FELEM2)(v2 - val) / c->src_incr * frac;
184# endif
185#endif
186 OUT(dst[dst_index], (FELEM2)val);
187
188 frac += c->dst_incr_mod;
189 index += c->dst_incr_div;
190 if (frac >= c->src_incr) {
191 frac -= c->src_incr;
192 index++;
193 }
194
195 while (index >= c->phase_count) {
196 sample_index++;
197 index -= c->phase_count;
198 }
199 }
200
201 if(update_ctx){
202 c->frac= frac;
203 c->index= index;
204 }
205
206 return sample_index;
207}
208
209#undef RENAME
210#undef FILTER_SHIFT
211#undef DELEM
212#undef FELEM
213#undef FELEM2
214#undef FELEM2U
215#undef FELEML
216#undef FELEM_MAX
217#undef FELEM_MIN
218#undef OUT
219#undef FOFFSET
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define RENAME(element)
static double val(void *priv, double ch)
Definition aeval.c:77
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
long long int64_t
Definition coverity.c:34
#define OUT(n)
int index
Definition gxfenc.c:90
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
#define src
Definition vp8dsp.c:248
static int resample_linear(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
static double c[64]