我对CoreAudio中数字滤镜的实现有疑问。我遇到了大麻烦,因为我试图了解如何实施它们需要几周时间。基本的想法是这样的:当我与iPhone的麦克风交谈时,我的声音被低通滤波器或高通或带通滤波。
我研究了这些书和#34;学习核心音频"为了实现CoreAudio(虽然我必须工作几周并进行研究,但现在工作得非常好)和书籍#34;数字信号处理" (非常有名,因为我看到他总是在专门讨论过滤器的讨论中表示。)
DSP之书我理解这一点:我必须创建一个过滤器,一种内核过滤器,它是一种"掩码"应用于信号本身。在这种状态下,过滤器被称为"脉冲响应"或者也称为IIR。现在我通过功能卷积成为FIR滤波器来应用掩码来发信号。我写的是正确的吗?
我尝试实现所编写的内容,甚至采用与文档一样的AudioGraph应用程序示例,但没有。不起作用。
我还找到了一个文档,它以简单的方式解释了该怎么做(名称是"在C ++中创建FIR滤波器"),其中提到了滤波器的算法,但即使在这里,一旦实施已经无效。
因为这对我来说是个疑问:也许我还有别的东西要跟我得到的信号有什么关系?我唯一理解的是我必须转换Sint16中的信号。我做了,但那又怎么样?我该怎么做才能实现数字滤波器?
为此我请求帮助。我没有人可以面对,所以现在我失明了。我给你留下我目前的CoreAudio代码,我工作得很完美,甚至在设备上,但是,也许可能是一些错误的设置?
AudioComponentDescription AudioCompDesc;
AudioCompDesc.componentType = kAudioUnitType_Output;
AudioCompDesc.componentSubType = kAudioUnitSubType_RemoteIO;
AudioCompDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
AudioCompDesc.componentFlags = 0;
AudioCompDesc.componentFlagsMask = 0;
AudioComponent RIOComponente = AudioComponentFindNext(NULL, &AudioCompDesc);
CheckError(AudioComponentInstanceNew(RIOComponente, &strutturaAscolto.RIO), "Impossibile ottenre un'istanza dell'unità RIO");
UInt32 oneFlag = 1;
AudioUnitElement bus0 = 0;
CheckError(AudioUnitSetProperty (strutturaAscolto.RIO, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output,bus0, &oneFlag, sizeof(oneFlag)), "Impossibile abilitare l'uscita RIO");
AudioUnitElement bus1 = 1;
CheckError(AudioUnitSetProperty(strutturaAscolto.RIO, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, bus1, &oneFlag, sizeof(oneFlag)),"Imposibile abilitare l'ingresso RIO");
strutturaAscolto.AudioAscoltoASBD.mSampleRate = 44100;
strutturaAscolto.AudioAscoltoASBD.mFormatID = kAudioFormatLinearPCM;
strutturaAscolto.AudioAscoltoASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;
strutturaAscolto.AudioAscoltoASBD.mBytesPerPacket = 4;
strutturaAscolto.AudioAscoltoASBD.mFramesPerPacket = 1;
strutturaAscolto.AudioAscoltoASBD.mBytesPerFrame = 4;
strutturaAscolto.AudioAscoltoASBD.mChannelsPerFrame = 2;
strutturaAscolto.AudioAscoltoASBD.mBitsPerChannel = 16;
CheckError(AudioUnitSetProperty (strutturaAscolto.RIO, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, bus0, &strutturaAscolto.AudioAscoltoASBD, sizeof (strutturaAscolto.AudioAscoltoASBD)), "Impossibile impostare la descrizione audio (ASBD) per RIO sull'applicazione di ingresso 0");
CheckError(AudioUnitSetProperty (strutturaAscolto.RIO, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, bus1, &strutturaAscolto.AudioAscoltoASBD, sizeof (strutturaAscolto.AudioAscoltoASBD)), "Impossibile impostare la descrizione audio (ASBD) per RIO sull'applicazione di uscita 1");
strutturaAscolto.SenoFrequenza = 30;
strutturaAscolto.SenoFase = 0;
AURenderCallbackStruct CallbackStruct;
CallbackStruct.inputProc = ModulazioneAudio;
CallbackStruct.inputProcRefCon = &strutturaAscolto;
CheckError(AudioUnitSetProperty(strutturaAscolto.RIO, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, bus0, &CallbackStruct, sizeof (CallbackStruct)), "Impossibile impostare il rendering di callback di RIO sul bus 0");
CheckError(AudioUnitInitialize(strutturaAscolto.RIO), "Non è stato possibile inizializzare l'unità RIO");
CheckError(AudioOutputUnitStart(strutturaAscolto.RIO), "Non è stato possibile avviare l'unità RIO");
虽然应该容纳过滤器的功能就是这个。
static OSStatus ModulazioneAudio(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,AudioBufferList *ioData) {
StrutturaAscolto *strutturaAscolto = (StrutturaAscolto*) inRefCon;
UInt32 bus1 = 1;
CheckError(AudioUnitRender(strutturaAscolto->RIO, ioActionFlags, inTimeStamp, bus1, inNumberFrames, ioData), "Non è stato possibile fare il render dell'unità RIO");
return noErr;
}
我带了一些过滤器,我测试过的(不是全部)。将此算法用于文档的高通滤波器"用C ++创建FIR滤波器":
int N = 1024;
float f_c = 5000/44100;
float ω_c = 2*M_PI*f_c;
int middle = N/2;
int i = -N/2;
float fltr[middle];
do {
if (i == 0) {
fltr[middle] = 1 - 2*f_c;
}
else {
fltr[i+middle] = -sin(ω_c*i)/(M_PI*i);
}
i++;
} while(i != N/2);
这是我读过DPS(第16章)所做的,并且在应用程序AudioGraph中也有提及。
void lowPassWindowedSincFilter( float *buf , float fc ) {
int i;
int m = 100;
float sum = 0;
for( i = 0; i < 101 ; i++ ) {
if((i - m / 2) == 0 ) {
buf[i] = 2 * M_PI * fc;
}
else {
buf[i] = sin(2 * M_PI * fc * (i - m / 2)) / (i - m / 2);
}
buf[i] = buf[i] * (.54 - .46 * cos(2 * M_PI * i / m ));
}
for ( i = 0 ; i < 101 ; i++ ) {
sum = sum + buf[i];
}
for ( i = 0 ; i < 101 ; i++ ) {
buf[i] = buf[i] / sum;
}
}
至于卷积函数,我习惯使用Hamming,我在StackOverflow上找到的非常简单。
for (int i = 0; i < 1024; i++) {
double multiplier = 0.5 * (1 - cos(2*M_PI*i/1023));
dataOut[i] = multiplier * dataIn[i];
}
感谢您的关注。