diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst index b56fc919a1..e0431713fa 100644 --- a/DOCS/man/af.rst +++ b/DOCS/man/af.rst @@ -91,81 +91,6 @@ Available filters are: Select the libavcodec encoder used. Currently, this should be an AC-3 encoder, and using another codec will fail horribly. -``equalizer=g1:g2:g3:...:g10`` - 10 octave band graphic equalizer, implemented using 10 IIR band-pass - filters. This means that it works regardless of what type of audio is - being played back. The center frequencies for the 10 bands are: - - === ========== - No. frequency - === ========== - 0 31.25 Hz - 1 62.50 Hz - 2 125.00 Hz - 3 250.00 Hz - 4 500.00 Hz - 5 1.00 kHz - 6 2.00 kHz - 7 4.00 kHz - 8 8.00 kHz - 9 16.00 kHz - === ========== - - If the sample rate of the sound being played is lower than the center - frequency for a frequency band, then that band will be disabled. A known - bug with this filter is that the characteristics for the uppermost band - are not completely symmetric if the sample rate is close to the center - frequency of that band. This problem can be worked around by upsampling - the sound using a resampling filter before it reaches this filter. - - ``:::...:`` - floating point numbers representing the gain in dB for each frequency - band (-12-12) - - .. admonition:: Example - - ``mpv --af=equalizer=11:11:10:5:0:-12:0:5:12:12 media.avi`` - Would amplify the sound in the upper and lower frequency region - while canceling it almost completely around 1 kHz. - -``channels=nch[:routes]`` - Can be used for adding, removing, routing and copying audio channels. If - only ```` is given, the default routing is used. It works as follows: - If the number of output channels is greater than the number of input - channels, empty channels are inserted (except when mixing from mono to - stereo; then the mono channel is duplicated). If the number of output - channels is less than the number of input channels, the exceeding - channels are truncated. - - ```` - number of output channels (1-8) - ```` - List of ``,`` separated routes, in the form ``from1-to1,from2-to2,...``. - Each pair defines where to route each channel. There can be at most - 8 routes. Without this argument, the default routing is used. Since - ``,`` is also used to separate filters, you must quote this argument - with ``[...]`` or similar. - - .. admonition:: Examples - - ``mpv --af=channels=4:[0-1,1-0,2-2,3-3] media.avi`` - Would change the number of channels to 4 and set up 4 routes that - swap channel 0 and channel 1 and leave channel 2 and 3 intact. - Observe that if media containing two channels were played back, - channels 2 and 3 would contain silence but 0 and 1 would still be - swapped. - - ``mpv --af=channels=6:[0-0,0-1,0-2,0-3] media.avi`` - 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. - - .. note:: - - You should probably not use this filter. If you want to change the - output channel layout, try the ``format`` filter, which can make mpv - automatically up- and downmix standard channel layouts. - ``format=format:srate:channels:out-format:out-srate:out-channels`` Does not do any format conversion itself. Rather, it may cause the filter system to insert necessary conversion filters before or after this @@ -205,107 +130,6 @@ Available filters are: used to do conversion itself, unlike this one which lets the filter system handle the conversion. -``volume[=[:...]]`` - Implements software volume control. Use this filter with caution since it - can reduce the signal to noise ratio of the sound. In most cases it is - best to use the *Master* volume control of your sound card or the volume - knob on your amplifier. - - *WARNING*: This filter is deprecated. Use the top-level options like - ``--volume`` and ``--replaygain...`` instead. - - *NOTE*: This filter is not reentrant and can therefore only be enabled - once for every audio stream. - - ```` - Sets the desired gain in dB for all channels in the stream from -200 dB - to +60 dB, where -200 dB mutes the sound completely and +60 dB equals a - gain of 1000 (default: 0). - ``replaygain-track`` - Adjust volume gain according to the track-gain replaygain value stored - in the file metadata. - ``replaygain-album`` - Like replaygain-track, but using the album-gain value instead. - ``replaygain-preamp`` - Pre-amplification gain in dB to apply to the selected replaygain gain - (default: 0). - ``replaygain-clip=yes|no`` - Prevent clipping caused by replaygain by automatically lowering the - gain (default). Use ``replaygain-clip=no`` to disable this. - ``replaygain-fallback`` - Gain in dB to apply if the file has no replay gain tags. This option - is always applied if the replaygain logic is somehow inactive. If this - is applied, no other replaygain options are applied. - ``softclip`` - Turns soft clipping on. Soft-clipping can make the - sound more smooth if very high volume levels are used. Enable this - option if the dynamic range of the loudspeakers is very low. - - *WARNING*: This feature creates distortion and should be considered a - last resort. - ``s16`` - Force S16 sample format if set. Lower quality, but might be faster - in some situations. - ``detach`` - Remove the filter if the volume is not changed at audio filter config - time. Useful with replaygain: if the current file has no replaygain - tags, then the filter will be removed if this option is enabled. - (If ``--softvol=yes`` is used and the player volume controls are used - during playback, a different volume filter will be inserted.) - - .. admonition:: Example - - ``mpv --af=volume=10.1 media.avi`` - Would amplify the sound by 10.1 dB and hard-clip if the sound level - is too high. - -``pan=n:[]`` - Mixes channels arbitrarily. Basically a combination of the volume and the - channels filter that can be used to down-mix many channels to only a few, - e.g. stereo to mono, or vary the "width" of the center speaker in a - surround sound system. This filter is hard to use, and will require some - tinkering before the desired result is obtained. The number of options for - this filter depends on the number of output channels. An example how to - downmix a six-channel file to two channels with this filter can be found - in the examples section near the end. - - ```` - Number of output channels (1-8). - ```` - A list of values ``[L00,L01,L02,...,L10,L11,L12,...,Ln0,Ln1,Ln2,...]``, - where each element ``Lij`` means how much of input channel i is mixed - into output channel j (range 0-1). So in principle you first have n - numbers saying what to do with the first input channel, then n numbers - that act on the second input channel etc. If you do not specify any - numbers for some input channels, 0 is assumed. - Note that the values are separated by ``,``, which is already used - by the option parser to separate filters. This is why you must quote - the value list with ``[...]`` or similar. - - .. admonition:: Examples - - ``mpv --af=pan=1:[0.5,0.5] media.avi`` - Would downmix from stereo to mono. - - ``mpv --af=pan=3:[1,0,0.5,0,1,0.5] media.avi`` - Would give 3 channel output leaving channels 0 and 1 intact, and mix - 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 is easier to use the ``format`` filter. For example, - ``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force - remixing audio to 5.1 and output it like this. - - This filter supports the following ``af-command`` commands: - - ``set-matrix`` - Set the ```` argument dynamically. This can be used to change - the mixing matrix at runtime, without reinitializing the entire filter - chain. - ``scaletempo[=option1:option2:...]`` Scales audio tempo without altering pitch, optionally synced to playback speed (default). diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 2954bc3d1f..f3564cffb6 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1289,14 +1289,6 @@ Audio is always applied if the replaygain logic is somehow inactive. If this is applied, no other replaygain options are applied. -``--balance=`` - How much left/right channels contribute to the audio. (The implementation - of this feature is rather odd. It doesn't change the volumes of each - channel, but instead sets up a pan matrix to mix the left and right - channels.) - - Deprecated. - ``--audio-delay=`` Audio delay in seconds (positive or negative float value). Positive values delay the audio, and negative values delay the video. diff --git a/audio/filter/af.c b/audio/filter/af.c index a76945feea..dd78bb0cb5 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -31,25 +31,16 @@ #include "af.h" // Static list of filters -extern const struct af_info af_info_channels; 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_lavcac3enc; extern const struct af_info af_info_lavrresample; extern const struct af_info af_info_scaletempo; -extern const struct af_info af_info_bs2b; extern const struct af_info af_info_lavfi; extern const struct af_info af_info_lavfi_bridge; extern const struct af_info af_info_rubberband; static const struct af_info *const filter_list[] = { - &af_info_channels, &af_info_format, - &af_info_volume, - &af_info_equalizer, - &af_info_pan, &af_info_lavcac3enc, &af_info_lavrresample, #if HAVE_RUBBERBAND diff --git a/audio/filter/af.h b/audio/filter/af.h index f66b189f14..58f67727a2 100644 --- a/audio/filter/af.h +++ b/audio/filter/af.h @@ -120,11 +120,6 @@ struct af_stream { enum af_control { AF_CONTROL_REINIT = 1, AF_CONTROL_RESET, - AF_CONTROL_SET_VOLUME, - AF_CONTROL_SET_PAN_LEVEL, - AF_CONTROL_SET_PAN_NOUT, - AF_CONTROL_SET_PAN_BALANCE, - AF_CONTROL_GET_PAN_BALANCE, AF_CONTROL_SET_PLAYBACK_SPEED, AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE, AF_CONTROL_GET_METADATA, diff --git a/audio/filter/af_channels.c b/audio/filter/af_channels.c deleted file mode 100644 index 7cd7810d08..0000000000 --- a/audio/filter/af_channels.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Audio filter that adds and removes channels, according to the - * command line parameter channels. It is stupid and can only add - * silence or copy channels, not mix or filter. - * - * Original author: Anders - * - * 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 . - */ - -#include -#include -#include -#include - -#include "common/common.h" -#include "af.h" - -#define FR 0 -#define TO 1 - -typedef struct af_channels_s{ - int route[AF_NCH][2]; - int nch, nr; - int router; - char *routes; -}af_channels_t; - -// Local function for copying data -static void copy(struct af_instance *af, void* in, void* out, - int ins, int inos,int outs, int outos, int len, int bps) -{ - switch(bps){ - case 1:{ - int8_t* tin = (int8_t*)in; - int8_t* tout = (int8_t*)out; - tin += inos; - tout += outos; - len = len/ins; - while(len--){ - *tout=*tin; - tin +=ins; - tout+=outs; - } - break; - } - case 2:{ - int16_t* tin = (int16_t*)in; - int16_t* tout = (int16_t*)out; - tin += inos; - tout += outos; - len = len/(2*ins); - while(len--){ - *tout=*tin; - tin +=ins; - tout+=outs; - } - break; - } - case 3:{ - int8_t* tin = (int8_t*)in; - int8_t* tout = (int8_t*)out; - tin += 3 * inos; - tout += 3 * outos; - len = len / ( 3 * ins); - while (len--) { - tout[0] = tin[0]; - tout[1] = tin[1]; - tout[2] = tin[2]; - tin += 3 * ins; - tout += 3 * outs; - } - break; - } - case 4:{ - int32_t* tin = (int32_t*)in; - int32_t* tout = (int32_t*)out; - tin += inos; - tout += outos; - len = len/(4*ins); - while(len--){ - *tout=*tin; - tin +=ins; - tout+=outs; - } - break; - } - case 8:{ - int64_t* tin = (int64_t*)in; - int64_t* tout = (int64_t*)out; - tin += inos; - tout += outos; - len = len/(8*ins); - while(len--){ - *tout=*tin; - tin +=ins; - tout+=outs; - } - break; - } - default: - MP_ERR(af, "Unsupported number of bytes/sample: %i" - " please report this error on the MPlayer mailing list. \n",bps); - } -} - -// Make sure the routes are sane -static int check_routes(struct af_instance *af, int nin, int nout) -{ - af_channels_t* s = af->priv; - int i; - if((s->nr < 1) || (s->nr > AF_NCH)){ - MP_ERR(af, "The number of routing pairs must be" - " between 1 and %i. Current value is %i\n",AF_NCH,s->nr); - return AF_ERROR; - } - - for(i=0;inr;i++){ - if((s->route[i][FR] >= nin) || (s->route[i][TO] >= nout)){ - MP_ERR(af, "Invalid routing in pair nr. %i.\n", i); - return AF_ERROR; - } - } - return AF_OK; -} - -// Initialization and runtime control -static int control(struct af_instance* af, int cmd, void* arg) -{ - af_channels_t* s = af->priv; - switch(cmd){ - case AF_CONTROL_REINIT: ; - - struct mp_chmap chmap; - mp_chmap_set_unknown(&chmap, s->nch); - mp_audio_set_channels(af->data, &chmap); - - // Set default channel assignment - if(!s->router){ - int i; - // Make sure this filter isn't redundant - if(af->data->nch == ((struct mp_audio*)arg)->nch) - return AF_DETACH; - - // If mono: fake stereo - if(((struct mp_audio*)arg)->nch == 1){ - s->nr = MPMIN(af->data->nch,2); - for(i=0;inr;i++){ - s->route[i][FR] = 0; - s->route[i][TO] = i; - } - } - else{ - s->nr = MPMIN(af->data->nch, ((struct mp_audio*)arg)->nch); - for(i=0;inr;i++){ - s->route[i][FR] = i; - s->route[i][TO] = i; - } - } - } - - af->data->rate = ((struct mp_audio*)arg)->rate; - mp_audio_force_interleaved_format((struct mp_audio*)arg); - mp_audio_set_format(af->data, ((struct mp_audio*)arg)->format); - return check_routes(af,((struct mp_audio*)arg)->nch,af->data->nch); - } - return AF_UNKNOWN; -} - -static int filter_frame(struct af_instance *af, struct mp_audio *c) -{ - af_channels_t* s = af->priv; - int i; - - if (!c) - return 0; - - struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples); - if (!l) { - talloc_free(c); - return -1; - } - mp_audio_copy_attributes(l, c); - - // Reset unused channels - memset(l->planes[0],0,mp_audio_psize(c) / c->nch * l->nch); - - if(AF_OK == check_routes(af,c->nch,l->nch)) - for(i=0;inr;i++) - copy(af, c->planes[0],l->planes[0],c->nch,s->route[i][FR], - l->nch,s->route[i][TO],mp_audio_psize(c),c->bps); - - talloc_free(c); - af_add_output_frame(af, l); - return 0; -} - -// Allocate memory and set function pointers -static int af_open(struct af_instance* af){ - af->control=control; - af->filter_frame = filter_frame; - af_channels_t *s = af->priv; - - MP_WARN(af, "This filter is deprecated (no replacement).\n"); - - // If router scan commandline for routing pairs - if(s->routes && s->routes[0]){ - char* cp = s->routes; - int ch = 0; - // Scan for pairs on commandline - do { - int n = 0; - if (ch >= AF_NCH) { - MP_FATAL(af, "Can't have more than %d routes.\n", AF_NCH); - return AF_ERROR; - } - sscanf(cp, "%i-%i%n" ,&s->route[ch][FR], &s->route[ch][TO], &n); - MP_VERBOSE(af, "Routing from channel %i to" - " channel %i\n",s->route[ch][FR],s->route[ch][TO]); - cp = &cp[n]; - ch++; - } while(*cp == ',' && *(cp++)); - s->nr = ch; - if (s->nr > 0) - s->router = 1; - } - - return AF_OK; -} - -#define OPT_BASE_STRUCT af_channels_t -const struct af_info af_info_channels = { - .info = "Insert or remove channels", - .name = "channels", - .open = af_open, - .priv_size = sizeof(af_channels_t), - .options = (const struct m_option[]) { - OPT_INTRANGE("nch", nch, 0, 1, AF_NCH, OPTDEF_INT(2)), - OPT_STRING("routes", routes, 0), - {0} - }, -}; diff --git a/audio/filter/af_equalizer.c b/audio/filter/af_equalizer.c deleted file mode 100644 index 3f132fdc0c..0000000000 --- a/audio/filter/af_equalizer.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Equalizer filter, implementation of a 10 band time domain graphic - * equalizer using IIR filters. The IIR filters are implemented using a - * Direct Form II approach, but has been modified (b1 == 0 always) to - * save computation. - * - * Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au - * - * 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 . - */ - -#include -#include - -#include -#include - -#include "common/common.h" -#include "af.h" - -#define L 2 // Storage for filter taps -#define KM 10 // Max number of bands - -#define Q 1.2247449 /* Q value for band-pass filters 1.2247=(3/2)^(1/2) - gives 4dB suppression @ Fc*2 and Fc/2 */ - -/* Center frequencies for band-pass filters - The different frequency bands are: - nr. center frequency - 0 31.25 Hz - 1 62.50 Hz - 2 125.0 Hz - 3 250.0 Hz - 4 500.0 Hz - 5 1.000 kHz - 6 2.000 kHz - 7 4.000 kHz - 8 8.000 kHz - 9 16.00 kHz -*/ -#define CF {31.25,62.5,125,250,500,1000,2000,4000,8000,16000} - -// Maximum and minimum gain for the bands -#define G_MAX +12.0 -#define G_MIN -12.0 - -// Data for specific instances of this filter -typedef struct af_equalizer_s -{ - float a[KM][L]; // A weights - float b[KM][L]; // B weights - float wq[AF_NCH][KM][L]; // Circular buffer for W data - float g[AF_NCH][KM]; // Gain factor for each channel and band - int K; // Number of used eq bands - int channels; // Number of channels - float gain_factor; // applied at output to avoid clipping - double p[KM]; -} af_equalizer_t; - -// 2nd order Band-pass Filter design -static void bp2(float* a, float* b, float fc, float q){ - double th= 2.0 * M_PI * fc; - double C = (1.0 - tan(th*q/2.0))/(1.0 + tan(th*q/2.0)); - - a[0] = (1.0 + C) * cos(th); - a[1] = -1 * C; - - b[0] = (1.0 - C)/2.0; - b[1] = -1.0050; -} - -// Initialization and runtime control -static int control(struct af_instance* af, int cmd, void* arg) -{ - af_equalizer_t* s = (af_equalizer_t*)af->priv; - - switch(cmd){ - case AF_CONTROL_REINIT:{ - int k =0, i =0; - float F[KM] = CF; - - s->gain_factor=0.0; - - // Sanity check - if(!arg) return AF_ERROR; - - mp_audio_copy_config(af->data, (struct mp_audio*)arg); - mp_audio_set_format(af->data, AF_FORMAT_FLOAT); - - // Calculate number of active filters - s->K=KM; - while(F[s->K-1] > (float)af->data->rate/2.2) - s->K--; - - if(s->K != KM) - MP_INFO(af, "Limiting the number of filters to" - " %i due to low sample rate.\n",s->K); - - // Generate filter taps - for(k=0;kK;k++) - bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q); - - // Calculate how much this plugin adds to the overall time delay - af->delay = 2.0 / (double)af->data->rate; - - // Calculate gain factor to prevent clipping at output - for(k=0;kgain_factor < s->g[k][i]) s->gain_factor=s->g[k][i]; - } - } - - s->gain_factor=log10(s->gain_factor + 1.0) * 20.0; - - if(s->gain_factor > 0.0) - { - s->gain_factor=0.1+(s->gain_factor/12.0); - }else{ - s->gain_factor=1; - } - - return af_test_output(af,arg); - } - } - return AF_UNKNOWN; -} - -static int filter(struct af_instance* af, struct mp_audio* data) -{ - struct mp_audio* c = data; // Current working data - if (!c) - return 0; - af_equalizer_t* s = (af_equalizer_t*)af->priv; // Setup - uint32_t ci = af->data->nch; // Index for channels - uint32_t nch = af->data->nch; // Number of channels - - if (af_make_writeable(af, data) < 0) { - talloc_free(data); - return -1; - } - - while(ci--){ - float* g = s->g[ci]; // Gain factor - float* in = ((float*)c->planes[0])+ci; - float* out = ((float*)c->planes[0])+ci; - float* end = in + c->samples*c->nch; // Block loop end - - while(in < end){ - register int k = 0; // Frequency band index - register float yt = *in; // Current input sample - in+=nch; - - // Run the filters - for(;kK;k++){ - // Pointer to circular buffer wq - register float* wq = s->wq[ci][k]; - // Calculate output from AR part of current filter - register float w=yt*s->b[k][0] + wq[0]*s->a[k][0] + wq[1]*s->a[k][1]; - // Calculate output form MA part of current filter - yt+=(w + wq[1]*s->b[k][1])*g[k]; - // Update circular buffer - wq[1] = wq[0]; - wq[0] = w; - } - // Calculate output - *out=yt*s->gain_factor; - out+=nch; - } - } - af_add_output_frame(af, data); - return 0; -} - -// Allocate memory and set function pointers -static int af_open(struct af_instance* af){ - MP_WARN(af, "This filter is deprecated. Use 'anequalizer' or 'firequalizer' instead.\n"); - af->control=control; - af->filter_frame = filter; - af_equalizer_t *priv = af->priv; - for(int i=0;ig[i][j] = pow(10.0,MPCLAMP(priv->p[j],G_MIN,G_MAX)/20.0)-1.0; - } - } - return AF_OK; -} - -#define OPT_BASE_STRUCT af_equalizer_t -const struct af_info af_info_equalizer = { - .info = "Equalizer audio filter", - .name = "equalizer", - .open = af_open, - .priv_size = sizeof(af_equalizer_t), - .options = (const struct m_option[]) { -#define BAND(n) OPT_DOUBLE("e" #n, p[n], 0) - BAND(0), BAND(1), BAND(2), BAND(3), BAND(4), - BAND(5), BAND(6), BAND(7), BAND(8), BAND(9), - {0} - }, -}; diff --git a/audio/filter/af_pan.c b/audio/filter/af_pan.c deleted file mode 100644 index b2233a7191..0000000000 --- a/audio/filter/af_pan.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au - * - * 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 . - */ - -#include -#include - -#include -#include -#include - -#include "common/common.h" -#include "af.h" - -// Data for specific instances of this filter -typedef struct af_pan_s { - int nch; // Number of output channels; zero means same as input - float level[AF_NCH][AF_NCH]; // Gain level for each channel - char *matrixstr; -} af_pan_t; - -static void set_channels(struct mp_audio *mpa, int num) -{ - struct mp_chmap map; - // "unknown" channel layouts make it easier to pass through audio data, - // without triggering remixing. - mp_chmap_set_unknown(&map, num); - mp_audio_set_channels(mpa, &map); -} - -static void parse_matrix(struct af_instance *af, const char *cp) -{ - af_pan_t *s = af->priv; - int j = 0, k = 0, n; - while (*cp && k < AF_NCH) { - sscanf(cp, "%f%n" , &s->level[j][k], &n); - MP_VERBOSE(af, "Pan level from channel %i to" - " channel %i = %f\n", k, j, s->level[j][k]); - cp = &cp[n]; - j++; - if (j >= s->nch) { - j = 0; - k++; - } - if (*cp != ',') - break; - cp++; - } - -} - -// Initialization and runtime control -static int control(struct af_instance *af, int cmd, void *arg) -{ - af_pan_t* s = af->priv; - - switch(cmd){ - case AF_CONTROL_REINIT: - // Sanity check - if (!arg) - return AF_ERROR; - - af->data->rate = ((struct mp_audio*)arg)->rate; - mp_audio_set_format(af->data, AF_FORMAT_FLOAT); - set_channels(af->data, s->nch ? s->nch : ((struct mp_audio*)arg)->nch); - - if ((af->data->format != ((struct mp_audio*)arg)->format) || - (af->data->bps != ((struct mp_audio*)arg)->bps)) { - mp_audio_set_format((struct mp_audio*)arg, af->data->format); - return AF_FALSE; - } - return AF_OK; - case AF_CONTROL_SET_PAN_LEVEL: { - int i; - int ch = ((af_control_ext_t*)arg)->ch; - float *level = ((af_control_ext_t*)arg)->arg; - if (ch >= AF_NCH) - return AF_FALSE; - for (i = 0; i < AF_NCH; i++) - s->level[ch][i] = level[i]; - return AF_OK; - } - case AF_CONTROL_SET_PAN_NOUT: - // Reinit must be called after this function has been called - // Sanity check - if (((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH) { - MP_ERR(af, "The number of output channels must be" - " between 1 and %i. Current value is %i\n", - AF_NCH, ((int*)arg)[0]); - return AF_ERROR; - } - s->nch = ((int*)arg)[0]; - return AF_OK; - case AF_CONTROL_SET_PAN_BALANCE: { - float val = *(float*)arg; - if (s->nch) - return AF_ERROR; - if (af->data->nch >= 2) { - s->level[0][0] = MPMIN(1.f, 1.f - val); - s->level[0][1] = MPMAX(0.f, val); - s->level[1][0] = MPMAX(0.f, -val); - s->level[1][1] = MPMIN(1.f, 1.f + val); - } - return AF_OK; - } - case AF_CONTROL_GET_PAN_BALANCE: - if (s->nch) - return AF_ERROR; - *(float*)arg = s->level[0][1] - s->level[1][0]; - return AF_OK; - case AF_CONTROL_COMMAND: { - char **args = arg; - if (!strcmp(args[0], "set-matrix")) { - parse_matrix(af, args[1]); - return CONTROL_OK; - } else { - return CONTROL_ERROR; - } - } - } - return AF_UNKNOWN; -} - -static int filter_frame(struct af_instance *af, struct mp_audio *c) -{ - if (!c) - return 0; - struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples); - if (!l) { - talloc_free(c); - return -1; - } - mp_audio_copy_attributes(l, c); - - af_pan_t* s = af->priv; // Setup for this instance - float *in = c->planes[0]; // Input audio data - float *out = NULL; // Output audio data - float *end = in+c->samples * c->nch; // End of loop - int nchi = c->nch; // Number of input channels - int ncho = l->nch; // Number of output channels - register int j, k; - - out = l->planes[0]; - // Execute panning - // FIXME: Too slow - while (in < end) { - for (j = 0; j < ncho; j++) { - register float x = 0.0; - register float *tin = in; - for (k = 0; k < nchi; k++) - x += tin[k] * s->level[j][k]; - out[j] = x; - } - out += ncho; - in += nchi; - } - - talloc_free(c); - af_add_output_frame(af, l); - return 0; -} - -// Allocate memory and set function pointers -static int af_open(struct af_instance *af) -{ - af->control = control; - af->filter_frame = filter_frame; - MP_WARN(af, "This filter is deprecated. Use lavfi pan instead.\n"); - af_pan_t *s = af->priv; - int nch = s->nch; - if (nch && AF_OK != control(af, AF_CONTROL_SET_PAN_NOUT, &nch)) - return AF_ERROR; - - // Read pan values - if (s->matrixstr) - parse_matrix(af, s->matrixstr); - return AF_OK; -} - -#define OPT_BASE_STRUCT af_pan_t -const struct af_info af_info_pan = { - .info = "Panning audio filter", - .name = "pan", - .open = af_open, - .priv_size = sizeof(af_pan_t), - .options = (const struct m_option[]) { - OPT_INTRANGE("channels", nch, 0, 0, AF_NCH), - OPT_STRING("matrix", matrixstr, 0), - {0} - }, -}; diff --git a/audio/filter/af_volume.c b/audio/filter/af_volume.c deleted file mode 100644 index 8fffc08853..0000000000 --- a/audio/filter/af_volume.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C)2002 Anders Johansson ajh@atri.curtin.edu.au - * - * 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 . - */ - -#include -#include -#include - -#include -#include -#include - -#include "common/common.h" -#include "af.h" -#include "demux/demux.h" - -struct priv { - float level; // User-specified gain level for each channel - float rgain; // Replaygain level - int rgain_track; // Enable/disable track based replaygain - int rgain_album; // Enable/disable album based replaygain - float rgain_preamp; // Set replaygain pre-amplification - int rgain_clip; // Enable/disable clipping prevention - float replaygain_fallback; - int soft; // Enable/disable soft clipping - int fast; // Use fix-point volume control - int detach; // Detach if gain volume is neutral - float cfg_volume; - int warn; -}; - -// Convert to gain value from dB. input <= -200dB will become 0 gain. -static float from_dB(float in, float k, float mi, float ma) -{ - if (in <= -200) - return 0.0; - return pow(10.0, MPCLAMP(in, mi, ma) / k); -} - -static int control(struct af_instance *af, int cmd, void *arg) -{ - struct priv *s = af->priv; - - switch (cmd) { - case AF_CONTROL_REINIT: { - struct mp_audio *in = arg; - - mp_audio_copy_config(af->data, in); - mp_audio_force_interleaved_format(af->data); - - if (s->fast && af_fmt_from_planar(in->format) != AF_FORMAT_FLOAT) { - mp_audio_set_format(af->data, AF_FORMAT_S16); - } else { - mp_audio_set_format(af->data, AF_FORMAT_FLOAT); - } - if (af_fmt_is_planar(in->format)) - mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format)); - s->rgain = 1.0; - struct replaygain_data *rg = af->replaygain_data; - if ((s->rgain_track || s->rgain_album) && rg) { - MP_VERBOSE(af, "Replaygain: Track=%f/%f Album=%f/%f\n", - rg->track_gain, rg->track_peak, - rg->album_gain, rg->album_peak); - - float gain, peak; - if (s->rgain_track) { - gain = rg->track_gain; - peak = rg->track_peak; - } else { - gain = rg->album_gain; - peak = rg->album_peak; - } - - gain += s->rgain_preamp; - s->rgain = from_dB(gain, 20.0, -200.0, 60.0); - - MP_VERBOSE(af, "Applying replay-gain: %f\n", s->rgain); - - if (!s->rgain_clip) { // clipping prevention - s->rgain = MPMIN(s->rgain, 1.0 / peak); - MP_VERBOSE(af, "...with clipping prevention: %f\n", s->rgain); - } - } else if (s->replaygain_fallback) { - s->rgain = from_dB(s->replaygain_fallback, 20.0, -200.0, 60.0); - MP_VERBOSE(af, "Applying fallback gain: %f\n", s->rgain); - } - if (s->detach && fabs(s->level * s->rgain - 1.0) < 0.00001) - return AF_DETACH; - return af_test_output(af, in); - } - case AF_CONTROL_SET_VOLUME: - s->level = *(float *)arg; - MP_VERBOSE(af, "volume gain: %f\n", s->level); - return AF_OK; - } - return AF_UNKNOWN; -} - -static void filter_plane(struct af_instance *af, struct mp_audio *data, int p) -{ - struct priv *s = af->priv; - - float level = s->level * s->rgain * from_dB(s->cfg_volume, 20.0, -200.0, 60.0); - int num_samples = data->samples * data->spf; - - if (af_fmt_from_planar(af->data->format) == AF_FORMAT_S16) { - int vol = 256.0 * level; - if (vol != 256) { - if (af_make_writeable(af, data) < 0) - return; // oom - int16_t *a = data->planes[p]; - for (int i = 0; i < num_samples; i++) { - int x = (a[i] * vol) >> 8; - a[i] = MPCLAMP(x, SHRT_MIN, SHRT_MAX); - } - } - } else if (af_fmt_from_planar(af->data->format) == AF_FORMAT_FLOAT) { - float vol = level; - if (vol != 1.0) { - if (af_make_writeable(af, data) < 0) - return; // oom - float *a = data->planes[p]; - for (int i = 0; i < num_samples; i++) { - float x = a[i] * vol; - a[i] = s->soft ? af_softclip(x) : MPCLAMP(x, -1.0, 1.0); - } - } - } -} - -static int filter(struct af_instance *af, struct mp_audio *data) -{ - if (data) { - for (int n = 0; n < data->num_planes; n++) - filter_plane(af, data, n); - af_add_output_frame(af, data); - } - return 0; -} - -static int af_open(struct af_instance *af) -{ - struct priv *s = af->priv; - if (s->warn) - MP_WARN(af, "This filter is deprecated. Use --volume directly.\n"); - af->control = control; - af->filter_frame = filter; - s->level = 1.0; - return AF_OK; -} - -#define OPT_BASE_STRUCT struct priv - -// Description of this filter -const struct af_info af_info_volume = { - .info = "Volume control audio filter", - .name = "volume", - .open = af_open, - .priv_size = sizeof(struct priv), - .options = (const struct m_option[]) { - OPT_FLOATRANGE("volumedb", cfg_volume, 0, -200, 60), - OPT_FLAG("replaygain-track", rgain_track, 0), - OPT_FLAG("replaygain-album", rgain_album, 0), - OPT_FLOATRANGE("replaygain-preamp", rgain_preamp, 0, -15, 15), - OPT_FLAG("replaygain-clip", rgain_clip, 0), - OPT_FLOATRANGE("replaygain-fallback", replaygain_fallback, 0, -200, 60), - OPT_FLAG("softclip", soft, 0), - OPT_FLAG("s16", fast, 0), - OPT_FLAG("detach", detach, 0), - OPT_FLAG("warn", warn, 0, OPTDEF_INT(1)), - {0} - }, -}; diff --git a/options/options.c b/options/options.c index d3e7bd2c34..348cc2f5d2 100644 --- a/options/options.c +++ b/options/options.c @@ -557,7 +557,6 @@ const m_option_t mp_opts[] = { {"weak", -1})), OPT_DOUBLE("audio-buffer", audio_buffer, M_OPT_MIN | M_OPT_MAX, .min = 0, .max = 10), - OPT_FLOATRANGE("balance", balance, 0, -1, 1), OPT_STRING("title", wintitle, 0), OPT_STRING("force-media-title", media_title, 0), diff --git a/options/options.h b/options/options.h index 170de9cddc..e2e1220fda 100644 --- a/options/options.h +++ b/options/options.h @@ -107,7 +107,6 @@ typedef struct MPOpts { float rgain_preamp; // Set replaygain pre-amplification int rgain_clip; // Enable/disable clipping prevention float rgain_fallback; - float balance; int softvol_mute; float softvol_max; int gapless_audio; diff --git a/player/audio.c b/player/audio.c index 3b63f92d7e..e08259b1b5 100644 --- a/player/audio.c +++ b/player/audio.c @@ -185,57 +185,6 @@ void audio_update_volume(struct MPContext *mpctx) gain *= compute_replaygain(mpctx); if (opts->softvol_mute == 1) gain = 0.0; - - if (!af_control_any_rev(ao_c->af, AF_CONTROL_SET_VOLUME, &gain)) { - if (gain == 1.0) - return; - MP_VERBOSE(mpctx, "Inserting volume filter.\n"); - char *args[] = {"warn", "no", NULL}; - if (!(af_add(ao_c->af, "volume", "softvol", args) - && af_control_any_rev(ao_c->af, AF_CONTROL_SET_VOLUME, &gain))) - MP_ERR(mpctx, "No volume control available.\n"); - } -} - -/* NOTE: Currently the balance code is seriously buggy: it always changes - * the af_pan mapping between the first two input channels and first two - * output channels to particular values. These values make sense for an - * af_pan instance that was automatically inserted for balance control - * only and is otherwise an identity transform, but if the filter was - * there for another reason, then ignoring and overriding the original - * values is completely wrong. - */ -void audio_update_balance(struct MPContext *mpctx) -{ - struct MPOpts *opts = mpctx->opts; - struct ao_chain *ao_c = mpctx->ao_chain; - if (!ao_c || ao_c->af->initialized < 1) - return; - - float val = opts->balance; - - if (af_control_any_rev(ao_c->af, AF_CONTROL_SET_PAN_BALANCE, &val)) - return; - - if (val == 0) - return; - - struct af_instance *af_pan_balance; - if (!(af_pan_balance = af_add(ao_c->af, "pan", "autopan", NULL))) { - MP_ERR(mpctx, "No balance control available.\n"); - return; - } - - /* make all other channels pass through since by default pan blocks all */ - for (int i = 2; i < AF_NCH; i++) { - float level[AF_NCH] = {0}; - level[i] = 1.f; - af_control_ext_t arg_ext = { .ch = i, .arg = level }; - af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_LEVEL, - &arg_ext); - } - - af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_BALANCE, &val); } static int recreate_audio_filters(struct MPContext *mpctx) @@ -254,7 +203,6 @@ static int recreate_audio_filters(struct MPContext *mpctx) MP_ERR(mpctx, "--softvol=no is not supported anymore.\n"); audio_update_volume(mpctx); - audio_update_balance(mpctx); mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL); @@ -289,7 +237,6 @@ int reinit_audio_filters(struct MPContext *mpctx) #else /* HAVE_LIBAV */ void audio_update_volume(struct MPContext *mpctx) {} -void audio_update_balance(struct MPContext *mpctx) {} int reinit_audio_filters(struct MPContext *mpctx) { return 0; } #endif /* else HAVE_LIBAF */ diff --git a/player/command.c b/player/command.c index c89f6a7f6f..569272c680 100644 --- a/player/command.c +++ b/player/command.c @@ -2100,35 +2100,6 @@ static int mp_property_audio_out_params(void *ctx, struct m_property *prop, return r; } -/// Balance (RW) -static int mp_property_balance(void *ctx, struct m_property *prop, - int action, void *arg) -{ - MPContext *mpctx = ctx; - - if (action == M_PROPERTY_PRINT) { - char **str = arg; - float bal = mpctx->opts->balance; - if (bal == 0.f) - *str = talloc_strdup(NULL, "center"); - else if (bal == -1.f) - *str = talloc_strdup(NULL, "left only"); - else if (bal == 1.f) - *str = talloc_strdup(NULL, "right only"); - else { - unsigned right = (bal + 1.f) / 2.f * 100.f; - *str = talloc_asprintf(NULL, "left %d%%, right %d%%", - 100 - right, right); - } - return M_PROPERTY_OK; - } - - int r = mp_property_generic_option(mpctx, prop, action, arg); - if (action == M_PROPERTY_SET) - audio_update_balance(mpctx); - return r; -} - static struct track* track_next(struct MPContext *mpctx, enum stream_type type, int direction, struct track *track) { @@ -4011,7 +3982,6 @@ static const struct m_property mp_properties_base[] = { {"audio-params", mp_property_audio_params}, {"audio-out-params", mp_property_audio_out_params}, {"aid", mp_property_audio}, - {"balance", mp_property_balance}, {"audio-device", mp_property_audio_device}, {"audio-device-list", mp_property_audio_devices}, {"current-ao", mp_property_ao}, @@ -4167,7 +4137,7 @@ static const char *const *const mp_event_property_change[] = { "colormatrix-primaries", "video-aspect", "video-dec-params", "hwdec", "hwdec-current", "hwdec-interop"), E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate", - "samplerate", "channels", "audio", "volume", "mute", "balance", + "samplerate", "channels", "audio", "volume", "mute", "current-ao", "audio-codec-name", "audio-params", "audio-out-params", "volume-max", "mixer-active"), E(MPV_EVENT_SEEK, "seeking", "core-idle", "eof-reached"), @@ -4361,7 +4331,6 @@ static const struct property_osd_display { { "ao-mute", "AO Mute" }, { "audio-delay", "A-V delay" }, { "audio", "Audio" }, - { "balance", "Balance", .osd_progbar = OSD_BALANCE }, // video { "panscan", "Panscan", .osd_progbar = OSD_PANSCAN }, { "taskbar-progress", "Progress in taskbar" }, diff --git a/wscript_build.py b/wscript_build.py index 274ef663cd..e20af74c7e 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -184,16 +184,12 @@ def build(ctx): ( "audio/decode/ad_spdif.c" ), ( "audio/decode/dec_audio.c" ), ( "audio/filter/af.c", "libaf" ), - ( "audio/filter/af_channels.c", "libaf" ), - ( "audio/filter/af_equalizer.c", "libaf" ), ( "audio/filter/af_format.c", "libaf" ), ( "audio/filter/af_lavcac3enc.c", "libaf" ), ( "audio/filter/af_lavfi.c", "libaf" ), ( "audio/filter/af_lavrresample.c", "libaf" ), - ( "audio/filter/af_pan.c", "libaf" ), ( "audio/filter/af_rubberband.c", "rubberband" ), ( "audio/filter/af_scaletempo.c", "libaf" ), - ( "audio/filter/af_volume.c", "libaf" ), ( "audio/filter/tools.c", "libaf" ), ( "audio/out/ao.c" ), ( "audio/out/ao_alsa.c", "alsa" ),