diff options
author | anders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-12-28 13:59:53 +0000 |
---|---|---|
committer | anders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-12-28 13:59:53 +0000 |
commit | 6adaa78ee935ef89439d4b38550165f13e880320 (patch) | |
tree | 6612adc09121e661363b1370cb43981007d36b60 /libaf/af_gate.c | |
parent | 0e9c0e8aa2aa7df6aad5d78c4b664927a9d2421e (diff) | |
download | mpv-6adaa78ee935ef89439d4b38550165f13e880320.tar.bz2 mpv-6adaa78ee935ef89439d4b38550165f13e880320.tar.xz |
Changes includes:
- Improved runtime control system
- 3 New filter panning, compressor/limiter and a noise gate
- The compressor/limiter and the noise gate are not yet finished
- The panning filter does combined mixing and channel routing and
can be used to down-mix from stereo to mono (for example)
- Improvements to volume and channel
- volume now has a very good soft clipping using sin()
- channel can handle generic routing of audio data
- Conversion of all filters to handle floating point data
- Cleanup of message printing
- Fix for the sig 11 bug reported by Denes
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8608 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf/af_gate.c')
-rw-r--r-- | libaf/af_gate.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/libaf/af_gate.c b/libaf/af_gate.c new file mode 100644 index 0000000000..033c8603df --- /dev/null +++ b/libaf/af_gate.c @@ -0,0 +1,157 @@ +/*============================================================================= +// +// This software has been released under the terms of the GNU Public +// license. See http://www.gnu.org/copyleft/gpl.html for details. +// +// Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au +// +//============================================================================= +*/ + +#include <stdio.h> +#include <stdlib.h> + +#include <unistd.h> +#include <inttypes.h> +#include <math.h> +#include <limits.h> + +#include "af.h" + +// Data for specific instances of this filter +typedef struct af_gate_s +{ + int enable[AF_NCH]; // Enable/disable / channel + float time[AF_NCH]; // Forgetting factor for power estimate + float pow[AF_NCH]; // Estimated power level [dB] + float tresh[AF_NCH]; // Threshold [dB] + float attack[AF_NCH]; // Attack time [ms] + float release[AF_NCH]; // Release time [ms] + float range[AF_NCH]; // Range level [dB] +}af_gate_t; + +// Initialization and runtime control +static int control(struct af_instance_s* af, int cmd, void* arg) +{ + af_gate_t* s = (af_gate_t*)af->setup; + switch(cmd){ + case AF_CONTROL_REINIT: + // Sanity check + if(!arg) return AF_ERROR; + + af->data->rate = ((af_data_t*)arg)->rate; + af->data->nch = ((af_data_t*)arg)->nch; + af->data->format = AF_FORMAT_F | AF_FORMAT_NE; + af->data->bps = 4; + + // Time constant set to 0.1s + // s->alpha = (1.0/0.2)/(2.0*M_PI*(float)((af_data_t*)arg)->rate); + return af_test_output(af,(af_data_t*)arg); + case AF_CONTROL_COMMAND_LINE:{ +/* float v=-10.0; */ +/* float vol[AF_NCH]; */ +/* float s=0.0; */ +/* float clipp[AF_NCH]; */ +/* int i; */ +/* sscanf((char*)arg,"%f:%f", &v, &s); */ +/* for(i=0;i<AF_NCH;i++){ */ +/* vol[i]=v; */ +/* clipp[i]=s; */ +/* } */ +/* if(AF_OK != control(af,AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_SET, clipp)) */ +/* return AF_ERROR; */ +/* return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol); */ + } + + case AF_CONTROL_GATE_ON_OFF | AF_CONTROL_SET: + memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int)); + return AF_OK; + case AF_CONTROL_GATE_ON_OFF | AF_CONTROL_GET: + memcpy((int*)arg,s->enable,AF_NCH*sizeof(int)); + return AF_OK; + case AF_CONTROL_GATE_THRESH | AF_CONTROL_SET: + return af_from_dB(AF_NCH,(float*)arg,s->tresh,20.0,-60.0,-1.0); + case AF_CONTROL_GATE_THRESH | AF_CONTROL_GET: + return af_to_dB(AF_NCH,s->tresh,(float*)arg,10.0); + case AF_CONTROL_GATE_ATTACK | AF_CONTROL_SET: + return af_from_ms(AF_NCH,(float*)arg,s->attack,af->data->rate,500.0,0.1); + case AF_CONTROL_GATE_ATTACK | AF_CONTROL_GET: + return af_to_ms(AF_NCH,s->attack,(float*)arg,af->data->rate); + case AF_CONTROL_GATE_RELEASE | AF_CONTROL_SET: + return af_from_ms(AF_NCH,(float*)arg,s->release,af->data->rate,3000.0,10.0); + case AF_CONTROL_GATE_RELEASE | AF_CONTROL_GET: + return af_to_ms(AF_NCH,s->release,(float*)arg,af->data->rate); + case AF_CONTROL_GATE_RANGE | AF_CONTROL_SET: + return af_from_dB(AF_NCH,(float*)arg,s->range,20.0,100.0,0.0); + case AF_CONTROL_GATE_RANGE | AF_CONTROL_GET: + return af_to_dB(AF_NCH,s->range,(float*)arg,10.0); + } + return AF_UNKNOWN; +} + +// Deallocate memory +static void uninit(struct af_instance_s* af) +{ + if(af->data) + free(af->data); + if(af->setup) + free(af->setup); +} + +// Filter data through filter +static af_data_t* play(struct af_instance_s* af, af_data_t* data) +{ + af_data_t* c = data; // Current working data + af_gate_t* s = (af_gate_t*)af->setup; // Setup for this instance + float* a = (float*)c->audio; // Audio data + int len = c->len/4; // Number of samples + int ch = 0; // Channel counter + register int nch = c->nch; // Number of channels + register int i = 0; + + + // Noise gate + for(ch = 0; ch < nch ; ch++){ + if(s->enable[ch]){ + float t = 1.0 - s->time[ch]; + for(i=ch;i<len;i+=nch){ + register float x = a[i]; + register float pow = x*x; + s->pow[ch] = t*s->pow[ch] + + pow*s->time[ch]; // LP filter + if(pow < s->pow[ch]){ + ; + } + else{ + ; + } + a[i] = x; + } + } + } + return c; +} + +// Allocate memory and set function pointers +static int open(af_instance_t* af){ + af->control=control; + af->uninit=uninit; + af->play=play; + af->mul.n=1; + af->mul.d=1; + af->data=calloc(1,sizeof(af_data_t)); + af->setup=calloc(1,sizeof(af_gate_t)); + if(af->data == NULL || af->setup == NULL) + return AF_ERROR; + return AF_OK; +} + +// Description of this filter +af_info_t af_info_gate = { + "Noise gate audio filter", + "gate", + "Anders", + "", + AF_FLAGS_NOT_REENTRANT, + open +}; |