FFmpeg
Loading...
Searching...
No Matches
af_bs2b.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 * Bauer stereo-to-binaural filter
22 */
23
24#include <bs2b.h>
25
27#include "libavutil/common.h"
28#include "libavutil/opt.h"
29
30#include "audio.h"
31#include "avfilter.h"
32#include "filters.h"
33#include "formats.h"
34
35typedef void (*filter_func)(t_bs2bdp bs2bdp, uint8_t *sample, int n);
36
37typedef struct Bs2bContext {
38 const AVClass *class;
39
41 int fcut;
42 int feed;
43
44 t_bs2bdp bs2bp;
45
48
49#define OFFSET(x) offsetof(Bs2bContext, x)
50#define A AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
51
52static const AVOption bs2b_options[] = {
53 { "profile", "Apply a pre-defined crossfeed level",
54 OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = BS2B_DEFAULT_CLEVEL }, 0, INT_MAX, A, .unit = "profile" },
55 { "default", "default profile", 0, AV_OPT_TYPE_CONST, { .i64 = BS2B_DEFAULT_CLEVEL }, 0, 0, A, .unit = "profile" },
56 { "cmoy", "Chu Moy circuit", 0, AV_OPT_TYPE_CONST, { .i64 = BS2B_CMOY_CLEVEL }, 0, 0, A, .unit = "profile" },
57 { "jmeier", "Jan Meier circuit", 0, AV_OPT_TYPE_CONST, { .i64 = BS2B_JMEIER_CLEVEL }, 0, 0, A, .unit = "profile" },
58 { "fcut", "Set cut frequency (in Hz)",
59 OFFSET(fcut), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, BS2B_MAXFCUT, A },
60 { "feed", "Set feed level (in Hz)",
61 OFFSET(feed), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, BS2B_MAXFEED, A },
62 { NULL },
63};
64
66
68{
69 Bs2bContext *bs2b = ctx->priv;
70
71 if (!(bs2b->bs2bp = bs2b_open()))
72 return AVERROR(ENOMEM);
73
74 bs2b_set_level(bs2b->bs2bp, bs2b->profile);
75
76 if (bs2b->fcut)
77 bs2b_set_level_fcut(bs2b->bs2bp, bs2b->fcut);
78
79 if (bs2b->feed)
80 bs2b_set_level_feed(bs2b->bs2bp, bs2b->feed);
81
82 return 0;
83}
84
86{
87 Bs2bContext *bs2b = ctx->priv;
88
89 if (bs2b->bs2bp)
90 bs2b_close(bs2b->bs2bp);
91}
92
94 AVFilterFormatsConfig **cfg_in,
95 AVFilterFormatsConfig **cfg_out)
96{
97 static const AVChannelLayout layouts[] = {
99 { .nb_channels = 0 },
100 };
101
102 static const enum AVSampleFormat sample_fmts[] = {
109 };
110 int ret;
111
113 if (ret < 0)
114 return ret;
115
116 ret = ff_set_sample_formats_from_list2(ctx, cfg_in, cfg_out, sample_fmts);
117 if (ret < 0)
118 return ret;
119
120 return 0;
121}
122
124{
125 int ret;
126 AVFrame *out_frame;
127
128 Bs2bContext *bs2b = inlink->dst->priv;
129 AVFilterLink *outlink = inlink->dst->outputs[0];
130
132 out_frame = frame;
133 } else {
134 out_frame = ff_get_audio_buffer(outlink, frame->nb_samples);
135 if (!out_frame) {
137 return AVERROR(ENOMEM);
138 }
139 av_frame_copy(out_frame, frame);
140 ret = av_frame_copy_props(out_frame, frame);
141 if (ret < 0) {
142 av_frame_free(&out_frame);
144 return ret;
145 }
146 }
147
148 bs2b->filter(bs2b->bs2bp, out_frame->extended_data[0], out_frame->nb_samples);
149
150 if (frame != out_frame)
152
153 return ff_filter_frame(outlink, out_frame);
154}
155
156static int config_output(AVFilterLink *outlink)
157{
158 AVFilterContext *ctx = outlink->src;
159 Bs2bContext *bs2b = ctx->priv;
160 AVFilterLink *inlink = ctx->inputs[0];
161
162 int srate = inlink->sample_rate;
163
164 switch (inlink->format) {
165 case AV_SAMPLE_FMT_U8:
166 bs2b->filter = (filter_func) bs2b_cross_feed_u8;
167 break;
169 bs2b->filter = (filter_func) bs2b_cross_feed_s16;
170 break;
172 bs2b->filter = (filter_func) bs2b_cross_feed_s32;
173 break;
175 bs2b->filter = (filter_func) bs2b_cross_feed_f;
176 break;
178 bs2b->filter = (filter_func) bs2b_cross_feed_d;
179 break;
180 default:
181 return AVERROR_BUG;
182 }
183
184 if ((srate < BS2B_MINSRATE) || (srate > BS2B_MAXSRATE))
185 return AVERROR(ENOSYS);
186
187 bs2b_set_srate(bs2b->bs2bp, srate);
188
189 return 0;
190}
191
192static const AVFilterPad bs2b_inputs[] = {
193 {
194 .name = "default",
195 .type = AVMEDIA_TYPE_AUDIO,
196 .filter_frame = filter_frame,
197 },
198};
199
200static const AVFilterPad bs2b_outputs[] = {
201 {
202 .name = "default",
203 .type = AVMEDIA_TYPE_AUDIO,
204 .config_props = config_output,
205 },
206};
207
209 .p.name = "bs2b",
210 .p.description = NULL_IF_CONFIG_SMALL("Bauer stereo-to-binaural filter."),
211 .p.priv_class = &bs2b_class,
212 .priv_size = sizeof(Bs2bContext),
213 .init = init,
214 .uninit = uninit,
218};
static enum AVSampleFormat sample_fmts[]
Definition adpcmenc.c:933
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition aeval.c:246
static void feed(AVFilterContext *ctx, int ch, const float *in_samples, float *out_samples, float *in_frame, float *out_dist_frame, float *windowed_frame, float *drc_frame, float *spectrum_buf, float *energy, float *target_gain, float *envelope, float *factors)
Definition af_adrc.c:275
static const AVFilterPad bs2b_inputs[]
Definition af_bs2b.c:192
void(* filter_func)(t_bs2bdp bs2bdp, uint8_t *sample, int n)
Definition af_bs2b.c:35
const FFFilter ff_af_bs2b
Definition af_bs2b.c:208
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition af_bs2b.c:123
static const AVFilterPad bs2b_outputs[]
Definition af_bs2b.c:200
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition af_bs2b.c:93
static av_cold void uninit(AVFilterContext *ctx)
Definition af_bs2b.c:85
#define OFFSET(x)
Definition af_bs2b.c:49
static int config_output(AVFilterLink *outlink)
Definition af_bs2b.c:156
static const AVOption bs2b_options[]
Definition af_bs2b.c:52
static AVFormatContext * ctx
#define A(x)
Definition vpx_arith.h:28
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition audio.c:74
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
Public libavutil channel layout APIs header.
common internal and external API header
#define NULL
Definition coverity.c:32
static AVFrame * frame
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define sample
int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const AVChannelLayout *fmts)
Definition formats.c:1026
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition formats.c:1154
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AV_CHANNEL_LAYOUT_STEREO
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR(e)
Definition error.h:45
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition frame.c:535
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition frame.c:711
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition samplefmt.h:59
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition samplefmt.h:57
@ AV_SAMPLE_FMT_DBL
double
Definition samplefmt.h:61
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
enum MovChannelLayoutTag * layouts
Definition mov_chan.c:335
int profile
Definition mxfenc.c:2299
AVOptions.
An AVChannelLayout holds information about the channel layout of audio data.
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
Lists of formats / etc.
Definition avfilter.h:120
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int nb_samples
number of audio samples (per channel) described by this frame
Definition frame.h:552
uint8_t ** extended_data
pointers to the data planes/channels.
Definition frame.h:533
AVOption.
Definition opt.h:428
int profile
Definition af_bs2b.c:40
filter_func filter
Definition af_bs2b.c:46
t_bs2bdp bs2bp
Definition af_bs2b.c:44