summaryrefslogtreecommitdiffstats
path: root/libao2
diff options
context:
space:
mode:
authoranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-12-20 15:30:22 +0000
committeranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-12-20 15:30:22 +0000
commit30c2c12d50b1b6b3b2dda4ecc9ce40e951f57b33 (patch)
treefacfd96b7b63c5d3ef24cea4c7929d890a234b38 /libao2
parent12dd9ded9cb31217a9a43a5404e35c0b1559becf (diff)
downloadmpv-30c2c12d50b1b6b3b2dda4ecc9ce40e951f57b33.tar.bz2
mpv-30c2c12d50b1b6b3b2dda4ecc9ce40e951f57b33.tar.xz
Added plugin for fractional resampling (alpha code)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3632 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2')
-rw-r--r--libao2/Makefile3
-rw-r--r--libao2/audio_plugin.h8
-rw-r--r--libao2/filter.h223
-rw-r--r--libao2/fir.h144
-rw-r--r--libao2/pl_resample.c239
5 files changed, 614 insertions, 3 deletions
diff --git a/libao2/Makefile b/libao2/Makefile
index 1ae0862619..fe4a787fbc 100644
--- a/libao2/Makefile
+++ b/libao2/Makefile
@@ -4,7 +4,8 @@ include config.mak
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)
diff --git a/libao2/audio_plugin.h b/libao2/audio_plugin.h
index 59f20d7c05..cfe71792ce 100644
--- a/libao2/audio_plugin.h
+++ b/libao2/audio_plugin.h
@@ -34,6 +34,7 @@ typedef struct ao_plugin_cfg_s
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 @@ extern volatile ao_plugin_cfg_t ao_plugin_cfg;
#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 */
diff --git a/libao2/filter.h b/libao2/filter.h
new file mode 100644
index 0000000000..964e335672
--- /dev/null
+++ b/libao2/filter.h
@@ -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, \
+}
diff --git a/libao2/fir.h b/libao2/fir.h
new file mode 100644
index 0000000000..0124d03d9e
--- /dev/null
+++ b/libao2/fir.h
@@ -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__ */
+
+
diff --git a/libao2/pl_resample.c b/libao2/pl_resample.c
new file mode 100644
index 0000000000..3ab049ca08
--- /dev/null
+++ b/libao2/pl_resample.c
@@ -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;
+}
+
+
+
+
+