diff liba52/downmix.c @ 1072:68d0a38bd802 libavcodec

* sync with main liba52 sources
author kabi
date Tue, 18 Feb 2003 11:48:57 +0000
parents dd4f4c3d7171
children e101d1cffec6
line wrap: on
line diff
--- a/liba52/downmix.c	Tue Feb 18 09:33:21 2003 +0000
+++ b/liba52/downmix.c	Tue Feb 18 11:48:57 2003 +0000
@@ -1,6 +1,6 @@
 /*
  * downmix.c
- * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
  * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  *
  * This file is part of a52dec, a free ATSC A-52 stream decoder.
@@ -21,13 +21,18 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "config.h"
+
+#include <string.h>
+#include <inttypes.h>
+
 #include "a52.h"
 #include "a52_internal.h"
 
 #define CONVERT(acmod,output) (((output) << 3) + (acmod))
 
-int a52_downmix_init (int input, int flags, sample_t * level,
-		      sample_t clev, sample_t slev)
+int a52_downmix_init (int input, int flags, level_t * level,
+		      level_t clev, level_t slev)
 {
     static uint8_t table[11][8] = {
 	{A52_CHANNEL,	A52_DOLBY,	A52_STEREO,	A52_STEREO,
@@ -61,94 +66,106 @@
 
     output = table[output][input & 7];
 
-    if ((output == A52_STEREO) &&
-	((input == A52_DOLBY) || ((input == A52_3F) && (clev == LEVEL_3DB))))
+    if (output == A52_STEREO &&
+	(input == A52_DOLBY || (input == A52_3F && clev == LEVEL (LEVEL_3DB))))
 	output = A52_DOLBY;
 
-    if (flags & A52_ADJUST_LEVEL)
+    if (flags & A52_ADJUST_LEVEL) {
+	level_t adjust;
+
 	switch (CONVERT (input & 7, output)) {
 
 	case CONVERT (A52_3F, A52_MONO):
-	    *level *= LEVEL_3DB / (1 + clev);
+	    adjust = DIV (LEVEL_3DB, LEVEL (1) + clev);
 	    break;
 
 	case CONVERT (A52_STEREO, A52_MONO):
 	case CONVERT (A52_2F2R, A52_2F1R):
 	case CONVERT (A52_3F2R, A52_3F1R):
 	level_3db:
-	    *level *= LEVEL_3DB;
+	    adjust = LEVEL (LEVEL_3DB);
 	    break;
 
 	case CONVERT (A52_3F2R, A52_2F1R):
-	    if (clev < LEVEL_PLUS3DB - 1)
+	    if (clev < LEVEL (LEVEL_PLUS3DB - 1))
 		goto level_3db;
 	    /* break thru */
 	case CONVERT (A52_3F, A52_STEREO):
 	case CONVERT (A52_3F1R, A52_2F1R):
 	case CONVERT (A52_3F1R, A52_2F2R):
 	case CONVERT (A52_3F2R, A52_2F2R):
-	    *level /= 1 + clev;
+	    adjust = DIV (1, LEVEL (1) + clev);
 	    break;
 
 	case CONVERT (A52_2F1R, A52_MONO):
-	    *level *= LEVEL_PLUS3DB / (2 + slev);
+	    adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev);
 	    break;
 
 	case CONVERT (A52_2F1R, A52_STEREO):
 	case CONVERT (A52_3F1R, A52_3F):
-	    *level /= 1 + slev * LEVEL_3DB;
+	    adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB));
 	    break;
 
 	case CONVERT (A52_3F1R, A52_MONO):
-	    *level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
+	    adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5));
 	    break;
 
 	case CONVERT (A52_3F1R, A52_STEREO):
-	    *level /= 1 + clev + slev * LEVEL_3DB;
+	    adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB));
 	    break;
 
 	case CONVERT (A52_2F2R, A52_MONO):
-	    *level *= LEVEL_3DB / (1 + slev);
+	    adjust = DIV (LEVEL_3DB, LEVEL (1) + slev);
 	    break;
 
 	case CONVERT (A52_2F2R, A52_STEREO):
 	case CONVERT (A52_3F2R, A52_3F):
-	    *level /= 1 + slev;
+	    adjust = DIV (1, LEVEL (1) + slev);
 	    break;
 
 	case CONVERT (A52_3F2R, A52_MONO):
-	    *level *= LEVEL_3DB / (1 + clev + slev);
+	    adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev);
 	    break;
 
 	case CONVERT (A52_3F2R, A52_STEREO):
