Mercurial > mplayer.hg
changeset 18082:0aa3fef68422
very simple filter which can remove a sine at a specified frequency, usefull to get rid of the 50/60hz noise on ultra crappy equipment
probably works only with 1 channel input
author | michael |
---|---|
date | Thu, 13 Apr 2006 10:36:17 +0000 |
parents | 192e778f1ba1 |
children | b069afd2a0de |
files | libaf/Makefile libaf/af.c libaf/af_sinesupress.c libaf/control.h |
diffstat | 4 files changed, 186 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libaf/Makefile Wed Apr 12 20:17:07 2006 +0000 +++ b/libaf/Makefile Thu Apr 13 10:36:17 2006 +0000 @@ -16,6 +16,7 @@ af_hrtf.c \ af_pan.c \ af_resample.c \ + af_sinesupress.c \ af_sub.c \ af_surround.c \ af_sweep.c \
--- a/libaf/af.c Wed Apr 12 20:17:07 2006 +0000 +++ b/libaf/af.c Thu Apr 13 10:36:17 2006 +0000 @@ -29,6 +29,7 @@ extern af_info_t af_info_hrtf; extern af_info_t af_info_ladspa; extern af_info_t af_info_center; +extern af_info_t af_info_sinesupress; static af_info_t* filter_list[]={ &af_info_dummy, @@ -57,6 +58,7 @@ &af_info_ladspa, #endif &af_info_center, + &af_info_sinesupress, NULL };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libaf/af_sinesupress.c Thu Apr 13 10:36:17 2006 +0000 @@ -0,0 +1,178 @@ +/*============================================================================= +// +// This software has been released under the terms of the GNU General Public +// license. See http://www.gnu.org/copyleft/gpl.html for details. +// +// Copyright 2006 Michael Niedermayer +// Copyright 2004 Alex Beregszaszi & Pierre Lombard (original af_extrastereo.c upon which this is based) +// +//============================================================================= +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.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_sinesupress_s +{ + double freq; + double decay; + double real; + double imag; + double ref; + double pos; +}af_sinesupress_t; + +static af_data_t* play_s16(struct af_instance_s* af, af_data_t* data); +static af_data_t* play_float(struct af_instance_s* af, af_data_t* data); + +// Initialization and runtime control +static int control(struct af_instance_s* af, int cmd, void* arg) +{ + af_sinesupress_t* s = (af_sinesupress_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 = 1; +#if 0 + if (((af_data_t*)arg)->format == AF_FORMAT_FLOAT_NE) + { + af->data->format = AF_FORMAT_FLOAT_NE; + af->data->bps = 4; + af->play = play_float; + }// else +#endif + { + af->data->format = AF_FORMAT_S16_NE; + af->data->bps = 2; + af->play = play_s16; + } + + return af_test_output(af,(af_data_t*)arg); + } + case AF_CONTROL_COMMAND_LINE:{ + float f1,f2; + sscanf((char*)arg,"%f:%f", &f1,&f2); + s->freq = f1; + s->decay = f2; + return AF_OK; + } + case AF_CONTROL_SS_FREQ | AF_CONTROL_SET: + s->freq = *(float*)arg; + return AF_OK; + case AF_CONTROL_SS_FREQ | AF_CONTROL_GET: + *(float*)arg = s->freq; + return AF_OK; + case AF_CONTROL_SS_DECAY | AF_CONTROL_SET: + s->decay = *(float*)arg; + return AF_OK; + case AF_CONTROL_SS_DECAY | AF_CONTROL_GET: + *(float*)arg = s->decay; + return AF_OK; + } + 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_s16(struct af_instance_s* af, af_data_t* data) +{ + af_sinesupress_t *s = af->setup; + register int i = 0; + int16_t *a = (int16_t*)data->audio; // Audio data + int len = data->len/2; // Number of samples + int avg, l, r; + + for (i = 0; i < len; i++) + { + double co= cos(s->pos); + double si= sin(s->pos); + + s->real += co * a[i]; + s->imag += si * a[i]; + s->ref += co * co; + + a[i] -= (s->real * co + s->imag * si) / s->ref; + + s->real -= s->real * s->decay; + s->imag -= s->imag * s->decay; + s->ref -= s->ref * s->decay; + + s->pos += 2 * M_PI * s->freq / data->rate; + } + + af_msg(AF_MSG_VERBOSE,"[sinesupress] f:%8.2f: amp:%8.2f\n", s->freq, sqrt(s->real*s->real + s->imag*s->imag) / s->ref); + + return data; +} + +#if 0 +static af_data_t* play_float(struct af_instance_s* af, af_data_t* data) +{ + af_sinesupress_t *s = af->setup; + register int i = 0; + float *a = (float*)data->audio; // Audio data + int len = data->len/4; // Number of samples + float avg, l, r; + + for (i = 0; i < len; i+=2) + { + avg = (a[i] + a[i + 1]) / 2; + +/* l = avg + (s->mul * (a[i] - avg)); + r = avg + (s->mul * (a[i + 1] - avg));*/ + + a[i] = af_softclip(l); + a[i + 1] = af_softclip(r); + } + + return data; +} +#endif + +// Allocate memory and set function pointers +static int open(af_instance_t* af){ + af->control=control; + af->uninit=uninit; + af->play=play_s16; + af->mul.n=1; + af->mul.d=1; + af->data=calloc(1,sizeof(af_data_t)); + af->setup=calloc(1,sizeof(af_sinesupress_t)); + if(af->data == NULL || af->setup == NULL) + return AF_ERROR; + + ((af_sinesupress_t*)af->setup)->freq = 50.0; + ((af_sinesupress_t*)af->setup)->decay = 0.0001; + return AF_OK; +} + +// Description of this filter +af_info_t af_info_sinesupress = { + "Sine Supress", + "sinesupress", + "Michael Niedermayer", + "", + 0, + open +};
--- a/libaf/control.h Wed Apr 12 20:17:07 2006 +0000 +++ b/libaf/control.h Thu Apr 13 10:36:17 2006 +0000 @@ -224,4 +224,9 @@ // Channel number which to inster the filtered data, arg in int* #define AF_CONTROL_CENTER_CH 0x00002200 | AF_CONTROL_FILTER_SPECIFIC + +// SineSupress +#define AF_CONTROL_SS_FREQ 0x00002300 | AF_CONTROL_FILTER_SPECIFIC +#define AF_CONTROL_SS_DECAY 0x00002400 | AF_CONTROL_FILTER_SPECIFIC + #endif /*__af_control_h */