From c9050afc826a9b20ebfa0d5a34700a422375b54d Mon Sep 17 00:00:00 2001
From: richard <xwang@xwang-laptop.(none)>
Date: Tue, 30 Mar 2010 22:09:57 +0800
Subject: [PATCH] from xiangwang <wangxiang68@gmail.com>

---
 modules/audio_filter/headphone.c |  119 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 119 insertions(+), 0 deletions(-)
 create mode 100644 modules/audio_filter/headphone.c

diff --git a/modules/audio_filter/headphone.c b/modules/audio_filter/headphone.c
new file mode 100644
index 0000000..f7ae23f
--- /dev/null
+++ b/modules/audio_filter/headphone.c
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * headphone.c: The filter make it more comfortable to listen to headphones
+ *****************************************************************************
+ * VideoLAN
+ *
+ * Authors: Xiang Wang <wangxiang68@gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_aout.h>
+#include <vlc_filter.h>
+
+#define FIR_Length 32*2
+
+static const double fir[FIR_Length] = {
+    4,   -6,     /* 32 tap stereo FIR filter. */
+    4,  -11,     /* One side filters as if the */
+   -1,   -5,     /* signal was from 30 degrees */
+    3,    3,     /* from the ear, the other as */
+   -2,    5,     /* if 330 degrees. */
+   -5,    0,
+    9,    1,
+    6,    3,     /*                         Input                         */
+   -4,   -1,     /*                   Left         Right                  */
+   -5,   -3,     /*                __________   __________                */
+   -2,   -5,     /*               |          | |          |               */
+   -7,    1,     /*           .---|  Hh,0(f) | |  Hh,0(f) |---.           */
+    6,   -7,     /*          /    |__________| |__________|    \          */
+   30,  -29,     /*         /                \ /                \         */
+   12,   -3,     /*        /                  X                  \        */
+  -11,    4,     /*       /                  / \                  \       */
+   -3,    7,     /*  ____V_____   __________V   V__________   _____V____  */
+  -20,   23,     /* |          | |          |   |          | |          | */
+    2,    0,     /* | Hh,30(f) | | Hh,330(f)|   | Hh,330(f)| | Hh,30(f) | */
+    1,   -6,     /* |__________| |__________|   |__________| |__________| */
+  -14,   -5,     /*      \     ___      /           \      ___     /      */
+   15,  -18,     /*       \   /   \    /    _____    \    /   \   /       */
+    6,    7,     /*        `->| + |<--'    /     \    `-->| + |<-'        */
+   15,  -10,     /*           \___/      _/       \_      \___/           */
+  -14,   22,     /*               \     / \       / \     /               */
+   -7,   -2,     /*                `--->| |       | |<---'                */
+   -4,    9,     /*                     \_/       \_/                     */
+    6,  -12,     /*                                                       */
+    6,   -6,     /*                       Headphones                      */
+    0,  -11,
+    0,   -5,
+    4,    0};
+
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+static int  Open( vlc_object_t * );
+static block_t *DoWork( filter_t *, block_t * );
+
+static int Open( vlc_object_t *p_this)
+{
+    filter_t *p_filter = (filter_t*)p_this;
+	 
+     if ( p_filter->fmt_in.audio.i_rate != p_filter->fmt_out.audio.i_rate
+          || p_filter->fmt_in.audio.i_format != p_filter->fmt_out.audio.i_format
+          || p_filter->fmt_in.audio.i_physical_channels
+          != p_filter->fmt_out.audio.i_physical_channels)
+    {
+       return VLC_EGENERIC;
+    }
+    p_filter->pf_audio_filter = DoWork;
+    return VLC_SUCCESS;
+}
+
+static block_t *DoWork(filter * p_filter, block_t * p_in_buf)
+{
+    if(aout_FormatNbChannels(&p_filter->fmt_in.audio)!=2)
+	return p_in_buf; /*******Only Work For Two Channels**********/
+    
+    block_t * p_out_buf = p_in_buf;
+    
+    unsigned char *p_out = p_out_buf->p_buffer;
+    unsigned char *p_in = p_in_buf->p_buffer;
+    
+    unsigned int i_out_nb = p_in_buf->i_nb_samples;
+    
+    double tab[FIR_Length];
+    
+    for(int i=0; i<FIR_Length; i++)
+    {
+       tab[i] = 0.0;
+    }  
+
+    while(i_out_nb--)
+    {
+       double output = 0.0;
+       for(i=FIR_Length-1; i>0; i--)
+       {
+          tab[i] = tab[i-1];
+          output += tab[i] * FIR[i];
+       }
+       tab[0] = *p_in++ / 64;
+       output += tab[0] * fir[0];
+       *p_out++ = output;
+    }
+    
+    return p_out_buf;
+}
-- 
1.6.3.3

