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 
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
static int64_t get_out_samples(struct SwrContext *s, int in_samples)
int out_sample_rate
output sample rate
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:121
int ch_count
number of channels
SwrFilterType
Resampling Filter Types.
Definition: swresample.h:166
double delayed_samples_fixup
soxr 0.1.1: needed to fixup delayed_samples after flush has been called.
double, planar
Definition: samplefmt.h:70
GLint GLenum type
Definition: opengl_enc.c:105
static float kaiser_beta(float att, float tr_bw)
Definition: asrc_sinc.c:140
static int64_t get_delay(struct SwrContext *s, int64_t base)
Definition: soxr_resample.c:99
struct ResampleContext * resample
resampling context
#define src
Definition: vp8dsp.c:254
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
static int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
Definition: soxr_resample.c:84
#define f(width, name)
Definition: cbs_vp9.c:255
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
enum AVResampleFilterType filter_type
Definition: resample.h:42
signed 32 bits
Definition: samplefmt.h:62
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
The libswresample context.
#define FFMAX(a, b)
Definition: common.h:94
#define FFMIN(a, b)
Definition: common.h:96
signed 32 bits, planar
Definition: samplefmt.h:68
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
int in_sample_rate
input sample rate
#define s(width, name)
Definition: cbs_vp9.c:257
static void error(const char *err)
static int flush(struct SwrContext *s)
Definition: soxr_resample.c:69
static void destroy(struct ResampleContext **c)
Definition: soxr_resample.c:64
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int flushed
1 if data is to be flushed and no further input is expected
int
signed 16 bits
Definition: samplefmt.h:61
static int invert_initial_buffer(struct ResampleContext *c, AudioData *dst, const AudioData *src, int in_count, int *out_idx, int *out_sz)
signed 16 bits, planar
Definition: samplefmt.h:67
struct Resampler const swri_soxr_resampler
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel