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