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
Danach sample ich das ganze runter von 16kHz auf 8kHz indem ich jeden
2ten Sample einfach wegwerfe.
1
pTmpBuffer2[0]=0;
2
intx=0;
3
for(inti=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
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?
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?
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.
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).
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
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.
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.
Wieviele der letzten Werte des alten Blocks sind denn sinnvoll?
Also z.B. habe ich einen Buffer von 320Byte der gefiltert wird.
Kann ich hier berechnen wieviele genommen werden sollen???
Ich schnall es gerade einfach nicht.
Hat irgendwer mal ein Beispiel für mich wie ich meinen Code(s.o.)
anpassen könnte???
Pseudocode reicht ja schon nur nicht zu mathematisch bitte:D:D
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?
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.
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.
pBuffer ist der Eingang, pTmpBuffer der Ausgang (gib denen doch mal
sinnvolle Namen)? Dann sollte das eigentlich funktionieren. Probier es
am besten erst mal ohne DirectSound, Netzwerkuebertragung usw. aus,
einfach von Buffer zu Buffer, und schau ob das funktioniert.
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?
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?
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.