diff options
-rw-r--r-- | DOCS/man/af.rst | 176 | ||||
-rw-r--r-- | DOCS/man/options.rst | 8 | ||||
-rw-r--r-- | audio/filter/af.c | 9 | ||||
-rw-r--r-- | audio/filter/af.h | 5 | ||||
-rw-r--r-- | audio/filter/af_channels.c | 255 | ||||
-rw-r--r-- | audio/filter/af_equalizer.c | 215 | ||||
-rw-r--r-- | audio/filter/af_pan.c | 206 | ||||
-rw-r--r-- | audio/filter/af_volume.c | 188 | ||||
-rw-r--r-- | options/options.c | 1 | ||||
-rw-r--r-- | options/options.h | 1 | ||||
-rw-r--r-- | player/audio.c | 53 | ||||
-rw-r--r-- | player/command.c | 33 | ||||
-rw-r--r-- | wscript_build.py | 4 |
13 files changed, 1 insertions, 1153 deletions
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. - - ``<g1>:<g2>:<g3>:...:<g10>`` - 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 ``<nch>`` 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. - - ``<nch>`` - number of output channels (1-8) - ``<routes>`` - 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[=<volumedb>[:...]]`` - 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. - - ``<volumedb>`` - 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:[<matrix>]`` - 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. - - ``<n>`` - Number of output channels (1-8). - ``<matrix>`` - 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 ``<matrix>`` 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=<value>`` - 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=<sec>`` 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 <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#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;i<s->nr;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;i<s->nr;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;i<s->nr;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;i<s->nr;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 <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> - -#include <inttypes.h> -#include <math.h> - -#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;k<s->K;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;k<AF_NCH;k++) - { - for(i=0;i<KM;i++) - { - if(s->gain_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(;k<s->K;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;i<AF_NCH;i++){ - for(int j=0;j<KM;j++){ - priv->g[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 <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> - -#include <inttypes.h> -#include <math.h> -#include <limits.h> - -#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} - }, -}; |