Knacken trotz FIR Filter

OP #1051188
Hallo an alle,

ich habe einen VOIP Client entwickelt und tu mich gerade schwer mit der 
Implentierung der Sprache.
Ich zeichne die Sprache via Microphone auf und zwar unter DirectSound.

Dann gebe ich die ungefilterten Rohdaten an einen FIR Filter
1
    short* pTmpBuffer = (short*)pBuffer; //pBuffer = unbehandelte Rohdaten
2
    short* pTmpBuffer2 = new short[160];
3
    for(int i = 0; i < (size - m_nCoeffSize); i++)
4
    {
5
        pTmpBuffer[i] = 0;
6
        for(int y = 0; y < m_nCoeffSize; y++)
7
        {
8
            pTmpBuffer[i] += (pBuffer[y + i] * fCoeffs[y]);
9
        }
10
    }

Danach sample ich das ganze runter von 16kHz auf 8kHz indem ich jeden 
2ten Sample einfach wegwerfe.
1
pTmpBuffer2[0] = 0;
2
    int x = 0;
3
    for(int i = 0; i < size; i++)
4
    {
5
        
6
        if((i+1)%2 == 0)
7
        {
8
            pTmpBuffer2[x] = pTmpBuffer[i];
9
            x++;
10
        }
11
    }

Und encodiere das ganze dann noch mal ins uLaw Format
Am anderen Ende bekomme ich dann die Sprache leicht verzerrt mit einem 
störendem Knacken im Hintergrund.

Ich weiß gerade gar nicht mehr weiter. Kann mir evtl jemand helfen?

Die Filterkoeffizienten hole ich mir über dieses Programm
http://www.winfilter.20m.com

Gruß

Karsten
OP #1051302
Ich behandle direkt die Rohdaten nach dem sie über den ADC der 
Soundkarte abgetastet wurden. Also ganz normal PCM.
Was brauch ich für einen Antialiasing Filter?.

Ich muss dazu sagen ich bin absoluter Beginner auf dem Gebiet und froh, 
dass ich den FIR Filter verstanden habe.

@Anton2:
Wie kann man denn besser runtersamplen?
Admin Persönliche Seite #1051353
Das ist im Prinzip schon richtig. Erst mit Tiefpassfilter auf < 4 kHz 
begrenzen, dann jedes zweite Sample wegwerfen. Das Knacken kommt 
wahrscheinlich durch falsches Bufferhandling zustande (wie das bei 
DirectSound funktioniert weiß ich leider nicht), die "Verzerrungen" 
könnten Aliasing durch unzureichende Filterung sein.

Hat DirectSound keine Funktion zum Downsampling auf 8 kHz?
OP #1051369
Ich hab leider nichts dazu finden können ob es unter DirectSound eine 
Funktion zum runtersamplen gibt. In der SDK Dokumentation hab ich nichts 
gefunden und unter google ebensowenig.

Als Buffer hab ich einen Ringbuffer. Es wird immer eine Nachricht 
geschickt, wenn genügend Daten im Buffer vorhanden sind die bearbeitet 
werden können. Dann kann man mit den Signalen arbeiten.

Was heißt denn unzureichenden Filterung? Ich filtere derzewit mit 31 
Koeffizienten.
Admin Persönliche Seite #1051927
Ist der Eingangsbuffer gross genug dass er nicht ueberlaueft? Ist der 
Ausgangsbuffer gross genug dass er nicht leer laeuft? Fuellst du den 
Ausgangsbuffer am Anfang und nach einem Leerlaufen immer komplett voll? 
Ich bin sicher dass DirectSound Programmbeispiele bereitstellt die 
solche Fehlerquellen ausschliessen.

Wie hast du den Filter designt (Grenzfrequenz)? Du musst ueber 4 kHz 
eine moeglichst gute Daempfung haben (ich sag mal >30 dB als 
Hausnummer). Winfilter ist uebrigens etwas mit Vorsicht zu geniessen, 
verwende besser Scilab oder Octave (oder, falls vorhanden, MATLAB mit 
fdatool).
#1052276
Roland Bumm wrote:
> Müssen die Abtastwerte sich nicht überlappen? Sprich im Ringpuffer liegt
> ein Wert (der letzte vom vorherigen)? Oder mehr sogar?
> Wenn das Stoss an Stoss liegt, dann kann es doch zum knacken kommen?
>
> mfg

Argh Sorry. Die Ausgangswerte müssen sich überlappen:

If the support of the impulse response, h(n), has length M
and the support of the k-th segment, xk(n), has length L,
then the discrete linear convolution of h and xk has support of length 
L+M-1

