Line | Branch | Exec | Source |
---|---|---|---|
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 | #if defined(TEMPLATE_RESAMPLE_DBL) | ||
29 | |||
30 | # define RENAME(N) N ## _double | ||
31 | # define FILTER_SHIFT 0 | ||
32 | # define DELEM double | ||
33 | # define FELEM double | ||
34 | # define FELEM2 double | ||
35 | # define FOFFSET 0 | ||
36 | # define OUT(d, v) d = v | ||
37 | |||
38 | #elif defined(TEMPLATE_RESAMPLE_FLT) | ||
39 | |||
40 | # define RENAME(N) N ## _float | ||
41 | # define FILTER_SHIFT 0 | ||
42 | # define DELEM float | ||
43 | # define FELEM float | ||
44 | # define FELEM2 float | ||
45 | # define FOFFSET 0 | ||
46 | # define OUT(d, v) d = v | ||
47 | |||
48 | #elif defined(TEMPLATE_RESAMPLE_S32) | ||
49 | |||
50 | # define RENAME(N) N ## _int32 | ||
51 | # define FILTER_SHIFT 30 | ||
52 | # define DELEM int32_t | ||
53 | # define FELEM int32_t | ||
54 | # define FELEM2 int64_t | ||
55 | # define FELEM_MAX INT32_MAX | ||
56 | # define FELEM_MIN INT32_MIN | ||
57 | # define FOFFSET (1<<(FILTER_SHIFT-1)) | ||
58 | # define OUT(d, v) (d) = av_clipl_int32((v)>>FILTER_SHIFT) | ||
59 | |||
60 | #elif defined(TEMPLATE_RESAMPLE_S16) | ||
61 | |||
62 | # define RENAME(N) N ## _int16 | ||
63 | # define FILTER_SHIFT 15 | ||
64 | # define DELEM int16_t | ||
65 | # define FELEM int16_t | ||
66 | # define FELEM2 int32_t | ||
67 | # define FELEML int64_t | ||
68 | # define FELEM_MAX INT16_MAX | ||
69 | # define FELEM_MIN INT16_MIN | ||
70 | # define FOFFSET (1<<(FILTER_SHIFT-1)) | ||
71 | # define OUT(d, v) (d) = av_clip_int16((v)>>FILTER_SHIFT) | ||
72 | |||
73 | #endif | ||
74 | |||
75 | 160 | static void RENAME(resample_one)(void *dest, const void *source, | |
76 | int dst_size, int64_t index2, int64_t incr) | ||
77 | { | ||
78 | 160 | DELEM *dst = dest; | |
79 | 160 | const DELEM *src = source; | |
80 | int dst_index; | ||
81 | |||
82 |
2/2✓ Branch 0 taken 112896 times.
✓ Branch 1 taken 80 times.
|
225952 | for (dst_index = 0; dst_index < dst_size; dst_index++) { |
83 | 225792 | dst[dst_index] = src[index2 >> 32]; | |
84 | 225792 | index2 += incr; | |
85 | } | ||
86 | 160 | } | |
87 | |||
88 | 181800 | static int RENAME(resample_common)(ResampleContext *c, | |
89 | void *dest, const void *source, | ||
90 | int n, int update_ctx) | ||
91 | { | ||
92 | 181800 | DELEM *dst = dest; | |
93 | 181800 | const DELEM *src = source; | |
94 | int dst_index; | ||
95 | 181800 | int index= c->index; | |
96 | 181800 | int frac= c->frac; | |
97 | 181800 | int sample_index = 0; | |
98 | |||
99 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 90900 times.
|
181800 | while (index >= c->phase_count) { |
100 | ✗ | sample_index++; | |
101 | ✗ | index -= c->phase_count; | |
102 | } | ||
103 | |||
104 |
2/2✓ Branch 0 taken 31980691 times.
✓ Branch 1 taken 90900 times.
|
64143182 | for (dst_index = 0; dst_index < n; dst_index++) { |
105 | 63961382 | FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |
106 | |||
107 | 63961382 | FELEM2 val = FOFFSET; | |
108 | 63961382 | FELEM2 val2= 0; | |
109 | int i; | ||
110 |
2/2✓ Branch 0 taken 574515605 times.
✓ Branch 1 taken 31980691 times.
|
1212992592 | for (i = 0; i + 1 < c->filter_length; i+=2) { |
111 | 1149031210 | val += src[sample_index + i ] * (FELEM2)filter[i ]; | |
112 | 1149031210 | val2 += src[sample_index + i + 1] * (FELEM2)filter[i + 1]; | |
113 | } | ||
114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31980691 times.
|
63961382 | if (i < c->filter_length) |
115 | ✗ | val += src[sample_index + i ] * (FELEM2)filter[i ]; | |
116 | #ifdef FELEML | ||
117 | 11624226 | OUT(dst[dst_index], val + (FELEML)val2); | |
118 | #else | ||
119 | 52337156 | OUT(dst[dst_index], val + val2); | |
120 | #endif | ||
121 | |||
122 | 63961382 | frac += c->dst_incr_mod; | |
123 | 63961382 | index += c->dst_incr_div; | |
124 |
2/2✓ Branch 0 taken 2913928 times.
✓ Branch 1 taken 29066763 times.
|
63961382 | if (frac >= c->src_incr) { |
125 | 5827856 | frac -= c->src_incr; | |
126 | 5827856 | index++; | |
127 | } | ||
128 | |||
129 |
2/2✓ Branch 0 taken 21704000 times.
✓ Branch 1 taken 31980691 times.
|
107369382 | while (index >= c->phase_count) { |
130 | 43408000 | sample_index++; | |
131 | 43408000 | index -= c->phase_count; | |
132 | } | ||
133 | } | ||
134 | |||
135 |
2/2✓ Branch 0 taken 53783 times.
✓ Branch 1 taken 37117 times.
|
181800 | if(update_ctx){ |
136 | 107566 | c->frac= frac; | |
137 | 107566 | c->index= index; | |
138 | } | ||
139 | |||
140 | 181800 | return sample_index; | |
141 | } | ||
142 | |||
143 | 5242 | static int RENAME(resample_linear)(ResampleContext *c, | |
144 | void *dest, const void *source, | ||
145 | int n, int update_ctx) | ||
146 | { | ||
147 | 5242 | DELEM *dst = dest; | |
148 | 5242 | const DELEM *src = source; | |
149 | int dst_index; | ||
150 | 5242 | int index= c->index; | |
151 | 5242 | int frac= c->frac; | |
152 | 5242 | int sample_index = 0; | |
153 | #if FILTER_SHIFT == 0 | ||
154 | 2732 | double inv_src_incr = 1.0 / c->src_incr; | |
155 | #endif | ||
156 | |||
157 | 5242 | while (index >= c->phase_count) { | |
158 | ✗ | sample_index++; | |
159 | ✗ | index -= c->phase_count; | |
160 | } | ||
161 | |||
162 | 4441919 | for (dst_index = 0; dst_index < n; dst_index++) { | |
163 | 4436677 | FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |
164 | 4436677 | FELEM2 val = FOFFSET, v2 = FOFFSET; | |
165 | |||
166 | int i; | ||
167 | 254782083 | for (i = 0; i < c->filter_length; i++) { | |
168 | 250345406 | val += src[sample_index + i] * (FELEM2)filter[i]; | |
169 | 250345406 | v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; | |
170 | } | ||
171 | #ifdef FELEML | ||
172 | 1158131 | val += (v2 - val) * (FELEML) frac / c->src_incr; | |
173 | #else | ||
174 | # if FILTER_SHIFT == 0 | ||
175 | 2313368 | val += (v2 - val) * inv_src_incr * frac; | |
176 | # else | ||
177 | 965178 | val += (v2 - val) / c->src_incr * frac; | |
178 | # endif | ||
179 | #endif | ||
180 | 4436677 | OUT(dst[dst_index], val); | |
181 | |||
182 | 4436677 | frac += c->dst_incr_mod; | |
183 | 4436677 | index += c->dst_incr_div; | |
184 | 4436677 | if (frac >= c->src_incr) { | |
185 | 1528899 | frac -= c->src_incr; | |
186 | 1528899 | index++; | |
187 | } | ||
188 | |||
189 | 8436664 | while (index >= c->phase_count) { | |
190 | 3999987 | sample_index++; | |
191 | 3999987 | index -= c->phase_count; | |
192 | } | ||
193 | } | ||
194 | |||
195 | 5242 | if(update_ctx){ | |
196 | 5242 | c->frac= frac; | |
197 | 5242 | c->index= index; | |
198 | } | ||
199 | |||
200 | 5242 | return sample_index; | |
201 | } | ||
202 | |||
203 | #undef RENAME | ||
204 | #undef FILTER_SHIFT | ||
205 | #undef DELEM | ||
206 | #undef FELEM | ||
207 | #undef FELEM2 | ||
208 | #undef FELEML | ||
209 | #undef FELEM_MAX | ||
210 | #undef FELEM_MIN | ||
211 | #undef OUT | ||
212 | #undef FOFFSET | ||
213 |