1193640Sariff#!/usr/bin/awk -f 2193640Sariff# 3193640Sariff# Copyright (c) 2008-2009 Ariff Abdullah <ariff@FreeBSD.org> 4193640Sariff# All rights reserved. 5193640Sariff# 6193640Sariff# Redistribution and use in source and binary forms, with or without 7193640Sariff# modification, are permitted provided that the following conditions 8193640Sariff# are met: 9193640Sariff# 1. Redistributions of source code must retain the above copyright 10193640Sariff# notice, this list of conditions and the following disclaimer. 11193640Sariff# 2. Redistributions in binary form must reproduce the above copyright 12193640Sariff# notice, this list of conditions and the following disclaimer in the 13193640Sariff# documentation and/or other materials provided with the distribution. 14193640Sariff# 15193640Sariff# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16193640Sariff# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17193640Sariff# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18193640Sariff# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19193640Sariff# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20193640Sariff# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21193640Sariff# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22193640Sariff# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23193640Sariff# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24193640Sariff# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25193640Sariff# SUCH DAMAGE. 26193640Sariff# 27193640Sariff# $FreeBSD$ 28193640Sariff# 29193640Sariff 30193640Sariff# 31193640Sariff# Biquad coefficients generator for Parametric Software Equalizer. Not as ugly 32193640Sariff# as 'feeder_rate_mkfilter.awk' 33193640Sariff# 34193640Sariff# Based on: 35193640Sariff# 36193640Sariff# "Cookbook formulae for audio EQ biquad filter coefficients" 37193640Sariff# by Robert Bristow-Johnson <rbj@audioimagination.com> 38193640Sariff# 39193640Sariff# - http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt 40193640Sariff# 41193640Sariff 42193640Sariff 43193640Sariff 44193640Sariff# 45193640Sariff# Some basic Math functions. 46193640Sariff# 47193640Sarifffunction abs(x) 48193640Sariff{ 49193640Sariff return (((x < 0) ? -x : x) + 0); 50193640Sariff} 51193640Sariff 52193640Sarifffunction fabs(x) 53193640Sariff{ 54193640Sariff return (((x < 0.0) ? -x : x) + 0.0); 55193640Sariff} 56193640Sariff 57193640Sarifffunction floor(x, r) 58193640Sariff{ 59193640Sariff r = int(x); 60193640Sariff if (r > x) 61193640Sariff r--; 62193640Sariff return (r + 0); 63193640Sariff} 64193640Sariff 65193640Sarifffunction pow(x, y) 66193640Sariff{ 67193640Sariff return (exp(1.0 * y * log(1.0 * x))); 68193640Sariff} 69193640Sariff 70193640Sariff# 71193640Sariff# What the hell... 72193640Sariff# 73193640Sarifffunction shl(x, y) 74193640Sariff{ 75193640Sariff while (y > 0) { 76193640Sariff x *= 2; 77193640Sariff y--; 78193640Sariff } 79193640Sariff return (x); 80193640Sariff} 81193640Sariff 82193640Sarifffunction feedeq_w0(fc, rate) 83193640Sariff{ 84193640Sariff return ((2.0 * M_PI * fc) / (1.0 * rate)); 85193640Sariff} 86193640Sariff 87193640Sarifffunction feedeq_A(gain, A) 88193640Sariff{ 89193640Sariff if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ || FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) 90193640Sariff A = pow(10, gain / 40.0); 91193640Sariff else 92193640Sariff A = sqrt(pow(10, gain / 20.0)); 93193640Sariff 94193640Sariff return (A); 95193640Sariff} 96193640Sariff 97193640Sarifffunction feedeq_alpha(w0, A, QS) 98193640Sariff{ 99193640Sariff if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ) 100193640Sariff alpha = sin(w0) / (2.0 * QS); 101193640Sariff else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) 102193640Sariff alpha = sin(w0) * 0.5 * sqrt(A + ((1.0 / A) * \ 103193640Sariff ((1.0 / QS) - 1.0)) + 2.0); 104193640Sariff else 105193640Sariff alpha = 0.0; 106193640Sariff 107193640Sariff return (alpha); 108193640Sariff} 109193640Sariff 110193640Sarifffunction feedeq_fx_floor(v, r) 111193640Sariff{ 112193640Sariff if (fabs(v) < fabs(smallest)) 113193640Sariff smallest = v; 114193640Sariff if (fabs(v) > fabs(largest)) 115193640Sariff largest = v; 116193640Sariff 117193640Sariff r = floor((v * FEEDEQ_COEFF_ONE) + 0.5); 118193640Sariff 119193640Sariff if (r < INT32_MIN || r > INT32_MAX) 120193640Sariff printf("\n#error overflow v=%f, " \ 121193640Sariff "please reduce FEEDEQ_COEFF_SHIFT\n", v); 122193640Sariff 123193640Sariff return (r); 124193640Sariff} 125193640Sariff 126193640Sarifffunction feedeq_gen_biquad_coeffs(coeffs, rate, gain, \ 127193640Sariff w0, A, alpha, a0, a1, a2, b0, b1, b2) 128193640Sariff{ 129193640Sariff w0 = feedeq_w0(FEEDEQ_TREBLE_SFREQ, 1.0 * rate); 130193640Sariff A = feedeq_A(1.0 * gain); 131193640Sariff alpha = feedeq_alpha(w0, A, FEEDEQ_TREBLE_SLOPE); 132193640Sariff 133193640Sariff if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ) { 134193640Sariff b0 = 1.0 + (alpha * A); 135193640Sariff b1 = -2.0 * cos(w0); 136193640Sariff b2 = 1.0 - (alpha * A); 137193640Sariff a0 = 1.0 + (alpha / A); 138193640Sariff a1 = -2.0 * cos(w0); 139193640Sariff a2 = 1.0 - (alpha / A); 140193640Sariff } else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) { 141193640Sariff b0 = A*((A+1.0)+((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha)); 142193640Sariff b1 = -2.0*A*((A-1.0)+((A+1.0)*cos(w0)) ); 143193640Sariff b2 = A*((A+1.0)+((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha)); 144193640Sariff a0 = (A+1.0)-((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha ); 145193640Sariff a1 = 2.0 * ((A-1.0)-((A+1.0)*cos(w0)) ); 146193640Sariff a2 = (A+1.0)-((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha ); 147193640Sariff } else 148193640Sariff b0 = b1 = b2 = a0 = a1 = a2 = 0.0; 149193640Sariff 150193640Sariff b0 /= a0; 151193640Sariff b1 /= a0; 152193640Sariff b2 /= a0; 153193640Sariff a1 /= a0; 154193640Sariff a2 /= a0; 155193640Sariff 156193640Sariff coeffs["treble", gain, 0] = feedeq_fx_floor(a0); 157193640Sariff coeffs["treble", gain, 1] = feedeq_fx_floor(a1); 158193640Sariff coeffs["treble", gain, 2] = feedeq_fx_floor(a2); 159193640Sariff coeffs["treble", gain, 3] = feedeq_fx_floor(b0); 160193640Sariff coeffs["treble", gain, 4] = feedeq_fx_floor(b1); 161193640Sariff coeffs["treble", gain, 5] = feedeq_fx_floor(b2); 162193640Sariff 163193640Sariff w0 = feedeq_w0(FEEDEQ_BASS_SFREQ, 1.0 * rate); 164193640Sariff A = feedeq_A(1.0 * gain); 165193640Sariff alpha = feedeq_alpha(w0, A, FEEDEQ_BASS_SLOPE); 166193640Sariff 167193640Sariff if (FEEDEQ_TYPE == FEEDEQ_TYPE_PEQ) { 168193640Sariff b0 = 1.0 + (alpha * A); 169193640Sariff b1 = -2.0 * cos(w0); 170193640Sariff b2 = 1.0 - (alpha * A); 171193640Sariff a0 = 1.0 + (alpha / A); 172193640Sariff a1 = -2.0 * cos(w0); 173193640Sariff a2 = 1.0 - (alpha / A); 174193640Sariff } else if (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) { 175193640Sariff b0 = A*((A+1.0)-((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha)); 176193640Sariff b1 = 2.0*A*((A-1.0)-((A+1.0)*cos(w0)) ); 177193640Sariff b2 = A*((A+1.0)-((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha)); 178193640Sariff a0 = (A+1.0)+((A-1.0)*cos(w0))+(2.0*sqrt(A)*alpha ); 179193640Sariff a1 = -2.0 * ((A-1.0)+((A+1.0)*cos(w0)) ); 180193640Sariff a2 = (A+1.0)+((A-1.0)*cos(w0))-(2.0*sqrt(A)*alpha ); 181193640Sariff } else 182193640Sariff b0 = b1 = b2 = a0 = a1 = a2 = 0.0; 183193640Sariff 184193640Sariff b0 /= a0; 185193640Sariff b1 /= a0; 186193640Sariff b2 /= a0; 187193640Sariff a1 /= a0; 188193640Sariff a2 /= a0; 189193640Sariff 190193640Sariff coeffs["bass", gain, 0] = feedeq_fx_floor(a0); 191193640Sariff coeffs["bass", gain, 1] = feedeq_fx_floor(a1); 192193640Sariff coeffs["bass", gain, 2] = feedeq_fx_floor(a2); 193193640Sariff coeffs["bass", gain, 3] = feedeq_fx_floor(b0); 194193640Sariff coeffs["bass", gain, 4] = feedeq_fx_floor(b1); 195193640Sariff coeffs["bass", gain, 5] = feedeq_fx_floor(b2); 196193640Sariff} 197193640Sariff 198193640Sarifffunction feedeq_gen_freq_coeffs(frq, g, i, v) 199193640Sariff{ 200193640Sariff coeffs[0] = 0; 201193640Sariff 202193640Sariff for (g = (FEEDEQ_GAIN_MIN * FEEDEQ_GAIN_DIV); \ 203193640Sariff g <= (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV); \ 204193640Sariff g += FEEDEQ_GAIN_STEP) { 205193640Sariff feedeq_gen_biquad_coeffs(coeffs, frq, \ 206193640Sariff g * FEEDEQ_GAIN_RECIPROCAL); 207193640Sariff } 208193640Sariff 209193640Sariff printf("\nstatic struct feed_eq_coeff eq_%d[%d] " \ 210193640Sariff "= {\n", frq, FEEDEQ_LEVELS); 211193640Sariff for (g = (FEEDEQ_GAIN_MIN * FEEDEQ_GAIN_DIV); \ 212193640Sariff g <= (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV); \ 213193640Sariff g += FEEDEQ_GAIN_STEP) { 214193640Sariff printf(" {{ "); 215193640Sariff for (i = 1; i < 6; i++) { 216193640Sariff v = coeffs["treble", g * FEEDEQ_GAIN_RECIPROCAL, i]; 217193640Sariff printf("%s0x%08x%s", \ 218193640Sariff (v < 0) ? "-" : " ", abs(v), \ 219193640Sariff (i == 5) ? " " : ", "); 220193640Sariff } 221193640Sariff printf("},\n { "); 222193640Sariff for (i = 1; i < 6; i++) { 223193640Sariff v = coeffs["bass", g * FEEDEQ_GAIN_RECIPROCAL, i]; 224193640Sariff printf("%s0x%08x%s", \ 225193640Sariff (v < 0) ? "-" : " ", abs(v), \ 226193640Sariff (i == 5) ? " " : ", "); 227193640Sariff } 228193640Sariff printf("}}%s\n", \ 229193640Sariff (g < (FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV)) ? "," : ""); 230193640Sariff } 231193640Sariff printf("};\n"); 232193640Sariff} 233193640Sariff 234193640Sarifffunction feedeq_calc_preamp(norm, gain, shift, mul, bit, attn) 235193640Sariff{ 236193640Sariff shift = FEEDEQ_PREAMP_SHIFT; 237193640Sariff 238193640Sariff if (floor(FEEDEQ_PREAMP_BITDB) == 6 && \ 239193640Sariff (1.0 * floor(gain)) == gain && (floor(gain) % 6) == 0) { 240193640Sariff mul = 1; 241193640Sariff shift = floor(floor(gain) / 6); 242193640Sariff } else { 243193640Sariff bit = 32.0 - ((1.0 * gain) / (1.0 * FEEDEQ_PREAMP_BITDB)); 244193640Sariff attn = pow(2.0, bit) / pow(2.0, 32.0); 245193640Sariff mul = floor((attn * FEEDEQ_PREAMP_ONE) + 0.5); 246193640Sariff } 247193640Sariff 248193640Sariff while ((mul % 2) == 0 && shift > 0) { 249193640Sariff mul = floor(mul / 2); 250193640Sariff shift--; 251193640Sariff } 252193640Sariff 253193640Sariff norm["mul"] = mul; 254193640Sariff norm["shift"] = shift; 255193640Sariff} 256193640Sariff 257193640SariffBEGIN { 258193640Sariff M_PI = atan2(0.0, -1.0); 259193640Sariff 260193640Sariff INT32_MAX = 1 + ((shl(1, 30) - 1) * 2); 261193640Sariff INT32_MIN = -1 - INT32_MAX; 262193640Sariff 263193640Sariff FEEDEQ_TYPE_PEQ = 0; 264193640Sariff FEEDEQ_TYPE_SHELF = 1; 265193640Sariff 266193640Sariff FEEDEQ_TYPE = FEEDEQ_TYPE_PEQ; 267193640Sariff 268193640Sariff FEEDEQ_COEFF_SHIFT = 24; 269193640Sariff FEEDEQ_COEFF_ONE = shl(1, FEEDEQ_COEFF_SHIFT); 270193640Sariff 271193640Sariff FEEDEQ_PREAMP_SHIFT = 31; 272193640Sariff FEEDEQ_PREAMP_ONE = shl(1, FEEDEQ_PREAMP_SHIFT); 273193640Sariff FEEDEQ_PREAMP_BITDB = 6; # 20.0 * (log(2.0) / log(10.0)); 274193640Sariff 275193640Sariff FEEDEQ_GAIN_DIV = 10; 276193640Sariff i = 0; 277193640Sariff j = 1; 278193640Sariff while (j < FEEDEQ_GAIN_DIV) { 279193640Sariff j *= 2; 280193640Sariff i++; 281193640Sariff } 282193640Sariff FEEDEQ_GAIN_SHIFT = i; 283193640Sariff FEEDEQ_GAIN_FMASK = shl(1, FEEDEQ_GAIN_SHIFT) - 1; 284193640Sariff 285193640Sariff FEEDEQ_GAIN_RECIPROCAL = 1.0 / FEEDEQ_GAIN_DIV; 286193640Sariff 287193640Sariff if (ARGC == 2) { 288193640Sariff i = 1; 289193640Sariff split(ARGV[1], arg, ":"); 290193640Sariff while (match(arg[i], "^[^0-9]*$")) { 291193640Sariff if (arg[i] == "PEQ") { 292193640Sariff FEEDEQ_TYPE = FEEDEQ_TYPE_PEQ; 293193640Sariff } else if (arg[i] == "SHELF") { 294193640Sariff FEEDEQ_TYPE = FEEDEQ_TYPE_SHELF; 295193640Sariff } 296193640Sariff i++; 297193640Sariff } 298193640Sariff split(arg[i++], subarg, ","); 299193640Sariff FEEDEQ_TREBLE_SFREQ = 1.0 * subarg[1]; 300193640Sariff FEEDEQ_TREBLE_SLOPE = 1.0 * subarg[2]; 301193640Sariff split(arg[i++], subarg, ","); 302193640Sariff FEEDEQ_BASS_SFREQ = 1.0 * subarg[1]; 303193640Sariff FEEDEQ_BASS_SLOPE = 1.0 * subarg[2]; 304193640Sariff split(arg[i++], subarg, ","); 305193640Sariff FEEDEQ_GAIN_MIN = floor(1.0 * subarg[1]); 306193640Sariff FEEDEQ_GAIN_MAX = floor(1.0 * subarg[2]); 307193640Sariff if (length(subarg) > 2) { 308193640Sariff j = floor(1.0 * FEEDEQ_GAIN_DIV * subarg[3]); 309193640Sariff if (j < 2) 310193640Sariff j = 1; 311193640Sariff else if (j < 5) 312193640Sariff j = 2; 313193640Sariff else if (j < 10) 314193640Sariff j = 5; 315193640Sariff else 316193640Sariff j = 10; 317193640Sariff if (j > FEEDEQ_GAIN_DIV || (FEEDEQ_GAIN_DIV % j) != 0) 318193640Sariff j = FEEDEQ_GAIN_DIV; 319193640Sariff FEEDEQ_GAIN_STEP = j; 320193640Sariff } else 321193640Sariff FEEDEQ_GAIN_STEP = FEEDEQ_GAIN_DIV; 322193640Sariff split(arg[i], subarg, ","); 323193640Sariff for (i = 1; i <= length(subarg); i++) 324193640Sariff allfreq[i - 1] = floor(1.0 * subarg[i]); 325193640Sariff } else { 326193640Sariff FEEDEQ_TREBLE_SFREQ = 16000.0; 327193640Sariff FEEDEQ_TREBLE_SLOPE = 0.25; 328193640Sariff FEEDEQ_BASS_SFREQ = 62.0; 329193640Sariff FEEDEQ_BASS_SLOPE = 0.25; 330193640Sariff 331193640Sariff FEEDEQ_GAIN_MIN = -9; 332193640Sariff FEEDEQ_GAIN_MAX = 9; 333193640Sariff 334193640Sariff FEEDEQ_GAIN_STEP = FEEDEQ_GAIN_DIV; 335193640Sariff 336193640Sariff 337193640Sariff allfreq[0] = 44100; 338193640Sariff allfreq[1] = 48000; 339193640Sariff allfreq[2] = 88200; 340193640Sariff allfreq[3] = 96000; 341193640Sariff allfreq[4] = 176400; 342193640Sariff allfreq[5] = 192000; 343193640Sariff } 344193640Sariff 345193640Sariff FEEDEQ_LEVELS = ((FEEDEQ_GAIN_MAX - FEEDEQ_GAIN_MIN) * \ 346193640Sariff floor(FEEDEQ_GAIN_DIV / FEEDEQ_GAIN_STEP)) + 1; 347193640Sariff 348193640Sariff FEEDEQ_ERR_CLIP = 0; 349193640Sariff 350193640Sariff smallest = 10.000000; 351193640Sariff largest = 0.000010; 352193640Sariff 353193640Sariff printf("#ifndef _FEEDER_EQ_GEN_H_\n"); 354193640Sariff printf("#define _FEEDER_EQ_GEN_H_\n\n"); 355193640Sariff printf("/*\n"); 356193640Sariff printf(" * Generated using feeder_eq_mkfilter.awk, heaven, wind and awesome.\n"); 357193640Sariff printf(" *\n"); 358193640Sariff printf(" * DO NOT EDIT!\n"); 359193640Sariff printf(" */\n\n"); 360193640Sariff printf("/*\n"); 361193640Sariff printf(" * EQ: %s\n", (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) ? \ 362193640Sariff "Shelving" : "Peaking EQ"); 363193640Sariff printf(" */\n"); 364193640Sariff printf("#define FEEDER_EQ_PRESETS\t\""); 365193640Sariff printf("%s:%d,%.4f,%d,%.4f:%d,%d,%.1f:", \ 366193640Sariff (FEEDEQ_TYPE == FEEDEQ_TYPE_SHELF) ? "SHELF" : "PEQ", \ 367193640Sariff FEEDEQ_TREBLE_SFREQ, FEEDEQ_TREBLE_SLOPE, \ 368193640Sariff FEEDEQ_BASS_SFREQ, FEEDEQ_BASS_SLOPE, \ 369193640Sariff FEEDEQ_GAIN_MIN, FEEDEQ_GAIN_MAX, \ 370193640Sariff FEEDEQ_GAIN_STEP * FEEDEQ_GAIN_RECIPROCAL); 371193640Sariff for (i = 0; i < length(allfreq); i++) { 372193640Sariff if (i != 0) 373193640Sariff printf(","); 374193640Sariff printf("%d", allfreq[i]); 375193640Sariff } 376193640Sariff printf("\"\n\n"); 377193640Sariff printf("struct feed_eq_coeff_tone {\n"); 378193640Sariff printf("\tint32_t a1, a2;\n"); 379193640Sariff printf("\tint32_t b0, b1, b2;\n"); 380193640Sariff printf("};\n\n"); 381193640Sariff printf("struct feed_eq_coeff {\n"); 382193640Sariff #printf("\tstruct {\n"); 383193640Sariff #printf("\t\tint32_t a1, a2;\n"); 384193640Sariff #printf("\t\tint32_t b0, b1, b2;\n"); 385193640Sariff #printf("\t} treble, bass;\n"); 386193640Sariff printf("\tstruct feed_eq_coeff_tone treble;\n"); 387193640Sariff printf("\tstruct feed_eq_coeff_tone bass;\n"); 388193640Sariff #printf("\tstruct {\n"); 389193640Sariff #printf("\t\tint32_t a1, a2;\n"); 390193640Sariff #printf("\t\tint32_t b0, b1, b2;\n"); 391193640Sariff #printf("\t} bass;\n"); 392193640Sariff printf("};\n"); 393193640Sariff for (i = 0; i < length(allfreq); i++) 394193640Sariff feedeq_gen_freq_coeffs(allfreq[i]); 395193640Sariff printf("\n"); 396193640Sariff printf("static const struct {\n"); 397193640Sariff printf("\tuint32_t rate;\n"); 398193640Sariff printf("\tstruct feed_eq_coeff *coeff;\n"); 399193640Sariff printf("} feed_eq_tab[] = {\n"); 400193640Sariff for (i = 0; i < length(allfreq); i++) { 401193640Sariff printf("\t{ %6d, eq_%-6d },\n", allfreq[i], allfreq[i]); 402193640Sariff } 403193640Sariff printf("};\n"); 404193640Sariff 405193640Sariff printf("\n#define FEEDEQ_RATE_MIN\t\t%d\n", allfreq[0]); 406193640Sariff printf("#define FEEDEQ_RATE_MAX\t\t%d\n", allfreq[length(allfreq) - 1]); 407193640Sariff printf("\n#define FEEDEQ_TAB_SIZE\t\t\t\t\t\t\t\\\n"); 408193640Sariff printf("\t((int32_t)(sizeof(feed_eq_tab) / sizeof(feed_eq_tab[0])))\n"); 409193640Sariff 410193640Sariff printf("\nstatic const struct {\n"); 411193640Sariff printf("\tint32_t mul, shift;\n"); 412193640Sariff printf("} feed_eq_preamp[] = {\n"); 413193640Sariff for (i = (FEEDEQ_GAIN_MAX * 2 * FEEDEQ_GAIN_DIV); i >= 0; \ 414193640Sariff i -= FEEDEQ_GAIN_STEP) { 415193640Sariff feedeq_calc_preamp(norm, i * FEEDEQ_GAIN_RECIPROCAL); 416193640Sariff dbgain = ((FEEDEQ_GAIN_MAX * FEEDEQ_GAIN_DIV) - i) * \ 417193640Sariff FEEDEQ_GAIN_RECIPROCAL; 418193640Sariff printf("\t{ 0x%08x, 0x%08x },\t/* %+5.1f dB */\n", \ 419193640Sariff norm["mul"], norm["shift"], dbgain); 420193640Sariff } 421193640Sariff printf("};\n"); 422193640Sariff 423193640Sariff printf("\n#define FEEDEQ_GAIN_MIN\t\t%d", FEEDEQ_GAIN_MIN); 424193640Sariff printf("\n#define FEEDEQ_GAIN_MAX\t\t%d\n", FEEDEQ_GAIN_MAX); 425193640Sariff 426193640Sariff printf("\n#define FEEDEQ_GAIN_SHIFT\t%d\n", FEEDEQ_GAIN_SHIFT); 427193640Sariff printf("#define FEEDEQ_GAIN_DIV\t\t%d\n", FEEDEQ_GAIN_DIV); 428193640Sariff printf("#define FEEDEQ_GAIN_FMASK\t0x%08x\n", FEEDEQ_GAIN_FMASK); 429193640Sariff printf("#define FEEDEQ_GAIN_STEP\t%d\n", FEEDEQ_GAIN_STEP); 430193640Sariff 431193640Sariff #printf("\n#define FEEDEQ_PREAMP_MIN\t-%d\n", \ 432193640Sariff # shl(FEEDEQ_GAIN_MAX, FEEDEQ_GAIN_SHIFT)); 433193640Sariff #printf("#define FEEDEQ_PREAMP_MAX\t%d\n", \ 434193640Sariff # shl(FEEDEQ_GAIN_MAX, FEEDEQ_GAIN_SHIFT)); 435193640Sariff 436193640Sariff printf("\n#define FEEDEQ_COEFF_SHIFT\t%d\n", FEEDEQ_COEFF_SHIFT); 437193640Sariff 438193640Sariff #feedeq_calc_preamp(norm, FEEDEQ_GAIN_MAX); 439193640Sariff 440193640Sariff #printf("#define FEEDEQ_COEFF_NORM(v)\t("); 441193640Sariff #if (norm["mul"] == 1) 442193640Sariff # printf("(v) >> %d", norm["shift"]); 443193640Sariff #else 444193640Sariff # printf("(0x%xLL * (v)) >> %d", norm["mul"], norm["shift"]); 445193640Sariff #printf(")\n"); 446193640Sariff 447193640Sariff #printf("\n#define FEEDEQ_LEVELS\t\t%d\n", FEEDEQ_LEVELS); 448193640Sariff if (FEEDEQ_ERR_CLIP != 0) 449193640Sariff printf("\n#define FEEDEQ_ERR_CLIP\t\t%d\n", FEEDEQ_ERR_CLIP); 450193640Sariff printf("\n/*\n"); 451193640Sariff printf(" * volume level mapping (0 - 100):\n"); 452193640Sariff printf(" *\n"); 453193640Sariff 454193640Sariff for (i = 0; i <= 100; i++) { 455193640Sariff ind = floor((i * FEEDEQ_LEVELS) / 100); 456193640Sariff if (ind >= FEEDEQ_LEVELS) 457193640Sariff ind = FEEDEQ_LEVELS - 1; 458193640Sariff printf(" *\t%3d -> %3d (%+5.1f dB)\n", \ 459193640Sariff i, ind, FEEDEQ_GAIN_MIN + \ 460193640Sariff (ind * (FEEDEQ_GAIN_RECIPROCAL * FEEDEQ_GAIN_STEP))); 461193640Sariff } 462193640Sariff 463193640Sariff printf(" */\n"); 464193640Sariff printf("\n/*\n * smallest: %.32f\n * largest: %.32f\n */\n", \ 465193640Sariff smallest, largest); 466193640Sariff printf("\n#endif\t/* !_FEEDER_EQ_GEN_H_ */\n"); 467193640Sariff} 468