mirror of
https://github.com/mpv-player/mpv
synced 2024-12-18 21:06:00 +00:00
audio/filters: add af_force
Its main purpose is for testing in case channel layout stuff breaks, in particular in connection with old audio filters.
This commit is contained in:
parent
ce2515ddb8
commit
d9582ad0a4
@ -210,6 +210,34 @@ channels=nch[:nr:from1:to1:from2:to2:from3:to3:...]
|
||||
Would change the number of channels to 6 and set up 4 routes that copy
|
||||
channel 0 to channels 0 to 3. Channel 4 and 5 will contain silence.
|
||||
|
||||
force=in-format:in-srate:in-channels:out-format:out-srate:out-channels
|
||||
Force a specific audio format/configuration without actually changing the
|
||||
audio data. Keep in mind that the filter system might auto-insert actual
|
||||
conversion filters before or after this filter if needed.
|
||||
|
||||
All parameters are optional. The ``in-`` variants restrict what the filter
|
||||
accepts as input. The ``out-`` variants change the audio format, without
|
||||
actually doing a conversion. The data will be 'reinterpreted' by the
|
||||
filters or audio outputs following this filter.
|
||||
|
||||
<in-format>
|
||||
Force conversion to this format. See ``format`` filter for valid audio
|
||||
format values.
|
||||
|
||||
<in-srate>
|
||||
Force conversion to a specific sample rate. The rate is an integer,
|
||||
48000 for example.
|
||||
|
||||
<in-channels>
|
||||
Force mixing to a specific channel layout. See ``--channels`` option
|
||||
for possible values.
|
||||
|
||||
<out-format>
|
||||
|
||||
<out-srate>
|
||||
|
||||
<out-channels>
|
||||
|
||||
format[=format]
|
||||
Convert between different sample formats. Automatically enabled when
|
||||
needed by the sound card or another filter. See also ``--format``.
|
||||
@ -293,6 +321,11 @@ pan=n[:L00:L01:L02:...L10:L11:L12:...Ln0:Ln1:Ln2:...]
|
||||
channels 0 and 1 into output channel 2 (which could be sent to a
|
||||
subwoofer for example).
|
||||
|
||||
*NOTE*: if you just want to force remixing to a certain output channel
|
||||
layout, it's easier to use the ``force`` filter. For example,
|
||||
``mpv '--af=force=channels=5.1' '--channels=5.1'`` would always force
|
||||
remixing audio to 5.1 and output it like this.
|
||||
|
||||
sub[=fc:ch]
|
||||
Adds a subwoofer channel to the audio stream. The audio data used for
|
||||
creating the subwoofer channel is an average of the sound in channel 0 and
|
||||
|
1
Makefile
1
Makefile
@ -139,6 +139,7 @@ SOURCES = talloc.c \
|
||||
audio/filter/af_dummy.c \
|
||||
audio/filter/af_equalizer.c \
|
||||
audio/filter/af_extrastereo.c \
|
||||
audio/filter/af_force.c \
|
||||
audio/filter/af_format.c \
|
||||
audio/filter/af_hrtf.c \
|
||||
audio/filter/af_karaoke.c \
|
||||
|
@ -56,6 +56,12 @@ void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src)
|
||||
dst->rate = src->rate;
|
||||
}
|
||||
|
||||
bool mp_audio_config_equals(const struct mp_audio *a, const struct mp_audio *b)
|
||||
{
|
||||
return a->format == b->format && a->rate == b->rate &&
|
||||
mp_chmap_equals(&a->channels, &b->channels);
|
||||
}
|
||||
|
||||
char *mp_audio_fmt_to_str(int srate, const struct mp_chmap *chmap, int format)
|
||||
{
|
||||
char *chstr = mp_chmap_to_str(chmap);
|
||||
|
@ -38,6 +38,7 @@ void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels);
|
||||
void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels);
|
||||
void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap);
|
||||
void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src);
|
||||
bool mp_audio_config_equals(const struct mp_audio *a, const struct mp_audio *b);
|
||||
|
||||
char *mp_audio_fmt_to_str(int srate, const struct mp_chmap *chmap, int format);
|
||||
char *mp_audio_config_to_str(struct mp_audio *mpa);
|
||||
|
@ -29,6 +29,7 @@ extern struct af_info af_info_dummy;
|
||||
extern struct af_info af_info_delay;
|
||||
extern struct af_info af_info_channels;
|
||||
extern struct af_info af_info_format;
|
||||
extern struct af_info af_info_force;
|
||||
extern struct af_info af_info_volume;
|
||||
extern struct af_info af_info_equalizer;
|
||||
extern struct af_info af_info_pan;
|
||||
@ -52,6 +53,7 @@ static struct af_info* filter_list[] = {
|
||||
&af_info_dummy,
|
||||
&af_info_delay,
|
||||
&af_info_channels,
|
||||
&af_info_force,
|
||||
&af_info_volume,
|
||||
&af_info_equalizer,
|
||||
&af_info_pan,
|
||||
|
146
audio/filter/af_force.c
Normal file
146
audio/filter/af_force.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavutil/common.h>
|
||||
|
||||
#include "core/m_config.h"
|
||||
#include "core/m_option.h"
|
||||
|
||||
#include "audio/format.h"
|
||||
#include "af.h"
|
||||
|
||||
struct priv {
|
||||
struct m_config *config;
|
||||
|
||||
int in_format;
|
||||
int in_srate;
|
||||
struct mp_chmap in_channels;
|
||||
int out_format;
|
||||
int out_srate;
|
||||
struct mp_chmap out_channels;
|
||||
|
||||
struct mp_audio data;
|
||||
struct mp_audio temp;
|
||||
};
|
||||
|
||||
static const struct priv defaults = {
|
||||
.in_format = AF_FORMAT_UNKNOWN,
|
||||
.out_format = AF_FORMAT_UNKNOWN,
|
||||
};
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
static const struct m_option options[] = {
|
||||
OPT_AUDIOFORMAT("format", in_format, 0),
|
||||
OPT_INTRANGE("srate", in_srate, 0, 1000, 8*48000),
|
||||
OPT_CHMAP("channels", in_channels, CONF_MIN, .min = 0),
|
||||
OPT_AUDIOFORMAT("out-format", out_format, 0),
|
||||
OPT_INTRANGE("out-srate", out_srate, 0, 1000, 8*48000),
|
||||
OPT_CHMAP("out-channels", out_channels, CONF_MIN, .min = 0),
|
||||
{0}
|
||||
};
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *priv = af->setup;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio orig_in = *in;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
if (priv->in_format != AF_FORMAT_UNKNOWN)
|
||||
mp_audio_set_format(in, priv->in_format);
|
||||
|
||||
if (priv->in_channels.num)
|
||||
mp_audio_set_channels(in, &priv->in_channels);
|
||||
|
||||
if (priv->in_srate)
|
||||
in->rate = priv->in_srate;
|
||||
|
||||
mp_audio_copy_config(out, in);
|
||||
|
||||
if (priv->out_format != AF_FORMAT_UNKNOWN)
|
||||
mp_audio_set_format(out, priv->out_format);
|
||||
|
||||
if (priv->out_channels.num)
|
||||
mp_audio_set_channels(out, &priv->out_channels);
|
||||
|
||||
if (priv->out_srate)
|
||||
out->rate = priv->out_srate;
|
||||
|
||||
if (in->nch != out->nch || in->bps != out->bps) {
|
||||
mp_msg(MSGT_AFILTER, MSGL_ERR,
|
||||
"[af_force] Forced input/output format are incompatible.\n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_COMMAND_LINE: {
|
||||
if (m_config_parse_suboptions(priv->config, "af_force", (char *)arg) < 0)
|
||||
return AF_ERROR;
|
||||
return AF_OK;
|
||||
}
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct priv *priv = af->setup;
|
||||
struct mp_audio *r = &priv->temp;
|
||||
|
||||
*r = *af->data;
|
||||
r->audio = data->audio;
|
||||
r->len = data->len;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void uninit(struct af_instance *af)
|
||||
{
|
||||
talloc_free(af->setup);
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
struct priv *priv = talloc(NULL, struct priv);
|
||||
af->setup = priv;
|
||||
*priv = defaults;
|
||||
priv->config = m_config_simple(priv);
|
||||
talloc_steal(priv, priv->config);
|
||||
m_config_register_options(priv->config, options);
|
||||
af->data = &priv->data;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
struct af_info af_info_force = {
|
||||
"Force audio format",
|
||||
"force",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
af_open
|
||||
};
|
Loading…
Reference in New Issue
Block a user