-	    *level /= 1 + clev + slev;
+	    adjust = DIV (1, LEVEL (1) + clev + slev);
 	    break;
 
 	case CONVERT (A52_MONO, A52_DOLBY):
-	    *level *= LEVEL_PLUS3DB;
+	    adjust = LEVEL (LEVEL_PLUS3DB);
 	    break;
 
 	case CONVERT (A52_3F, A52_DOLBY):
 	case CONVERT (A52_2F1R, A52_DOLBY):
-	    *level *= 1 / (1 + LEVEL_3DB);
+	    adjust = LEVEL (1 / (1 + LEVEL_3DB));
 	    break;
 
 	case CONVERT (A52_3F1R, A52_DOLBY):
 	case CONVERT (A52_2F2R, A52_DOLBY):
-	    *level *= 1 / (1 + 2 * LEVEL_3DB);
+	    adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB));
 	    break;
 
 	case CONVERT (A52_3F2R, A52_DOLBY):
-	    *level *= 1 / (1 + 3 * LEVEL_3DB);
+	    adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB));
 	    break;
+
+	default:
+	    return output;
 	}
 
+	*level = MUL_L (*level, adjust);
+    }
+
     return output;
 }
 
-int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
-		       sample_t clev, sample_t slev)
+int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
+		       level_t clev, level_t slev)
 {
+    level_t level_3db;
+
+    level_3db = MUL_C (level, LEVEL_3DB);
+
     switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
 
     case CONVERT (A52_CHANNEL, A52_CHANNEL):
@@ -164,120 +181,138 @@
 	return 0;
 
     case CONVERT (A52_CHANNEL, A52_MONO):
-	coeff[0] = coeff[1] = level * LEVEL_6DB;
+	coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB);
 	return 3;
 
     case CONVERT (A52_STEREO, A52_MONO):
-	coeff[0] = coeff[1] = level * LEVEL_3DB;
+	coeff[0] = coeff[1] = level_3db;
 	return 3;
 
     case CONVERT (A52_3F, A52_MONO):
-	coeff[0] = coeff[2] = level * LEVEL_3DB;
-	coeff[1] = level * clev * LEVEL_PLUS3DB;
+	coeff[0] = coeff[2] = level_3db;
+	coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
 	return 7;
 
     case CONVERT (A52_2F1R, A52_MONO):
-	coeff[0] = coeff[1] = level * LEVEL_3DB;
-	coeff[2] = level * slev * LEVEL_3DB;
+	coeff[0] = coeff[1] = level_3db;
+	coeff[2] = MUL_L (level_3db, slev);
 	return 7;
 
     case CONVERT (A52_2F2R, A52_MONO):
-	coeff[0] = coeff[1] = level * LEVEL_3DB;
-	coeff[2] = coeff[3] = level * slev * LEVEL_3DB;
+	coeff[0] = coeff[1] = level_3db;
+	coeff[2] = coeff[3] = MUL_L (level_3db, slev);
 	return 15;
 
     case CONVERT (A52_3F1R, A52_MONO):
-	coeff[0] = coeff[2] = level * LEVEL_3DB;
-	coeff[1] = level * clev * LEVEL_PLUS3DB;
-	coeff[3] = level * slev * LEVEL_3DB;
+	coeff[0] = coeff[2] = level_3db;
+	coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
+	coeff[3] = MUL_L (level_3db, slev);
 	return 15;
 
     case CONVERT (A52_3F2R, A52_MONO):
-	coeff[0] = coeff[2] = level * LEVEL_3DB;
-	coeff[1] = level * clev * LEVEL_PLUS3DB;
-	coeff[3] = coeff[4] = level * slev * LEVEL_3DB;
+	coeff[0] = coeff[2] = level_3db;
+	coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
+	coeff[3] = coeff[4] = MUL_L (level_3db, slev);
 	return 31;
 
     case CONVERT (A52_MONO, A52_DOLBY):
-	coeff[0] = level * LEVEL_3DB;
+	coeff[0] = level_3db;
 	return 0;
 
     case CONVERT (A52_3F, A52_DOLBY):
-	clev = LEVEL_3DB;
+	coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
+	coeff[1] = level_3db;
+	return 7;
+
     case CONVERT (A52_3F, A52_STEREO):
     case CONVERT (A52_3F1R, A52_2F1R):
     case CONVERT (A52_3F2R, A52_2F2R):
 	coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
-	coeff[1] = level * clev;
+	coeff[1] = MUL_L (level, clev);
 	return 7;
 
     case CONVERT (A52_2F1R, A52_DOLBY):
