svn commit: r193889 - in head/sys: conf modules/sound/sound tools tools/sound

Ariff Abdullah ariff at FreeBSD.org
Wed Jun 10 06:49:46 UTC 2009


Author: ariff
Date: Wed Jun 10 06:49:45 2009
New Revision: 193889
URL: http://svn.freebsd.org/changeset/base/193889

Log:
  Move all sound related scripts to its own 'sound' subdir.
  
  Suggested by:	jmallett

Added:
  head/sys/tools/sound/
  head/sys/tools/sound/emu10k1-mkalsa.sh
     - copied unchanged from r193887, head/sys/tools/emu10k1-mkalsa.sh
  head/sys/tools/sound/feeder_eq_mkfilter.awk
     - copied unchanged from r193887, head/sys/tools/feeder_eq_mkfilter.awk
  head/sys/tools/sound/feeder_rate_mkfilter.awk
     - copied unchanged from r193887, head/sys/tools/feeder_rate_mkfilter.awk
  head/sys/tools/sound/snd_fxdiv_gen.awk
     - copied unchanged from r193887, head/sys/tools/snd_fxdiv_gen.awk
Deleted:
  head/sys/tools/emu10k1-mkalsa.sh
  head/sys/tools/feeder_eq_mkfilter.awk
  head/sys/tools/feeder_rate_mkfilter.awk
  head/sys/tools/snd_fxdiv_gen.awk
Modified:
  head/sys/conf/files
  head/sys/modules/sound/sound/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Wed Jun 10 05:26:21 2009	(r193888)
+++ head/sys/conf/files	Wed Jun 10 06:49:45 2009	(r193889)
@@ -51,33 +51,33 @@ aic79xx_reg_print.o		optional ahd pci ah
 	compile-with	"${NORMAL_C}"					   \
 	no-implicit-rule local
 emu10k1-alsa%diked.h		optional snd_emu10k1 | snd_emu10kx	   \
-	dependency	"$S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h" \
-	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h emu10k1-alsa%diked.h" \
+	dependency	"$S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h" \
+	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h emu10k1-alsa%diked.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"emu10k1-alsa%diked.h"
 p16v-alsa%diked.h		optional snd_emu10kx pci			   \
-	dependency	"$S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h" \
-	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h p16v-alsa%diked.h" \
+	dependency	"$S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h" \
+	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h p16v-alsa%diked.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"p16v-alsa%diked.h"
 p17v-alsa%diked.h		optional snd_emu10kx pci			   \
-	dependency	"$S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h" \
-	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h p17v-alsa%diked.h" \
+	dependency	"$S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h" \
+	compile-with	"CC='${CC}' AWK=${AWK} sh $S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h p17v-alsa%diked.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"p17v-alsa%diked.h"
 feeder_eq_gen.h			optional sound				   \
-	dependency	"$S/tools/feeder_eq_mkfilter.awk"		   \
-	compile-with	"${AWK} -f $S/tools/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \
+	dependency	"$S/tools/sound/feeder_eq_mkfilter.awk"		   \
+	compile-with	"${AWK} -f $S/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"feeder_eq_gen.h"
 feeder_rate_gen.h		optional sound				   \
