changeset 3631:5f5189ac6a41

Added plugin for fractional resampling (alpha code)
author anders
date Thu, 20 Dec 2001 15:30:22 +0000
parents f24527fc1b79
children 06911836febd
files cfg-mplayer.h libao2/Makefile libao2/audio_plugin.h libao2/filter.h libao2/fir.h libao2/pl_resample.c
diffstat 6 files changed, 615 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/cfg-mplayer.h	Thu Dec 20 08:02:38 2001 +0000
+++ b/cfg-mplayer.h	Thu Dec 20 15:30:22 2001 +0000
@@ -83,6 +83,7 @@
 	{"list", &ao_plugin_cfg.plugin_list, CONF_TYPE_STRING, 0, 0, 0},
 	{"delay", &ao_plugin_cfg.pl_delay_len, CONF_TYPE_INT, CONF_MIN, 0, 0},
 	{"format", &ao_plugin_cfg.pl_format_type, CONF_TYPE_INT, CONF_MIN, 0, 0},
+	{"fout", &ao_plugin_cfg.pl_resample_fout, CONF_TYPE_INT, CONF_MIN, 0, 0},
 	{NULL, NULL, 0, 0, 0, 0}
 };
 
--- a/libao2/Makefile	Thu Dec 20 08:02:38 2001 +0000
+++ b/libao2/Makefile	Thu Dec 20 15:30:22 2001 +0000
@@ -4,7 +4,8 @@
 LIBNAME = libao2.a
 
 # TODO: moveout ao_sdl.c so it's only used when SDL is detected
-SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c pl_format.c pl_surround.c remez.c $(OPTIONAL_SRCS)
+SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c pl_format.c pl_surround.c remez.c pl_resample.c $(OPTIONAL_SRCS)
+
 OBJS=$(SRCS:.c=.o)
 
 CFLAGS  = $(OPTFLAGS) -I. -I.. $(SDL_INC) $(X11_INC) $(EXTRA_INC)
--- a/libao2/audio_plugin.h	Thu Dec 20 08:02:38 2001 +0000
+++ b/libao2/audio_plugin.h	Thu Dec 20 15:30:22 2001 +0000
@@ -34,6 +34,7 @@
   char* plugin_list; 	// List of used plugins read from cfg
   int pl_format_type;	// Output format
   int pl_delay_len;	// Number of samples to delay sound output
+  int pl_resample_fout;	// Output frequency from resampling
 } ao_plugin_cfg_t;
 
 extern volatile ao_plugin_cfg_t ao_plugin_cfg;
@@ -42,23 +43,26 @@
 #define CFG_DEFAULTS { \
  NULL, \
  AFMT_S16_LE, \
- 0 \
+ 0, \
+ 48000 \
 };
 
 // This block should not be available in the pl_xxxx files
 // due to compilation issues
 #ifndef PLUGIN
-#define NPL 3+1 // Number of PLugins ( +1 list ends with NULL )
+#define NPL 4+1 // Number of PLugins ( +1 list ends with NULL )
 // List of plugins 
 extern ao_plugin_functions_t audio_plugin_delay;
 extern ao_plugin_functions_t audio_plugin_format; 
 extern ao_plugin_functions_t audio_plugin_surround;
+extern ao_plugin_functions_t audio_plugin_resample;
 
 
 #define AO_PLUGINS { \
    &audio_plugin_delay, \
    &audio_plugin_format, \
    &audio_plugin_surround, \
+   &audio_plugin_resample, \
    NULL \
 }
 #endif /* PLUGIN */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libao2/filter.h	Thu Dec 20 15:30:22 2001 +0000
