2 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/mathematics.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "avresample.h"
28 #include "audio_mix.h"
32 * Options definition for AVAudioResampleContext.
35 #define OFFSET(x) offsetof(AVAudioResampleContext, x)
36 #define PARAM AV_OPT_FLAG_AUDIO_PARAM
38 static const AVOption avresample_options
[] = {
39 { "in_channel_layout", "Input Channel Layout", OFFSET(in_channel_layout
), AV_OPT_TYPE_INT64
, { .i64
= 0 }, INT64_MIN
, INT64_MAX
, PARAM
},
40 { "in_sample_fmt", "Input Sample Format", OFFSET(in_sample_fmt
), AV_OPT_TYPE_INT
, { .i64
= AV_SAMPLE_FMT_S16
}, AV_SAMPLE_FMT_U8
, AV_SAMPLE_FMT_NB
-1, PARAM
},
41 { "in_sample_rate", "Input Sample Rate", OFFSET(in_sample_rate
), AV_OPT_TYPE_INT
, { .i64
= 48000 }, 1, INT_MAX
, PARAM
},
42 { "out_channel_layout", "Output Channel Layout", OFFSET(out_channel_layout
), AV_OPT_TYPE_INT64
, { .i64
= 0 }, INT64_MIN
, INT64_MAX
, PARAM
},
43 { "out_sample_fmt", "Output Sample Format", OFFSET(out_sample_fmt
), AV_OPT_TYPE_INT
, { .i64
= AV_SAMPLE_FMT_S16
}, AV_SAMPLE_FMT_U8
, AV_SAMPLE_FMT_NB
-1, PARAM
},
44 { "out_sample_rate", "Output Sample Rate", OFFSET(out_sample_rate
), AV_OPT_TYPE_INT
, { .i64
= 48000 }, 1, INT_MAX
, PARAM
},
45 { "internal_sample_fmt", "Internal Sample Format", OFFSET(internal_sample_fmt
), AV_OPT_TYPE_INT
, { .i64
= AV_SAMPLE_FMT_NONE
}, AV_SAMPLE_FMT_NONE
, AV_SAMPLE_FMT_NB
-1, PARAM
, "internal_sample_fmt" },
46 {"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_U8
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
47 {"s16", "16-bit signed integer", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_S16
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
48 {"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_S32
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
49 {"flt", "32-bit float", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_FLT
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
50 {"dbl", "64-bit double", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_DBL
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
51 {"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_U8P
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
52 {"s16p", "16-bit signed integer planar", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_S16P
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
53 {"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_S32P
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
54 {"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_FLTP
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
55 {"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST
, {.i64
= AV_SAMPLE_FMT_DBLP
}, INT_MIN
, INT_MAX
, PARAM
, "internal_sample_fmt"},
56 { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type
), AV_OPT_TYPE_INT
, { .i64
= AV_MIX_COEFF_TYPE_FLT
}, AV_MIX_COEFF_TYPE_Q8
, AV_MIX_COEFF_TYPE_NB
-1, PARAM
, "mix_coeff_type" },
57 { "q8", "16-bit 8.8 Fixed-Point", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MIX_COEFF_TYPE_Q8
}, INT_MIN
, INT_MAX
, PARAM
, "mix_coeff_type" },
58 { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MIX_COEFF_TYPE_Q15
}, INT_MIN
, INT_MAX
, PARAM
, "mix_coeff_type" },
59 { "flt", "Floating-Point", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MIX_COEFF_TYPE_FLT
}, INT_MIN
, INT_MAX
, PARAM
, "mix_coeff_type" },
60 { "center_mix_level", "Center Mix Level", OFFSET(center_mix_level
), AV_OPT_TYPE_DOUBLE
, { .dbl
= M_SQRT1_2
}, -32.0, 32.0, PARAM
},
61 { "surround_mix_level", "Surround Mix Level", OFFSET(surround_mix_level
), AV_OPT_TYPE_DOUBLE
, { .dbl
= M_SQRT1_2
}, -32.0, 32.0, PARAM
},
62 { "lfe_mix_level", "LFE Mix Level", OFFSET(lfe_mix_level
), AV_OPT_TYPE_DOUBLE
, { .dbl
= 0.0 }, -32.0, 32.0, PARAM
},
63 { "normalize_mix_level", "Normalize Mix Level", OFFSET(normalize_mix_level
), AV_OPT_TYPE_INT
, { .i64
= 1 }, 0, 1, PARAM
},
64 { "force_resampling", "Force Resampling", OFFSET(force_resampling
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, PARAM
},
65 { "filter_size", "Resampling Filter Size", OFFSET(filter_size
), AV_OPT_TYPE_INT
, { .i64
= 16 }, 0, 32, /* ??? */ PARAM
},
66 { "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift
), AV_OPT_TYPE_INT
, { .i64
= 10 }, 0, 30, /* ??? */ PARAM
},
67 { "linear_interp", "Use Linear Interpolation", OFFSET(linear_interp
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, PARAM
},
68 { "cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff
), AV_OPT_TYPE_DOUBLE
, { .dbl
= 0.8 }, 0.0, 1.0, PARAM
},
69 /* duplicate option in order to work with avconv */
70 { "resample_cutoff", "Cutoff Frequency Ratio", OFFSET(cutoff
), AV_OPT_TYPE_DOUBLE
, { .dbl
= 0.8 }, 0.0, 1.0, PARAM
},
71 { "matrix_encoding", "Matrixed Stereo Encoding", OFFSET(matrix_encoding
), AV_OPT_TYPE_INT
, {.i64
= AV_MATRIX_ENCODING_NONE
}, AV_MATRIX_ENCODING_NONE
, AV_MATRIX_ENCODING_NB
-1, PARAM
, "matrix_encoding" },
72 { "none", "None", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MATRIX_ENCODING_NONE
}, INT_MIN
, INT_MAX
, PARAM
, "matrix_encoding" },
73 { "dolby", "Dolby", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MATRIX_ENCODING_DOLBY
}, INT_MIN
, INT_MAX
, PARAM
, "matrix_encoding" },
74 { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_MATRIX_ENCODING_DPLII
}, INT_MIN
, INT_MAX
, PARAM
, "matrix_encoding" },
75 { "filter_type", "Filter Type", OFFSET(filter_type
), AV_OPT_TYPE_INT
, { .i64
= AV_RESAMPLE_FILTER_TYPE_KAISER
}, AV_RESAMPLE_FILTER_TYPE_CUBIC
, AV_RESAMPLE_FILTER_TYPE_KAISER
, PARAM
, "filter_type" },
76 { "cubic", "Cubic", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_FILTER_TYPE_CUBIC
}, INT_MIN
, INT_MAX
, PARAM
, "filter_type" },
77 { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL
}, INT_MIN
, INT_MAX
, PARAM
, "filter_type" },
78 { "kaiser", "Kaiser Windowed Sinc", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_FILTER_TYPE_KAISER
}, INT_MIN
, INT_MAX
, PARAM
, "filter_type" },
79 { "kaiser_beta", "Kaiser Window Beta", OFFSET(kaiser_beta
), AV_OPT_TYPE_INT
, { .i64
= 9 }, 2, 16, PARAM
},
80 { "dither_method", "Dither Method", OFFSET(dither_method
), AV_OPT_TYPE_INT
, { .i64
= AV_RESAMPLE_DITHER_NONE
}, 0, AV_RESAMPLE_DITHER_NB
-1, PARAM
, "dither_method"},
81 {"none", "No Dithering", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_DITHER_NONE
}, INT_MIN
, INT_MAX
, PARAM
, "dither_method"},
82 {"rectangular", "Rectangular Dither", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_DITHER_RECTANGULAR
}, INT_MIN
, INT_MAX
, PARAM
, "dither_method"},
83 {"triangular", "Triangular Dither", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_DITHER_TRIANGULAR
}, INT_MIN
, INT_MAX
, PARAM
, "dither_method"},
84 {"triangular_hp", "Triangular Dither With High Pass", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_DITHER_TRIANGULAR_HP
}, INT_MIN
, INT_MAX
, PARAM
, "dither_method"},
85 {"triangular_ns", "Triangular Dither With Noise Shaping", 0, AV_OPT_TYPE_CONST
, { .i64
= AV_RESAMPLE_DITHER_TRIANGULAR_NS
}, INT_MIN
, INT_MAX
, PARAM
, "dither_method"},
89 static const AVClass av_resample_context_class
= {
90 .class_name
= "AVAudioResampleContext",
91 .item_name
= av_default_item_name
,
92 .option
= avresample_options
,
93 .version
= LIBAVUTIL_VERSION_INT
,
96 AVAudioResampleContext
*avresample_alloc_context(void)
98 AVAudioResampleContext
*avr
;
100 avr
= av_mallocz(sizeof(*avr
));
104 avr
->av_class
= &av_resample_context_class
;
105 av_opt_set_defaults(avr
);
110 const AVClass
*avresample_get_class(void)
112 return &av_resample_context_class
;