Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52868 views
1
/*
2
* audio resampling
3
* Copyright (c) 2004-2012 Michael Niedermayer <[email protected]>
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 <[email protected]>
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 OUT(d, v) d = v
36
37
#elif defined(TEMPLATE_RESAMPLE_FLT)
38
39
# define RENAME(N) N ## _float
40
# define FILTER_SHIFT 0
41
# define DELEM float
42
# define FELEM float
43
# define FELEM2 float
44
# define OUT(d, v) d = v
45
46
#elif defined(TEMPLATE_RESAMPLE_S32)
47
48
# define RENAME(N) N ## _int32
49
# define FILTER_SHIFT 30
50
# define DELEM int32_t
51
# define FELEM int32_t
52
# define FELEM2 int64_t
53
# define FELEM_MAX INT32_MAX
54
# define FELEM_MIN INT32_MIN
55
# define OUT(d, v) (v) = ((v) + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
56
(d) = av_clipl_int32(v)
57
58
#elif defined(TEMPLATE_RESAMPLE_S16)
59
60
# define RENAME(N) N ## _int16
61
# define FILTER_SHIFT 15
62
# define DELEM int16_t
63
# define FELEM int16_t
64
# define FELEM2 int32_t
65
# define FELEML int64_t
66
# define FELEM_MAX INT16_MAX
67
# define FELEM_MIN INT16_MIN
68
# define OUT(d, v) (v) = ((v) + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
69
(d) = av_clip_int16(v)
70
71
#endif
72
73
static void RENAME(resample_one)(void *dest, const void *source,
74
int dst_size, int64_t index2, int64_t incr)
75
{
76
DELEM *dst = dest;
77
const DELEM *src = source;
78
int dst_index;
79
80
for (dst_index = 0; dst_index < dst_size; dst_index++) {
81
dst[dst_index] = src[index2 >> 32];
82
index2 += incr;
83
}
84
}
85
86
static int RENAME(resample_common)(ResampleContext *c,
87
void *dest, const void *source,
88
int n, int update_ctx)
89
{
90
DELEM *dst = dest;
91
const DELEM *src = source;
92
int dst_index;
93
int index= c->index;
94
int frac= c->frac;
95
int sample_index = index >> c->phase_shift;
96
97
index &= c->phase_mask;
98
for (dst_index = 0; dst_index < n; dst_index++) {
99
FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
100
101
FELEM2 val=0;
102
int i;
103
for (i = 0; i < c->filter_length; i++) {
104
val += src[sample_index + i] * (FELEM2)filter[i];
105
}
106
OUT(dst[dst_index], val);
107
108
frac += c->dst_incr_mod;
109
index += c->dst_incr_div;
110
if (frac >= c->src_incr) {
111
frac -= c->src_incr;
112
index++;
113
}
114
sample_index += index >> c->phase_shift;
115
index &= c->phase_mask;
116
}
117
118
if(update_ctx){
119
c->frac= frac;
120
c->index= index;
121
}
122
123
return sample_index;
124
}
125
126
static int RENAME(resample_linear)(ResampleContext *c,
127
void *dest, const void *source,
128
int n, int update_ctx)
129
{
130
DELEM *dst = dest;
131
const DELEM *src = source;
132
int dst_index;
133
int index= c->index;
134
int frac= c->frac;
135
int sample_index = index >> c->phase_shift;
136
#if FILTER_SHIFT == 0
137
double inv_src_incr = 1.0 / c->src_incr;
138
#endif
139
140
index &= c->phase_mask;
141
for (dst_index = 0; dst_index < n; dst_index++) {
142
FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;
143
FELEM2 val=0, v2 = 0;
144
145
int i;
146
for (i = 0; i < c->filter_length; i++) {
147
val += src[sample_index + i] * (FELEM2)filter[i];
148
v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
149
}
150
#ifdef FELEML
151
val += (v2 - val) * (FELEML) frac / c->src_incr;
152
#else
153
# if FILTER_SHIFT == 0
154
val += (v2 - val) * inv_src_incr * frac;
155
# else
156
val += (v2 - val) / c->src_incr * frac;
157
# endif
158
#endif
159
OUT(dst[dst_index], val);
160
161
frac += c->dst_incr_mod;
162
index += c->dst_incr_div;
163
if (frac >= c->src_incr) {
164
frac -= c->src_incr;
165
index++;
166
}
167
sample_index += index >> c->phase_shift;
168
index &= c->phase_mask;
169
}
170
171
if(update_ctx){
172
c->frac= frac;
173
c->index= index;
174
}
175
176
return sample_index;
177
}
178
179
#undef RENAME
180
#undef FILTER_SHIFT
181
#undef DELEM
182
#undef FELEM
183
#undef FELEM2
184
#undef FELEML
185
#undef FELEM_MAX
186
#undef FELEM_MIN
187
#undef OUT
188
189