freq_xlating_fir_filter

Eines der Block-Tests-Unterverzeichnisse (siehe ../README.md
für die Übersicht). Testet Freq Xlating FIR Filter (Variante ccf:
komplexer Ein-/Ausgang, reelle Taps) — den Block, der Frequenzverschiebung,
Tiefpassfilterung und Dezimierung in einem einzigen, optimierten Schritt
kombiniert (siehe Einsatz im USB-Empfänger).

Testaufbau

test_freq_xlating_fir_filter.py erzeugt ein synthetisches IQ-Signal mit
drei Tönen (1 MHz Abtastrate):

Ton Frequenz Rolle
Zielton +100 kHz soll nach der Verschiebung bei 0 Hz landen
Störer 1 −300 kHz soll unterdrückt werden
Störer 2 +350 kHz soll unterdrückt werden

plus komplexes weißes Rauschen. Der Block wird mit center_freq=100 kHz
(verschiebt den Zielton exakt auf 0 Hz), decim=10 (Ausgangsrate
100 kHz) und einem Tiefpass (Grenzfrequenz 40 kHz, Übergangsbreite
10 kHz, Hamming-Fenster) konfiguriert.

Ausführen

python3 test_freq_xlating_fir_filter.py
python3 test_freq_xlating_fir_filter.py
``` === Block-Parameter (Freq Xlating FIR Filter, Variante ccf) === center_freq (Frequenzverschiebung): +100.0 kHz decim (Dezimierungsfaktor): 10 Eingangs-Abtastrate: 1.000 MHz Ausgangs-Abtastrate: 100.0 kHz Tiefpass-Grenzfrequenz: 40.0 kHz Uebergangsbreite: 10.0 kHz Fenster: Hamming Anzahl Filter-Taps: 241 Gruppenlaufzeit (Taps // 2): 120 Samples bei 1.000 MHz = 120.00 us relative_rate() (GNU-Radio-intern): 0.1000 (erwartet 1/10 = 0.1000) Eingangs-Samples: 200000, Ausgangs-Samples: 20000 (erwartet ca. 20000)

=== Messung: Unterdrueckung der Stoerer ===
Zielton vorher (bei 100 kHz): 62.8 dB
Zielton nachher (bei 0 Hz): 63.3 dB
Stoerer 1 vorher (bei -300 kHz): 61.3 dB
(Stoerer liegen nach der Dezimierung ausserhalb des Ausgangsbands - vom Filter samt Alias-Schutz entfernt, siehe PNG.)


![Spektrum vor und nach dem Freq Xlating FIR Filter](freq_xlating_fir_filter_fft.png)
</div>

## Einordnung des Ergebnisses

Oben das Eingangsspektrum (drei deutliche Peaks über dem Rauschteppich),
unten das Ausgangsspektrum: Der Zielton sitzt exakt bei 0&nbsp;Hz, beide
Störer sind komplett verschwunden — sie lägen nach der Verschiebung bei
−400&nbsp;kHz bzw. +250&nbsp;kHz, weit außerhalb sowohl des Filterdurchlassbereichs
als auch der Nyquist-Grenze der dezimierten 100-kHz-Ausgangsrate (±50&nbsp;kHz).
Der Block erledigt Tuning, Anti-Alias-Filterung vor der Dezimierung und die
Dezimierung selbst in einem Durchgang.

<div class="info box">Der Rauschteppich im Ausgangsspektrum ist keine flache Linie, sondern steigt zur Mitte hin leicht an ("Huckel"-Form um den 63-dB-Zielton). Das ist <strong>kein Filterfehler</strong>, sondern spektrales Leckage der Fensterfunktion (Blackman-Harris) bei der FFT-Analyse: Ein derart starker, schmalbandiger Ton hinterlässt auch mit gutem Fenster einen sichtbaren Leckage-"Skirt" in benachbarten Bins. Kontrollmessung ohne Ton (nur Rauschen durch denselben Filter): Rauschteppich flach bei ca. −16&nbsp;dB im Durchlassbereich, Abfall auf ca. −45&nbsp;dB im Sperrbereich — der eigentliche Frequenzgang des Filters ist also einwandfrei flach, nur die Analyse-Darstellung neben dem starken Ton täuscht das optisch an.</div>

## Was die einzelnen Parameter bedeuten

<div class="table-scroll table-striped">

| Parameter | Bedeutung |
| :--- | :--- |
| `center_freq` | Frequenz, die auf 0&nbsp;Hz gemischt wird — bestimmt die Empfangs-/Sendefrequenz |
| `decim` | Dezimierungsfaktor; Ausgangsrate = Eingangsrate / `decim` |
| `taps` | Tiefpass-Filterkoeffizienten (hier via `firdes.low_pass` erzeugt) — legen Durchlassbereich, Übergangsbreite und Anzahl der Taps fest |
| `relative_rate()` | GNU-Radio-interne Kenngröße, die das Verhältnis Ausgangs- zu Eingangsrate bestätigt (hier 0,1 = 1/`decim`) |
| Gruppenlaufzeit | `len(taps) // 2` Samples — Verzögerung, die der Filter dem Signal aufprägt (symmetrisches FIR-Filter) |

