중요 업데이트 : 이미 대답을 찾아서이 간단한 오픈 소스 라이브러리에 넣어 둡니다 : IOS에서 오디오 필터에 문제가 있으면 확인해보십시오!2 차 IIR 필터, 버터 워스 대역 통과 계수 (EQ)?
^상이한 주파수와 약간 파도 sin(theta)
보유
I은 (실시간) 오디오 버퍼 (float *data
)을 만들었다.
아래 코드는 내 버퍼를 생성하는 방법을 보여줍니다, 나는 대역 통과 필터를하려고 노력했지만 그것은 단지 소음/일시적으로 신호를 전환 :
// 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];
}];
내 목표는 10을 만드는 것입니다 vDSP_deq22
를 사용하여이 버퍼 밴드 EQ, 방법의 구문은 다음 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
,536,913,632 10
10 개의 필터 (10 번 vDSP_deq22
)를 만들어야합니다. 그런 다음 모든 밴드의 이득을 설정하고 함께 결합합니다. 그러나 모든 계수에 어떤 계수를 적용합니까? 나는 vDSP_deq22
이 2 차 (버터 워스) IIR 필터라는 것을 알고 있지만 이것을 어떻게 대역 통과로 바꾸는가?
은 지금은 세 가지 질문이 있습니다
A) 내가 인터리브 드 오디오 버퍼를 인터리브해야합니까? 보폭을 2로 설정하는 것은 채널에서 필터링하는 것 뿐이지 만 다른 채널을 필터링하는 방법은 스트라이드 1이 두 채널을 하나로 처리합니다.
b) vDSP_deq22
방법으로 들어가기 전에 버퍼를 변환/처리해야합니까? 그렇다면 정상으로 다시 변환해야합니까?
c) 1vDSP_deq22
에 어떤 계수 값을 설정해야합니까?
나는 지금 일 동안 노력하고 있었지만 나는 이것을 알아낼 수 없었다. 도와주세요!
감사합니다. 모든 주파수를 다루기 위해 어떤 Q 값을 설정해야합니까? (Q는 내가 생각하는 밴드의 넓이를 의미합니까?) 그리고 여러분은 제가 bandpass에 대해 a0..a2와 b0..b2 값을 올바르게 계산했다고 생각합니까? – bartolsthoorn
위와 같이 f0에 옥타브 간격을 사용한다면 약 2 o 정도의 Q가 필요합니다. 다른 계산은 괜찮아 보입니다.팁 : 명목상의 f0, 예를 들어 하나의 필터를 먼저 작동 시키십시오. 400 Hz로 설정 한 다음 전체 필터 뱅크로 이동하십시오. –
고맙습니다. 밴드 패스 대신에 첨단 (파라 메트릭) EQ를 사용하기로 결정했습니다. 지금 생각해 보았습니다. 감사! – bartolsthoorn