For example if  L = 125 and M = 26 then the support of the individual 
discrete linear convolutions each have length

N = L + K - 1
    = 125 + 26 - 1
    = 150

The first 25 elements of the k-th DLC overlap the last 25 elements of 
the previous DLC.
Angehängte Dateien:
Admin Persönliche Seite #1052885
Der FIR-Filter muss am Anfang eines neuen Blocks auf die letzte Werte 
des alten Blocks zurueckgreifen. Am einfachsten geht das, indem die 
Filterfunktion einen eigenen Buffer fuer die letzten L-1 Samples 
bereithaelt, so dass sie nur mit einem Sample als Argument aufgerufen 
wird und ein Sample zurueckgibt.

Suche mal nach "Winfilter" im Forum. Alternativen fuer Filterdesign habe 
ich oben genannt, gibt aber natuerlich noch mehr.
OP #1053849
Andreas Schwarz wrote:

> So viele wie der FIR-Filter braucht (Anzahl der Koeffizienten).

Das hatte ich mir schon fast gedacht, dass es die Anzahl er 
Koeffizienten sein muss. Aber sicher ist sicher:D Danke.
Was ich noch nicht so ganz klar verstanden habe, aus deiner Erklärung

> so dass sie nur mit einem Sample als Argument aufgerufen
> wird und ein Sample zurueckgibt

sprich ich arbeite nur mit einem Wert und rechne darauf die letzten 5 
Werte aus meinem Buffer?

Also
pTmpBuffer[0] = Sample[2] //bspw.
y += pTmpBuffer[0]*Coeffs[0];
pTmpBuffer[1] = y //pTmpBuffer wird immer der zuletzt berechnete Wert an
                  //erste Stelle gesetzt

Was mache ich während ich noch die ersten 5 Buffer bearbeite und somit 
vorher zwischen 0 und 4 Werte habe, womit rechne ich das auf?
OP #1053888
Jetzt habe ich es mit dem Algorithmus des fir_basics aus deinem Beispiel 
ausprobiert. Die Sprache ist zwar besser aber es ist immer noch ein 
Knistern beim Sprechen und der Sound selbst ist noch ein wenig verzerrt.
1
for(int i = 0; i < size; i++)
2
{
3
     m_pAliasBuffer[0] = pBuffer[i];
4
     /* calc FIR */
5
     accum = 0;
6
     for (ii = 0; ii < m_nCoeffSize; ii++) 
7
     {
8
         accum += fCoeffs[ii] * m_pAliasBuffer[ii];
9
     }
10
     /* shift delay line */
11
     for (ii = m_nCoeffSize - 2; ii >= 0; ii--) 
12
     {
13
         m_pAliasBuffer[ii + 1] = m_pAliasBuffer[ii];
14
     }
15
     pTmpBuffer[i] = accum;
16
}

Ich bin echt langsam überfragt
Admin Persönliche Seite #1053976
OK, ich sehe gerade dass du mit Integern rechnest. Wenn du das machst, 
dann musst du fuer den Akkumulator eine groessere Wortbreite (z.B. long) 
verwenden und nach dem Aufaddieren einen Rechtsshift durchfuehren, 
entsprechend der Skalierung deiner Filterkoeffizienten. Bessere 
Alternative: lass dir die Koeffizienten in Floating Point ausgeben und 
rechne in Floating Point, dann must du dir darum keine Gedanken machen.
OP #1053984
Oh sorry hätte ich vllt. mal anmerken können, die Koeffizienten sind in 
double
1
double fCoeffs[5] = { 
2
        -0.00112053738724361000,
3
        0.00112128133087145220,
4
        0.99999851211274415000,
5
        0.00112128133087145220,
6
        -0.00112053738724361000
7
    };
und accum ist ebenfalls vom Typ double
OP #1054007
Ja pBuffer ist der Eingang und pTmpBuffer Ausgang.
Sorry für meine schlechte Namensgebung;)
Wie meinst du das genau von Buffer zu Buffer?
DirectSound liefert mir ja den Buffer oder soll ich den Filter einfach 
mal mit ner normalen WaveDatei, welche ich einlese austesten?
OP #1054927
So habe jetzt noch mal ein paar unterschiedliche Koeffizienten 
ausprobiert.
Jetzt ist das Knacken fast weg.
Allerdings hört sich die Sprache noch sehr mechanisch an. Aber sie ist 
mittlerweile sehr deutlich zu verstehen.

Was kann man da noch machen?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.