4

중요 업데이트 : 이미 대답을 찾아서이 간단한 오픈 소스 라이브러리에 넣어 둡니다 : 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에 어떤 계수 값을 설정해야합니까?

나는 지금 일 동안 노력하고 있었지만 나는 이것을 알아낼 수 없었다. 도와주세요!

답변

7

귀하의 omega 값은 Fs를의 분수로 표현, 즉 표준화 할 필요가 - 당신이 잘못 너무 alpha를 만들 것입니다 당신이 omega을 계산 f0, 탈락 것 같습니다 :

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

아마되어야한다 :

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

여기서 f0는 Hz 단위의 중심 주파수입니다.

10 밴드 이퀄라이저의 f0 값을 10 개 선택해야합니다. 25 Hz, 50 Hz, 100 Hz, 200 Hz, 400 Hz, 800 Hz, 1.6 kHz, 3.2 kHz, 6.4 kHz, 12.8 kHz이다.

+0

감사합니다. 모든 주파수를 다루기 위해 어떤 Q 값을 설정해야합니까? (Q는 내가 생각하는 밴드의 넓이를 의미합니까?) 그리고 여러분은 제가 bandpass에 대해 a0..a2와 b0..b2 값을 올바르게 계산했다고 생각합니까? – bartolsthoorn

+1

위와 같이 f0에 옥타브 간격을 사용한다면 약 2 o 정도의 Q가 필요합니다. 다른 계산은 괜찮아 보입니다.팁 : 명목상의 f0, 예를 들어 하나의 필터를 먼저 작동 시키십시오. 400 Hz로 설정 한 다음 전체 필터 뱅크로 이동하십시오. –

+0

고맙습니다. 밴드 패스 대신에 첨단 (파라 메트릭) EQ를 사용하기로 결정했습니다. 지금 생각해 보았습니다. 감사! – bartolsthoorn