Wer eigene Versuche auf dem Weg zur Programmierung eines Software Defined Radio unternehmen will, benötigt zuerst einmal einen geeigneten Zugang zur Soundkarte. Im Prinzip holt man sich Daten von der Soundkarte, bearbeitet sie mit einem DSP (Digitaler Signal-Prozessor) und schickt sie dann wieder an die Soundkarte. Das ganze funktioniert mit Datenblöcken, die jeweils so schnell bearbeitet werden müssen, dass keine Pause im Ausgangssignal entsteht.
Gerald Youngblood (AC5OG) hat in seinem Artikel "A Software-Defined Radio for the Masses" (QEX 7/8 2002) nicht nur das Grundprinzip eines SDR erklärt, sondern auch einen Zugang zur Soundkarte gezeigt. Sein VB-Beispielprogramm Sound.vbp zeigt den Zugang über DirectX 8. Auf der Basis dieses Beispiels ist die Entwicklung eigener DSP-Software relativ einfach.
Das VB-Beispiel von Gerald Youngblood definiert einen Puffer "inBuffer", der von der Soundkarte mit Daten gefüllt wird. Immer wenn Daten vorhanden sind, ruft ein zugehöriges Event die Sub DirectXEvent8_DXCallback auf. Hier werden die Daten in InBuffer kopiert. Das ursprüngliche Beispiel gibt die Daten gleich wieder aus. Was also an Line-In gelesen wurde, geht über die PC-Lautsprecher mit einer kleinen Verzögerung wieder raus. Es ist aber relativ einfach, die Daten vorher zu verändern. Dazu wird eine Sub DSP geschrieben und zwischen Lesen und Ausgeben aufgerufen. Die DSP-Routine muss Inbuffer umrechnen und in OutBuffer die veränderten Daten wieder ausgeben.
Verstärkungseinstellung 0…60 dB
Das erste eigene Beispiel soll einfach nur eine einstellbare Verstärkung liefern. Das ist bereits eine sinnvolle Anwendung, denn erste Versuche mit Direktmischern und SDR-Schaltungen leiden oft darunter, dass die empfangenen Signale zu leise sind. Bis zu 60 dB mehr bringen oft die Lösung.
Das ursprüngliche Programmbeispiel soll also um eine DSP-Routine erweitert werden. In ihr werden die 2048 gemessenen Daten aus inBuffer getrennt nach linkem und rechtem Kanal auf zwei eigene Fließkomma-Puffer Single1 und Single2 aufgeteilt. Die Messwerte liegen nun im Bereich -1 bis +1. Da nur ein Mono-Signal am Ausgang benötigt wird, addiert das Programm beide Kanäle. Dann wird die Summe mit einem einstellbaren Faktor zwischen 1 und 1000 multipliziert. Eine Begrenzung auf den Bereich -1 bis +1 verhindert Überläufe. Die umgerechneten Daten werden schließlich in den Ausgabepuffer outBuffer geschrieben. Bei einer Abtastrate von 48 kHz und einer Pufferlänge von 2048 Samples pro Kanal dauert es übrigens 42,7 ms, bis DSP erneut aufgerufen wird. Alles was hier passiert muss also deutlich schneller als 40 ms sein.
Sub DSP()
Dim i, j, n
If Multiplier < 1 Then Multiplier = 1
For i = 0 To 2047
Single1(i) = inBuffer(2 * i) / 32768 'Left in
Single2(i) = inBuffer(2 * i + 1) / 32768 'Right in
Next i
For i = 0 To 2047
Single1(i) = Single1(i) + Single2(i) 'L+R
Single1(i) = Single1(i) * Multiplier '+ xxx dB
If Single1(i) > 1 Then Single1(i) = 1 'limit 1
If Single1(i) < -1 Then Single1(i) = -1 'limit -1
Next i
For i = 0 To 2047
outBuffer(2 * i) = Int(Single1(i) * 32000) 'Left out
outBuffer(2 * i + 1) = outBuffer(2 * i) '= Right out
Next i
End Sub
Private Sub HScroll1_Change()
Multiplier = Int(Exp(HScroll1.Value / 60 * 6.908))
Label1.Caption = "+" + Str(C) + " dB " + Str(Multiplier)
End Sub
Die Verstärkung wird über den Schieberegler Hscroll1 eingestellt. Der übergebene Wert HScroll1.Value hat einen Bereich zwischen 0 und 60 und wird in den Verstärkungsfaktor "Multiplier" umgerechnet.
Download Exe und Quelltext (DSP1_60dB.zip, 10 KB)