#define AX_PB_LPF_OFF 0x0000 // LPF switch
#define AX_PB_LPF_ON 0x0001
typedef struct _AXPBLPF
{
u16 on; // Filter is enabled when AX_PB_LPF_ON(1). Filter is invalid when AX_PB_LPF_OFF(0).
u16 yn1; // history sample. Must be initialized once to zero.
u16 a0; // Coefficient
u16 b0; // Coefficient
} AXPBLPF;
The lpf values are used by the DSP to implement a low-pass filter (LPF) on each voice independently.
The on value is a switch for the filter process on the specified voice. LPF is enabled when AX_PB_LPF_ON(1) is set to on. LPF is disabled when AX_PB_LPF_OFF(0) is set.
The yn1 value is a history value and must be initialized to zero. This value is thereafter maintained by AX and must not be touched.
The a0 and b0 values are the coefficients for the filter, and must be provided by the application. These values determine the cut-off frequency of the filter, and may be changed at any time.
The filter is a simple one-pole function:
y(n) = a0*x(n) - b0*y(n-1)
Here, x(n) is the current input sample, and y(n-1) is the previous output sample. The coefficients a0 and b0 can be calculated as follows:
c = 2.0 - cos(2.0*pi*freq/32000.0)
b0 = sqrt(c^2 - 1) - c
a0 = 1 + b0
Where freq is in Hertz (Hz) and must be within the range:
0 <= freq <= 16,000
The coefficients must be unsigned, 16-bit words in fixed-point format, having 1 bit of integer and 15 bits of fraction. Furthermore, the b0 term must be (arithmetically) negated before being sent to the DSP. This is because of an optimization in the DSP filter calculation provided by the absence of a sign bit in the coefficients.
A sample table of coefficients is provided below:
static u16 __lpf_coefs[48] = { // a0 b0 cut-off frequency //------ ------ ----------------- 0x6a09, 0x15f6, // 16000Hz 0x6871, 0x178e, // 12800Hz 0x6463, 0x1b9c, // 10240Hz 0x5db3, 0x224c, // 8000Hz 0x5618, 0x29e7, // 6400Hz 0x4d7a, 0x3285, // 5120Hz 0x4367, 0x3c98, // 4000Hz 0x3a5a, 0x45a5, // 3200Hz 0x31c5, 0x4e3a, // 2560Hz 0x2924, 0x56db, // 2000Hz 0x2244, 0x5dbb, // 1600Hz 0x1c50, 0x63af, // 1280Hz 0x16c0, 0x693f, // 1000Hz 0x1292, 0x6d6d, // 800Hz 0x0f18, 0x70e7, // 640Hz 0x0bf5, 0x740a, // 500Hz 0x09a9, 0x7656, // 400Hz 0x07ca, 0x7835, // 320Hz 0x0646, 0x79b9, // 256Hz 0x04ed, 0x7b12, // 200Hz 0x03f5, 0x7c0a, // 160Hz 0x032d, 0x7cd2, // 128Hz 0x027d, 0x7d82, // 100Hz 0x01fe, 0x7e01 // 80Hz };
Notice that the table above provides cut-off frequencies from 80Hz to 16,000Hz, in (approximately) 1/3 octave steps. This granularity is sufficient to achieve a smooth 'sweep' of the cut-off frequency across the spectrum.
This filter provides 6dB of attenuation per octave.
Use the AXGetLpfCoefs function to get the coefficients of the specified cut-off frequency.
To apply changes to a0 or b0 in the DSP, the application must assert the AX_SYNC_USER_LPF_COEF bit in the axvpb.sync member.
To synchronize the entire structure, assert the AX_SYNC_USER_LPF bit.
axvpb.sync, AXSetVoiceLpf, AXSetVoiceLpfCoefs, AXGetLpfCoefs
2006/11/14 Added macro.
2006/03/01 Initial version.
CONFIDENTIAL