This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TAS3251:精确的双二阶系数计算

Guru**** 661510 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1191086/tas3251-exact-biquad-coefficient-computation

器件型号:TAS3251

大家好、

您能否为我提供 PPC3计算双二阶系数十六进制值的精确算法?
我想要的是直接在 MCU 上实现该功能、从而调节均衡器设置、而无需始终从 PPC3复制寄存器值。

我已经编写了一个 python 脚本、该脚本可以大致正确地计算值、但根据 Q 因子和增益、似乎有一种行为我不太理解。 尤其是在较高的频率下、这些值的偏差似乎会变得更大。

import numpy as np
import scipy

### Define Filter Tyoe
f_type = 'PEQ' # LP, HP, PEQ
a_type = "Q" # Q, BW, S

# constants

fs  = 96000.00      # Sample Rate
fc  = 7000.00       # Filter Frequency
G   = 16.00         # Gain (for peak and shelf filters) in dB
Q   = 10.00         # Quality factor 
bw   = 2000.00      # Bandwidth for BW Option filters
pi  = np.pi

# intermediate variables

f0 = fc
A   = 10**(G/40)            # Only for shelf and peak EQs 
w0  = (2*np.pi*f0)/fs       # filter frequency normalized to samplerate

C   = np.cos(w0)
S   = np.sin(w0)

if(a_type == 'Q'):
    ax = np.sin(w0)/(2*Q)
elif(a_type == 'BW'):
    ax = np.sin(w0)*np.sinh((np.log(2)/2)*bw*(w0/np.sin(w0)))


if (f_type == "LP"):
    # for lowpass filters
    b0 =  (1-C)/2
    b1 = 1-C
    b2 = (1-C)/2

    a0 = 1+ax
    a1 = -2*C
    a2 = 1-ax
elif(f_type == "HP"):
    ## for high pass filters
    b0 =  (1+C)/2
    b1 = -(1+C)
    b2 = (1+C)/2

    a0 = 1+ax
    a1 = -2*C
    a2 = 1-ax

elif(f_type == 'PEQ'):
    b0 = (1+ (ax*A)) #(10**(G/20))*
    b1 = (-2 * C)
    b2 = (1- (ax*A))
    a0 = 1 + (ax/A)
    a1 = -2 * C
    a2 = 1 - (ax/A)

# Normalisation (see TAS3251 datasheet, page 55)
B0_DSP = b0/a0
B1_DSP = b1/(a0*2)
B2_DSP = b2/a0
A1_DSP = a1/(-a0*2)
A2_DSP = a2/(-a0)

# Gain Scaling if one of the B values is larger than 1

B_array = [B0_DSP, B1_DSP, B2_DSP]
Max_k = np.max(np.abs(B_array))

if (Max_k >= 1.0 and f_type == 'PEQ'):
    B0_DSP = (B0_DSP /Max_k)* 0.9999999995343387
    B1_DSP = (B1_DSP /Max_k)* 0.9999999995343387
    B2_DSP = (B2_DSP /Max_k)* 0.9999999995343387

# Float to fixed point conversion (see SLAA799A)
B0_FIXED = int(np.round(B0_DSP*(1 << 31)))
B1_FIXED = int(np.round(B1_DSP*(2 << 30)))
B2_FIXED = int(np.round(B2_DSP*(1 << 31)))
A1_FIXED = int(np.round(A1_DSP*(2 << 30)))
A2_FIXED = int(np.round(A2_DSP*(1 << 31)))

B0_reg0 = B0_FIXED & 0xFF000000
B0_reg1 = B0_FIXED & 0x00FF0000
B0_reg2 = B0_FIXED & 0x0000FF00
B0_reg3 = B0_FIXED & 0x000000FF

...

谢谢!

此致

S.