| 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 | // 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 | |||
| 81 | 160 | static void RENAME(resample_one)(void *dest, const void *source, | |
| 82 | int dst_size, int64_t index2, int64_t incr) | ||
| 83 | { | ||
| 84 | 160 | DELEM *dst = dest; | |
| 85 | 160 | const DELEM *src = source; | |
| 86 | int dst_index; | ||
| 87 | |||
| 88 |
2/2✓ Branch 0 taken 112896 times.
✓ Branch 1 taken 80 times.
|
225952 | for (dst_index = 0; dst_index < dst_size; dst_index++) { |
| 89 | 225792 | dst[dst_index] = src[index2 >> 32]; | |
| 90 | 225792 | index2 += incr; | |
| 91 | } | ||
| 92 | 160 | } | |
| 93 | |||
| 94 | 181940 | static int RENAME(resample_common)(ResampleContext *c, | |
| 95 | void *dest, const void *source, | ||
| 96 | int n, int update_ctx) | ||
| 97 | { | ||
| 98 | 181940 | DELEM *dst = dest; | |
| 99 | 181940 | const DELEM *src = source; | |
| 100 | int dst_index; | ||
| 101 | 181940 | int index= c->index; | |
| 102 | 181940 | int frac= c->frac; | |
| 103 | 181940 | int sample_index = 0; | |
| 104 | |||
| 105 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 90970 times.
|
181940 | while (index >= c->phase_count) { |
| 106 | ✗ | sample_index++; | |
| 107 | ✗ | index -= c->phase_count; | |
| 108 | } | ||
| 109 | |||
| 110 |
2/2✓ Branch 0 taken 31992467 times.
✓ Branch 1 taken 90970 times.
|
64166874 | for (dst_index = 0; dst_index < n; dst_index++) { |
| 111 | 63984934 | FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |
| 112 | |||
| 113 | 63984934 | FELEM2 val = FOFFSET; | |
| 114 | 63984934 | FELEM2 val2= 0; | |
| 115 | int i; | ||
| 116 |
2/2✓ Branch 0 taken 574904213 times.
✓ Branch 1 taken 31992467 times.
|
1213793360 | for (i = 0; i + 1 < c->filter_length; i+=2) { |
| 117 | 1149808426 | val += src[sample_index + i ] * (FELEM2)filter[i ]; | |
| 118 | 1149808426 | val2 += src[sample_index + i + 1] * (FELEM2)filter[i + 1]; | |
| 119 | } | ||
| 120 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31992467 times.
|
63984934 | if (i < c->filter_length) |
| 121 | ✗ | val += src[sample_index + i ] * (FELEM2)filter[i ]; | |
| 122 | #ifdef FELEML | ||
| 123 | 11624226 | OUT(dst[dst_index], val + (FELEML)val2); | |
| 124 | #else | ||
| 125 | 52360708 | OUT(dst[dst_index], val + val2); | |
| 126 | #endif | ||
| 127 | |||
| 128 | 63984934 | frac += c->dst_incr_mod; | |
| 129 | 63984934 | index += c->dst_incr_div; | |
| 130 |
2/2✓ Branch 0 taken 2913928 times.
✓ Branch 1 taken 29078539 times.
|
63984934 | if (frac >= c->src_incr) { |
| 131 | 5827856 | frac -= c->src_incr; | |
| 132 | 5827856 | index++; | |
| 133 | } | ||
| 134 | |||
| 135 |
2/2✓ Branch 0 taken 21727552 times.
✓ Branch 1 taken 31992467 times.
|
107440038 | while (index >= c->phase_count) { |
| 136 | 43455104 | sample_index++; | |
| 137 | 43455104 | index -= c->phase_count; | |
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 |
2/2✓ Branch 0 taken 53853 times.
✓ Branch 1 taken 37117 times.
|
181940 | if(update_ctx){ |
| 142 | 107706 | c->frac= frac; | |
| 143 | 107706 | c->index= index; | |
| 144 | } | ||
| 145 | |||
| 146 | 181940 | return sample_index; | |
| 147 | } | ||
| 148 | |||
| 149 | 5242 | static int RENAME(resample_linear)(ResampleContext *c, | |
| 150 | void *dest, const void *source, | ||
| 151 | int n, int update_ctx) | ||
| 152 | { | ||
| 153 | 5242 | DELEM *dst = dest; | |
| 154 | 5242 | const DELEM *src = source; | |
| 155 | int dst_index; | ||
| 156 | 5242 | int index= c->index; | |
| 157 | 5242 | int frac= c->frac; | |
| 158 | 5242 | int sample_index = 0; | |
| 159 | #if FILTER_SHIFT == 0 | ||
| 160 | 2732 | double inv_src_incr = 1.0 / c->src_incr; | |
| 161 | #endif | ||
| 162 | |||
| 163 | 5242 | while (index >= c->phase_count) { | |
| 164 | ✗ | sample_index++; | |
| 165 | ✗ | index -= c->phase_count; | |
| 166 | } | ||
| 167 | |||
| 168 | 4441919 | for (dst_index = 0; dst_index < n; dst_index++) { | |
| 169 | 4436677 | FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; | |
| 170 | 4436677 | FELEM2U val = FOFFSET, v2 = FOFFSET; | |
| 171 | |||
| 172 | int i; | ||
| 173 | 254782083 | for (i = 0; i < c->filter_length; i++) { | |
| 174 | 250345406 | val += src[sample_index + i] * (FELEM2)filter[i]; | |
| 175 | 250345406 | v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; | |
| 176 | } | ||
| 177 | #ifdef FELEML | ||
| 178 | 1158131 | val += (FELEM2)(v2 - val) * (FELEML) frac / c->src_incr; | |
| 179 | #else | ||
| 180 | # if FILTER_SHIFT == 0 | ||
| 181 | 2313368 | val += (FELEM2)(v2 - val) * inv_src_incr * frac; | |
| 182 | # else | ||
| 183 | 965178 | val += (FELEM2)(v2 - val) / c->src_incr * frac; | |
| 184 | # endif | ||
| 185 | #endif | ||
| 186 | 4436677 | OUT(dst[dst_index], (FELEM2)val); | |
| 187 | |||
| 188 | 4436677 | frac += c->dst_incr_mod; | |
| 189 | 4436677 | index += c->dst_incr_div; | |
| 190 | 4436677 | if (frac >= c->src_incr) { | |
| 191 | 1528899 | frac -= c->src_incr; | |
| 192 | 1528899 | index++; | |
| 193 | } | ||
| 194 | |||
| 195 | 8436664 | while (index >= c->phase_count) { | |
| 196 | 3999987 | sample_index++; | |
| 197 | 3999987 | index -= c->phase_count; | |
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | 5242 | if(update_ctx){ | |
| 202 | 5242 | c->frac= frac; | |
| 203 | 5242 | c->index= index; | |
| 204 | } | ||
| 205 | |||
| 206 | 5242 | 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 | ||
| 220 |