[MPlayer-dev-eng] [PATCH] simple 3-band equalizer
Nicolas George
nicolas.george at ens.fr
Mon May 28 13:50:15 CEST 2007
Hi.
Here is a patch implementing a simple 3-band equalizer based on the
simulation of the RLC electronic circuit.
It is used this way: -af rlceq=440:1:0:0 . That will keep only the bass, the
cut-off frequencies being 440/2 and 440*2.
It appears to be much faster than -af equalizer (a quick benchmark tells me
five times faster). Furthermore, for certain values of the center-frequency,
it could be done with pure integer arithmetic.
Before submitting a complete patch, with manual page and algorithmic
comments, especially about the way the float format is selected.
Regards,
--
Nicolas George
Index: libaf/Makefile
===================================================================
--- libaf/Makefile (revision 23396)
+++ libaf/Makefile (working copy)
@@ -16,6 +16,7 @@
af_karaoke.c \
af_pan.c \
af_resample.c \
+ af_rlceq.c \
af_sinesuppress.c \
af_sub.c \
af_surround.c \
Index: libaf/af_rlceq.c
===================================================================
--- libaf/af_rlceq.c (revision 0)
+++ libaf/af_rlceq.c (revision 0)
@@ -0,0 +1,165 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "af.h"
+
+typedef struct af_rlceq_state_s {
+ float old_u, old_du;
+ float uc, duc;
+ /*float ur, dur;*/
+ float ul, dul;
+} af_rlceq_state_t;
+
+typedef struct af_rlceq_s {
+ float mul_c, mul_r, mul_l;
+ float base_freq;
+ float k, k2;
+ af_rlceq_state_t *state;
+} af_rlceq_t;
+
+static int
+control_reinit(af_instance_t *af, af_data_t *data)
+{
+ af_rlceq_t *setup;
+ int i;
+
+ *af->data = *data;
+ af->data->format = AF_FORMAT_FLOAT_NE;
+ setup = af->setup;
+ if(setup->state != NULL)
+ free(setup->state);
+ setup->state = malloc(data->nch * sizeof(af_rlceq_state_t));
+ if(setup->state == NULL)
+ return(AF_ERROR);
+ for(i = 0; i < data->nch; i++) {
+ setup->state[i].old_u = 0;
+ setup->state[i].old_du = 0;
+ setup->state[i].uc = 0;
+ setup->state[i].duc = 0;
+ /*setup->state[i].ur = 0;
+ setup->state[i].dur = 0;*/
+ setup->state[i].ul = 0;
+ setup->state[i].dul = 0;
+ }
+ setup->k = 2 * 3.14159265 * setup->base_freq / data->rate;
+ setup->k2 = setup->k * setup->k;
+ return(af_test_output(af, data));
+}
+
+static int
+control_command_line(af_instance_t *af, const char *arg)
+{
+ af_rlceq_t *setup;
+
+ setup = af->setup;
+ sscanf(arg, "%f:%f:%f:%f", &setup->base_freq,
+ &setup->mul_c, &setup->mul_r, &setup->mul_l);
+ return(AF_OK);
+}
+
+static int
+control(struct af_instance_s *af, int cmd, void *arg)
+{
+ switch(cmd) {
+ case AF_CONTROL_REINIT:
+ return(control_reinit(af, arg));
+ case AF_CONTROL_COMMAND_LINE:
+ return(control_command_line(af, arg));
+ }
+ return(AF_UNKNOWN);
+}
+
+static void
+uninit(struct af_instance_s *af)
+{
+ af_rlceq_t *setup;
+
+ if(af->data != NULL)
+ free(af->data);
+ setup = af->setup;
+ if(setup != NULL) {
+ if(setup->state != NULL)
+ free(setup->state);
+ free(af->setup);
+ }
+}
+
+static af_data_t *
+play(struct af_instance_s *af, af_data_t *data)
+{
+ int len;
+ int i, j;
+ float *a;
+ int nc;
+ float u, du, d2u;
+ float d2uc, /*d2ur,*/ d2ul;
+ float k, k2, mul_c, mul_r, mul_l;
+ af_rlceq_t *setup;
+ af_rlceq_state_t *s;
+ float ur;
+
+ setup = af->setup;
+ k = setup->k;
+ k2 = setup->k2;
+ mul_c = setup->mul_c;
+ mul_r = setup->mul_r;
+ mul_l = setup->mul_l;
+ len = data->len / sizeof(float);
+ nc = data->nch;
+ a = data->audio;
+ for(i = 0; i < len; i += nc) {
+ for(j = 0; j < nc; j++) {
+ s = &setup->state[j];
+ u = *a;
+ du = u - s->old_u;
+ d2u = du - s->old_du;
+ d2uc = - k2 * s->uc - 2 * k * s->duc + k2 * u;
+ /*d2ur = - k2 * s->ur - 2 * k * s->dur + 2 * k * du;*/
+ d2ul = - k2 * s->ul - 2 * k * s->dul + d2u;
+ s->duc += d2uc;
+ /*s->dur += d2ur;*/
+ s->dul += d2ul;
+ s->uc += s->duc;
+ /*s->ur += s->dur;*/
+ s->ul += s->dul;
+ //ur = u - ul - uc;
+ s->old_u = u;
+ s->old_du = du;
+ ur = u - s->uc - s->ul;
+ *a = mul_c * s->uc + mul_r * /*s->*/ur + mul_l * s->ul;
+ a++;
+ }
+ }
+ return(data);
+}
+
+static int
+af_open(af_instance_t *af){
+ af_rlceq_t *setup;
+
+ af->control = control;
+ af->uninit = uninit;
+ af->play = play;
+ af->mul.d = 1;
+ af->mul.n = 1;
+ af->data = malloc(sizeof(af_data_t));
+ af->setup = setup = malloc(sizeof(af_rlceq_state_t));
+ if(af->data == NULL || af->setup == NULL)
+ return(AF_ERROR);
+ setup->mul_c = 1;
+ setup->mul_r = 1;
+ setup->mul_l = 1;
+ setup->base_freq = 440;
+ setup->state = NULL;
+ return(AF_OK);
+}
+
+af_info_t af_info_rlceq = {
+ "RLC-based equalizer",
+ "rlceq",
+ "Nicolas George",
+ "",
+ AF_FLAGS_REENTRANT,
+ af_open
+};
Index: libaf/af.c
===================================================================
--- libaf/af.c (revision 23396)
+++ libaf/af.c (working copy)
@@ -31,6 +31,7 @@
extern af_info_t af_info_center;
extern af_info_t af_info_sinesuppress;
extern af_info_t af_info_karaoke;
+extern af_info_t af_info_rlceq;
static af_info_t* filter_list[]={
&af_info_dummy,
@@ -61,6 +62,7 @@
&af_info_center,
&af_info_sinesuppress,
&af_info_karaoke,
+ &af_info_rlceq,
NULL
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 185 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20070528/c237c793/attachment.pgp>
More information about the MPlayer-dev-eng
mailing list