]> git.sesse.net Git - vlc/commitdiff
Spatializer audio filter, work for Google Summer of Code, by Isaac Biodun Osunkunle...
authorJean-Baptiste Kempf <jb@videolan.org>
Sat, 1 Sep 2007 11:30:58 +0000 (11:30 +0000)
committerJean-Baptiste Kempf <jb@videolan.org>
Sat, 1 Sep 2007 11:30:58 +0000 (11:30 +0000)
This is the first part of his work.

modules/audio_filter/spatializer/Modules.am [new file with mode: 0644]
modules/audio_filter/spatializer/allpass.cpp [new file with mode: 0644]
modules/audio_filter/spatializer/allpass.hpp [new file with mode: 0644]
modules/audio_filter/spatializer/comb.cpp [new file with mode: 0644]
modules/audio_filter/spatializer/comb.hpp [new file with mode: 0644]
modules/audio_filter/spatializer/denormals.h [new file with mode: 0644]
modules/audio_filter/spatializer/revmodel.cpp [new file with mode: 0644]
modules/audio_filter/spatializer/revmodel.hpp [new file with mode: 0644]
modules/audio_filter/spatializer/spatializer.cpp [new file with mode: 0644]
modules/audio_filter/spatializer/tuning.h [new file with mode: 0644]

