audio: add af_lavrresample, remove old resampling filters
[mplayer.git] / libaf / af_lavrresample.c
blob1185e1529403a143ceca914bf87904710c35354b
1 /*
2 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
4 * Copyright (c) 2013 Uoti Urpala <uau@mplayer2.org>
6 * This file is part of mplayer2.
8 * mplayer2 is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * mplayer2 is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with mplayer2. If not, see <http://www.gnu.org/licenses/>.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <inttypes.h>
26 #include <stdbool.h>
28 #include <libavutil/common.h>
29 #include <libavutil/opt.h>
30 #include <libavutil/samplefmt.h>
31 #include <libavutil/mathematics.h>
32 #include <libavresample/avresample.h>
34 #include "talloc.h"
35 #include "config.h"
37 #include "mp_msg.h"
38 #include "subopt-helper.h"
39 #include "af.h"
41 struct af_resample_opts {
42 int filter_size;
43 int phase_shift;
44 int linear;
45 double cutoff;
47 int out_rate;
48 int in_rate;
51 struct af_resample {
52 struct AVAudioResampleContext *avrctx;
53 struct af_resample_opts ctx; // opts in the context
54 struct af_resample_opts opts; // opts requested by the user
57 static double af_resample_default_cutoff(int filter_size)
59 return FFMAX(1.0 - 6.5 / (filter_size + 8), 0.80);
62 static bool needs_lavrctx_reconfigure(struct af_resample *s,
63 struct af_data *in,
64 struct af_data *out)
66 return s->ctx.out_rate != out->rate ||
67 s->ctx.in_rate != in->rate ||
68 s->ctx.filter_size != s->opts.filter_size ||
69 s->ctx.phase_shift != s->opts.phase_shift ||
70 s->ctx.linear != s->opts.linear ||
71 s->ctx.cutoff != s->opts.cutoff;
75 #define ctx_opt_set_int(a,b) av_opt_set_int(s->avrctx, (a), (b), 0)
76 #define ctx_opt_set_dbl(a,b) av_opt_set_double(s->avrctx, (a), (b), 0)
78 static int control(struct af_instance_s *af, int cmd, void *arg)
80 struct af_resample *s = af->setup;
81 struct af_data *in = arg;
82 struct af_data *out = af->data;
84 switch (cmd) {
85 case AF_CONTROL_REINIT: {
86 if ((out->rate == in->rate) || (out->rate == 0))
87 return AF_DETACH;
89 out->nch = FFMIN(in->nch, AF_NCH);
90 out->format = AF_FORMAT_S16_NE;
91 out->bps = 2;
92 af->mul = (double) out->rate / in->rate;
93 af->delay = out->nch * s->opts.filter_size / FFMIN(af->mul, 1);
95 if (needs_lavrctx_reconfigure(s, in, out)) {
96 if (s->avrctx)
97 avresample_close(s->avrctx);
99 s->ctx.out_rate = out->rate;
100 s->ctx.in_rate = in->rate;
101 s->ctx.filter_size = s->opts.filter_size;
102 s->ctx.phase_shift = s->opts.phase_shift;
103 s->ctx.linear = s->opts.linear;
104 s->ctx.cutoff = s->opts.cutoff;
106 int ch_layout = av_get_default_channel_layout(out->nch);
108 ctx_opt_set_int("in_channel_layout", ch_layout);
109 ctx_opt_set_int("out_channel_layout", ch_layout);
111 ctx_opt_set_int("in_sample_rate", s->ctx.in_rate);
112 ctx_opt_set_int("out_sample_rate", s->ctx.out_rate);
114 ctx_opt_set_int("in_sample_fmt", AV_SAMPLE_FMT_S16);
115 ctx_opt_set_int("out_sample_fmt", AV_SAMPLE_FMT_S16);
117 ctx_opt_set_int("filter_size", s->ctx.filter_size);
118 ctx_opt_set_int("phase_shift", s->ctx.phase_shift);
119 ctx_opt_set_int("linear_interp", s->ctx.linear);
121 ctx_opt_set_dbl("cutoff", s->ctx.cutoff);
123 if (avresample_open(s->avrctx) < 0) {
124 mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Cannot open "
125 "Libavresample Context. \n");
126 return AF_ERROR;
130 int out_rate, test_output_res;
131 // hack to make af_test_output ignore the samplerate change
132 out_rate = out->rate;
133 out->rate = in->rate;
134 test_output_res = af_test_output(af, in);
135 out->rate = out_rate;
136 return test_output_res;
138 case AF_CONTROL_COMMAND_LINE: {
139 s->opts.cutoff = 0.0;
141 const opt_t subopts[] = {
142 {"srate", OPT_ARG_INT, &out->rate, NULL},
143 {"filter_size", OPT_ARG_INT, &s->opts.filter_size, NULL},
144 {"phase_shift", OPT_ARG_INT, &s->opts.phase_shift, NULL},
145 {"linear", OPT_ARG_BOOL, &s->opts.linear, NULL},
146 {"cutoff", OPT_ARG_FLOAT, &s->opts.cutoff, NULL},
149 if (subopt_parse(arg, subopts) != 0) {
150 mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Invalid option "
151 "specified.\n");
152 return AF_ERROR;
155 if (s->opts.cutoff <= 0.0)
156 s->opts.cutoff = af_resample_default_cutoff(s->opts.filter_size);
157 return AF_OK;
159 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
160 out->rate = *(int *)arg;
161 return AF_OK;
163 return AF_UNKNOWN;
166 #undef ctx_opt_set_int
167 #undef ctx_opt_set_dbl
169 static void uninit(struct af_instance_s *af)
171 if (af->setup) {
172 struct af_resample *s = af->setup;
173 if (s->avrctx)
174 avresample_close(s->avrctx);
175 talloc_free(af->setup);
179 static struct af_data *play(struct af_instance_s *af, struct af_data *data)
181 struct af_resample *s = af->setup;
182 struct af_data *in = data;
183 struct af_data *out = af->data;
186 int in_size = data->len;
187 int in_samples = in_size / (data->bps * data->nch);
188 int out_samples = avresample_available(s->avrctx) +
189 av_rescale_rnd(avresample_get_delay(s->avrctx) + in_samples,
190 s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
191 int out_size = out->bps * out_samples * out->nch;
193 if (talloc_get_size(out->audio) < out_size)
194 out->audio = talloc_realloc_size(out, out->audio, out_size);
196 af->delay = out->bps * av_rescale_rnd(avresample_get_delay(s->avrctx),
197 s->ctx.out_rate, s->ctx.in_rate,
198 AV_ROUND_UP);
200 out_samples = avresample_convert(s->avrctx,
201 (uint8_t **) &out->audio, out_size, out_samples,
202 (uint8_t **) &in->audio, in_size, in_samples);
204 out_size = out->bps * out_samples * out->nch;
205 in->audio = out->audio;
206 in->len = out_size;
207 in->rate = s->ctx.out_rate;
208 return data;
211 static int af_open(struct af_instance_s *af)
213 struct af_resample *s = talloc_zero(NULL, struct af_resample);
215 af->control = control;
216 af->uninit = uninit;
217 af->play = play;
218 af->mul = 1;
219 af->data = talloc_zero(s, struct af_data);
221 af->data->rate = 44100;
223 int default_filter_size = 16;
224 s->opts = (struct af_resample_opts) {
225 .linear = 0,
226 .filter_size = default_filter_size,
227 .cutoff = af_resample_default_cutoff(default_filter_size),
228 .phase_shift = 10,
231 s->avrctx = avresample_alloc_context();
232 af->setup = s;
234 if (s->avrctx) {
235 return AF_OK;
236 } else {
237 mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Cannot initialize "
238 "libavresample context. \n");
239 uninit(af);
240 return AF_ERROR;
244 struct af_info af_info_lavrresample = {
245 "Sample frequency conversion using libavresample",
246 "lavrresample",
247 "Stefano Pigozzi (based on Michael Niedermayer's lavcresample)",
249 AF_FLAGS_REENTRANT,
250 af_open
252 #warning don't use subopt / positional arguments
253 #warning use lavr default option values
254 #warning support float and other data types