</div>

![Spektrum vor und nach dem Freq Xlating FIR Filter](freq_xlating_fir_filter_fft.png)
</div>

## Einordnung des Ergebnisses

Oben das Eingangsspektrum (drei deutliche Peaks über dem Rauschteppich),
unten das Ausgangsspektrum: Der Zielton sitzt exakt bei 0&nbsp;Hz, beide
Störer sind komplett verschwunden — sie lägen nach der Verschiebung bei
−400&nbsp;kHz bzw. +250&nbsp;kHz, weit außerhalb sowohl des Filterdurchlassbereichs
als auch der Nyquist-Grenze der dezimierten 100-kHz-Ausgangsrate (±50&nbsp;kHz).
Der Block erledigt Tuning, Anti-Alias-Filterung vor der Dezimierung und die
Dezimierung selbst in einem Durchgang.

<div class="info box">Der Rauschteppich im Ausgangsspektrum ist keine flache Linie, sondern steigt zur Mitte hin leicht an ("Huckel"-Form um den 63-dB-Zielton). Das ist <strong>kein Filterfehler</strong>, sondern spektrales Leckage der Fensterfunktion (Blackman-Harris) bei der FFT-Analyse: Ein derart starker, schmalbandiger Ton hinterlässt auch mit gutem Fenster einen sichtbaren Leckage-"Skirt" in benachbarten Bins. Kontrollmessung ohne Ton (nur Rauschen durch denselben Filter): Rauschteppich flach bei ca. −16&nbsp;dB im Durchlassbereich, Abfall auf ca. −45&nbsp;dB im Sperrbereich — der eigentliche Frequenzgang des Filters ist also einwandfrei flach, nur die Analyse-Darstellung neben dem starken Ton täuscht das optisch an.</div>

## Was die einzelnen Parameter bedeuten

<div class="table-scroll table-striped">

| Parameter | Bedeutung |
| :--- | :--- |
| `center_freq` | Frequenz, die auf 0&nbsp;Hz gemischt wird — bestimmt die Empfangs-/Sendefrequenz |
| `decim` | Dezimierungsfaktor; Ausgangsrate = Eingangsrate / `decim` |
| `taps` | Tiefpass-Filterkoeffizienten (hier via `firdes.low_pass` erzeugt) — legen Durchlassbereich, Übergangsbreite und Anzahl der Taps fest |
| `relative_rate()` | GNU-Radio-interne Kenngröße, die das Verhältnis Ausgangs- zu Eingangsrate bestätigt (hier 0,1 = 1/`decim`) |
| Gruppenlaufzeit | `len(taps) // 2` Samples — Verzögerung, die der Filter dem Signal aufprägt (symmetrisches FIR-Filter) |

</div>