如何在Core Audio中实现数字滤波器?

时间:2017-02-01 00:06:57

标签: ios objective-c filter signal-processing audiounit

我对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];
}

感谢您的关注。

0 个答案:

没有答案