diff --git a/modules/audio_filter/spatializer/Modules.am b/modules/audio_filter/spatializer/Modules.am
new file mode 100644 (file)
index 0000000..0406a5f
--- /dev/null
@@ -0,0 +1,4 @@
+SOURCES_spatializer = spatializer.cpp \
+    allpass.cpp allpass.hpp comb.cpp comb.hpp \
+    denormals.h tuning.h revmodel.cpp revmodel.hpp
+
diff --git a/modules/audio_filter/spatializer/allpass.cpp b/modules/audio_filter/spatializer/allpass.cpp
new file mode 100644 (file)
index 0000000..5d80eda
--- /dev/null
@@ -0,0 +1,36 @@
+// Allpass filter implementation
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+#include "allpass.hpp"
+
+allpass::allpass()
+{
+       bufidx = 0;
+}
+
+void allpass::setbuffer(float *buf, int size) 
+{
+       buffer = buf; 
+       bufsize = size;
+}
+
+void allpass::mute()
+{
+       for (int i=0; i<bufsize; i++)
+               buffer[i]=0;
+}
+
+void allpass::setfeedback(float val) 
+{
+       feedback = val;
+}
+
+float allpass::getfeedback() 
+{
+       return feedback;
+}
+
+//ends
\ No newline at end of file
diff --git a/modules/audio_filter/spatializer/allpass.hpp b/modules/audio_filter/spatializer/allpass.hpp
new file mode 100644 (file)
index 0000000..ed2df99
--- /dev/null
@@ -0,0 +1,48 @@
+// Allpass filter declaration
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+#ifndef _allpass_
+#define _allpass_
+#include "denormals.h"
+
+class allpass
+{
+public:
+        allpass();
+       void    setbuffer(float *buf, int size);
+       inline  float   process(float inp);
+       void    mute();
+       void    setfeedback(float val);
+       float   getfeedback();
+// private:
+       float   feedback;
+       float   *buffer;
+       int     bufsize;
+       int     bufidx;
+};
+
+
+// Big to inline - but crucial for speed
+
+inline float allpass::process(float input)
+{
+       float output;
+       float bufout;
+       
+       bufout = buffer[bufidx];
+       undenormalise(bufout);
+       
+       output = -input + bufout;
+       buffer[bufidx] = input + (bufout*feedback);
+
+       if(++bufidx>=bufsize) bufidx = 0;
+
+       return output;
+}
+
+#endif//_allpass
+
+//ends
diff --git a/modules/audio_filter/spatializer/comb.cpp b/modules/audio_filter/spatializer/comb.cpp
new file mode 100644 (file)
index 0000000..c05f506
--- /dev/null
@@ -0,0 +1,48 @@
+// Comb filter implementation
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+#include "comb.hpp"
+
+comb::comb()
+{
+       filterstore = 0;
+       bufidx = 0;
+}
+
+void comb::setbuffer(float *buf, int size) 
+{
+       buffer = buf; 
+       bufsize = size;
+}
+
+void comb::mute()
+{
+       for (int i=0; i<bufsize; i++)
+               buffer[i]=0;
+}
+
+void comb::setdamp(float val) 
+{
+       damp1 = val; 
+       damp2 = 1-val;
+}
+
+float comb::getdamp() 
+{
+       return damp1;
+}
+
+void comb::setfeedback(float val) 
+{
+       feedback = val;
+}
+
+float comb::getfeedback() 
+{
+       return feedback;
+}
+
+// ends
diff --git a/modules/audio_filter/spatializer/comb.hpp b/modules/audio_filter/spatializer/comb.hpp
new file mode 100644 (file)
index 0000000..94f6d40
--- /dev/null
@@ -0,0 +1,55 @@
+// Comb filter class declaration
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+#ifndef _comb_
+#define _comb_
+
+#include "denormals.h"
+
+class comb
+{
+public:
+       comb();
+       void    setbuffer(float *buf, int size);
+       inline  float   process(float inp);
+       void    mute();
+       void    setdamp(float val);
+       float   getdamp();
+       void    setfeedback(float val);
+       float   getfeedback();
+private:
+       float   feedback;
+       float   filterstore;
+       float   damp1;
+       float   damp2;
+       float   *buffer;
+       int     bufsize;
+       int     bufidx;
+};
+
+
+// Big to inline - but crucial for speed
+
+inline float comb::process(float input)
+{
+       float output;
+
+       output = buffer[bufidx];
+       undenormalise(output);
+
+       filterstore = (output*damp2) + (filterstore*damp1);
+       undenormalise(filterstore);
+
+       buffer[bufidx] = input + (filterstore*feedback);
+
+       if(++bufidx>=bufsize) bufidx = 0;
+
+       return output;
+}
+
+#endif //_comb_
+
+//ends
diff --git a/modules/audio_filter/spatializer/denormals.h b/modules/audio_filter/spatializer/denormals.h
new file mode 100644 (file)
index 0000000..f871412
--- /dev/null
@@ -0,0 +1,15 @@
+// Macro for killing denormalled numbers
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// Based on IS_DENORMAL macro by Jon Watte
+// This code is public domain
+
+#ifndef _denormals_
+#define _denormals_
+
+#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0f
+
+#endif//_denormals_
+
+//ends
diff --git a/modules/audio_filter/spatializer/revmodel.cpp b/modules/audio_filter/spatializer/revmodel.cpp
new file mode 100644 (file)
index 0000000..059c374
--- /dev/null
@@ -0,0 +1,257 @@
+// Reverb model implementation
+// 
+// 
+// Google Summer of Code 2007
+// 
+// Authors: Biodun Osunkunle <biodun@videolan.org> 
+// 
+// Mentor : Jean-Baptiste Kempf <jb@videolan.org>
+//
+// Original written by Jezar at Dreampoint, June 2000
+
+// This code is public domain
+
+#include "revmodel.hpp"
+#include <stdlib.h>
+
+revmodel::revmodel()
+{
+       // Tie the components to their buffers
+       combL[0].setbuffer(bufcombL1,combtuningL1);
+       combR[0].setbuffer(bufcombR1,combtuningR1);
+       combL[1].setbuffer(bufcombL2,combtuningL2);
+       combR[1].setbuffer(bufcombR2,combtuningR2);
+       combL[2].setbuffer(bufcombL3,combtuningL3);
+       combR[2].setbuffer(bufcombR3,combtuningR3);
+       combL[3].setbuffer(bufcombL4,combtuningL4);
+       combR[3].setbuffer(bufcombR4,combtuningR4);
+       combL[4].setbuffer(bufcombL5,combtuningL5);
+       combR[4].setbuffer(bufcombR5,combtuningR5);
+       combL[5].setbuffer(bufcombL6,combtuningL6);
+       combR[5].setbuffer(bufcombR6,combtuningR6);
+       combL[6].setbuffer(bufcombL7,combtuningL7);
+       combR[6].setbuffer(bufcombR7,combtuningR7);
+       combL[7].setbuffer(bufcombL8,combtuningL8);
+       combR[7].setbuffer(bufcombR8,combtuningR8);
+       allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
+       allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
+       allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
+       allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
+       allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
+       allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
+       allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
+       allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
+
+       // Set default values
+       allpassL[0].setfeedback(0.5f);
+       allpassR[0].setfeedback(0.5f);
+       allpassL[1].setfeedback(0.5f);
+       allpassR[1].setfeedback(0.5f);
+       allpassL[2].setfeedback(0.5f);
+       allpassR[2].setfeedback(0.5f);
+       allpassL[3].setfeedback(0.5f);
+       allpassR[3].setfeedback(0.5f);
+       setwet(initialwet);
+       setroomsize(initialroom);
+       setdry(initialdry);
+       setdamp(initialdamp);
+       setwidth(initialwidth);
+       setmode(initialmode);
+
+       // Buffer will be full of rubbish - so we MUST mute them
+       mute();
+}
+
+void revmodel::mute()
+{
+       int i;
+       if (getmode() >= freezemode)
+               return;
+
+       for (i = 0 ; i < numcombs ; i++)
+       {
+               combL[i].mute();
+               combR[i].mute();
+       }
+       for (i=0;i<numallpasses;i++)
+       {
+               allpassL[i].mute();
+               allpassR[i].mute();
+       }
+}
+
+void revmodel::processreplace(float *inputL, float *outputL, long numsamples, int skip)
+{
+       float outL,outR,input;
+       float inputR;
+       int i;
+
+       outL = outR = 0;
+        if (skip > 1) 
+           inputR = inputL[1];
+        else 
+           inputR = inputL[0];         
+               input = (inputL[0] + inputR) * gain;
+               
+               // Accumulate comb filters in parallel
+               for(i=0; i<numcombs; i++)
+               {
+                       outL += combL[i].process(input);
+                       outR += combR[i].process(input);
+               }
+
+               // Feed through allpasses in series
+               for(i=0; i<numallpasses; i++)
+               {
+                       outL = allpassL[i].process(outL);
+                       outR = allpassR[i].process(outR);
+               }
+
+               // Calculate output REPLACING anything already there
+               outputL[0] = (outL*wet1 + outR*wet2 + inputR*dry);
+           if (skip > 1)
+               outputL[1] = (outR*wet1 + outL*wet2 + inputR*dry);
+}
+
+void revmodel::processmix(float *inputL, float *outputL, long numsamples, int skip)
+{
+       float outL,outR,input;
+       float inputR;
+       int i;
+
+       outL = outR = 0;
+        if (skip > 1) 
+           inputR = inputL[1];
+        else 
+           inputR = inputL[0];         
+               input = (inputL[0] + inputR) * gain;
+               
+               // Accumulate comb filters in parallel
+               for(i=0; i<numcombs; i++)
+               {
+                       outL += combL[i].process(input);
+                       outR += combR[i].process(input);
+               }
+
+               // Feed through allpasses in series
+               for(i=0; i<numallpasses; i++)
+               {
+                       outL = allpassL[i].process(outL);
+                       outR = allpassR[i].process(outR);
+               }
+
+               // Calculate output REPLACING anything already there
+               outputL[0] += (outL*wet1 + outR*wet2 + inputR*dry);
+           if (skip > 1)
+               outputL[1] += (outR*wet1 + outL*wet2 + inputR*dry);
+}
+
+void revmodel::update()
+{
+// Recalculate internal values after parameter change
+
+       int i;
+
+       wet1 = wet*(width/2 + 0.5f);
+       wet2 = wet*((1-width)/2);
+
+       if (mode >= freezemode)
+       {
+               roomsize1 = 1;
+               damp1 = 0;
+               gain = muted;
+       }
+       else
+       {
+               roomsize1 = roomsize;
+               damp1 = damp;
+               gain = fixedgain;
+       }
+
+       for(i=0; i<numcombs; i++)
+       {
+               combL[i].setfeedback(roomsize1);
+               combR[i].setfeedback(roomsize1);
+       }
+
+       for(i=0; i<numcombs; i++)
+       {
+               combL[i].setdamp(damp1);
+               combR[i].setdamp(damp1);
+       }
+}
+
+// The following get/set functions are not inlined, because
+// speed is never an issue when calling them, and also
+// because as you develop the reverb model, you may
+// wish to take dynamic action when they are called.
+
+void revmodel::setroomsize(float value)
+{
+       roomsize = (value*scaleroom) + offsetroom;
+       update();
+}
+
+float revmodel::getroomsize()
+{
+       return (roomsize-offsetroom)/scaleroom;
+}
+
+void revmodel::setdamp(float value)
+{
+       damp = value*scaledamp;
+       update();
+}
+
+float revmodel::getdamp()
+{
+       return damp/scaledamp;
+}
+
+void revmodel::setwet(float value)
+{
+       wet = value*scalewet;
+       update();
+}
+
+float revmodel::getwet()
+{
+       return wet/scalewet;
+}
+
+void revmodel::setdry(float value)
+{
+       dry = value*scaledry;
+}
+
+float revmodel::getdry()
+{
+       return dry/scaledry;
+}
+
+void revmodel::setwidth(float value)
+{
+       width = value;
+       update();
+}
+
+float revmodel::getwidth()
+{
+       return width;
+}
+
+void revmodel::setmode(float value)
+{
+       mode = value;
+       update();
+}
+
+float revmodel::getmode()
+{
+       if (mode >= freezemode)
+               return 1;
+       else
+               return 0;
+}
+
+//ends
diff --git a/modules/audio_filter/spatializer/revmodel.hpp b/modules/audio_filter/spatializer/revmodel.hpp
new file mode 100644 (file)
index 0000000..cd4efda
--- /dev/null
@@ -0,0 +1,91 @@
+// Reverb model declaration
+//
+// Google Summer of Code 2007
+// 
+// Authors: Biodun Osunkunle <biodun@videolan.org> 
+// 
+// Mentor : Jean-Baptiste Kempf <jb@videolan.org>
+//
+// Original written by Jezar at Dreampoint, June 2000
+
+#ifndef _revmodel_
+#define _revmodel_
+
+#include "comb.hpp"
+#include "allpass.hpp"
+#include "tuning.h"
+
+class revmodel
+{
+public:
+               revmodel();
+       void    mute();
+       void    processreplace(float *inputL, float *outputL, long numsamples, int skip);
+       void    processmix(float *inputL, float *outputL, long numsamples, int skip);
+       void    setroomsize(float value);
+       float   getroomsize();
+       void    setdamp(float value);
+       float   getdamp();
+       void    setwet(float value);
+       float   getwet();
+       void    setdry(float value);
+       float   getdry();
+       void    setwidth(float value);
+       float   getwidth();
+       void    setmode(float value);
+       float   getmode();
+private:
+       void    update();
+private:
+       float   gain;
+       float   roomsize,roomsize1;
+       float   damp,damp1;
+       float   wet,wet1,wet2;
+       float   dry;
+       float   width;
+       float   mode;
+
+// The following are all declared inline 
+// to remove the need for dynamic allocation
+// with its subsequent error-checking messiness
+
+// Comb filters
+       comb    combL[numcombs];
+       comb    combR[numcombs];
+
+       // Allpass filters
+       allpass allpassL[numallpasses];
+       allpass allpassR[numallpasses];
+
+       // Buffers for the combs
+       float   bufcombL1[combtuningL1];
+       float   bufcombR1[combtuningR1];
+       float   bufcombL2[combtuningL2];
+       float   bufcombR2[combtuningR2];
+       float   bufcombL3[combtuningL3];
+       float   bufcombR3[combtuningR3];
+       float   bufcombL4[combtuningL4];
+       float   bufcombR4[combtuningR4];
+       float   bufcombL5[combtuningL5];
+       float   bufcombR5[combtuningR5];
+       float   bufcombL6[combtuningL6];
+       float   bufcombR6[combtuningR6];
+       float   bufcombL7[combtuningL7];
+       float   bufcombR7[combtuningR7];
+       float   bufcombL8[combtuningL8];
+       float   bufcombR8[combtuningR8];
+
+       // Buffers for the allpasses
+       float   bufallpassL1[allpasstuningL1];
+       float   bufallpassR1[allpasstuningR1];
+       float   bufallpassL2[allpasstuningL2];
+       float   bufallpassR2[allpasstuningR2];
+       float   bufallpassL3[allpasstuningL3];
+       float   bufallpassR3[allpasstuningR3];
+       float   bufallpassL4[allpasstuningL4];
+       float   bufallpassR4[allpasstuningR4];
+};
+
+#endif//_revmodel_
+
+//ends
diff --git a/modules/audio_filter/spatializer/spatializer.cpp b/modules/audio_filter/spatializer/spatializer.cpp
new file mode 100644 (file)
index 0000000..20f0473
--- /dev/null
@@ -0,0 +1,272 @@
+/*****************************************************************************
+ * spatializer.cpp:
+ *****************************************************************************
+ * Copyright (C) 2004, 2006, 2007 the VideoLAN team
+ * 
+ * Google Summer of Code 2007
+ * 
+ * Authors: Biodun Osunkunle <biodun@videolan.org> 
+ * 
+ * Mentor : Jean-Baptiste Kempf <jb@videolan.org>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <math.h>
+
+#include <vlc/vlc.h>
+#include "vlc_aout.h"
+#include "revmodel.hpp"
+#define SPAT_AMP 0.3
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+static int  Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
+
+vlc_module_begin();
+    set_description( _("spatializer") );
+    set_shortname( _("spatializer" ) );
+    set_capability( "audio filter", 0 );
+    set_category( CAT_AUDIO );
+    set_subcategory( SUBCAT_AUDIO_AFILTER );
+
+    set_callbacks( Open, Close );
+    add_shortcut( "spatializer" );
+    add_float( "Roomsize", 1.05, NULL, NULL,NULL, VLC_TRUE);
+    add_float( "Width", 10.0, NULL, NULL,NULL, VLC_TRUE);
+    add_float( "Wet", 3.0, NULL, NULL,NULL, VLC_TRUE);
+    add_float( "Dry", 2.0, NULL, NULL,NULL, VLC_TRUE);
+    add_float( "Damp", 1.0, NULL, NULL,NULL, VLC_TRUE);
+vlc_module_end();
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+typedef struct aout_filter_sys_t
+{
+    /* reverb static config */
+    vlc_bool_t b_first;
+    
+} aout_filter_sys_t;
+
+static revmodel reverbm;
+    
+static const char *psz_control_names[] =
+{
+    "Roomsize", "Width" , "Wet", "Dry", "Damp"
+};
+static void DoWork( aout_instance_t *, aout_filter_t *,
+                    aout_buffer_t *, aout_buffer_t * );
+
+static int  SpatInit( aout_filter_t *);
+static void SpatFilter( aout_instance_t *,aout_filter_t *, float *, float *,
+                        int, int );
+static void SpatClean( aout_filter_t * );
+static int RoomCallback ( vlc_object_t *, char const *,
+                                           vlc_value_t, vlc_value_t, void * );
+static int WetCallback ( vlc_object_t *, char const *,
+                                           vlc_value_t, vlc_value_t, void * );
+static int DryCallback ( vlc_object_t *, char const *,
+                                           vlc_value_t, vlc_value_t, void * );
+static int DampCallback ( vlc_object_t *, char const *,
+                                           vlc_value_t, vlc_value_t, void * );
+static int WidthCallback ( vlc_object_t *, char const *,
+                                           vlc_value_t, vlc_value_t, void * );                                                                                                                                 
+/*****************************************************************************
+ * Open:
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+    aout_filter_t     *p_filter = (aout_filter_t *)p_this;
+    aout_filter_sys_t *p_sys;
+    vlc_bool_t         b_fit = VLC_TRUE;
+    msg_Dbg(p_this, "Opening filter spatializer %s %s %d\n", __FILE__,__func__,__LINE__);
+
+    if( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' ) ||
+        p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
+    {
+        b_fit = VLC_FALSE;
+        p_filter->input.i_format = VLC_FOURCC('f','l','3','2');
+        p_filter->output.i_format = VLC_FOURCC('f','l','3','2');
+        msg_Warn( p_filter, "bad input or output format" );
+    }
+    if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
+    {
+        b_fit = VLC_FALSE;
+        memcpy( &p_filter->output, &p_filter->input,
+                sizeof(audio_sample_format_t) );
+        msg_Warn( p_filter, "input and output formats are not similar" );
+    }
+
+    if ( ! b_fit )
+    {
+        return VLC_EGENERIC;
+    }
+
+    p_filter->pf_do_work = DoWork;
+    p_filter->b_in_place = VLC_TRUE;
+    
+     /* Allocate structure */    
+    p_sys = p_filter->p_sys = (aout_filter_sys_t*)malloc( sizeof( aout_filter_sys_t ) );
+    reverbm.setroomsize(1.05);
+    reverbm.setwet(10.0f);
+    reverbm.setdry(1.0f);
+    reverbm.setdamp(0.3);
+    reverbm.setwidth(0.9);
+    SpatInit( p_filter);
+    
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close: close the plugin
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this ) 
+{
+    aout_filter_t     *p_filter = (aout_filter_t *)p_this;
+    aout_filter_sys_t *p_sys = p_filter->p_sys;
+    SpatClean( p_filter );
+    free( p_sys );
+    msg_Dbg(p_this, "Closing filter spatializer %s %s %d\n", __FILE__,__func__,__LINE__);
+}
+
+/*****************************************************************************
+ * DoWork: process samples buffer
+ *****************************************************************************
+ *
+ *****************************************************************************/
+static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
+                    aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
+{
+    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
+    p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes;
+
+    SpatFilter( p_aout, p_filter, (float*)p_out_buf->p_buffer,
+               (float*)p_in_buf->p_buffer, p_in_buf->i_nb_samples,
+               aout_FormatNbChannels( &p_filter->input ) );
+}
+
+static int SpatInit( aout_filter_t *p_filter )
+{
+    aout_filter_sys_t *p_sys = p_filter->p_sys;
+    int i, ch;
+    vlc_value_t val1, val2, val3, val4, val5;
+    aout_instance_t *p_aout = (aout_instance_t *)p_filter->p_parent;
+    
+    for( int i = 0; i < 5 ; i ++ )
+    {
+     var_CreateGetFloatCommand( p_aout, psz_control_names[i] );
+    }
+
+    /* Get initial values */
+    var_Get( p_aout, psz_control_names[0], &val1 );
+    var_Get( p_aout, psz_control_names[1], &val2 );
+    var_Get( p_aout, psz_control_names[2], &val3 );
+    var_Get( p_aout, psz_control_names[3], &val4 );
+    var_Get( p_aout, psz_control_names[4], &val5);
+
+    RoomCallback( VLC_OBJECT( p_aout ), NULL, val1, val1, p_sys );
+    WidthCallback( VLC_OBJECT( p_aout ), NULL, val2, val2, p_sys );
+    WetCallback( VLC_OBJECT( p_aout ), NULL, val3, val3, p_sys );
+    DryCallback( VLC_OBJECT( p_aout ), NULL, val4, val4, p_sys );
+    DampCallback( VLC_OBJECT( p_aout ), NULL, val5, val5, p_sys );
+
+    msg_Dbg( p_filter, "%f", val1.f_float );
+    /* Add our own callbacks */
+    var_AddCallback( p_aout, psz_control_names[0], RoomCallback, p_sys );
+    var_AddCallback( p_aout, psz_control_names[1], WidthCallback, p_sys );
+    var_AddCallback( p_aout, psz_control_names[2], WetCallback, p_sys );
+    var_AddCallback( p_aout, psz_control_names[3], DryCallback, p_sys );
+    var_AddCallback( p_aout, psz_control_names[4], DampCallback, p_sys );
+    
+    return VLC_SUCCESS;
+}
+
+static void SpatFilter( aout_instance_t *p_aout,
+                       aout_filter_t *p_filter, float *out, float *in,
+                       int i_samples, int i_channels )
+{
+    int i, ch, j;
+    for( i = 0; i < i_samples; i++ )
+    {
+        for( ch = 0 ; ch < 2; ch++)
+        {
+            in[ch] = in[ch] * SPAT_AMP;
+        }
+          reverbm.processreplace( in, out , 1, i_channels);
+         in  += i_channels;
+         out += i_channels;
+    }
+}
+
+static void SpatClean( aout_filter_t *p_filter )
+{
+    aout_filter_sys_t *p_sys = p_filter->p_sys;
+
+    var_DelCallback( (aout_instance_t *)p_filter->p_parent,
+                        "Roomsize", RoomCallback, p_sys );
+    var_DelCallback( (aout_instance_t *)p_filter->p_parent,
+                        "Width", WidthCallback, p_sys );
+    var_DelCallback( (aout_instance_t *)p_filter->p_parent,
+                        "Wet", WetCallback, p_sys );
+    var_DelCallback( (aout_instance_t *)p_filter->p_parent,
+                        "Dry", DryCallback, p_sys );
+    var_DelCallback( (aout_instance_t *)p_filter->p_parent,
+                        "Damp", DampCallback, p_sys );
+
+}
+
+static int RoomCallback( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    msg_Dbg (p_this,"room callback %3.1f %s %s %d\n", newval.f_float, __FILE__,__func__,__LINE__);    
+    reverbm.setroomsize(newval.f_float);
+    return VLC_SUCCESS;
+}
+
+static int WidthCallback( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    reverbm.setwidth(newval.f_float);
+    msg_Dbg (p_this,"width callback %3.1f %s %s %d\n", newval.f_float,  __FILE__,__func__,__LINE__);
+    return VLC_SUCCESS;
+}
+static int WetCallback( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    reverbm.setwet(newval.f_float);
+    msg_Dbg (p_this,"wet callback %3.1f %s %s %d\n", newval.f_float,  __FILE__,__func__,__LINE__);
+    return VLC_SUCCESS;
+}
+static int DryCallback( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    reverbm.setdry(newval.f_float);
+    msg_Dbg (p_this,"dry callback %3.1f %s %s %d\n", newval.f_float, __FILE__,__func__,__LINE__);
+    return VLC_SUCCESS;
+}
+static int DampCallback( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    reverbm.setdamp(newval.f_float);
+    msg_Dbg (p_this, "damp callback %3.1f %s %s %d\n", newval.f_float, __FILE__,__func__,__LINE__);
+    return VLC_SUCCESS;
+}
+
diff --git a/modules/audio_filter/spatializer/tuning.h b/modules/audio_filter/spatializer/tuning.h
new file mode 100644 (file)
index 0000000..9c4e6ca
--- /dev/null
@@ -0,0 +1,60 @@
+// Reverb model tuning values
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+#ifndef _tuning_
+#define _tuning_
+
+const int   numcombs           = 8;
+const int   numallpasses       = 4;
+const float muted              = 0;
+const float fixedgain          = 0.005f;
+const float scalewet           = 3;
+const float scaledry           = 2;
+const float scaledamp          = 0.4f;
+const float scaleroom          = 0.28f;
+const float offsetroom         = 0.7f;
+const float initialroom                = 0.5f;
+const float initialdamp                = 0.5f;
+const float initialwet         = 1/scalewet;
+const float initialdry         = 0;
+const float initialwidth       = 1;
+const float initialmode                = 0;
+const float freezemode         = 0.5f;
+const int   stereospread       = 23;
+
+// These values assume 44.1KHz sample rate
+// they will probably be OK for 48KHz sample rate
+// but would need scaling for 96KHz (or other) sample rates.
+// The values were obtained by listening tests.
+const int combtuningL1         = 1116;
+const int combtuningR1         = 1116+stereospread;
+const int combtuningL2         = 1188;
+const int combtuningR2         = 1188+stereospread;
+const int combtuningL3         = 1277;
+const int combtuningR3         = 1277+stereospread;
+const int combtuningL4         = 1356;
+const int combtuningR4         = 1356+stereospread;
+const int combtuningL5         = 1422;
+const int combtuningR5         = 1422+stereospread;
+const int combtuningL6         = 1491;
+const int combtuningR6         = 1491+stereospread;
+const int combtuningL7         = 1557;
+const int combtuningR7         = 1557+stereospread;
+const int combtuningL8         = 1617;
+const int combtuningR8         = 1617+stereospread;
+const int allpasstuningL1      = 556;
+const int allpasstuningR1      = 556+stereospread;
+const int allpasstuningL2      = 441;
+const int allpasstuningR2      = 441+stereospread;
+const int allpasstuningL3      = 341;
+const int allpasstuningR3      = 341+stereospread;
+const int allpasstuningL4      = 225;
+const int allpasstuningR4      = 225+stereospread;
+
+#endif//_tuning_
+
+//ends
+