FFmpeg
soxr_resample.c
Go to the documentation of this file.
1 /*
2  * audio resampling with soxr
3  * Copyright (c) 2012 Rob Sykes <robs@users.sourceforge.net>
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 with soxr
25  */
26 
27 #include "libavutil/log.h"
28 #include "swresample_internal.h"
29 
30 #include <soxr.h>
31 
32 static struct ResampleContext *create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
33  double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational){
34  soxr_error_t error;
35 
36  soxr_datatype_t type =
37  format == AV_SAMPLE_FMT_S16P? SOXR_INT16_S :
38  format == AV_SAMPLE_FMT_S16 ? SOXR_INT16_I :
39  format == AV_SAMPLE_FMT_S32P? SOXR_INT32_S :
40  format == AV_SAMPLE_FMT_S32 ? SOXR_INT32_I :
41  format == AV_SAMPLE_FMT_FLTP? SOXR_FLOAT32_S :
42  format == AV_SAMPLE_FMT_FLT ? SOXR_FLOAT32_I :
43  format == AV_SAMPLE_FMT_DBLP? SOXR_FLOAT64_S :
44  format == AV_SAMPLE_FMT_DBL ? SOXR_FLOAT64_I : (soxr_datatype_t)-1;
45 
46  soxr_io_spec_t io_spec = soxr_io_spec(type, type);
47 
48  soxr_quality_spec_t q_spec = soxr_quality_spec((int)((precision-2)/4), (SOXR_HI_PREC_CLOCK|SOXR_ROLLOFF_NONE)*!!cheby);
49  q_spec.precision = precision;
50 #if !defined SOXR_VERSION /* Deprecated @ March 2013: */
51  q_spec.bw_pc = cutoff? FFMAX(FFMIN(cutoff,.995),.8)*100 : q_spec.bw_pc;
52 #else
53  q_spec.passband_end = cutoff? FFMAX(FFMIN(cutoff,.995),.8) : q_spec.passband_end;
54 #endif
55 
56  soxr_delete((soxr_t)c);
57  c = (struct ResampleContext *)
58  soxr_create(in_rate, out_rate, 0, &error, &io_spec, &q_spec, 0);
59  if (!c)
60  av_log(NULL, AV_LOG_ERROR, "soxr_create: %s\n", error);
61  return c;
62 }
63 
64 static void destroy(struct ResampleContext * *c){
65  soxr_delete((soxr_t)*c);
66  *c = NULL;
67 }
68 
69 static int flush(struct SwrContext *s){
70  s->delayed_samples_fixup = soxr_delay((soxr_t)s->resample);
71 
72  soxr_process((soxr_t)s->resample, NULL, 0, NULL, NULL, 0, NULL);
73 
74  {
75  float f;
76  size_t idone, odone;
77  soxr_process((soxr_t)s->resample, &f, 0, &idone, &f, 0, &odone);
78  s->delayed_samples_fixup -= soxr_delay((soxr_t)s->resample);
79  }
80 
81  return 0;
82 }
83 
84 static int process(
85  struct ResampleContext * c, AudioData *dst, int dst_size,
86  AudioData *src, int src_size, int *consumed){
87  size_t idone, odone;
88  soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count));
89  if (!error)
90  error = soxr_process((soxr_t)c, src->ch, (size_t)src_size,
91  &idone, dst->ch, (size_t)dst_size, &odone);
92  else
93  idone = 0;
94 
95  *consumed = (int)idone;
96  return error? -1 : odone;
97 }
98 
99 static int64_t get_delay(struct SwrContext *s, int64_t base){
100  double delayed_samples = soxr_delay((soxr_t)s->resample);
101  double delay_s;
102 
103  if (s->flushed)
104  delayed_samples += s->delayed_samples_fixup;
105 
106  delay_s = delayed_samples / s->out_sample_rate;
107 
108  return (int64_t)(delay_s * base + .5);
109 }
110 
112  int in_count, int *out_idx, int *out_sz){
113  return 0;
114 }
115 
116 static int64_t get_out_samples(struct SwrContext *s, int in_samples){
117  double out_samples = (double)s->out_sample_rate / s->in_sample_rate * in_samples;
118  double delayed_samples = soxr_delay((soxr_t)s->resample);
119 
120  if (s->flushed)
121  delayed_samples += s->delayed_samples_fixup;
122 
123  return (int64_t)(out_samples + delayed_samples + 1 + .5);
124 }
125 
127  create, destroy, process, flush, NULL /* set_compensation */, get_delay,
129 };
130 
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
get_delay
static int64_t get_delay(struct SwrContext *s, int64_t base)
Definition: soxr_resample.c:99
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
destroy
static void destroy(struct ResampleContext **c)
Definition: soxr_resample.c:64
kaiser_beta
static float kaiser_beta(float att, float tr_bw)
Definition: asrc_sinc.c:134
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
linear
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:131
base
uint8_t base
Definition: vp3data.h:141
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AudioData
Definition: swresample_internal.h:45
flush
static int flush(struct SwrContext *s)
Definition: soxr_resample.c:69
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
get_out_samples
static int64_t get_out_samples(struct SwrContext *s, int in_samples)
Definition: soxr_resample.c:116
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
s
#define s(width, name)
Definition: cbs_vp9.c:257
ResampleContext
Definition: resample.h:30
ResampleContext::filter_type
enum SwrFilterType filter_type
Definition: resample.h:45
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
f
#define f(width, name)
Definition: cbs_vp9.c:255
AudioData::ch
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
Definition: swresample_internal.h:46
NULL
#define NULL
Definition: coverity.c:32
SwrFilterType
SwrFilterType
Resampling Filter Types.
Definition: swresample.h:166
create
static struct ResampleContext * create(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational)
Definition: soxr_resample.c:32
src
#define src
Definition: vp8dsp.c:255
swri_soxr_resampler
struct Resampler const swri_soxr_resampler
Definition: soxr_resample.c:126
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
process
static int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
Definition: soxr_resample.c:84
invert_initial_buffer
static int invert_initial_buffer(struct ResampleContext *c, AudioData *dst, const AudioData *src, int in_count, int *out_idx, int *out_sz)
Definition: soxr_resample.c:111
swresample_internal.h
Resampler
Definition: swresample_internal.h:81
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
log.h
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
format
fg outputs[0] format
Definition: ffmpeg_filter.c:175
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
int
int
Definition: ffmpeg_filter.c:156
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63