2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/common.h"
23 #include "libavutil/libm.h"
24 #include "libavutil/log.h"
26 #include "audio_data.h"
28 struct ResampleContext
{
29 AVAudioResampleContext
*avr
;
38 int compensation_distance
;
42 enum AVResampleFilterType filter_type
;
45 void (*set_filter
)(void *filter
, double *tab
, int phase
, int tap_count
);
46 void (*resample_one
)(struct ResampleContext
*c
, int no_filter
, void *dst0
,
47 int dst_index
, const void *src0
, int src_size
,
53 #define CONFIG_RESAMPLE_DBL
54 #include "resample_template.c"
55 #undef CONFIG_RESAMPLE_DBL
58 #define CONFIG_RESAMPLE_FLT
59 #include "resample_template.c"
60 #undef CONFIG_RESAMPLE_FLT
63 #define CONFIG_RESAMPLE_S32
64 #include "resample_template.c"
65 #undef CONFIG_RESAMPLE_S32
68 #include "resample_template.c"
71 /* 0th order modified bessel function of the first kind. */
72 static double bessel(double x
)
80 for (i
= 1; v
!= lastv
; i
++) {
88 /* Build a polyphase filterbank. */
89 static int build_filter(ResampleContext
*c
)
92 double x
, y
, w
, factor
;
94 int tap_count
= c
->filter_length
;
95 int phase_count
= 1 << c
->phase_shift
;
96 const int center
= (tap_count
- 1) / 2;
98 tab
= av_malloc(tap_count
* sizeof(*tab
));
100 return AVERROR(ENOMEM
);
102 /* if upsampling, only need to interpolate, no filter */
103 factor
= FFMIN(c
->factor
, 1.0);
105 for (ph
= 0; ph
< phase_count
; ph
++) {
107 for (i
= 0; i
< tap_count
; i
++) {
108 x
= M_PI
* ((double)(i
- center
) - (double)ph
/ phase_count
) * factor
;
111 switch (c
->filter_type
) {
112 case AV_RESAMPLE_FILTER_TYPE_CUBIC
: {
113 const float d
= -0.5; //first order derivative = -0.5
114 x
= fabs(((double)(i
- center
) - (double)ph
/ phase_count
) * factor
);
115 if (x
< 1.0) y
= 1 - 3 * x
*x
+ 2 * x
*x
*x
+ d
* ( -x
*x
+ x
*x
*x
);
116 else y
= d
* (-4 + 8 * x
- 5 * x
*x
+ x
*x
*x
);
119 case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL
:
120 w
= 2.0 * x
/ (factor
* tap_count
) + M_PI
;
121 y
*= 0.3635819 - 0.4891775 * cos( w
) +
122 0.1365995 * cos(2 * w
) -
123 0.0106411 * cos(3 * w
);
125 case AV_RESAMPLE_FILTER_TYPE_KAISER
:
126 w
= 2.0 * x
/ (factor
* tap_count
* M_PI
);
127 y
*= bessel(c
->kaiser_beta
* sqrt(FFMAX(1 - w
* w
, 0)));
134 /* normalize so that an uniform color remains the same */
135 for (i
= 0; i
< tap_count
; i
++)
136 tab
[i
] = tab
[i
] / norm
;
138 c
->set_filter(c
->filter_bank
, tab
, ph
, tap_count
);
145 ResampleContext
*ff_audio_resample_init(AVAudioResampleContext
*avr
)
148 int out_rate
= avr
->out_sample_rate
;
149 int in_rate
= avr
->in_sample_rate
;
150 double factor
= FFMIN(out_rate
* avr
->cutoff
/ in_rate
, 1.0);
151 int phase_count
= 1 << avr
->phase_shift
;
154 if (avr
->internal_sample_fmt
!= AV_SAMPLE_FMT_S16P
&&
155 avr
->internal_sample_fmt
!= AV_SAMPLE_FMT_S32P
&&
156 avr
->internal_sample_fmt
!= AV_SAMPLE_FMT_FLTP
&&
157 avr
->internal_sample_fmt
!= AV_SAMPLE_FMT_DBLP
) {
158 av_log(avr
, AV_LOG_ERROR
, "Unsupported internal format for "
160 av_get_sample_fmt_name(avr
->internal_sample_fmt
));
163 c
= av_mallocz(sizeof(*c
));
168 c
->phase_shift
= avr
->phase_shift
;
169 c
->phase_mask
= phase_count
- 1;
170 c
->linear
= avr
->linear_interp
;
172 c
->filter_length
= FFMAX((int)ceil(avr
->filter_size
/ factor
), 1);
173 c
->filter_type
= avr
->filter_type
;
174 c
->kaiser_beta
= avr
->kaiser_beta
;
176 switch (avr
->internal_sample_fmt
) {
177 case AV_SAMPLE_FMT_DBLP
:
178 c
->resample_one
= resample_one_dbl
;
179 c
->set_filter
= set_filter_dbl
;
181 case AV_SAMPLE_FMT_FLTP
:
182 c
->resample_one
= resample_one_flt
;
183 c
->set_filter
= set_filter_flt
;
185 case AV_SAMPLE_FMT_S32P
:
186 c
->resample_one
= resample_one_s32
;
187 c
->set_filter
= set_filter_s32
;
189 case AV_SAMPLE_FMT_S16P
:
190 c
->resample_one
= resample_one_s16
;
191 c
->set_filter
= set_filter_s16
;
195 felem_size
= av_get_bytes_per_sample(avr
->internal_sample_fmt
);
196 c
->filter_bank
= av_mallocz(c
->filter_length
* (phase_count
+ 1) * felem_size
);
200 if (build_filter(c
) < 0)
203 memcpy(&c
->filter_bank
[(c
->filter_length
* phase_count
+ 1) * felem_size
],
204 c
->filter_bank
, (c
->filter_length
- 1) * felem_size
);
205 memcpy(&c
->filter_bank
[c
->filter_length
* phase_count
* felem_size
],
206 &c
->filter_bank
[(c
->filter_length
- 1) * felem_size
], felem_size
);
208 c
->compensation_distance
= 0;
209 if (!av_reduce(&c
->src_incr
, &c
->dst_incr
, out_rate
,
210 in_rate
* (int64_t)phase_count
, INT32_MAX
/ 2))
212 c
->ideal_dst_incr
= c
->dst_incr
;
214 c
->index
= -phase_count
* ((c
->filter_length
- 1) / 2);
217 /* allocate internal buffer */
218 c
->buffer
= ff_audio_data_alloc(avr
->resample_channels
, 0,
219 avr
->internal_sample_fmt
,
224 av_log(avr
, AV_LOG_DEBUG
, "resample: %s from %d Hz to %d Hz\n",
225 av_get_sample_fmt_name(avr
->internal_sample_fmt
),
226 avr
->in_sample_rate
, avr
->out_sample_rate
);
231 ff_audio_data_free(&c
->buffer
);
232 av_free(c
->filter_bank
);
237 void ff_audio_resample_free(ResampleContext
**c
)
241 ff_audio_data_free(&(*c
)->buffer
);
242 av_free((*c
)->filter_bank
);
246 int avresample_set_compensation(AVAudioResampleContext
*avr
, int sample_delta
,
247 int compensation_distance
)
250 AudioData
*fifo_buf
= NULL
;
253 if (compensation_distance
< 0)
254 return AVERROR(EINVAL
);
255 if (!compensation_distance
&& sample_delta
)
256 return AVERROR(EINVAL
);
258 /* if resampling was not enabled previously, re-initialize the
259 AVAudioResampleContext and force resampling */
260 if (!avr
->resample_needed
) {
262 double matrix
[AVRESAMPLE_MAX_CHANNELS
* AVRESAMPLE_MAX_CHANNELS
] = { 0 };
264 /* buffer any remaining samples in the output FIFO before closing */
265 fifo_samples
= av_audio_fifo_size(avr
->out_fifo
);
266 if (fifo_samples
> 0) {
267 fifo_buf
= ff_audio_data_alloc(avr
->out_channels
, fifo_samples
,
268 avr
->out_sample_fmt
, NULL
);
270 return AVERROR(EINVAL
);
271 ret
= ff_audio_data_read_from_fifo(avr
->out_fifo
, fifo_buf
,
276 /* save the channel mixing matrix */
277 ret
= avresample_get_matrix(avr
, matrix
, AVRESAMPLE_MAX_CHANNELS
);
281 /* close the AVAudioResampleContext */
282 avresample_close(avr
);
284 avr
->force_resampling
= 1;
286 /* restore the channel mixing matrix */
287 ret
= avresample_set_matrix(avr
, matrix
, AVRESAMPLE_MAX_CHANNELS
);
291 /* re-open the AVAudioResampleContext */
292 ret
= avresample_open(avr
);
296 /* restore buffered samples to the output FIFO */
297 if (fifo_samples
> 0) {
298 ret
= ff_audio_data_add_to_fifo(avr
->out_fifo
, fifo_buf
, 0,
302 ff_audio_data_free(&fifo_buf
);
306 c
->compensation_distance
= compensation_distance
;
307 if (compensation_distance
) {
308 c
->dst_incr
= c
->ideal_dst_incr
- c
->ideal_dst_incr
*
309 (int64_t)sample_delta
/ compensation_distance
;
311 c
->dst_incr
= c
->ideal_dst_incr
;
316 ff_audio_data_free(&fifo_buf
);
320 static int resample(ResampleContext
*c
, void *dst
, const void *src
,
321 int *consumed
, int src_size
, int dst_size
, int update_ctx
)
324 int index
= c
->index
;
326 int dst_incr_frac
= c
->dst_incr
% c
->src_incr
;
327 int dst_incr
= c
->dst_incr
/ c
->src_incr
;
328 int compensation_distance
= c
->compensation_distance
;
331 return AVERROR(EINVAL
);
333 if (compensation_distance
== 0 && c
->filter_length
== 1 &&
334 c
->phase_shift
== 0) {
335 int64_t index2
= ((int64_t)index
) << 32;
336 int64_t incr
= (1LL << 32) * c
->dst_incr
/ c
->src_incr
;
337 dst_size
= FFMIN(dst_size
,
338 (src_size
-1-index
) * (int64_t)c
->src_incr
/
342 for(dst_index
= 0; dst_index
< dst_size
; dst_index
++) {
343 c
->resample_one(c
, 1, dst
, dst_index
, src
, 0, index2
>> 32, 0);
347 dst_index
= dst_size
;
349 index
+= dst_index
* dst_incr
;
350 index
+= (frac
+ dst_index
* (int64_t)dst_incr_frac
) / c
->src_incr
;
351 frac
= (frac
+ dst_index
* (int64_t)dst_incr_frac
) % c
->src_incr
;
353 for (dst_index
= 0; dst_index
< dst_size
; dst_index
++) {
354 int sample_index
= index
>> c
->phase_shift
;
356 if (sample_index
+ c
->filter_length
> src_size
||
357 -sample_index
>= src_size
)
361 c
->resample_one(c
, 0, dst
, dst_index
, src
, src_size
, index
, frac
);
363 frac
+= dst_incr_frac
;
365 if (frac
>= c
->src_incr
) {
369 if (dst_index
+ 1 == compensation_distance
) {
370 compensation_distance
= 0;
371 dst_incr_frac
= c
->ideal_dst_incr
% c
->src_incr
;
372 dst_incr
= c
->ideal_dst_incr
/ c
->src_incr
;
377 *consumed
= FFMAX(index
, 0) >> c
->phase_shift
;
381 index
&= c
->phase_mask
;
383 if (compensation_distance
) {
384 compensation_distance
-= dst_index
;
385 if (compensation_distance
<= 0)
390 c
->dst_incr
= dst_incr_frac
+ c
->src_incr
*dst_incr
;
391 c
->compensation_distance
= compensation_distance
;
397 int ff_audio_resample(ResampleContext
*c
, AudioData
*dst
, AudioData
*src
,
400 int ch
, in_samples
, in_leftover
, out_samples
= 0;
401 int ret
= AVERROR(EINVAL
);
403 in_samples
= src ? src
->nb_samples
: 0;
404 in_leftover
= c
->buffer
->nb_samples
;
406 /* add input samples to the internal buffer */
408 ret
= ff_audio_data_combine(c
->buffer
, in_leftover
, src
, 0, in_samples
);
411 } else if (!in_leftover
) {
412 /* no remaining samples to flush */
415 /* TODO: pad buffer to flush completely */
418 /* calculate output size and reallocate output buffer if needed */
419 /* TODO: try to calculate this without the dummy resample() run */
420 if (!dst
->read_only
&& dst
->allow_realloc
) {
421 out_samples
= resample(c
, NULL
, NULL
, NULL
, c
->buffer
->nb_samples
,
423 ret
= ff_audio_data_realloc(dst
, out_samples
);
425 av_log(c
->avr
, AV_LOG_ERROR
, "error reallocating output\n");
430 /* resample each channel plane */
431 for (ch
= 0; ch
< c
->buffer
->channels
; ch
++) {
432 out_samples
= resample(c
, (void *)dst
->data
[ch
],
433 (const void *)c
->buffer
->data
[ch
], consumed
,
434 c
->buffer
->nb_samples
, dst
->allocated_samples
,
435 ch
+ 1 == c
->buffer
->channels
);
437 if (out_samples
< 0) {
438 av_log(c
->avr
, AV_LOG_ERROR
, "error during resampling\n");
442 /* drain consumed samples from the internal buffer */
443 ff_audio_data_drain(c
->buffer
, *consumed
);
445 av_dlog(c
->avr
, "resampled %d in + %d leftover to %d out + %d leftover\n",
446 in_samples
, in_leftover
, out_samples
, c
->buffer
->nb_samples
);
448 dst
->nb_samples
= out_samples
;
452 int avresample_get_delay(AVAudioResampleContext
*avr
)
454 if (!avr
->resample_needed
|| !avr
->resample
)
457 return avr
->resample
->buffer
->nb_samples
;