-	dependency	"$S/tools/feeder_rate_mkfilter.awk"		   \
-	compile-with	"${AWK} -f $S/tools/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \
+	dependency	"$S/tools/sound/feeder_rate_mkfilter.awk"		   \
+	compile-with	"${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"feeder_rate_gen.h"
 snd_fxdiv_gen.h			optional sound				   \
-	dependency	"$S/tools/snd_fxdiv_gen.awk"			   \
-	compile-with	"${AWK} -f $S/tools/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \
+	dependency	"$S/tools/sound/snd_fxdiv_gen.awk"			   \
+	compile-with	"${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"snd_fxdiv_gen.h"
 miidevs.h			optional miibus | mii			   \

Modified: head/sys/modules/sound/sound/Makefile
==============================================================================
--- head/sys/modules/sound/sound/Makefile	Wed Jun 10 05:26:21 2009	(r193888)
+++ head/sys/modules/sound/sound/Makefile	Wed Jun 10 06:49:45 2009	(r193889)
@@ -19,14 +19,14 @@ SRCS+=	ac97.c ac97_patch.c buffer.c chan
 SRCS+=	mixer.c sndstat.c sound.c unit.c vchan.c
 SRCS+=	midi.c mpu401.c sequencer.c
 
-feeder_eq_gen.h:	@ @/tools/feeder_eq_mkfilter.awk machine
-	${AWK} -f @/tools/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > ${.TARGET}
+feeder_eq_gen.h:	@ @/tools/sound/feeder_eq_mkfilter.awk machine
+	${AWK} -f @/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > ${.TARGET}
 
-feeder_rate_gen.h:	@ @/tools/feeder_rate_mkfilter.awk machine
-	${AWK} -f @/tools/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > ${.TARGET}
+feeder_rate_gen.h:	@ @/tools/sound/feeder_rate_mkfilter.awk machine
+	${AWK} -f @/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > ${.TARGET}
 
-snd_fxdiv_gen.h:	@ @/tools/snd_fxdiv_gen.awk machine
-	${AWK} -f @/tools/snd_fxdiv_gen.awk -- > ${.TARGET}
+snd_fxdiv_gen.h:	@ @/tools/sound/snd_fxdiv_gen.awk machine
+	${AWK} -f @/tools/sound/snd_fxdiv_gen.awk -- > ${.TARGET}
 
 CLEANFILES+=	feeder_eq_gen.h feeder_rate_gen.h snd_fxdiv_gen.h
 

Copied: head/sys/tools/sound/emu10k1-mkalsa.sh (from r193887, head/sys/tools/emu10k1-mkalsa.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/tools/sound/emu10k1-mkalsa.sh	Wed Jun 10 06:49:45 2009	(r193889, copy of r193887, head/sys/tools/emu10k1-mkalsa.sh)
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+GREP=${GREP:-grep}
+CC=${CC:-cc}
+AWK=${AWK:-awk}
+MV=${MV:=mv}
+RM=${RM:=rm}
+IN=$1
+OUT=$2
+
+trap "${RM} -f $OUT.tmp" EXIT
+
+$GREP -v '#include' $IN | \
+$CC -E -D__KERNEL__ -dM -  | \
+$AWK -F"[     (]" '
+/define/  {
+	print "#ifndef " $2;
+	print;
+	print "#endif";
+}' > $OUT.tmp
+${MV} -f $OUT.tmp $OUT

Copied: head/sys/tools/sound/feeder_eq_mkfilter.awk (from r193887, head/sys/tools/feeder_eq_mkfilter.awk)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/tools/sound/feeder_eq_mkfilter.awk	Wed Jun 10 06:49:45 2009	(r193889, copy of r193887, head/sys/tools/feeder_eq_mkfilter.awk)
@@ -0,0 +1,467 @@
+#!/usr/bin/awk -f
+#
+# Copyright (c) 2008-2009 Ariff Abdullah <ariff at FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#
+# Biquad coefficients generator for Parametric Software Equalizer. Not as ugly
+# as 'feeder_rate_mkfilter.awk'
+#
+# Based on:
+#
+#  "Cookbook formulae for audio EQ biquad filter coefficients"
+#    by Robert Bristow-Johnson  <rbj at audioimagination.com>
+#
+#    -  http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+#
+
+
+
+#
+# Some basic Math functions.
+#
+function abs(x)
+{
+	return (((x < 0) ? -x : x) + 0);
+}
+
+function fabs(x)
+{
+	return (((x < 0.0) ? -x : x) + 0.0);
+}
+
+function floor(x, r)
+{
+	r = int(x);
+	if (r > x)
+		r--;
+	return (r + 0);
+}
+
+function pow(x, y)
+{
+	return (exp(1.0 * y * log(1.0 * x)));
+}
+
+#
+# What the hell...
+#
+function shl(x, y)
+{
+	while (y > 0) {
+		x *= 2;
+		y--;
+	}
+	return (x);
+}
+
+function feedeq_w0(fc, rate)
+{
+	return ((2.0 * M_PI * fc) / (1.0 * rate));
+}
+
+function feedeq_A(gain, A)
+{
+	if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ || FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF)
+		A = pow(10, gain / 40.0);
+	else
+		A = sqrt(pow(10, gain / 20.0));
+
+	return (A);
+}
+
+function feedeq_alpha(w0, A, QS)
+{
+	if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ)
+		alpha = sin(w0) / (2.0 * QS);
+	else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF)
+		alpha = sin(w0) * 0.5 * sqrt(A + ((1.0 / A) *		\
+		    ((1.0 / QS) - 1.0)) + 2.0);
+	else
+		alpha = 0.0;
+
+	return (alpha);
+}
+
+function feedeq_fx_floor(v, r)
+{
+	if (fabs(v) < fabs(smallest))
+		smallest = v;
+	if (fabs(v) > fabs(largest))
+		largest = v;
+
+	r = floor((v * FEEDEQ_COEFF_ONE) + 0.5);
+
+	if (r < INT32_MIN || r > INT32_MAX)
+		printf("\n#error overflow v=%f, "			\
+		    "please reduce FEEDEQ_COEFF_SHIFT\n", v);
+
+	return (r);
+}
+
+function feedeq_gen_biquad_coeffs(coeffs, rate, gain,			\
+    w0, A, alpha, a0, a1, a2, b0, b1, b2)
+{
+	w0    = feedeq_w0(FEEDEQ_TREBLE_SFREQ, 1.0 * rate);
+	A     = feedeq_A(1.0 * gain);
+	alpha = feedeq_alpha(w0, A, FEEDEQ_TREBLE_SLOPE);
+
+	if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ) {
+		b0 =  1.0 + (alpha * A);
+		b1 = -2.0 * cos(w0);
+		b2 =  1.0 - (alpha * A);
+		a0 =  1.0 + (alpha / A);
+		a1 = -2.0 * cos(w0);
+		a2 =  1.0 - (alpha / A);
+	} else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) {
+		b0 =      A*((A+1.0)+((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha));
+		b1 = -2.0*A*((A-1.0)+((A+1.0)*cos(w0))                    );
+		b2 =      A*((A+1.0)+((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha));
+		a0 =         (A+1.0)-((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha );
+		a1 =  2.0 * ((A-1.0)-((A+1.0)*cos(w0))                    );
+		a2 =         (A+1.0)-((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha );
+	} else
+		b0 = b1 = b2 = a0 = a1 = a2 = 0.0;
+
+	b0 /= a0;
+	b1 /= a0;
+	b2 /= a0;
+	a1 /= a0;
+	a2 /= a0;
+
+	coeffs["treble", gain, 0] = feedeq_fx_floor(a0);
+	coeffs["treble", gain, 1] = feedeq_fx_floor(a1);
+	coeffs["treble", gain, 2] = feedeq_fx_floor(a2);
+	coeffs["treble", gain, 3] = feedeq_fx_floor(b0);
+	coeffs["treble", gain, 4] = feedeq_fx_floor(b1);
+	coeffs["treble", gain, 5] = feedeq_fx_floor(b2);
+
+	w0    = feedeq_w0(FEEDEQ_BASS_SFREQ, 1.0 * rate);
+	A     = feedeq_A(1.0 * gain);
+	alpha = feedeq_alpha(w0, A, FEEDEQ_BASS_SLOPE);
+
+	if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ) {
+		b0 =  1.0 + (alpha * A);
+		b1 = -2.0 * cos(w0);
+		b2 =  1.0 - (alpha * A);
+		a0 =  1.0 + (alpha / A);
+		a1 = -2.0 * cos(w0);
+		a2 =  1.0 - (alpha / A);
+	} else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) {
+		b0 =      A*((A+1.0)-((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha));
+		b1 =  2.0*A*((A-1.0)-((A+1.0)*cos(w0))                    );
+		b2 =      A*((A+1.0)-((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha));
+		a0 =         (A+1.0)+((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha );
+		a1 = -2.0 * ((A-1.0)+((A+1.0)*cos(w0))                    );
+		a2 =         (A+1.0)+((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha );
+	} else
+		b0 = b1 = b2 = a0 = a1 = a2 = 0.0;
+
+	b0 /= a0;
+	b1 /= a0;
+	b2 /= a0;
+	a1 /= a0;
+	a2 /= a0;
+
+	coeffs["bass", gain, 0] = feedeq_fx_floor(a0);
+	coeffs["bass", gain, 1] = feedeq_fx_floor(a1);
+	coeffs["bass", gain, 2] = feedeq_fx_floor(a2);
+	coeffs["bass", gain, 3] = feedeq_fx_floor(b0);
+	coeffs["bass", gain, 4] = feedeq_fx_floor(b1);
+	coeffs["bass", gain, 5] = feedeq_fx_floor(b2);
+}
+
+function feedeq_gen_freq_coeffs(frq, g, i, v)
+{
+	coeffs[0] = 0;
+
+	for (g = (FEEDEQ_GAIN_MIN * FEEDEQ_GAIN_DIV);			\
+	    g <= (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV);			\
+	    g += FEEDEQ_GAIN_STEP) {
+		feedeq_gen_biquad_coeffs(coeffs, frq,			\
+		    g * FEEDEQ_GAIN_RECIPROCAL);
+	}
+
+	printf("\nstatic struct feed_eq_coeff eq_%d[%d] "		\
+	    "= {\n", frq, FEEDEQ_LEVELS);
+	for (g = (FEEDEQ_GAIN_MIN * FEEDEQ_GAIN_DIV);			\
+	    g <= (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV);			\
+	    g += FEEDEQ_GAIN_STEP) {
+		printf("     {{ ");
+		for (i = 1; i < 6; i++) {
+			v = coeffs["treble", g * FEEDEQ_GAIN_RECIPROCAL, i];
+			printf("%s0x%08x%s",				\
+			    (v < 0) ? "-" : " ", abs(v),		\
+			    (i == 5) ? " " : ", ");
+		}
+		printf("},\n      { ");
+		for (i = 1; i < 6; i++) {
+			v = coeffs["bass", g * FEEDEQ_GAIN_RECIPROCAL, i];
+			printf("%s0x%08x%s",				\
+			    (v < 0) ? "-" : " ", abs(v),		\
+			    (i == 5) ? " " : ", ");
+		}
+		printf("}}%s\n",					\
+		    (g < (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV)) ? "," : "");
+	}
+	printf("};\n");
+}
+
+function feedeq_calc_preamp(norm, gain, shift, mul, bit, attn)
+{
+	shift = FEEDEQ_PREAMP_SHIFT;
+
+	if (floor(FEEDEQ_PREAMP_BITDB) == 6 &&				\
+	    (1.0 * floor(gain)) == gain && (floor(gain) % 6) == 0) {
+		mul = 1;
+		shift = floor(floor(gain) / 6);
+	} else {
+		bit = 32.0 - ((1.0 * gain) / (1.0 * FEEDEQ_PREAMP_BITDB));
+		attn = pow(2.0, bit) / pow(2.0, 32.0);
+		mul = floor((attn * FEEDEQ_PREAMP_ONE) + 0.5);
+	}
+
+	while ((mul % 2) == 0 && shift > 0) {
+		mul = floor(mul / 2);
+		shift--;
+	}
+
+	norm["mul"] = mul;
+	norm["shift"] = shift;
+}
+
+BEGIN {
+	M_PI = atan2(0.0, -1.0);
+
+	INT32_MAX = 1 + ((shl(1, 30) - 1) * 2);
+	INT32_MIN = -1 - INT32_MAX;
+
+	FEEDEQ_TYPE_PEQ   = 0;
+	FEEDEQ_TYPE_SHELF = 1;
+
+	FEEDEQ_TYPE       = FEEDEQ_TYPE_PEQ;
+
+	FEEDEQ_COEFF_SHIFT = 24;
+	FEEDEQ_COEFF_ONE   = shl(1, FEEDEQ_COEFF_SHIFT);
+
+	FEEDEQ_PREAMP_SHIFT = 31;
+	FEEDEQ_PREAMP_ONE   = shl(1, FEEDEQ_PREAMP_SHIFT);
+	FEEDEQ_PREAMP_BITDB = 6; # 20.0 * (log(2.0) / log(10.0));
+
+	FEEDEQ_GAIN_DIV   = 10;
+	i = 0;
+	j = 1;
+	while (j < FEEDEQ_GAIN_DIV) {
+		j *= 2;
+		i++;
+	}
+	FEEDEQ_GAIN_SHIFT = i;
+	FEEDEQ_GAIN_FMASK = shl(1, FEEDEQ_GAIN_SHIFT) - 1;
+
+	FEEDEQ_GAIN_RECIPROCAL = 1.0 / FEEDEQ_GAIN_DIV;
+
+	if (ARGC == 2) {
+		i = 1;
+		split(ARGV[1], arg, ":");
+		while (match(arg[i], "^[^0-9]*$")) {
+			if (arg[i] == "PEQ") {
+				FEEDEQ_TYPE = FEEDEQ_TYPE_PEQ;
+			} else if (arg[i] == "SHELF") {
+				FEEDEQ_TYPE = FEEDEQ_TYPE_SHELF;
+			}
+			i++;
+		}
+		split(arg[i++], subarg, ",");
+		FEEDEQ_TREBLE_SFREQ = 1.0 * subarg[1];
+		FEEDEQ_TREBLE_SLOPE = 1.0 * subarg[2];
+		split(arg[i++], subarg, ",");
+		FEEDEQ_BASS_SFREQ = 1.0 * subarg[1];
+		FEEDEQ_BASS_SLOPE = 1.0 * subarg[2];
+		split(arg[i++], subarg, ",");
+		FEEDEQ_GAIN_MIN = floor(1.0 * subarg[1]);
+		FEEDEQ_GAIN_MAX = floor(1.0 * subarg[2]);
+		if (length(subarg) > 2) {
+			j = floor(1.0 * FEEDEQ_GAIN_DIV * subarg[3]);
+			if (j < 2)
+				j = 1;
+			else if (j < 5)
+				j = 2;
+			else if (j < 10)
+				j = 5;
+			else
+				j = 10;
+			if (j > FEEDEQ_GAIN_DIV || (FEEDEQ_GAIN_DIV % j) != 0)
+				j = FEEDEQ_GAIN_DIV;
+			FEEDEQ_GAIN_STEP = j;
+		} else
+			FEEDEQ_GAIN_STEP = FEEDEQ_GAIN_DIV;
+		split(arg[i], subarg, ",");
+		for (i = 1; i <= length(subarg); i++)
+			allfreq[i - 1] = floor(1.0 * subarg[i]);
+	} else {
+		FEEDEQ_TREBLE_SFREQ  = 16000.0;
+		FEEDEQ_TREBLE_SLOPE  = 0.25;
+		FEEDEQ_BASS_SFREQ    = 62.0;
+		FEEDEQ_BASS_SLOPE    = 0.25;
+
+		FEEDEQ_GAIN_MIN  = -9;
+		FEEDEQ_GAIN_MAX  = 9;
+
+		FEEDEQ_GAIN_STEP = FEEDEQ_GAIN_DIV;
+
+
+		allfreq[0] = 44100;
+		allfreq[1] = 48000;
+		allfreq[2] = 88200;
+		allfreq[3] = 96000;
+		allfreq[4] = 176400;
+		allfreq[5] = 192000;
+	}
+
+	FEEDEQ_LEVELS = ((FEEDEQ_GAIN_MAX - FEEDEQ_GAIN_MIN) *		\
+	    floor(FEEDEQ_GAIN_DIV / FEEDEQ_GAIN_STEP)) + 1;
+
+	FEEDEQ_ERR_CLIP = 0;
+
+	smallest = 10.000000;
+	largest  =  0.000010;
+
+	printf("#ifndef _FEEDER_EQ_GEN_H_\n");
+	printf("#define _FEEDER_EQ_GEN_H_\n\n");
+	printf("/*\n");
+	printf(" * Generated using feeder_eq_mkfilter.awk, heaven, wind and awesome.\n");
+	printf(" *\n");
+	printf(" * DO NOT EDIT!\n");
+	printf(" */\n\n");
+	printf("/*\n");
+	printf(" * EQ: %s\n", (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) ?	\
+	    "Shelving" : "Peaking EQ");
+	printf(" */\n");
+	printf("#define FEEDER_EQ_PRESETS\t\"");
+	printf("%s:%d,%.4f,%d,%.4f:%d,%d,%.1f:",			\
+	    (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) ? "SHELF" : "PEQ",	\
+	    FEEDEQ_TREBLE_SFREQ, FEEDEQ_TREBLE_SLOPE,			\
+	    FEEDEQ_BASS_SFREQ, FEEDEQ_BASS_SLOPE,			\
+	    FEEDEQ_GAIN_MIN, FEEDEQ_GAIN_MAX,				\
+	    FEEDEQ_GAIN_STEP * FEEDEQ_GAIN_RECIPROCAL);
+	for (i = 0; i < length(allfreq); i++) {
+		if (i != 0)
+			printf(",");
+		printf("%d", allfreq[i]);
+	}
+	printf("\"\n\n");
+	printf("struct feed_eq_coeff_tone {\n");
+	printf("\tint32_t a1, a2;\n");
+	printf("\tint32_t b0, b1, b2;\n");
+	printf("};\n\n");
+	printf("struct feed_eq_coeff {\n");
+	#printf("\tstruct {\n");
+	#printf("\t\tint32_t a1, a2;\n");
+	#printf("\t\tint32_t b0, b1, b2;\n");
+	#printf("\t} treble, bass;\n");
+	printf("\tstruct feed_eq_coeff_tone treble;\n");
+	printf("\tstruct feed_eq_coeff_tone bass;\n");
+	#printf("\tstruct {\n");
+	#printf("\t\tint32_t a1, a2;\n");
+	#printf("\t\tint32_t b0, b1, b2;\n");
+	#printf("\t} bass;\n");
+	printf("};\n");
+	for (i = 0; i < length(allfreq); i++)
+		feedeq_gen_freq_coeffs(allfreq[i]);
+	printf("\n");
+	printf("static const struct {\n");
+	printf("\tuint32_t rate;\n");
+	printf("\tstruct feed_eq_coeff *coeff;\n");
+	printf("} feed_eq_tab[] = {\n");
+	for (i = 0; i < length(allfreq); i++) {
+		printf("\t{ %6d, eq_%-6d },\n", allfreq[i], allfreq[i]);
+	}
+	printf("};\n");
+
+	printf("\n#define FEEDEQ_RATE_MIN\t\t%d\n", allfreq[0]);
+	printf("#define FEEDEQ_RATE_MAX\t\t%d\n", allfreq[length(allfreq) - 1]);
+	printf("\n#define FEEDEQ_TAB_SIZE\t\t\t\t\t\t\t\\\n");
+	printf("\t((int32_t)(sizeof(feed_eq_tab) / sizeof(feed_eq_tab[0])))\n");
+
+	printf("\nstatic const struct {\n");
+	printf("\tint32_t mul, shift;\n");
+	printf("} feed_eq_preamp[] = {\n");
+	for (i = (FEEDEQ_GAIN_MAX * 2 * FEEDEQ_GAIN_DIV); i >= 0;	\
+	    i -= FEEDEQ_GAIN_STEP) {
+		feedeq_calc_preamp(norm, i * FEEDEQ_GAIN_RECIPROCAL);
+		dbgain = ((FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV) - i) *	\
+		    FEEDEQ_GAIN_RECIPROCAL;
+		printf("\t{ 0x%08x, 0x%08x },\t/* %+5.1f dB */\n",	\
+		    norm["mul"], norm["shift"], dbgain);
+	}
+	printf("};\n");
+
+	printf("\n#define FEEDEQ_GAIN_MIN\t\t%d", FEEDEQ_GAIN_MIN);
+	printf("\n#define FEEDEQ_GAIN_MAX\t\t%d\n", FEEDEQ_GAIN_MAX);
+
+	printf("\n#define FEEDEQ_GAIN_SHIFT\t%d\n", FEEDEQ_GAIN_SHIFT);
+	printf("#define FEEDEQ_GAIN_DIV\t\t%d\n", FEEDEQ_GAIN_DIV);
+	printf("#define FEEDEQ_GAIN_FMASK\t0x%08x\n", FEEDEQ_GAIN_FMASK);
+	printf("#define FEEDEQ_GAIN_STEP\t%d\n", FEEDEQ_GAIN_STEP);
+
+	#printf("\n#define FEEDEQ_PREAMP_MIN\t-%d\n",			\
+	#    shl(FEEDEQ_GAIN_MAX, FEEDEQ_GAIN_SHIFT));
+	#printf("#define FEEDEQ_PREAMP_MAX\t%d\n",			\
+	#    shl(FEEDEQ_GAIN_MAX, FEEDEQ_GAIN_SHIFT));
+
+	printf("\n#define FEEDEQ_COEFF_SHIFT\t%d\n", FEEDEQ_COEFF_SHIFT);
+
+	#feedeq_calc_preamp(norm, FEEDEQ_GAIN_MAX);
+
+	#printf("#define FEEDEQ_COEFF_NORM(v)\t(");
+	#if (norm["mul"] == 1)
+	#	printf("(v) >> %d", norm["shift"]);
+	#else
+	#	printf("(0x%xLL * (v)) >> %d", norm["mul"], norm["shift"]);
+	#printf(")\n");
+
+	#printf("\n#define FEEDEQ_LEVELS\t\t%d\n", FEEDEQ_LEVELS);
+	if (FEEDEQ_ERR_CLIP != 0)
+		printf("\n#define FEEDEQ_ERR_CLIP\t\t%d\n", FEEDEQ_ERR_CLIP);
+	printf("\n/*\n");
+	printf(" * volume level mapping (0 - 100):\n");
+	printf(" *\n");
+
+	for (i = 0; i <= 100; i++) {
+		ind = floor((i * FEEDEQ_LEVELS) / 100);
+		if (ind >= FEEDEQ_LEVELS)
+			ind = FEEDEQ_LEVELS - 1;
+		printf(" *\t%3d  ->  %3d (%+5.1f dB)\n",		\
+		    i, ind, FEEDEQ_GAIN_MIN +				\
+		    (ind * (FEEDEQ_GAIN_RECIPROCAL * FEEDEQ_GAIN_STEP)));
+	}
+
+	printf(" */\n");
+	printf("\n/*\n * smallest: %.32f\n *  largest: %.32f\n */\n",	\
+	    smallest, largest);
+	printf("\n#endif\t/* !_FEEDER_EQ_GEN_H_ */\n");
+}

Copied: head/sys/tools/sound/feeder_rate_mkfilter.awk (from r193887, head/sys/tools/feeder_rate_mkfilter.awk)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/tools/sound/feeder_rate_mkfilter.awk	Wed Jun 10 06:49:45 2009	(r193889, copy of r193887, head/sys/tools/feeder_rate_mkfilter.awk)
@@ -0,0 +1,767 @@
+#!/usr/bin/awk -f
+#
+# Copyright (c) 2007-2009 Ariff Abdullah <ariff at FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#
+# FIR filter design by windowing method. This might become one of the
+# funniest joke I've ever written due to too many tricks being applied to
+# ensure maximum precision (well, in fact this is already have the same
+# precision granularity compared to its C counterpart). Nevertheless, it's
+# working, precise, dynamically tunable based on "presets".
+#
+# XXX EXPECT TOTAL REWRITE! DON'T ARGUE!
+#
+# TODO: Using ultraspherical window might be a good idea.
+#
+# Based on:
+#
+# "Digital Audio Resampling" by Julius O. Smith III
+#
+#  - http://ccrma.stanford.edu/~jos/resample/
+#
+
+#
+# Some basic Math functions.
+#
+function abs(x)
+{
+	return (((x < 0) ? -x : x) + 0);
+}
+
+function fabs(x)
+{
+	return (((x < 0.0) ? -x : x) + 0.0);
+}
+
+function ceil(x, r)
+{
+	r = int(x);
+	if (r < x)
+		r++;
+	return (r + 0);
+}
+
+function floor(x, r)
+{
+	r = int(x);
+	if (r > x)
+		r--;
+	return (r + 0);
+}
+
+function pow(x, y)
+{
+	return (exp(1.0 * y * log(1.0 * x)));
+}
+
+#
+# What the hell...
+#
+function shl(x, y)
+{
+	while (y > 0) {
+		x *= 2;
+		y--;
+	}
+	return (x);
+}
+
+function shr(x, y)
+{
+	while (y > 0 && x != 0) {
+		x = floor(x / 2);
+		y--;
+	}
+	return (x);
+}
+
+function fx_floor(v, o, r)
+{
+	if (fabs(v) < fabs(smallest))
+		smallest = v;
+	if (fabs(v) > fabs(largest))
+		largest = v;
+
+	r = floor((v * o) + 0.5);
+	if (r < INT32_MIN || r > INT32_MAX)
+		printf("\n#error overflow v=%f, please reduce %d\n", v, o);
+
+	return (r);
+}
+
+#
+# Kaiser linear piecewise functions.
+#
+function kaiserAttn2Beta(attn, beta)
+{
+	if (attn < 0.0)
+		return (Z_KAISER_BETA_DEFAULT);
+
+	if (attn > 50.0)
+		beta = 0.1102 * ((1.0 * attn) - 8.7);
+	else if (attn > 21.0)
+		beta = (0.5842 * pow((1.0 * attn) - 21.0, 0.4)) +	\
+		    (0.07886 * ((1.0 * attn) - 21.0));
+	else
+		beta = 0.0;
+
+	return (beta);
+}
+
+function kaiserBeta2Attn(beta, x, y, i, attn, xbeta)
+{
+	if (beta < Z_WINDOW_KAISER)
+		return (Z_KAISER_ATTN_DEFAULT);
+	
+	if (beta > kaiserAttn2Beta(50.0))
+		attn = ((1.0 * beta) / 0.1102) + 8.7;
+	else {
+		x = 21.0;
+		y = 50.0;
+		attn = 0.5 * (x + y);
+		for (i = 0; i < 128; i++) {
+			xbeta = kaiserAttn2Beta(attn)
+			if (beta == xbeta ||				\
+			    (i > 63 &&					\
+			    fabs(beta - xbeta) < Z_KAISER_EPSILON))
+				break;
+			if (beta > xbeta)
+				x = attn;
+			else
+				y = attn;
+			attn = 0.5 * (x + y);
+		}
+	}
+
+	return (attn);
+}
+
+function kaiserRolloff(len, attn)
+{
+	return (1.0 - (((1.0 * attn) - 7.95) / (((1.0 * len) - 1.0) * 14.36)));
+}
+
+#
+# 0th order modified Bessel function of the first kind.
+#
+function I0(x, s, u, n, h, t)
+{
+	s = n = u = 1.0;
+	h = x * 0.5;
+
+	do {
+		t = h / n;
+		n += 1.0;
+		t *= t;
+		u *= t;
+		s += u;
+	} while (u >= (I0_EPSILON * s));
+
+	return (s);
+}
+
+function wname(beta)
+{
+	if (beta >= Z_WINDOW_KAISER)
+		return ("Kaiser");
+	else if (beta == Z_WINDOW_BLACKMAN_NUTTALL)
+		return ("Blackman - Nuttall");
+	else if (beta == Z_WINDOW_NUTTALL)
+		return ("Nuttall");
+	else if (beta == Z_WINDOW_BLACKMAN_HARRIS)
+		return ("Blackman - Harris");
+	else if (beta == Z_WINDOW_BLACKMAN)
+		return ("Blackman");
+	else if (beta == Z_WINDOW_HAMMING)
+		return ("Hamming");
+	else if (beta == Z_WINDOW_HANN)
+		return ("Hann");
+	else
+		return ("What The Hell !?!?");
+}
+
+function rolloff_round(x)
+{
+	if (x < 0.67)
+		x = 0.67;
+	else if (x > 1.0)
+		x = 1.0;
+	
+	return (x);
+}
+
+function tap_round(x, y)
+{
+	y = floor(x + 3);
+	y -= y % 4;
+	return (y);
+}
+
+function lpf(imp, n, rolloff, beta, num, i, j, x, nm, ibeta, w)
+{
+	rolloff = rolloff_round(rolloff + (Z_NYQUIST_HOVER * (1.0 - rolloff)));
+	imp[0] = rolloff;
+
+	#
+	# Generate ideal sinc impulses, locate the last zero-crossing and pad
+	# the remaining with 0.
+	#
+	# Note that there are other (faster) ways of calculating this without
+	# the misery of traversing the entire sinc given the fact that the
+	# distance between each zero crossings is actually the bandwidth of
+	# the impulses, but it seems having 0.0001% chances of failure due to
+	# limited precision.
+	#
+	j = n;
+	for (i = 1; i < n; i++) {
+		x = (M_PI * i) / (1.0 * num);
+		imp[i] = sin(x * rolloff) / x;
+		if (i != 1 && (imp[i] * imp[i - 1]) <= 0.0)
+			j = i;
+	}
+
+	for (i = j; i < n; i++)
+		imp[i] = 0.0;
+
+	nm = 1.0 * (j - 1);
+
+	if (beta >= Z_WINDOW_KAISER)
+		ibeta = I0(beta);
+
+	for (i = 1; i < j; i++) {
+		if (beta >= Z_WINDOW_KAISER) {
+			# Kaiser window...
+			x = (1.0 * i) / nm;
+			w = I0(beta * sqrt(1.0 - (x * x))) / ibeta;
+		} else {
+			# Cosined windows...
+			x = (M_PI * i) / nm;
+			if (beta == Z_WINDOW_BLACKMAN_NUTTALL) {
+				# Blackman - Nuttall
+				w = 0.36335819 + (0.4891775 * cos(x)) +	\
+				    (0.1365995 * cos(2 * x)) +		\
+				    (0.0106411 * cos(3 * x));
+			} else if (beta == Z_WINDOW_NUTTALL) {
+				# Nuttall
+		        	w = 0.355768 + (0.487396 * cos(x)) +	\
+				    (0.144232 * cos(2 * x)) +		\
+				    (0.012604 * cos(3 * x));
+			} else if (beta == Z_WINDOW_BLACKMAN_HARRIS) {
+				# Blackman - Harris
+				w = 0.422323 + (0.49755 * cos(x)) +	\
+				    (0.07922 * cos(2 * x));
+			} else if (beta == Z_WINDOW_BLACKMAN) {
+				# Blackman
+				w = 0.42 + (0.50 * cos(x)) +		\
+				    (0.08 * cos(2 * x));
+			} else if (beta == Z_WINDOW_HAMMING) {
+				# Hamming
+				w = 0.54 + (0.46 * cos(x));
+			} else if (beta == Z_WINDOW_HANN) {
+				# Hann
+				w = 0.50 + (0.50 * cos(x));
+			} else {
+				# What The Hell !?!?
+				w = 0.0;
+			}
+		}
+		imp[i] *= w;
+	}
+
+	imp["impulse_length"] = j;
+	imp["rolloff"] = rolloff;
+}
+
+function mkfilter(imp, nmult, rolloff, beta, num,			\
+    nwing, mwing, nrolloff, i, dcgain, v, quality)
+{
+	nwing = floor((nmult * num) / 2) + 1;
+
+	lpf(imp, nwing, rolloff, beta, num);
+
+	mwing = imp["impulse_length"];
+	nrolloff = imp["rolloff"];
+	quality = imp["quality"];
+
+	dcgain = 0.0;
+	for (i = num; i < mwing; i += num)
+		dcgain += imp[i];
+	dcgain *= 2.0;
+	dcgain += imp[0];
+
+	for (i = 0; i < nwing; i++)
+		imp[i] /= dcgain;
+
+	if (quality > 2)
+		printf("\n");
+	printf("/*\n");
+	printf(" *   quality = %d\n", quality);
+	printf(" *    window = %s\n", wname(beta));
+	if (beta >= Z_WINDOW_KAISER) {
+		printf(" *             beta: %.2f\n", beta);
+		printf(" *             stop: -%.2f dB\n",		\
+		    kaiserBeta2Attn(beta));
+	}
+	printf(" *    length = %d\n", nmult);
+	printf(" * bandwidth = %.2f%%", rolloff * 100.0);
+	if (rolloff != nrolloff) {
+		printf(" + %.2f%% = %.2f%% (nyquist hover: %.2f%%)",	\
+		    (nrolloff - rolloff) * 100.0, nrolloff * 100.0,	\
+		    Z_NYQUIST_HOVER * 100.0);
+	}
+	printf("\n");
+	printf(" *     drift = %d\n", num);
+	printf(" *     width = %d\n", mwing);
+	printf(" */\n");
+	printf("static int32_t z_coeff_q%d[%d] = {",			\
+	    quality, nwing + (Z_COEFF_OFFSET * 2));
+	for (i = 0; i < (nwing + (Z_COEFF_OFFSET * 2)); i++) {
+		if ((i % 5) == 0)
+			printf("\n      ");
+		if (i < Z_COEFF_OFFSET)
+			v = fx_floor(imp[Z_COEFF_OFFSET - i], Z_COEFF_ONE);
+		else if ((i - Z_COEFF_OFFSET) >= nwing)
+			v = fx_floor(					\
+			    imp[nwing + nwing - i + Z_COEFF_OFFSET - 1],\
+			    Z_COEFF_ONE);
+		else
+			v = fx_floor(imp[i - Z_COEFF_OFFSET], Z_COEFF_ONE);
+		printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
+	}
+	printf("\n};\n\n");
+	printf("/*\n");
+	printf(" * interpolated q%d differences.\n", quality);
+	printf(" */\n");
+	printf("static int32_t z_dcoeff_q%d[%d] = {", quality, nwing);
+	for (i = 1; i <= nwing; i++) {
+		if ((i % 5) == 1)
+			printf("\n      ");
+		v = -imp[i - 1];
+		if (i != nwing)
+			v += imp[i];
+		v = fx_floor(v, Z_INTERP_COEFF_ONE);
+		if (abs(v) > abs(largest_interp))
+			largest_interp = v;
+		printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
+	}
+	printf("\n};\n");
+
+	return (nwing);
+}
+
+function filter_parse(s, a, i, attn, alen)
+{
+	split(s, a, ":");
+	alen = length(a);
+
+	if (alen == 1 || alen == 2) {
+		if (a[1] == "nyquist_hover") {
+			i = 1.0 * a[2];
+			Z_NYQUIST_HOVER = (i > 0.0 && i < 1.0) ? i : 0.0;
+			return (-1);
+		}
+		i = 1;
+		if (alen == 1) {
+			attn = Z_KAISER_ATTN_DEFAULT;
+			Popts["beta"] = Z_KAISER_BETA_DEFAULT;
+		} else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER) {
+			Popts["beta"] = Z_WINDOWS[a[1]];
+			i = tap_round(a[2]);
+			Popts["nmult"] = i;
+			if (i < 28)
+				i = 28;
+			i = 1.0 - (6.44 / i);
+			Popts["rolloff"] = rolloff_round(i);
+			return (0);
+		} else {
+			attn = 1.0 * a[i++];
+			Popts["beta"] = kaiserAttn2Beta(attn);
+		}
+		i = tap_round(a[i]);
+		Popts["nmult"] = i;
+		if (i > 7 && i < 28)
+			i = 27;
+		i = kaiserRolloff(i, attn);
+		Popts["rolloff"] = rolloff_round(i);
+
+		return (0);
+	}
+
+	if (!(alen == 3 || alen == 4))
+		return (-1);
+
+	i = 2;
+
+	if (a[1] == "kaiser") {
+		if (alen > 2)
+			Popts["beta"] = 1.0 * a[i++];
+		else
+			Popts["beta"] = Z_KAISER_BETA_DEFAULT;
+	} else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER)
+		Popts["beta"] = Z_WINDOWS[a[1]];
+	else if (1.0 * a[1] < Z_WINDOW_KAISER)
+		return (-1);
+	else
+		Popts["beta"] = kaiserAttn2Beta(1.0 * a[1]);
+	Popts["nmult"] = tap_round(a[i++]);
+	if (a[1] == "kaiser" && alen == 3)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list