-	slev = 1;
+	coeff[0] = coeff[1] = level;
+	coeff[2] = level_3db;
+	return 7;
+
     case CONVERT (A52_2F1R, A52_STEREO):
 	coeff[0] = coeff[1] = level;
-	coeff[2] = level * slev * LEVEL_3DB;
+	coeff[2] = MUL_L (level_3db, slev);
 	return 7;
 
     case CONVERT (A52_3F1R, A52_DOLBY):
-	clev = LEVEL_3DB;
-	slev = 1;
+	coeff[0] = coeff[2] = level;
+	coeff[1] = coeff[3] = level_3db;
+	return 15;
+
     case CONVERT (A52_3F1R, A52_STEREO):
 	coeff[0] = coeff[2] = level;
-	coeff[1] = level * clev;
-	coeff[3] = level * slev * LEVEL_3DB;
+	coeff[1] = MUL_L (level, clev);
+	coeff[3] = MUL_L (level_3db, slev);
 	return 15;
 
     case CONVERT (A52_2F2R, A52_DOLBY):
-	slev = LEVEL_3DB;
+	coeff[0] = coeff[1] = level;
+	coeff[2] = coeff[3] = level_3db;
+	return 15;
+
     case CONVERT (A52_2F2R, A52_STEREO):
 	coeff[0] = coeff[1] = level;
-	coeff[2] = coeff[3] = level * slev;
+	coeff[2] = coeff[3] = MUL_L (level, slev);
 	return 15;
 
     case CONVERT (A52_3F2R, A52_DOLBY):
-	clev = LEVEL_3DB;
+	coeff[0] = coeff[2] = level;
+	coeff[1] = coeff[3] = coeff[4] = level_3db;
+	return 31;
+
     case CONVERT (A52_3F2R, A52_2F1R):
-	slev = LEVEL_3DB;
+	coeff[0] = coeff[2] = level;
+	coeff[1] = MUL_L (level, clev);
+	coeff[3] = coeff[4] = level_3db;
+	return 31;
+
     case CONVERT (A52_3F2R, A52_STEREO):
 	coeff[0] = coeff[2] = level;
-	coeff[1] = level * clev;
-	coeff[3] = coeff[4] = level * slev;
+	coeff[1] = MUL_L (level, clev);
+	coeff[3] = coeff[4] = MUL_L (level, slev);
 	return 31;
 
     case CONVERT (A52_3F1R, A52_3F):
 	coeff[0] = coeff[1] = coeff[2] = level;
-	coeff[3] = level * slev * LEVEL_3DB;
+	coeff[3] = MUL_L (level_3db, slev);
 	return 13;
 
     case CONVERT (A52_3F2R, A52_3F):
 	coeff[0] = coeff[1] = coeff[2] = level;
-	coeff[3] = coeff[4] = level * slev;
+	coeff[3] = coeff[4] = MUL_L (level, slev);
 	return 29;
 
     case CONVERT (A52_2F2R, A52_2F1R):
 	coeff[0] = coeff[1] = level;
-	coeff[2] = coeff[3] = level * LEVEL_3DB;
+	coeff[2] = coeff[3] = level_3db;
 	return 12;
 
     case CONVERT (A52_3F2R, A52_3F1R):
 	coeff[0] = coeff[1] = coeff[2] = level;
-	coeff[3] = coeff[4] = level * LEVEL_3DB;
+	coeff[3] = coeff[4] = level_3db;
 	return 24;
 
     case CONVERT (A52_2F1R, A52_2F2R):
 	coeff[0] = coeff[1] = level;
-	coeff[2] = level * LEVEL_3DB;
+	coeff[2] = level_3db;
 	return 0;
 
     case CONVERT (A52_3F1R, A52_2F2R):
 	coeff[0] = coeff[2] = level;
-	coeff[1] = level * clev;
-	coeff[3] = level * LEVEL_3DB;
+	coeff[1] = MUL_L (level, clev);
+	coeff[3] = level_3db;
 	return 7;
 
     case CONVERT (A52_3F1R, A52_3F2R):
 	coeff[0] = coeff[1] = coeff[2] = level;
-	coeff[3] = level * LEVEL_3DB;
+	coeff[3] = level_3db;
 	return 0;
 
     case CONVERT (A52_CHANNEL, A52_CHANNEL1):
@@ -299,7 +334,7 @@
     int i;
 
     for (i = 0; i < 256; i++)
-	dest[i] += src[i] + bias;
+	dest[i] += BIAS (src[i]);
 }
 
 static void mix3to1 (sample_t * samples, sample_t bias)
