[MPlayer-cvslog] CVS: main/libaf af.c, 1.39, 1.40 af.h, 1.22, 1.23 af_channels.c, 1.12, 1.13 af_format.c, 1.23, 1.24 af_lavcresample.c, 1.7, 1.8 af_pan.c, 1.5, 1.6 af_resample.c, 1.23, 1.24
Reimar Döffinger CVS
syncmail at mplayerhq.hu
Sat Jan 8 22:34:09 CET 2005
CVS change done by Reimar Döffinger CVS
Update of /cvsroot/mplayer/main/libaf
In directory mail:/var2/tmp/cvs-serv15266/libaf
Modified Files:
af.c af.h af_channels.c af_format.c af_lavcresample.c af_pan.c
af_resample.c
Log Message:
always cancel down fractions (frac_t) to avoid overflows and playback
problems (e.g. when using resample and equalizer filters together, see
http://mplayerhq.hu/pipermail/mplayer-users/2004-December/050058.html)
Index: af.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- af.c 3 Jan 2005 18:59:16 -0000 1.39
+++ af.c 8 Jan 2005 21:34:06 -0000 1.40
@@ -524,8 +524,7 @@
register frac_t mul = {1,1};
// Iterate through all filters
do{
- mul.n *= af->mul.n;
- mul.d *= af->mul.d;
+ af_frac_mul(&mul, &af->mul);
af=af->next;
}while(af);
return t * (((len/t)*mul.n + 1)/mul.d);
@@ -542,8 +541,7 @@
register frac_t mul = {1,1};
// Iterate through all filters
do{
- mul.n *= af->mul.n;
- mul.d *= af->mul.d;
+ af_frac_mul(&mul, &af->mul);
af=af->next;
}while(af);
return t * (((len/t) * mul.d - 1)/mul.n);
@@ -567,8 +565,7 @@
register frac_t mul = {1,1};
// Iterate through all filters and calculate total multiplication factor
do{
- mul.n *= af->mul.n;
- mul.d *= af->mul.d;
+ af_frac_mul(&mul, &af->mul);
af=af->next;
}while(af);
// Sanity check
@@ -645,6 +642,49 @@
return NULL;
}
+/**
+ * \brief calculate greatest common divisior of a and b.
+ * Extended for negative and 0 values. If both are 0 the result is 1.
+ * The sign of the result will be so that it has the same sign as b.
+ */
+int af_gcd(register int a, register int b) {
+ int b_org = b;
+ while (b != 0) {
+ a %= b;
+ if (a == 0)
+ break;
+ b %= a;
+ }
+ // the result is either in a or b. As the other one is 0 just add them.
+ a += b;
+ if (!a)
+ return 1;
+ if (a * b_org < 0)
+ return -a;
+ return a;
+}
+
+/**
+ * \brief cancel down a fraction f
+ */
+void af_frac_cancel(frac_t *f) {
+ int gcd = af_gcd(f->n, f->d);
+ f->n /= gcd;
+ f->d /= gcd;
+}
+
+/**
+ * \brief multiply out by in and store result in out.
+ * the resulting fraction wil be cancelled down
+ * if in and out were.
+ */
+void af_frac_mul(frac_t *out, const frac_t *in) {
+ int gcd1 = af_gcd(out->n, in->d);
+ int gcd2 = af_gcd(in->n, out->d);
+ out->n = (out->n / gcd1) * (in->n / gcd2);
+ out->d = (out->d / gcd2) * (in->d / gcd1);
+}
+
void af_help (void) {
int i = 0;
af_msg(AF_MSG_INFO, "Available audio filters:\n");
Index: af.h
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- af.h 1 Jan 2005 18:46:56 -0000 1.22
+++ af.h 8 Jan 2005 21:34:06 -0000 1.23
@@ -28,6 +28,10 @@
int d; // Denominator
} frac_t;
+int af_gcd(register int a, register int b);
+void af_frac_cancel(frac_t *f);
+void af_frac_mul(frac_t *out, const frac_t *in);
+
// Flags used for defining the behavior of an audio filter
#define AF_FLAGS_REENTRANT 0x00000000
#define AF_FLAGS_NOT_REENTRANT 0x00000001
Index: af_channels.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af_channels.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- af_channels.c 29 Jul 2004 16:23:16 -0000 1.12
+++ af_channels.c 8 Jan 2005 21:34:06 -0000 1.13
@@ -151,6 +151,7 @@
af->data->bps = ((af_data_t*)arg)->bps;
af->mul.n = af->data->nch;
af->mul.d = ((af_data_t*)arg)->nch;
+ af_frac_cancel(&af->mul);
return check_routes(s,((af_data_t*)arg)->nch,af->data->nch);
case AF_CONTROL_COMMAND_LINE:{
int nch = 0;
Index: af_format.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af_format.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- af_format.c 6 Jan 2005 14:32:08 -0000 1.23
+++ af_format.c 8 Jan 2005 21:34:06 -0000 1.24
@@ -306,6 +306,7 @@
af->data->nch = ((af_data_t*)arg)->nch;
af->mul.n = af->data->bps;
af->mul.d = ((af_data_t*)arg)->bps;
+ af_frac_cancel(&af->mul);
af->play = play; // set default
Index: af_lavcresample.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af_lavcresample.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- af_lavcresample.c 31 Dec 2004 13:14:01 -0000 1.7
+++ af_lavcresample.c 8 Jan 2005 21:34:06 -0000 1.8
@@ -40,7 +40,6 @@
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
- int g;
af_resample_t* s = (af_resample_t*)af->setup;
af_data_t *data= (af_data_t*)arg;
int out_rate, test_output_res; // helpers for checking input format
@@ -54,9 +53,9 @@
if (af->data->nch > CHANS) af->data->nch = CHANS;
af->data->format = AF_FORMAT_S16_NE;
af->data->bps = 2;
- g= ff_gcd(af->data->rate, data->rate);
- af->mul.n = af->data->rate/g;
- af->mul.d = data->rate/g;
+ af->mul.n = af->data->rate;
+ af->mul.d = data->rate;
+ af_frac_cancel(&af->mul);
af->delay = 500*s->filter_length/(double)min(af->data->rate, data->rate);
if(s->avrctx) av_resample_close(s->avrctx);
Index: af_pan.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af_pan.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- af_pan.c 27 Dec 2004 17:30:13 -0000 1.5
+++ af_pan.c 8 Jan 2005 21:34:06 -0000 1.6
@@ -41,6 +41,7 @@
af->data->bps = 4;
af->mul.n = af->data->nch;
af->mul.d = ((af_data_t*)arg)->nch;
+ af_frac_cancel(&af->mul);
if((af->data->format != ((af_data_t*)arg)->format) ||
(af->data->bps != ((af_data_t*)arg)->bps)){
Index: af_resample.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af_resample.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- af_resample.c 29 Dec 2004 19:50:44 -0000 1.23
+++ af_resample.c 8 Jan 2005 21:34:06 -0000 1.24
@@ -62,22 +62,6 @@
int setup; // Setup parameters cmdline or through postcreate
} af_resample_t;
-// Euclids algorithm for calculating Greatest Common Divisor GCD(a,b)
-static inline int gcd(register int a, register int b)
-{
- register int r = min(a,b);
- a=max(a,b);
- b=r;
-
- r=a%b;
- while(r!=0){
- a=b;
- b=r;
- r=a%b;
- }
- return b;
-}
-
// Fast linear interpolation resample with modest audio quality
static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
{
@@ -202,11 +186,12 @@
s->step);
af->mul.n = af->data->rate;
af->mul.d = n->rate;
+ af_frac_cancel(&af->mul);
return rv;
}
// Calculate up and down sampling factors
- d=gcd(af->data->rate,n->rate);
+ d=af_gcd(af->data->rate,n->rate);
// If sloppy resampling is enabled limit the upsampling factor
if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
@@ -214,7 +199,7 @@
int dn=n->rate/2;
int m=2;
while(af->data->rate/(d*m) > 5000){
- d=gcd(up,dn);
+ d=af_gcd(up,dn);
up/=2; dn/=2; m*=2;
}
d*=m;
More information about the MPlayer-cvslog
mailing list