@@ -0,0 +1,223 @@
+/*=============================================================================
+//	
+//  This file is part of mplayer.
+//
+//  mplayer 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.
+//
+//  mplayer 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 mplayer; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
+//
+//=============================================================================
+*/
+
+/* Polyphase filters. Designed using window method and kaiser window
+   with beta=10. */
+
+#define W4 { \
+0, 36, 32767, -35, 0, 113, 32756, -103, \
+0, 193, 32733, -167, 0, 278, 32699, -227, \
+0, 367, 32654, -282, -1, 461, 32597, -335, \
+-1, 560, 32530, -383, -1, 664, 32451, -429, \
+-1, 772, 32361, -470, -2, 886, 32260, -509, \
+-2, 1004, 32148, -544, -2, 1128, 32026, -577, \
+-3, 1257, 31892, -606, -4, 1392, 31749, -633, \
+-4, 1532, 31594, -657, -5, 1677, 31430, -678, \
+-6, 1828, 31255, -697, -7, 1985, 31070, -713, \
+-8, 2147, 30876, -727, -9, 2315, 30671, -739, \
+-10, 2489, 30457, -749, -11, 2668, 30234, -756, \
+-13, 2854, 30002, -762, -14, 3045, 29761, -766, \
+-16, 3243, 29511, -769, -18, 3446, 29252, -769, \
+-20, 3656, 28985, -769, -22, 3871, 28710, -766, \
+-25, 4093, 28427, -763, -27, 4320, 28137, -758, \
+-30, 4553, 27839, -752, -33, 4793, 27534, -745, \
+-36, 5038, 27222, -737, -39, 5290, 26904, -727, \
+-43, 5547, 26579, -717, -47, 5811, 26248, -707, \
+-51, 6080, 25911, -695, -55, 6355, 25569, -683, \
+-60, 6636, 25221, -670, -65, 6922, 24868, -657, \
+-70, 7214, 24511, -643, -76, 7512, 24149, -628, \
+-81, 7815, 23782, -614, -87, 8124, 23412, -599, \
+-94, 8437, 23038, -583, -101, 8757, 22661, -568, \
+-108, 9081, 22281, -552, -115, 9410, 21898, -537, \
+-123, 9744, 21513, -521, -131, 10082, 21125, -505, \
+-139, 10425, 20735, -489, -148, 10773, 20344, -473, \
+-157, 11125, 19951, -457, -166, 11481, 19557, -441, \
+-176, 11841, 19162, -426, -186, 12205, 18767, -410, \
+-197, 12572, 18372, -395, -208, 12942, 17976, -380, \
+-219, 13316, 17581, -365, -231, 13693, 17186, -350, \
+-243, 14073, 16791, -336, -255, 14455, 16398, -321, \
+-268, 14840, 16006, -307, -281, 15227, 15616, -294, \
+-294, 15616, 15227, -281, -307, 16006, 14840, -268, \
+-321, 16398, 14455, -255, -336, 16791, 14073, -243, \
+-350, 17186, 13693, -231, -365, 17581, 13316, -219, \
+-380, 17976, 12942, -208, -395, 18372, 12572, -197, \
+-410, 18767, 12205, -186, -426, 19162, 11841, -176, \
+-441, 19557, 11481, -166, -457, 19951, 11125, -157, \
+-473, 20344, 10773, -148, -489, 20735, 10425, -139, \
+-505, 21125, 10082, -131, -521, 21513, 9744, -123, \
+-537, 21898, 9410, -115, -552, 22281, 9081, -108, \
+-568, 22661, 8757, -101, -583, 23038, 8437, -94, \
+-599, 23412, 8124, -87, -614, 23782, 7815, -81, \
+-628, 24149, 7512, -76, -643, 24511, 7214, -70, \
+-657, 24868, 6922, -65, -670, 25221, 6636, -60, \
+-683, 25569, 6355, -55, -695, 25911, 6080, -51, \
+-707, 26248, 5811, -47, -717, 26579, 5547, -43, \
+-727, 26904, 5290, -39, -737, 27222, 5038, -36, \
+-745, 27534, 4793, -33, -752, 27839, 4553, -30, \
+-758, 28137, 4320, -27, -763, 28427, 4093, -25, \
+-766, 28710, 3871, -22, -769, 28985, 3656, -20, \
+-769, 29252, 3446, -18, -769, 29511, 3243, -16, \
+-766, 29761, 3045, -14, -762, 30002, 2854, -13, \
+-756, 30234, 2668, -11, -749, 30457, 2489, -10, \
+-739, 30671, 2315, -9, -727, 30876, 2147, -8, \
+-713, 31070, 1985, -7, -697, 31255, 1828, -6, \
+-678, 31430, 1677, -5, -657, 31594, 1532, -4, \
+-633, 31749, 1392, -4, -606, 31892, 1257, -3, \
+-577, 32026, 1128, -2, -544, 32148, 1004, -2, \
+-509, 32260, 886, -2, -470, 32361, 772, -1, \
+-429, 32451, 664, -1, -383, 32530, 560, -1, \
+-335, 32597, 461, -1, -282, 32654, 367, 0, \
+-227, 32699, 278, 0, -167, 32733, 193, 0, \
+-103, 32756, 113, 0, -35, 32767, 36, 0, \
+}
+
+#define W8 { \
+0, 2, -18, 95, 32767, -94, 18, -2, \
+0, 6, -55, 289, 32759, -279, 53, -5, \
+0, 9, -93, 488, 32744, -458, 87, -8, \
+0, 13, -132, 692, 32720, -633, 120, -11, \
+0, 18, -173, 900, 32689, -804, 151, -14, \
+0, 22, -214, 1113, 32651, -969, 182, -17, \
+0, 27, -256, 1331, 32604, -1130, 212, -20, \
+0, 31, -299, 1553, 32550, -1286, 241, -22, \
+0, 36, -343, 1780, 32488, -1437, 268, -25, \
+0, 41, -389, 2011, 32419, -1583, 295, -27, \
+-1, 47, -435, 2247, 32342, -1724, 320, -29, \
+-1, 52, -482, 2488, 32257, -1861, 345, -31, \
+-1, 58, -530, 2733, 32165, -1993, 368, -32, \
+-1, 64, -579, 2982, 32066, -2121, 391, -34, \
+-1, 70, -629, 3236, 31959, -2243, 412, -36, \
+-1, 76, -679, 3494, 31844, -2361, 433, -37, \
+-1, 82, -731, 3756, 31723, -2475, 452, -38, \
+-1, 89, -783, 4022, 31594, -2583, 471, -40, \
+-2, 96, -837, 4293, 31458, -2688, 488, -41, \
+-2, 102, -891, 4567, 31315, -2787, 505, -42, \
+-2, 110, -946, 4846, 31164, -2883, 521, -42, \
+-2, 117, -1001, 5128, 31007, -2973, 535, -43, \
+-2, 124, -1057, 5414, 30843, -3060, 549, -44, \
+-3, 132, -1114, 5704, 30672, -3142, 562, -44, \
+-3, 140, -1172, 5998, 30495, -3219, 574, -45, \
+-3, 148, -1230, 6295, 30311, -3292, 585, -45, \
+-3, 156, -1289, 6596, 30120, -3362, 596, -46, \
+-4, 164, -1349, 6900, 29923, -3426, 605, -46, \
+-4, 173, -1408, 7208, 29719, -3487, 614, -46, \
+-4, 181, -1469, 7519, 29509, -3544, 621, -46, \
+-4, 190, -1530, 7832, 29294, -3597, 628, -46, \
+-5, 199, -1591, 8149, 29072, -3645, 635, -46, \
+-5, 208, -1652, 8469, 28844, -3690, 640, -46, \
+-6, 217, -1714, 8792, 28610, -3731, 645, -46, \
+-6, 227, -1777, 9118, 28371, -3768, 649, -45, \
+-6, 236, -1839, 9446, 28126, -3801, 652, -45, \
+-7, 246, -1902, 9776, 27875, -3831, 655, -45, \
+-7, 255, -1964, 10109, 27620, -3857, 657, -44, \
+-8, 265, -2027, 10445, 27359, -3880, 658, -44, \
+-8, 275, -2090, 10782, 27092, -3899, 659, -43, \
+-9, 285, -2153, 11121, 26821, -3915, 659, -43, \
+-9, 295, -2216, 11463, 26546, -3927, 658, -42, \
+-10, 306, -2278, 11806, 26265, -3936, 657, -42, \
+-10, 316, -2341, 12151, 25980, -3942, 655, -41, \
+-11, 326, -2403, 12497, 25690, -3945, 653, -40, \
+-11, 337, -2465, 12845, 25396, -3945, 650, -40, \
+-12, 347, -2526, 13194, 25098, -3941, 647, -39, \
+-12, 358, -2588, 13544, 24796, -3935, 643, -38, \
+-13, 368, -2648, 13896, 24490, -3926, 639, -38, \
+-14, 379, -2708, 14248, 24181, -3914, 634, -37, \
+-14, 389, -2768, 14601, 23867, -3900, 629, -36, \
+-15, 400, -2827, 14954, 23551, -3883, 623, -35, \
+-16, 410, -2885, 15308, 23231, -3863, 617, -34, \
+-16, 421, -2943, 15662, 22908, -3841, 611, -34, \
+-17, 431, -2999, 16016, 22581, -3817, 604, -33, \
+-18, 442, -3055, 16371, 22252, -3790, 597, -32, \
+-19, 452, -3109, 16725, 21921, -3761, 590, -31, \
+-19, 462, -3163, 17079, 21587, -3730, 582, -30, \
+-20, 472, -3215, 17432, 21250, -3697, 574, -29, \
+-21, 483, -3266, 17785, 20911, -3662, 566, -28, \
+-22, 492, -3316, 18138, 20570, -3624, 558, -28, \
+-23, 502, -3365, 18489, 20227, -3585, 549, -27, \
+-23, 512, -3412, 18839, 19883, -3545, 540, -26, \
+-24, 522, -3458, 19188, 19536, -3502, 531, -25, \
+-25, 531, -3502, 19536, 19188, -3458, 522, -24, \
+-26, 540, -3545, 19883, 18839, -3412, 512, -23, \
+-27, 549, -3585, 20227, 18489, -3365, 502, -23, \
+-28, 558, -3624, 20570, 18138, -3316, 492, -22, \
+-28, 566, -3662, 20911, 17785, -3266, 483, -21, \
+-29, 574, -3697, 21250, 17432, -3215, 472, -20, \
+-30, 582, -3730, 21587, 17079, -3163, 462, -19, \
+-31, 590, -3761, 21921, 16725, -3109, 452, -19, \
+-32, 597, -3790, 22252, 16371, -3055, 442, -18, \
+-33, 604, -3817, 22581, 16016, -2999, 431, -17, \
+-34, 611, -3841, 22908, 15662, -2943, 421, -16, \
+-34, 617, -3863, 23231, 15308, -2885, 410, -16, \
+-35, 623, -3883, 23551, 14954, -2827, 400, -15, \
+-36, 629, -3900, 23867, 14601, -2768, 389, -14, \
+-37, 634, -3914, 24181, 14248, -2708, 379, -14, \
+-38, 639, -3926, 24490, 13896, -2648, 368, -13, \
+-38, 643, -3935, 24796, 13544, -2588, 358, -12, \
+-39, 647, -3941, 25098, 13194, -2526, 347, -12, \
+-40, 650, -3945, 25396, 12845, -2465, 337, -11, \
+-40, 653, -3945, 25690, 12497, -2403, 326, -11, \
+-41, 655, -3942, 25980, 12151, -2341, 316, -10, \
+-42, 657, -3936, 26265, 11806, -2278, 306, -10, \
+-42, 658, -3927, 26546, 11463, -2216, 295, -9, \
+-43, 659, -3915, 26821, 11121, -2153, 285, -9, \
+-43, 659, -3899, 27092, 10782, -2090, 275, -8, \
+-44, 658, -3880, 27359, 10445, -2027, 265, -8, \
+-44, 657, -3857, 27620, 10109, -1964, 255, -7, \
+-45, 655, -3831, 27875, 9776, -1902, 246, -7, \
+-45, 652, -3801, 28126, 9446, -1839, 236, -6, \
+-45, 649, -3768, 28371, 9118, -1777, 227, -6, \
+-46, 645, -3731, 28610, 8792, -1714, 217, -6, \
+-46, 640, -3690, 28844, 8469, -1652, 208, -5, \
+-46, 635, -3645, 29072, 8149, -1591, 199, -5, \
+-46, 628, -3597, 29294, 7832, -1530, 190, -4, \
+-46, 621, -3544, 29509, 7519, -1469, 181, -4, \
+-46, 614, -3487, 29719, 7208, -1408, 173, -4, \
+-46, 605, -3426, 29923, 6900, -1349, 164, -4, \
+-46, 596, -3362, 30120, 6596, -1289, 156, -3, \
+-45, 585, -3292, 30311, 6295, -1230, 148, -3, \
+-45, 574, -3219, 30495, 5998, -1172, 140, -3, \
+-44, 562, -3142, 30672, 5704, -1114, 132, -3, \
+-44, 549, -3060, 30843, 5414, -1057, 124, -2, \
+-43, 535, -2973, 31007, 5128, -1001, 117, -2, \
+-42, 521, -2883, 31164, 4846, -946, 110, -2, \
+-42, 505, -2787, 31315, 4567, -891, 102, -2, \
+-41, 488, -2688, 31458, 4293, -837, 96, -2, \
+-40, 471, -2583, 31594, 4022, -783, 89, -1, \
+-38, 452, -2475, 31723, 3756, -731, 82, -1, \
+-37, 433, -2361, 31844, 3494, -679, 76, -1, \
+-36, 412, -2243, 31959, 3236, -629, 70, -1, \
+-34, 391, -2121, 32066, 2982, -579, 64, -1, \
+-32, 368, -1993, 32165, 2733, -530, 58, -1, \
+-31, 345, -1861, 32257, 2488, -482, 52, -1, \
+-29, 320, -1724, 32342, 2247, -435, 47, -1, \
+-27, 295, -1583, 32419, 2011, -389, 41, 0, \
+-25, 268, -1437, 32488, 1780, -343, 36, 0, \
+-22, 241, -1286, 32550, 1553, -299, 31, 0, \
+-20, 212, -1130, 32604, 1331, -256, 27, 0, \
+-17, 182, -969, 32651, 1113, -214, 22, 0, \
+-14, 151, -804, 32689, 900, -173, 18, 0, \
+-11, 120, -633, 32720, 692, -132, 13, 0, \
+-8, 87, -458, 32744, 488, -93, 9, 0, \
+-5, 53, -279, 32759, 289, -55, 6, 0, \
+-2, 18, -94, 32767, 95, -18, 2, 0, \
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libao2/fir.h	Thu Dec 20 15:30:22 2001 +0000
@@ -0,0 +1,144 @@
+/*=============================================================================
+//	
+//  This file is part of mplayer.
+//
+//  mplayer 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.
+//
+//  mplayer 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 mplayer; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
+//
+//=============================================================================
+*/
+
+#ifndef __FIR_H__
+#define __FIR_H__
+
+/* 4, 8 and 16 tap FIR filters implemented using SSE instructions 
+   int16_t* x Input data
+   int16_t* y Output value
+   int16_t* w Filter weights 
+   
+   C function
+   for(int i = 0 ; i < L ; i++)
+     *y += w[i]*x[i];
+*/
+
+#ifdef HAVE_SSE
+
+// This block should be MMX only compatible, but it isn't...
+#ifdef L4
+#define LOAD_QUE(x) \
+        __asm __volatile("movq %0, %%mm2\n\t" \
+                         :                    \
+                         :"m"((x)[0])         \
+                         :"memory");
+#define SAVE_QUE(x) \
+        __asm __volatile("movq %%mm2, %0\n\t" \
+                         :"=m"(x[0])          \
+                         :                    \
+                         :"memory");
+#define UPDATE_QUE(in) \
+        __asm __volatile("psllq   $16,   %%mm2\n\t"    \
+                         "pinsrw  $0,    %0,%%mm2\n\t" \
+                          :                            \
+                          :"m" ((in)[0])               \
+                          :"memory");                  
+#define FIR(x,w,y) \
+        __asm __volatile("movq	  %%mm2, %%mm0\n\t" \
+                         "pmaddwd %1,    %%mm0\n\t" \
+                         "movq    %%mm0, %%mm1\n\t" \
+                         "psrlq   $32, 	 %%mm1\n\t" \
+                         "paddd   %%mm0, %%mm1\n\t" \
+                         "movd    %%mm1, %%esi\n\t" \
+                         "shrl    $16,   %%esi\n\t" \
+                         "movw    %%si,  %0\n\t"    \
+			 : "=m" ((y)[0])            \
+			 : "m" ((w)[0])             \
+			 : "memory", "%esi"); 
+#endif /* L4 */
+
+// It is possible to make the 8 bit filter a lot faster by using the
+// 128 bit registers, feel free to optimize.
+#ifdef L8
+#define LOAD_QUE(x) \
+        __asm __volatile("movq %0, %%mm5\n\t" \
+                         "movq %1, %%mm4\n\t" \
+                         :                    \
+                         :"m"((x)[0]),        \
+                          "m"((x)[4])         \
+                         :"memory");
+#define SAVE_QUE(x) \
+        __asm __volatile("movq %%mm5, %0\n\t" \
+                         "movq %%mm4, %1\n\t" \
+                         :"=m"((x)[0]),       \
+                          "=m"((x)[4])        \
+                         :                    \
+                         :"memory");
+
+// Below operation could replace line 2 to 5 in macro below but can
+// not cause of compiler bug ???
+// "pextrw $3, %%mm5,%%eax\n\t"
+#define UPDATE_QUE(in) \
+        __asm __volatile("psllq    $16,   %%mm4\n\t"        \
+                         "movq	   %%mm5, %%mm0\n\t" 	    \
+                         "psrlq    $48,   %%mm0\n\t"        \
+                         "movd     %%mm0, %%eax\n\t"        \
+			 "pinsrw   $0,    %%eax,%%mm4\n\t"  \
+                         "psllq    $16,   %%mm5\n\t"        \
+                         "pinsrw   $0,    %0,%%mm5\n\t"     \
+                          :                                 \
+                          :"m" ((in)[0])                    \
+                          :"memory", "%eax");                  
+#define FIR(x,w,y) \
+        __asm __volatile("movq	  %%mm5, %%mm0\n\t" \
+                         "pmaddwd %1,    %%mm0\n\t" \
+                         "movq	  %%mm4, %%mm1\n\t" \
+                         "pmaddwd %2,    %%mm1\n\t" \
+                         "paddd   %%mm1, %%mm0\n\t" \
+                         "movq    %%mm0, %%mm1\n\t" \
+                         "psrlq   $32, 	 %%mm1\n\t" \
+                         "paddd   %%mm0, %%mm1\n\t" \
+                         "movd    %%mm1, %%esi\n\t" \
+                         "shrl    $16,   %%esi\n\t" \
+                         "movw    %%si,  %0\n\t"    \
+			 : "=m" ((y)[0])            \
+			 : "m" ((w)[0]),            \
+			   "m" ((w)[4])             \
+			 : "memory", "%esi"); 
+#endif /* L8 */
+
+#else /* HAVE_SSE */
+
+#define LOAD_QUE(x)
+#define SAVE_QUE(x)
+#define UPDATE_QUE(inm) \
+  xi=(--xi)&(L-1);     \
+  x[xi]=x[xi+L]=*inm;
+
+#ifdef L4
+#define FIR(x,w,y) \
+        y[0]=(w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]) >> 16;
+#else
+#define FIR(x,w,y){ \
+  int16_t a = (w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]) >> 16; \
+  int16_t b = (w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7]) >> 16; \
+  y[0]      = a+b; \
+}
+#endif /* L4 */
+
+#endif /* HAVE_SSE */
+
+#endif /* __FIR_H__ */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libao2/pl_resample.c	Thu Dec 20 15:30:22 2001 +0000
@@ -0,0 +1,239 @@
+/*=============================================================================
+//	
+//  This file is part of mplayer.
+//
+//  mplayer 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.
+//
+//  mplayer 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 mplayer; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//  Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
+//
+//=============================================================================
+*/
+
+/* This audio output plugin changes the sample rate. The output
+   samplerate from this plugin is specified by using the switch
+   `fout=F' where F is the desired output sample frequency 
+*/
+
+#define PLUGIN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "audio_out.h"
+#include "audio_plugin.h"
+#include "audio_plugin_internal.h"
+#include "afmt.h"
+//#include "../config.h"
+
+static ao_info_t info =
+{
+        "Sample frequency conversion audio plugin",
+        "resample",
+        "Anders",
+        ""
+};
+
+LIBAO_PLUGIN_EXTERN(resample)
+
+#define min(a,b)   (((a) < (b)) ? (a) : (b))
+#define max(a,b)   (((a) > (b)) ? (a) : (b))
+
+/* Below definition selects the length of each poly phase component.
+   Valid definitions are L4 and L8, where the number denotes the
+   length of the filter. This definition affects the computational
+   complexity (see play()), the performance (see filter.h) and the
+   memory usage. For now the filterlenght is choosen to 4 and without
+   assembly optimization if no SSE is present.
+*/
+#ifdef HAVE_SSE
+#define L8    	1	// Filter bank type
+#define W 	W8	// Filter bank parameters
+#define L   	8	// Filter length
+#else	
+#define L4	1
+#define W 	W4
+#define L   	4
+#endif
+
+#define CH  6	// Max number of channels
+#define UP  128  /* Up sampling factor. Increasing this value will
+                    improve frequency accuracy. Think about the L1
+                    cashing of filter parameters - how big can it be? */
+
+#include "fir.h"
+#include "filter.h"
+
+// local data
+typedef struct pl_resample_s
+{
+  int16_t*	data;		// Data buffer
+  int16_t*  	w;		// Current filter weights
+  uint16_t  	dn;     	// Down sampling factor
+  uint16_t	up;		// Up sampling factor 
+  int 		channels;	// Number of channels
+  int 		len;		// Lenght of buffer
+  int 		bypass;		// Bypass this plugin
+  int16_t	ws[UP*L];	// List of all available filters	
+  int16_t 	xs[CH][L*2]; 	// Circular buffers
+} pl_resample_t;
+
+static pl_resample_t 	pl_resample	= {NULL,NULL,1,1,1,0,0,W};
+
+// to set/get/query special features/parameters
+static int control(int cmd,int arg){
+  switch(cmd){
+  case AOCONTROL_PLUGIN_SET_LEN:
+    if(pl_resample.data) 
+      free(pl_resample.data);
+    pl_resample.len = ao_plugin_data.len;
+    pl_resample.data=(int16_t*)malloc(pl_resample.len);
+    if(!pl_resample.data)
+      return CONTROL_ERROR;
+    ao_plugin_data.len = (int)((double)ao_plugin_data.len * 
+			     ((double)pl_resample.up)/
+			     ((double)pl_resample.dn));
+    return CONTROL_OK;
+  }
+  return -1;
+}
+
+// open & setup audio device
+// return: 1=success 0=fail
+static int init(){
+  int fin=ao_plugin_data.rate;
+  int fout=ao_plugin_cfg.pl_resample_fout;
+  pl_resample.w=pl_resample.ws;
+  pl_resample.up=UP;
+
+  // Sheck input format
+  if(ao_plugin_data.format != AFMT_S16_LE){
+    fprintf(stderr,"[pl_resample] Input audio format not yet suported. \n");
+    return 0;
+  }
+  // Sanity check and calculate down sampling factor
+  if((float)max(fin,fout)/(float)min(fin,fout) > 10){
+    fprintf(stderr,"[pl_resample] The difference between fin and fout is too large.\n");
+    return 0;
+  }
+  pl_resample.dn=(int)(0.5+((float)(fin*pl_resample.up))/((float)fout));
+  if(pl_resample.dn == pl_resample.up){
+    fprintf(stderr,"[pl_resample] Fin is too close to fout no conversion is needed.\n");
+    pl_resample.bypass=1;
+    return 1;
+  }
+  pl_resample.channels=ao_plugin_data.channels;
+  if(ao_plugin_data.channels>CH){
+     fprintf(stderr,"[pl_resample] Too many channels, max is 6.\n");
+    return 0;
+  }
+
+  // Tell the world what we are up to
+  printf("[pl_resample] Up=%i, Down=%i, True fout=%f\n",
+	 pl_resample.up,pl_resample.dn,
+	 ((float)fin*pl_resample.up)/((float)pl_resample.dn));
+
+  // This plugin changes buffersize and adds some delay
+  ao_plugin_data.sz_mult/=((float)pl_resample.up)/((float)pl_resample.dn);
+  ao_plugin_data.delay_fix-= ((float)L/2) * (1/fout);
+  ao_plugin_data.rate=fout;
+  return 1;
+}
+
+// close plugin
+static void uninit(){
+  if(pl_resample.data) 
+    free(pl_resample.data);
+  pl_resample.data=NULL;
+}
+
+// empty buffers
+static void reset(){
+}
+
+// processes 'ao_plugin_data.len' bytes of 'data'
+// called for every block of data
+// FIXME: this routine needs to be optimized (it is probably possible to do a lot here)
+static int play(){
+  static uint16_t	pwi = 0; // Index for w
+  static uint16_t	pxi = 0; // Index for circular queue
+  static uint16_t	pi =  1; // Number of new samples to put in x queue
+
+  uint16_t		ci    = pl_resample.channels; 	// Index for channels
+  uint16_t		len   = 0; 			// Number of output samples
+  uint16_t		nch   = pl_resample.channels;   // Number of channels
+  uint16_t		inc   = pl_resample.dn/pl_resample.up; 
+  uint16_t		level = pl_resample.dn%pl_resample.up; 
+  uint16_t		up    = pl_resample.up;
+  uint16_t		dn    = pl_resample.dn;
+
+  register uint16_t	i,wi,xi; // Temporary indexes
+
+  if(pl_resample.bypass)
+    return 1;
+  
+  // Index current channel
+  while(ci--){
+    // Temporary pointers
+    register int16_t*	x     = pl_resample.xs[ci];
+    register int16_t*	in    = ((int16_t*)ao_plugin_data.data)+ci;
+    register int16_t*	out   = pl_resample.data+ci;
+    // Block loop end
+    register int16_t* 	end   = in+ao_plugin_data.len/2;
+    i = pi; wi = pwi; xi = pxi;
+
+    LOAD_QUE(x);
+    if(0!=i) goto L1; 
+    while(in < end){
+      // Update wi to point at the correct polyphase component
+      wi=(wi+dn)%up;  
+
+      /* Update circular buffer x. This loop will be updated 0 or 1 time
+	 for upsamling and inc or inc + 1 times for downsampling */
+      if(wi<level) goto L3;
+      if(0==i) goto L2;
+  L1:   i--;
+  L3:  	UPDATE_QUE(in);
+        in+=nch;
+	if(in >= end) goto L2;
+      if(i) goto L1;
+  L2: if(i) goto L5;
+      i=inc;
+
+      /* Get the correct polyphase component and the correct startpoint
+	 in the circular bufer and run the FIR filter */
+      FIR((&x[xi]),(&pl_resample.w[wi*L]),out);
+      len++;
+      out+=nch;
+    }
+L5:
+    SAVE_QUE(x);
+  }
+
+  // Save values that needs to be kept for next time
+  pwi = wi;
+  pxi = xi;
+  pi = i;
+  // Set new data
+  ao_plugin_data.len=len*2;
+  ao_plugin_data.data=pl_resample.data;
+  return 1;
+}
+
+
+
+
+