summaryrefslogtreecommitdiffstats
path: root/libaf/af_resample.h
diff options
context:
space:
mode:
authoranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-28 13:59:53 +0000
committeranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-28 13:59:53 +0000
commit6adaa78ee935ef89439d4b38550165f13e880320 (patch)
tree6612adc09121e661363b1370cb43981007d36b60 /libaf/af_resample.h
parent0e9c0e8aa2aa7df6aad5d78c4b664927a9d2421e (diff)
downloadmpv-6adaa78ee935ef89439d4b38550165f13e880320.tar.bz2
mpv-6adaa78ee935ef89439d4b38550165f13e880320.tar.xz
Changes includes:
- Improved runtime control system - 3 New filter panning, compressor/limiter and a noise gate - The compressor/limiter and the noise gate are not yet finished - The panning filter does combined mixing and channel routing and can be used to down-mix from stereo to mono (for example) - Improvements to volume and channel - volume now has a very good soft clipping using sin() - channel can handle generic routing of audio data - Conversion of all filters to handle floating point data - Cleanup of message printing - Fix for the sig 11 bug reported by Denes git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8608 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf/af_resample.h')
-rw-r--r--libaf/af_resample.h161
1 files changed, 161 insertions, 0 deletions
diff --git a/libaf/af_resample.h b/libaf/af_resample.h
new file mode 100644
index 0000000000..4f373e2c06
--- /dev/null
+++ b/libaf/af_resample.h
@@ -0,0 +1,161 @@
+/*=============================================================================
+//
+// This software has been released under the terms of the GNU Public
+// license. See http://www.gnu.org/copyleft/gpl.html for details.
+//
+// Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
+//
+//=============================================================================
+*/
+
+/* This file contains the resampling engine, the sample format is
+ controlled by the FORMAT parameter, the filter length by the L
+ parameter and the resampling type by UP and DN. This file should
+ only be included by af_resample.c
+*/
+
+#undef L
+#undef SHIFT
+#undef FORMAT
+#undef FIR
+#undef ADDQUE
+
+/* The lenght Lxx definition selects the length of each poly phase
+ component. Valid definitions are L8 and L16 where the number
+ defines the nuber of taps. This definition affects the
+ computational complexity, the performance and the memory usage.
+*/
+
+/* The FORMAT_x parameter selects the sample format type currently
+ float and int16 are supported. Thes two formats are selected by
+ defining eiter FORMAT_F or FORMAT_I. The advantage of using float
+ is that the amplitude and therefore the SNR isn't affected by the
+ filtering, the disadvantage is that it is a lot slower.
+*/
+
+#if defined(FORMAT_I)
+#define SHIFT >>16
+#define FORMAT int16_t
+#else
+#define SHIFT
+#define FORMAT float
+#endif
+
+// Short filter
+#if defined(L8)
+
+#define L 8 // Filter length
+// Unrolled loop to speed up execution
+#define FIR(x,w,y) \
+ (y[0]) = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
+ + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
+
+
+
+#else /* L8/L16 */
+
+#define L 16
+// Unrolled loop to speed up execution
+#define FIR(x,w,y) \
+ y[0] = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
+ + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
+ + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
+ + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
+
+#endif /* L8/L16 */
+
+// Macro to add data to circular que
+#define ADDQUE(xi,xq,in)\
+ xq[xi]=xq[xi+L]=(*in);\
+ xi=(xi-1)&(L-1);
+
+#if defined(UP)
+
+ uint32_t ci = l->nch; // Index for channels
+ uint32_t nch = l->nch; // Number of channels
+ uint32_t inc = s->up/s->dn;
+ uint32_t level = s->up%s->dn;
+ uint32_t up = s->up;
+ uint32_t dn = s->dn;
+ uint32_t ns = c->len/l->bps;
+ register FORMAT* w = s->w;
+
+ register uint32_t wi = 0;
+ register uint32_t xi = 0;
+
+ // Index current channel
+ while(ci--){
+ // Temporary pointers
+ register FORMAT* x = s->xq[ci];
+ register FORMAT* in = ((FORMAT*)c->audio)+ci;
+ register FORMAT* out = ((FORMAT*)l->audio)+ci;
+ FORMAT* end = in+ns; // Block loop end
+ wi = s->wi; xi = s->xi;
+
+ while(in < end){
+ register uint32_t i = inc;
+ if(wi<level) i++;
+
+ ADDQUE(xi,x,in);
+ in+=nch;
+ while(i--){
+ // Run the FIR filter
+ FIR((&x[xi]),(&w[wi*L]),out);
+ len++; out+=nch;
+ // Update wi to point at the correct polyphase component
+ wi=(wi+dn)%up;
+ }
+ }
+
+ }
+ // Save values that needs to be kept for next time
+ s->wi = wi;
+ s->xi = xi;
+#endif /* UP */
+
+#if defined(DN) /* DN */
+ uint32_t ci = l->nch; // Index for channels
+ uint32_t nch = l->nch; // Number of channels
+ uint32_t inc = s->dn/s->up;
+ uint32_t level = s->dn%s->up;
+ uint32_t up = s->up;
+ uint32_t dn = s->dn;
+ uint32_t ns = c->len/l->bps;
+ FORMAT* w = s->w;
+
+ register int32_t i = 0;
+ register uint32_t wi = 0;
+ register uint32_t xi = 0;
+
+ // Index current channel
+ while(ci--){
+ // Temporary pointers
+ register FORMAT* x = s->xq[ci];
+ register FORMAT* in = ((FORMAT*)c->audio)+ci;
+ register FORMAT* out = ((FORMAT*)l->audio)+ci;
+ register FORMAT* end = in+ns; // Block loop end
+ i = s->i; wi = s->wi; xi = s->xi;
+
+ while(in < end){
+
+ ADDQUE(xi,x,in);
+ in+=nch;
+ if((--i)<=0){
+ // Run the FIR filter
+ FIR((&x[xi]),(&w[wi*L]),out);
+ len++; out+=nch;
+
+ // Update wi to point at the correct polyphase component
+ wi=(wi+dn)%up;
+
+ // Insert i number of new samples in queue
+ i = inc;
+ if(wi<level) i++;
+ }
+ }
+ }
+ // Save values that needs to be kept for next time
+ s->wi = wi;
+ s->xi = xi;
+ s->i = i;
+#endif /* DN */