diff options
-rw-r--r-- | DOCS/interface-changes.rst | 1 | ||||
-rw-r--r-- | DOCS/man/af.rst | 23 | ||||
-rw-r--r-- | DOCS/mplayer-changes.rst | 2 | ||||
-rw-r--r-- | TOOLS/lua/drc-control.lua | 99 | ||||
-rw-r--r-- | audio/filter/af.c | 2 | ||||
-rw-r--r-- | audio/filter/af_drc.c | 334 | ||||
-rw-r--r-- | wscript_build.py | 1 |
7 files changed, 2 insertions, 460 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index c82b0a62d0..911f6f8717 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -25,6 +25,7 @@ Interface changes - remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and --vo-image-format options - the "jpeg" choice in the option above now leads to a ".jpg" file extension + - --af=drc is gone (you can use e.g. lavfi/acompressor instead) --- mpv 0.24.0 --- - deprecate --hwdec-api and replace it with --opengl-hwdec-interop. The new option accepts both --hwdec values, as well as named backends. diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst index 4c91b5a9b5..040b44cd64 100644 --- a/DOCS/man/af.rst +++ b/DOCS/man/af.rst @@ -319,29 +319,6 @@ Available filters are: the mixing matrix at runtime, without reinitializing the entire filter chain. -``drc[=method:target]`` - Applies dynamic range compression. This maximizes the volume by compressing - the audio signal's dynamic range. (Formerly called ``volnorm``.) - - ``<method>`` - Sets the used method. - - 1 - Use a single sample to smooth the variations via the standard - weighted mean over past samples (default). - 2 - Use several samples to smooth the variations via the standard - weighted mean over past samples. - - ``<target>`` - Sets the target amplitude as a fraction of the maximum for the sample - type (default: 0.25). - - .. note:: - - This filter can cause distortion with audio signals that have a very - large dynamic range. - ``scaletempo[=option1:option2:...]`` Scales audio tempo without altering pitch, optionally synced to playback speed (default). diff --git a/DOCS/mplayer-changes.rst b/DOCS/mplayer-changes.rst index df33f66e3f..7c8ec50a90 100644 --- a/DOCS/mplayer-changes.rst +++ b/DOCS/mplayer-changes.rst @@ -212,7 +212,7 @@ Command Line Switches ``-no<opt>`` ``--no-<opt>`` (add a dash) ``-a52drc level`` ``--ad-lavc-ac3drc=level`` ``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``) - ``-af volnorm`` ``--af=drc`` (renamed) + ``-af volnorm`` (removed; use acompressor ffmpeg filter instead) ``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts`` ``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]`` ``-aspect`` ``--video-aspect`` diff --git a/TOOLS/lua/drc-control.lua b/TOOLS/lua/drc-control.lua deleted file mode 100644 index 83cdb9c935..0000000000 --- a/TOOLS/lua/drc-control.lua +++ /dev/null @@ -1,99 +0,0 @@ --- This script enables live control of the dynamic range compression --- (drc) audio filter while the video is playing back. This can be --- useful to avoid having to stop and restart mpv to adjust filter --- parameters. See the entry for "drc" under the "AUDIO FILTERS" --- section of the man page for a complete description of the filter. --- --- This script registers the key-binding "\" to toggle the filter between --- --- * off --- * method=1 (single-sample smoothing) --- * method=2 (multi-sample smoothing) --- --- It registers the keybindings ctrl+9/ctrl+0 to decrease/increase the --- target ampltiude. These keys will insert the filter at the default --- target amplitude of 0.25 if it was not previously present. --- --- OSD feedback of the current filter state is displayed on pressing --- each bound key. - -script_name = mp.get_script_name() - -function print_state(params) - if params then - mp.osd_message(script_name..":\n" - .."method = "..params["method"].."\n" - .."target = "..params["target"]) - else - mp.osd_message(script_name..":\noff") - end -end - -function get_index_of_drc(afs) - for i,af in pairs(afs) do - if af["label"] == script_name then - return i - end - end -end - -function append_drc(afs) - afs[#afs+1] = { - name = "drc", - label = script_name, - params = { - method = "1", - target = "0.25" - } - } - print_state(afs[#afs]["params"]) -end - -function modify_or_create_af(fun) - afs = mp.get_property_native("af") - i = get_index_of_drc(afs) - if not i then - append_drc(afs) - else - fun(afs, i) - end - mp.set_property_native("af", afs) -end - -function drc_toggle_method_handler() - modify_or_create_af( - function (afs, i) - new_method=(afs[i]["params"]["method"]+1)%3 - if new_method == 0 then - table.remove(afs, i) - print_state(nil) - else - afs[i]["params"]["method"] = tostring((afs[i]["params"]["method"])%2+1) - print_state(afs[i]["params"]) - end - end - ) -end - -function drc_scale_target(factor) - modify_or_create_af( - function (afs) - afs[i]["params"]["target"] = tostring(afs[i]["params"]["target"]*factor) - print_state(afs[i]["params"]) - end - ) -end - -function drc_louder_handler() - drc_scale_target(2.0) -end - -function drc_quieter_handler() - drc_scale_target(0.5) -end - --- toggle between off, method 1 and method 2 -mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler) --- increase or decrease target volume -mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler) -mp.add_key_binding("ctrl+0", "drc_louder", drc_louder_handler) diff --git a/audio/filter/af.c b/audio/filter/af.c index e6f19b3e37..31f4e45614 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -36,7 +36,6 @@ extern const struct af_info af_info_format; extern const struct af_info af_info_volume; extern const struct af_info af_info_equalizer; extern const struct af_info af_info_pan; -extern const struct af_info af_info_drc; extern const struct af_info af_info_lavcac3enc; extern const struct af_info af_info_lavrresample; extern const struct af_info af_info_scaletempo; @@ -50,7 +49,6 @@ static const struct af_info *const filter_list[] = { &af_info_volume, &af_info_equalizer, &af_info_pan, - &af_info_drc, &af_info_lavcac3enc, &af_info_lavrresample, #if HAVE_RUBBERBAND diff --git a/audio/filter/af_drc.c b/audio/filter/af_drc.c deleted file mode 100644 index 7b375febf4..0000000000 --- a/audio/filter/af_drc.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard - * - * 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <inttypes.h> -#include <math.h> -#include <limits.h> - -#include "common/common.h" -#include "af.h" - -// Methods: -// 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1) -// 2: uses several samples to smooth the variations (standard weighted mean -// on past samples) - -// Size of the memory array -// FIXME: should depend on the frequency of the data (should be a few seconds) -#define NSAMPLES 128 - -// If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we -// choose to ignore the computed value as it's not significant enough -// FIXME: should depend on the frequency of the data (0.5s maybe) -#define MIN_SAMPLE_SIZE 32000 - -// mul is the value by which the samples are scaled -// and has to be in [MUL_MIN, MUL_MAX] -#define MUL_INIT 1.0 -#define MUL_MIN 0.1 -#define MUL_MAX 5.0 - -// Silence level -// FIXME: should be relative to the level of the samples -#define SIL_S16 (SHRT_MAX * 0.01) -#define SIL_FLOAT 0.01 - -// smooth must be in ]0.0, 1.0[ -#define SMOOTH_MUL 0.06 -#define SMOOTH_LASTAVG 0.06 - -#define DEFAULT_TARGET 0.25 - -// Data for specific instances of this filter -typedef struct af_volume_s -{ - int method; // method used - float mul; - // method 1 - float lastavg; // history value of the filter - // method 2 - int idx; - struct { - float avg; // average level of the sample - int len; // sample size (weight) - } mem[NSAMPLES]; - // "Ideal" level - float mid_s16; - float mid_float; -}af_drc_t; - -// Initialization and runtime control -static int control(struct af_instance* af, int cmd, void* arg) -{ - switch(cmd){ - case AF_CONTROL_REINIT: - // Sanity check - if(!arg) return AF_ERROR; - - mp_audio_force_interleaved_format((struct mp_audio*)arg); - mp_audio_copy_config(af->data, (struct mp_audio*)arg); - - if(((struct mp_audio*)arg)->format != (AF_FORMAT_S16)){ - mp_audio_set_format(af->data, AF_FORMAT_FLOAT); - } - return af_test_output(af,(struct mp_audio*)arg); - } - return AF_UNKNOWN; -} - -static void method1_int16(af_drc_t *s, struct mp_audio *c) -{ - register int i = 0; - int16_t *data = (int16_t*)c->planes[0]; // Audio data - int len = c->samples*c->nch; // Number of samples - float curavg = 0.0, newavg, neededmul; - int tmp; - - for (i = 0; i < len; i++) - { - tmp = data[i]; - curavg += tmp * tmp; - } - curavg = sqrt(curavg / (float) len); - - // Evaluate an adequate 'mul' coefficient based on previous state, current - // samples level, etc - - if (curavg > SIL_S16) - { - neededmul = s->mid_s16 / (curavg * s->mul); - s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul; - - // clamp the mul coefficient - s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX); - } - - // Scale & clamp the samples - for (i = 0; i < len; i++) - { - tmp = s->mul * data[i]; - tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX); - data[i] = tmp; - } - - // Evaluation of newavg (not 100% accurate because of values clamping) - newavg = s->mul * curavg; - - // Stores computed values for future smoothing - s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg; -} - -static void method1_float(af_drc_t *s, struct mp_audio *c) -{ - register int i = 0; - float *data = (float*)c->planes[0]; // Audio data - int len = c->samples*c->nch; // Number of samples - float curavg = 0.0, newavg, neededmul, tmp; - - for (i = 0; i < len; i++) - { - tmp = data[i]; - curavg += tmp * tmp; - } - curavg = sqrt(curavg / (float) len); - - // Evaluate an adequate 'mul' coefficient based on previous state, current - // samples level, etc - - if (curavg > SIL_FLOAT) // FIXME - { - neededmul = s->mid_float / (curavg * s->mul); - s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul; - - // clamp the mul coefficient - s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX); - } - - // Scale & clamp the samples - for (i = 0; i < len; i++) - data[i] *= s->mul; - - // Evaluation of newavg (not 100% accurate because of values clamping) - newavg = s->mul * curavg; - - // Stores computed values for future smoothing - s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg; -} - -static void method2_int16(af_drc_t *s, struct mp_audio *c) -{ - register int i = 0; - int16_t *data = (int16_t*)c->planes[0]; // Audio data - int len = c->samples*c->nch; // Number of samples - float curavg = 0.0, newavg, avg = 0.0; - int tmp, totallen = 0; - - for (i = 0; i < len; i++) - { - tmp = data[i]; - curavg += tmp * tmp; - } - curavg = sqrt(curavg / (float) len); - - // Evaluate an adequate 'mul' coefficient based on previous state, current - // samples level, etc - for (i = 0; i < NSAMPLES; i++) - { - avg += s->mem[i].avg * (float)s->mem[i].len; - totallen += s->mem[i].len; - } - - if (totallen > MIN_SAMPLE_SIZE) - { - avg /= (float)totallen; - if (avg >= SIL_S16) - { - s->mul = s->mid_s16 / avg; - s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX); - } - } - - // Scale & clamp the samples - for (i = 0; i < len; i++) - { - tmp = s->mul * data[i]; - tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX); - data[i] = tmp; - } - - // Evaluation of newavg (not 100% accurate because of values clamping) - newavg = s->mul * curavg; - - // Stores computed values for future smoothing - s->mem[s->idx].len = len; - s->mem[s->idx].avg = newavg; - s->idx = (s->idx + 1) % NSAMPLES; -} - -static void method2_float(af_drc_t *s, struct mp_audio *c) -{ - register int i = 0; - float *data = (float*)c->planes[0]; // Audio data - int len = c->samples*c->nch; // Number of samples - float curavg = 0.0, newavg, avg = 0.0, tmp; - int totallen = 0; - - for (i = 0; i < len; i++) - { - tmp = data[i]; - curavg += tmp * tmp; - } - curavg = sqrt(curavg / (float) len); - - // Evaluate an adequate 'mul' coefficient based on previous state, current - // samples level, etc - for (i = 0; i < NSAMPLES; i++) - { - avg += s->mem[i].avg * (float)s->mem[i].len; - totallen += s->mem[i].len; - } - - if (totallen > MIN_SAMPLE_SIZE) - { - avg /= (float)totallen; - if (avg >= SIL_FLOAT) - { - s->mul = s->mid_float / avg; - s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX); - } - } - - // Scale & clamp the samples - for (i = 0; i < len; i++) - data[i] *= s->mul; - - // Evaluation of newavg (not 100% accurate because of values clamping) - newavg = s->mul * curavg; - - // Stores computed values for future smoothing - s->mem[s->idx].len = len; - s->mem[s->idx].avg = newavg; - s->idx = (s->idx + 1) % NSAMPLES; -} - -static int filter(struct af_instance *af, struct mp_audio *data) -{ - af_drc_t *s = af->priv; - - if (!data) - return 0; - - if (af_make_writeable(af, data) < 0) { - talloc_free(data); - return -1; - } - - if(af->data->format == (AF_FORMAT_S16)) - { - if (s->method == 2) - method2_int16(s, data); - else - method1_int16(s, data); - } - else if(af->data->format == (AF_FORMAT_FLOAT)) - { - if (s->method == 2) - method2_float(s, data); - else - method1_float(s, data); - } - af_add_output_frame(af, data); - return 0; -} - -// Allocate memory and set function pointers -static int af_open(struct af_instance* af){ - int i = 0; - af->control=control; - af->filter_frame = filter; - af_drc_t *priv = af->priv; - - priv->mul = MUL_INIT; - priv->lastavg = ((float)SHRT_MAX) * DEFAULT_TARGET; - priv->idx = 0; - for (i = 0; i < NSAMPLES; i++) - { - priv->mem[i].len = 0; - priv->mem[i].avg = 0; - } - priv->mid_s16 = ((float)SHRT_MAX) * priv->mid_float; - return AF_OK; -} - -#define OPT_BASE_STRUCT af_drc_t -const struct af_info af_info_drc = { - .info = "Dynamic range compression filter", - .name = "drc", - .open = af_open, - .priv_size = sizeof(af_drc_t), - .options = (const struct m_option[]) { - OPT_INTRANGE("method", method, 0, 1, 2, OPTDEF_INT(1)), - OPT_FLOAT("target", mid_float, 0, OPTDEF_FLOAT(DEFAULT_TARGET)), - {0} - }, -}; diff --git a/wscript_build.py b/wscript_build.py index 6014367115..4f1d3440c0 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -124,7 +124,6 @@ def build(ctx): ( "audio/decode/dec_audio.c" ), ( "audio/filter/af.c" ), ( "audio/filter/af_channels.c" ), - ( "audio/filter/af_drc.c" ), ( "audio/filter/af_equalizer.c" ), ( "audio/filter/af_format.c" ), ( "audio/filter/af_lavcac3enc.c" ), |