[Mplayer-dev-eng] clicks/noise from AC3 audio decoder using 3dnowex instructions (AMD K7)

Juergen Keil jk at tools.de
Wed Jun 13 12:05:56 CEST 2001


Hi,

there's a problem in libac3/imdct.c and libac3/mmx/imdct_3dnow.c, function
imdct_do_512_nol().  In both files the routine ends with:

	...
	
        data_ptr = data;
        delay_ptr = delay;
        window_ptr = window;

        /* Window and convert to real valued signal, no overlap here*/
[1]     for(i=0; i< 64; i++) {
               *data_ptr++   = -buf[64+i].im   * *window_ptr++;
               *data_ptr++   =  buf[64-i-1].re * *window_ptr++;
        }
[2]
	/* The trailing edge of the window goes into the delay line */

   	delay_ptr = delay;

[3]     for(i=0; i< 64; i++) {
               *delay_ptr++  = -buf[64+i].re   * *--window_ptr;
               *delay_ptr++  =  buf[64-i-1].im * *--window_ptr;
        }

[4]     for(i=0; i<64; i++) {
               *delay_ptr++  =  buf[i].im       * *--window_ptr;
               *delay_ptr++  = -buf[128-i-1].re * *--window_ptr;
        }
}


'window' is an array with 256 float elements.  The loop at [1] uses the
elements 0 .. 127 (via window_ptr).  The loop at [3] use the same elements
in reverse order, 127 .. 0.

And finally the loop at [4] continues looping backwards, using elements 
-1 .. -128 .  Oops.  It access out-of-bound array elements,  which obviouly
is not ok.


Looking at the imdct_do_256*() variant of the code, I have the impression
that a second loop accessing the array elements 128 .. 255 is missing here [2].
With such a second loop added, [3] would access the elements 255 .. 128 and
[4] 127 .. 0.  The appended patch adds the missing second loop.  DCT experts
out there,  does that fix look OK?



The patch fixes some stange audio clicks I get on dvd video playback;
these clicks 'appeared' a few days ago with the mplayer cvs version due
to an unrelated change in mp3lib/decode_k7.s which triggered this noise
problem for me.


--
Jürgen Keil          		jk at tools.de
Tools GmbH			+49 (228) 9858011
-------------- next part --------------
diff -x config.mak -x config.h -ru /tmp/mplayer/main/libac3/imdct.c mplayer/main/libac3/imdct.c
--- /tmp/mplayer/main/libac3/imdct.c	Sat Jun  9 16:33:28 2001
+++ mplayer/main/libac3/imdct.c	Wed Jun 13 01:01:36 2001
@@ -192,12 +192,12 @@
 // Window and convert to real valued signal
 	for (i=0; i< 64; i++) {
 		*data_ptr++   = -buf[64+i].im   * *window_ptr++ + *delay_ptr++;
-		*data_ptr++   = buf[64-i-1].re * *window_ptr++ + *delay_ptr++;
+		*data_ptr++   =  buf[64-i-1].re * *window_ptr++ + *delay_ptr++;
 	}
 
 	for(i=0; i< 64; i++) {
 		*data_ptr++  = -buf[i].re       * *window_ptr++ + *delay_ptr++;
-		*data_ptr++  = buf[128-i-1].im * *window_ptr++ + *delay_ptr++;
+		*data_ptr++  =  buf[128-i-1].im * *window_ptr++ + *delay_ptr++;
 	}
 
 // The trailing edge of the window goes into the delay line
@@ -269,9 +269,15 @@
 
        /* Window and convert to real valued signal, no overlap here*/
         for(i=0; i< 64; i++) {
-               *data_ptr++   = -buf[64+i].im   * *window_ptr++;
-               *data_ptr++   = buf[64-i-1].re * *window_ptr++;
+		*data_ptr++   = -buf[64+i].im   * *window_ptr++;
+		*data_ptr++   =  buf[64-i-1].re * *window_ptr++;
         }
+
+	for(i=0; i< 64; i++) {
+		*data_ptr++  = -buf[i].re       * *window_ptr++;
+		*data_ptr++  =  buf[128-i-1].im * *window_ptr++;
+	}
+
 
         /* The trailing edge of the window goes into the delay line */
 
diff -x config.mak -x config.h -ru /tmp/mplayer/main/libac3/mmx/imdct_3dnow.c mplayer/main/libac3/mmx/imdct_3dnow.c
--- /tmp/mplayer/main/libac3/mmx/imdct_3dnow.c	Sat Jun  9 16:33:28 2001
+++ mplayer/main/libac3/mmx/imdct_3dnow.c	Wed Jun 13 01:08:07 2001
@@ -250,22 +250,27 @@
 
        /* Window and convert to real valued signal, no overlap here*/
         for(i=0; i< 64; i++) {
-               *data_ptr++   = -buf[64+i].im   * *window_ptr++;
-               *data_ptr++   = buf[64-i-1].re * *window_ptr++;
+		*data_ptr++   = -buf[64+i].im   * *window_ptr++;
+		*data_ptr++   =  buf[64-i-1].re * *window_ptr++;
         }
 
+	for(i=0; i< 64; i++) {
+		*data_ptr++  = -buf[i].re       * *window_ptr++;
+		*data_ptr++  =  buf[128-i-1].im * *window_ptr++;
+	}
+
         /* The trailing edge of the window goes into the delay line */
 
-   delay_ptr = delay;
+	delay_ptr = delay;
 
         for(i=0; i< 64; i++) {
-               *delay_ptr++  = -buf[64+i].re   * *--window_ptr;
-               *delay_ptr++  =  buf[64-i-1].im * *--window_ptr;
+		*delay_ptr++  = -buf[64+i].re   * *--window_ptr;
+		*delay_ptr++  =  buf[64-i-1].im * *--window_ptr;
         }
 
         for(i=0; i<64; i++) {
-               *delay_ptr++  =  buf[i].im       * *--window_ptr;
-               *delay_ptr++  = -buf[128-i-1].re * *--window_ptr;
+		*delay_ptr++  =  buf[i].im       * *--window_ptr;
+		*delay_ptr++  = -buf[128-i-1].re * *--window_ptr;
         }
 }
 
@@ -345,12 +350,12 @@
 	/* Window and convert to real valued signal */
 	for(i=0; i< 64; i++) { 
 		*data_ptr++  = -buf1[i].im      * *window_ptr++ + *delay_ptr++;
-		*data_ptr++  = buf1[64-i-1].re * *window_ptr++ + *delay_ptr++;
+		*data_ptr++  =  buf1[64-i-1].re * *window_ptr++ + *delay_ptr++;
 	}
 
 	for(i=0; i< 64; i++) {
 		*data_ptr++  = -buf1[i].re      * *window_ptr++ + *delay_ptr++;
-		*data_ptr++  = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
+		*data_ptr++  =  buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
 	}
 	
 	delay_ptr = delay;
@@ -443,12 +448,12 @@
        /* Window and convert to real valued signal, no overlap */
        for(i=0; i< 64; i++) {
                *data_ptr++  = -buf1[i].im      * *window_ptr++;
-               *data_ptr++  = buf1[64-i-1].re * *window_ptr++;
+               *data_ptr++  =  buf1[64-i-1].re * *window_ptr++;
        }
 
        for(i=0; i< 64; i++) {
                *data_ptr++  = -buf1[i].re      * *window_ptr++ + *delay_ptr++;
-               *data_ptr++  = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
+               *data_ptr++  =  buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
        }
 
        delay_ptr = delay;


More information about the MPlayer-dev-eng mailing list