gpt4 book ai didi

objective-c - 二阶 IIR 滤波器,巴特沃斯带通 (EQ) 的系数?

转载 作者:太空狗 更新时间:2023-10-30 04:01:15 30 4
gpt4 key购买 nike

重要更新:我已经找到答案并将它们放在这个简单的开源库中:http://bartolsthoorn.github.com/NVDSP/检查一下,如果您在 IOS 中遇到音频过滤器问题,它可能会为您节省不少时间!

^

我创建了一个(实时)音频缓冲区 ( float *data ),其中包含一些 sin(theta)不同频率的波。

下面的代码显示了我是如何创建缓冲区的,并且我尝试了一个带通滤波器,但它只是将信号转换为噪声/信号:

    // Multiple signal generator
__block float *phases = nil;
[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
{
float samplingRate = audioManager.samplingRate;
NSUInteger activeSignalCount = [tones count];

// Initialize phases
if (phases == nil) {
phases = new float[10];
for(int z = 0; z <= 10; z++) {
phases[z] = 0.0;
}
}

// Multiple signals
NSEnumerator * enumerator = [tones objectEnumerator];
id frequency;
UInt32 c = 0;
while(frequency = [enumerator nextObject])
{
for (int i=0; i < numFrames; ++i)
{
for (int iChannel = 0; iChannel < numChannels; ++iChannel)
{
float theta = phases[c] * M_PI * 2;
if (c == 0) {
data[i*numChannels + iChannel] = sin(theta);
} else {
data[i*numChannels + iChannel] = data[i*numChannels + iChannel] + sin(theta);
}
}
phases[c] += 1.0 / (samplingRate / [frequency floatValue]);
if (phases[c] > 1.0) phases[c] = -1;
}
c++;
}

// Normalize data with active signal count
float signalMulti = 1.0 / (float(activeSignalCount) * (sqrt(2.0)));
vDSP_vsmul(data, 1, &signalMulti, data, 1, numFrames*numChannels);


// Apply master volume
float volume = masterVolumeSlider.value;
vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels);


if (fxSwitch.isOn) {
// H(s) = (s/Q) / (s^2 + s/Q + 1)
// http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
// BW 2.0 Q 0.667
// http://www.rane.com/note170.html
//The order of the coefficients are, B1, B2, A1, A2, B0.
float Fs = samplingRate;

float omega = 2*M_PI*Fs; // w0 = 2*pi*f0/Fs

float Q = 0.50f;
float alpha = sin(omega)/(2*Q); // sin(w0)/(2*Q)

// Through H
for (int i=0; i < numFrames; ++i)
{
for (int iChannel = 0; iChannel < numChannels; ++iChannel)
{
data[i*numChannels + iChannel] = (data[i*numChannels + iChannel]/Q) / (pow(data[i*numChannels + iChannel],2) + data[i*numChannels + iChannel]/Q + 1);
}
}

float b0 = alpha;
float b1 = 0;
float b2 = -alpha;
float a0 = 1 + alpha;
float a1 = -2*cos(omega);
float a2 = 1 - alpha;

float *coefficients = (float *) calloc(5, sizeof(float));


coefficients[0] = b1;
coefficients[1] = b2;
coefficients[2] = a1;
coefficients[3] = a2;
coefficients[3] = b0;

vDSP_deq22(data, 2, coefficients, data, 2, numFrames);

free(coefficients);
}

// Measure dB
[self measureDB:data:numFrames:numChannels];
}];

我的目标是使用 vDSP_deq22 为这个缓冲区制作一个 10 段均衡器,该方法的语法是: vDSP_deq22(<float *vDSP_A>, <vDSP_Stride vDSP_I>, <float *vDSP_B>, <float *vDSP_C>, <vDSP_Stride vDSP_K>, <vDSP_Length __vDSP_N>)请参阅:http://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html#//apple_ref/doc/c_ref/vDSP_deq22

参数:

float *vDSP_A is the input data
float *vDSP_B are 5 filter coefficients
float *vDSP_C is the output data

我必须制作 10 个过滤器(10 次 vDSP_deq22 )。然后我为每个频段设置增益并将它们重新组合在一起。但是我为每个滤波器提供什么系数?我知道vDSP_deq22是二阶(巴特沃斯)IIR 滤波器,但我如何将其转换为带通滤波器?

现在我有三个问题:

a) 我是否必须去交织和交织音频缓冲区?我知道将步幅设置为 2 只是在 channel 上过滤,但我如何过滤另一个 channel ,步幅 1 会将两个 channel 作为一个 channel 处理。

b) 我是否必须在缓冲区进入 vDSP_deq22 之前转换/处理缓冲区?方法?如果是这样,我是否也必须将其转换回正常状态?

c) 我应该将哪些系数值设置为 10 vDSP_deq22是吗?

我已经尝试了好几天了,但我一直无法解决这个问题,请帮助我!

最佳答案

你的 omega值需要标准化,即表示为 Fs 的分数 - 看起来你遗漏了 f0当你计算 omega , 这将使 alpha也错了:

    float omega = 2*M_PI*Fs; // w0 = 2*pi*f0/Fs

应该是:

    float omega = 2*M_PI*f0/Fs; // w0 = 2*pi*f0/Fs

其中 f0 是以赫兹为单位的中心频率。

对于 10 频段均衡器,您需要选择 10 个 f0 值,以对数间隔,例如25 赫兹、50 赫兹、100 赫兹、200 赫兹、400 赫兹、800 赫兹、1.6 赫兹、3.2 赫兹、6.4 赫兹、12.8 赫兹。

关于objective-c - 二阶 IIR 滤波器,巴特沃斯带通 (EQ) 的系数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10349597/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com