重要な更新:私はすでに答えを見つけ出し、次のシンプルなオープンソース ライブラリに配置しました: 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 バンド EQ を作成することです。メソッドの構文は次のとおり
vDSP_deq22(<float *vDSP_A>, <vDSP_Stride vDSP_I>, <float *vDSP_B>, <float *vDSP_C>, <vDSP_Stride vDSP_K>, <vDSP_Length __vDSP_N>)
です。 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
2 次 (バターワース) IIR フィルターであることはわかっていますが、これをバンドパスに変換するにはどうすればよいですか?
ここで、3 つの質問があります。
a) オーディオ バッファのインターリーブ解除とインターリーブを行う必要がありますか? ストライドを 2 に設定するだけでチャンネルのフィルターを設定することはわかっていますが、もう一方をフィルター処理する方法、ストライド 1 は両方のチャンネルを 1 つとして処理します。
vDSP_deq22
b)メソッドに入る前にバッファを変換/処理する必要がありますか? もしそうなら、私もそれを通常に戻す必要がありますか?
c) 10 秒に設定する係数の値はvDSP_deq22
?
私は何日も試みてきましたが、これを理解することができませんでした。助けてください!