Filtre passe-bas en C

J’implémente un filtre passe-bas en C avec la bibliothèque PortAudio. J’enregistre l’entrée de mon microphone avec un script de PortAudio lui-même. Là j’ai ajouté le code suivant:

float cutoff = 4000.0; float filter(float cutofFreq){ float RC = 1.0/(cutofFreq * 2 * M_PI); float dt = 1.0/SAMPLE_RATE; float alpha = dt/(RC+dt); return alpha; } float filteredArray[numSamples]; filteredArray[0] = data.recordedSamples[0]; for(i=1; i<numSamples; i++){ if(i%SAMPLE_RATE == 0){ cutoff = cutoff - 400; } data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1])); } 

Lorsque je lance ce script pendant 5 secondes, cela fonctionne. Mais lorsque j’essaie de l’exécuter pendant plus de 5 secondes, cela échoue. L’application enregistre tout, mais se bloque lors de la lecture. Si je supprime le filtre, l’application fonctionne.

Aucun conseil?

    Le problème:

    1. vous abaissez la fréquence de coupure de 400 Hz à chaque fois que i%SAMPLE_RATE == 0

      • ne vous arrêtez jamais pour aller en dessous de zéro
      • ce n’est pas fait une fois par seconde !!!
      • à la place, chaque fois que votre passe passe par la deuxième barrière dans vos données
      • cela peut se produire plus souvent alors vous pensez si vous n’appelez pas vos appels au bon endroit
      • qui ne se voit pas dans votre code
    2. vous filtrez dans le mauvais ordre

      • ... a[i]=f(a[i],a[i-1]; i++;
      • cela signifie que vous filtrez avec déjà filtré a[i-1]

    Que dois-je faire avec ça

    1. vérifier le placement du code

      • il devrait être dans certains cas comme sur emballé fait sompling
      • ou en fil après un certain Sleep(...); (ou à l’intérieur de la timer)
      • changer la coupe changer (cas de bord de poignée)
    2. filtre inverse pour la direction

    Quelque chose comme ça:

     int i_done=0; void on_some_timer() { cutoff-=400; if (cutoff<1) cutoff=1; // here change 1 for limit frequency if (numSamples!=i_done) for (i=numSamples-1,i>=i_done;i--) data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1])); i_done=numSamples; } 

    si votre code est déjà correct (vous n’avez pas posté le tout pour que je puisse rater quelque chose)

    • alors ajoutez simplement le if (cutoff<1) cutoff=1; après le changement de coupure