@@ -307,7 +342,7 @@
     int i;
 
     for (i = 0; i < 256; i++)
-	samples[i] += samples[i + 256] + samples[i + 512] + bias;
+	samples[i] += BIAS (samples[i + 256] + samples[i + 512]);
 }
 
 static void mix4to1 (sample_t * samples, sample_t bias)
@@ -315,8 +350,8 @@
     int i;
 
     for (i = 0; i < 256; i++)
-	samples[i] += (samples[i + 256] + samples[i + 512] +
-		       samples[i + 768] + bias);
+	samples[i] += BIAS (samples[i + 256] + samples[i + 512] +
+			    samples[i + 768]);
 }
 
 static void mix5to1 (sample_t * samples, sample_t bias)
@@ -324,8 +359,8 @@
     int i;
 
     for (i = 0; i < 256; i++)
-	samples[i] += (samples[i + 256] + samples[i + 512] +
-		       samples[i + 768] + samples[i + 1024] + bias);
+	samples[i] += BIAS (samples[i + 256] + samples[i + 512] +
+			    samples[i + 768] + samples[i + 1024]);
 }
 
 static void mix3to2 (sample_t * samples, sample_t bias)
@@ -334,7 +369,7 @@
     sample_t common;
 
     for (i = 0; i < 256; i++) {
-	common = samples[i + 256] + bias;
+	common = BIAS (samples[i + 256]);
 	samples[i] += common;
 	samples[i + 256] = samples[i + 512] + common;
     }
@@ -346,7 +381,7 @@
     sample_t common;
 
     for (i = 0; i < 256; i++) {
-	common = right[i + 256] + bias;
+	common = BIAS (right[i + 256]);
 	left[i] += common;
 	right[i] += common;
     }
@@ -359,8 +394,8 @@
 
     for (i = 0; i < 256; i++) {
 	surround = samples[i + 512];
-	samples[i] += bias - surround;
-	samples[i + 256] += bias + surround;
+	samples[i] += BIAS (-surround);
+	samples[i + 256] += BIAS (surround);
     }
 }
 
@@ -370,7 +405,7 @@
     sample_t common;
 
     for (i = 0; i < 256; i++) {
-	common = samples[i + 256] + samples[i + 768] + bias;
+	common = BIAS (samples[i + 256] + samples[i + 768]);
 	samples[i] += common;
 	samples[i + 256] = samples[i + 512] + common;
     }
@@ -382,7 +417,7 @@
     sample_t common, surround;
 
     for (i = 0; i < 256; i++) {
-	common = samples[i + 256] + bias;
+	common = BIAS (samples[i + 256]);
 	surround = samples[i + 768];
 	samples[i] += common - surround;
 	samples[i + 256] = samples[i + 512] + common + surround;
@@ -396,8 +431,8 @@
 
     for (i = 0; i < 256; i++) {
 	surround = samples[i + 512] + samples[i + 768];
-	samples[i] += bias - surround;
-	samples[i + 256] += bias + surround;
+	samples[i] += BIAS (-surround);
+	samples[i + 256] += BIAS (surround);
     }
 }
 
@@ -407,7 +442,7 @@
     sample_t common;
 
     for (i = 0; i < 256; i++) {
-	common = samples[i + 256] + bias;
+	common = BIAS (samples[i + 256]);
 	samples[i] += common + samples[i + 768];
 	samples[i + 256] = common + samples[i + 512] + samples[i + 1024];
     }
@@ -419,7 +454,7 @@
     sample_t common, surround;
 
     for (i = 0; i < 256; i++) {
-	common = samples[i + 256] + bias;
+	common = BIAS (samples[i + 256]);
 	surround = samples[i + 768] + samples[i + 1024];
 	samples[i] += common - surround;
 	samples[i + 256] = samples[i + 512] + common + surround;
@@ -431,7 +466,7 @@
     int i;
 
     for (i = 0; i < 256; i++)
-	dest[i] = src[i] + src[i + 256] + bias;
+	dest[i] = BIAS (src[i] + src[i + 256]);
 }
 
 static void zero (sample_t * samples)
@@ -443,7 +478,7 @@
 }
 
 void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
-		  sample_t clev, sample_t slev)
+		  level_t clev, level_t slev)
 {
     switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
 
@@ -578,7 +613,7 @@
 	break;
 
     case CONVERT (A52_3F1R, A52_3F2R):
-	memcpy (samples + 1027, samples + 768, 256 * sizeof (sample_t));
+	memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
 	break;
     }
 }