📄 au88x0_eq.c
字号:
/*************************************************************************** * au88x0_eq.c * Aureal Vortex Hardware EQ control/access. * * Sun Jun 8 18:19:19 2003 * 2003 Manuel Jander (mjander@users.sourceforge.net) * * 02 July 2003: First time something works :) * November 2003: A3D Bypass code completed but untested. * * TODO: * - Debug (testing) * - Test peak visualization support. * ****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* The Aureal Hardware EQ is found on AU8810 and AU8830 chips only. it has 4 inputs (2 for general mix, 2 for A3D) and 2 outputs (supposed to be routed to the codec).*/#include "au88x0.h"#include "au88x0_eq.h"#include "au88x0_eqdata.c"#define VORTEX_EQ_BASE 0x2b000#define VORTEX_EQ_DEST (VORTEX_EQ_BASE + 0x410)#define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)#define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440)#define VORTEX_BAND_COEFF_SIZE 0x30/* CEqHw.s */static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level){ hwwrite(vortex->mmio, 0x2b3c4, gain); hwwrite(vortex->mmio, 0x2b3c8, level);}static inline u16 sign_invert(u16 a){ /* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */ if (a == (u16)-32768) return 32767; else return -a;}static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[]){ eqhw_t *eqhw = &(vortex->eq.this04); int i = 0, n /*esp2c */; for (n = 0; n < eqhw->this04; n++) { hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]); hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]); if (eqhw->this08 == 0) { hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]); hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]); hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]); } else { hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i])); hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i])); hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i])); } i += 5; }}static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[]){ eqhw_t *eqhw = &(vortex->eq.this04); int i = 0, n /*esp2c */; for (n = 0; n < eqhw->this04; n++) { hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]); hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]); if (eqhw->this08 == 0) { hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]); hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]); hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]); } else { hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i])); hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i])); hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i])); } i += 5; }}static void vortex_EqHw_SetLeftStates(vortex_t * vortex, u16 a[], u16 b[]){ eqhw_t *eqhw = &(vortex->eq.this04); int i = 0, ebx; hwwrite(vortex->mmio, 0x2b3fc, a[0]); hwwrite(vortex->mmio, 0x2b400, a[1]); for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]); hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]); hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]); hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]); i += 4; }}static void vortex_EqHw_SetRightStates(vortex_t * vortex, u16 a[], u16 b[]){ eqhw_t *eqhw = &(vortex->eq.this04); int i = 0, ebx; hwwrite(vortex->mmio, 0x2b404, a[0]); hwwrite(vortex->mmio, 0x2b408, a[1]); for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]); hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]); hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]); hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]); i += 4; }}#if 0static void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b){ *a = hwread(vortex->mmio, 0x2b3c4); *b = hwread(vortex->mmio, 0x2b3c8);}static void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[]){}static void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[]){}static void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[]){}static void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[]){}#endif/* Mix Gains */static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b){ eqhw_t *eqhw = &(vortex->eq.this04); if (eqhw->this08 == 0) { hwwrite(vortex->mmio, 0x2b3d4, a); hwwrite(vortex->mmio, 0x2b3ec, b); } else { hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a)); hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b)); }}static void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b){ hwwrite(vortex->mmio, 0x2b3e0, a); hwwrite(vortex->mmio, 0x2b3f8, b);}#if 0static void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b){ hwwrite(vortex->mmio, 0x2b3d0, a); hwwrite(vortex->mmio, 0x2b3e8, b);}static void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b){ hwwrite(vortex->mmio, 0x2b3dc, a); hwwrite(vortex->mmio, 0x2b3f4, b);}#endifstatic voidvortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b){ hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b);}static voidvortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b){ hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b);}static void vortex_EqHw_SetLeftGainsTarget(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx; for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]); }}static void vortex_EqHw_SetRightGainsTarget(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx; for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]); }}static void vortex_EqHw_SetLeftGainsCurrent(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx; for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]); }}static void vortex_EqHw_SetRightGainsCurrent(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx; for (ebx = 0; ebx < eqhw->this04; ebx++) { hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]); }}#if 0static void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx = 0; if (eqhw->this04 < 0) return; do { a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30); ebx++; } while (ebx < eqhw->this04);}static void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx = 0; if (eqhw->this04 < 0) return; do { a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30); ebx++; } while (ebx < eqhw->this04);}static void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx = 0; if (eqhw->this04 < 0) return; do { a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30); ebx++; } while (ebx < eqhw->this04);}static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx = 0; if (eqhw->this04 < 0) return; do { a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30); ebx++; } while (ebx < eqhw->this04);}#endif/* EQ band levels settings */static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[]){ eqhw_t *eqhw = &(vortex->eq.this04); int i; /* set left peaks */ for (i = 0; i < eqhw->this04; i++) { hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]); } hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]); hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]); /* set right peaks */ for (i = 0; i < eqhw->this04; i++) { hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE, peaks[i + (eqhw->this04 + 2)]); } hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]); hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);}#if 0static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[]){ eqhw_t *eqhw = &(vortex->eq.this04); int ebx; if (eqhw->this04 < 0) return; ebx = 0; do { a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30); ebx++; } while (ebx < eqhw->this04); a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc); a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8); ebx = 0; do { a[ebx + (eqhw->this04 + 2)] = hwread(vortex->mmio, 0x2b204 + ebx * 0x30); ebx++; } while (ebx < eqhw->this04); a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4); a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0);}#endif/* Global Control */static void vortex_EqHw_SetControlReg(vortex_t * vortex, unsigned long reg){ hwwrite(vortex->mmio, 0x2b440, reg);}static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int sr){ hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800);}#if 0static void vortex_EqHw_GetControlReg(vortex_t * vortex, unsigned long *reg){ *reg = hwread(vortex->mmio, 0x2b440);}static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *sr){ *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f;}#endifstatic void vortex_EqHw_Enable(vortex_t * vortex){ hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001);}static void vortex_EqHw_Disable(vortex_t * vortex){ hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000);}/* Reset (zero) buffers */static void vortex_EqHw_ZeroIO(vortex_t * vortex){ int i; for (i = 0; i < 0x8; i++) hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0); for (i = 0; i < 0x4; i++) hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0);}static void vortex_EqHw_ZeroA3DIO(vortex_t * vortex){ int i; for (i = 0; i < 0x4; i++) hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);}static void vortex_EqHw_ZeroState(vortex_t * vortex){ vortex_EqHw_SetControlReg(vortex, 0); vortex_EqHw_ZeroIO(vortex); hwwrite(vortex->mmio, 0x2b3c0, 0); vortex_EqHw_SetTimeConsts(vortex, 0, 0); vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros); vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros); vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero); vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero); vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero); vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero); vortex_EqHw_SetBypassGain(vortex, 0, 0); //vortex_EqHw_SetCurrBypassGain(vortex, 0, 0); vortex_EqHw_SetA3DBypassGain(vortex, 0, 0); //vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0); vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros); vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros); vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels);}/* Program coeficients as pass through */static void vortex_EqHw_ProgramPipe(vortex_t * vortex){ vortex_EqHw_SetTimeConsts(vortex, 0, 0); vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes); vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes); vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current); vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current); vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current); vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current);}/* Program EQ block as 10 band Equalizer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -