Interleave

Verschränkt mehrere Eingangsströme abwechselnd zu einem einzigen Ausgangsstrom — mit entsprechend erhöhter Ausgaberate.

1. Beschreibung des Blocks

Der Interleave-Block (blocks.interleave) fasst $N$ gleichartige Eingangsströme zu einem einzigen Ausgangsstrom zusammen, indem er reihum jeweils Block Size aufeinanderfolgende Samples aus jedem Eingang entnimmt und aneinanderreiht: bei Block Size = 1 also abwechselnd ein Sample aus in0, eines aus in1, …, eines aus in(N-1), dann wieder von vorn. Die Ausgaberate steigt dadurch um den Faktor $N$ gegenüber der (identischen) Rate jedes einzelnen Eingangs.

Interleave Block

2. Technischer Einsatz

Interleave wird eingesetzt, um mehrere parallele, gleichartige Datenströme wieder zu einem einzigen linearen Strom zusammenzuführen — z. B. um mehrkanalige Messdaten (mehrere Sensor- oder Empfangszweige mit identischer Abtastrate) in ein einziges Ausgabeformat zu bringen, das ein nachgelagerter Block oder eine Datei-Senke als fortlaufenden Strom erwartet. Das Gegenstück zum Entflechten eines bereits verschränkten Stroms zurück in $N$ Einzelströme ist der Deinterleave-Block.

Interleave ist kein Ersatz für Float To Complex: Letzterer kombiniert zwei reelle Ströme sample-synchron zu einem komplexen IQ-Signal (ein Ausgangssample pro Eingangssample-Paar), während Interleave die Eingangssamples unverändert nacheinander in denselben Strom schreibt, ohne sie rechnerisch zu kombinieren — die Ausgaberate multipliziert sich, der Datentyp bleibt gleich.

3. Anwendungsbeispiel: Frequenzinformation aus zwei Goertzel-Blöcken zusammenführen

Ein passendes Beispiel aus der Praxis knüpft an die Einzelton-Erkennung mit dem Goertzel-Block an: Soll eine Funktion erst nach Erkennung von zwei definierten Tönen aktiviert werden (z. B. ein einfaches Zwei-Ton-Aktivierungssignal, ähnlich einem DTMF-Paar), liefert jeder Goertzel-Block die Energie einer Zielfrequenz als eigenen, separaten Strom:

Audio Source ──┬──► Goertzel (Frequency: f1) ──► Complex to Mag ──► in0 ┐ │ ├──► Interleave ──► out └──► Goertzel (Frequency: f2) ──► Complex to Mag ──► in1 ┘

Statt zwei getrennte Pegelströme separat weiterzuverarbeiten (und dabei z. B. per Zeitstempel synchron halten zu müssen), führt Interleave (Num Streams: 2, Block Size: 1) beide Magnitudenwerte zu einem einzigen Strom zusammen: mag(f1)[0], mag(f2)[0], mag(f1)[1], mag(f2)[1], …. Ein einzelner nachgelagerter Konsument — z. B. ein eigener Python-Block, der abwechselnd gerade und ungerade Samples liest, oder ein Vector Sink zur gemeinsamen Aufzeichnung — bekommt damit beide Tonpegel in einem einzigen, fortlaufenden Strom, statt zwei separate Ports verwalten zu müssen.

Da beide Goertzel-Blöcke am selben Audio-Source-Takt hängen, liefern sie garantiert synchron neue Werte — genau die Voraussetzung, die Interleave für eine sinnvolle Verschränkung an allen Eingängen erwartet (siehe Warnhinweis in Abschnitt 5).

4. Parameter und Dimensionierung

Parameter Typ/Einheit Bedeutung Dimensionierungshinweis
type Enum Datentyp: Complex, Float, Int, Short, Byte muss für alle Eingänge identisch sein
Num Streams Integer Anzahl der Eingänge $N$ bestimmt sowohl die Zahl der Eingangsports als auch den Ausgaberaten-Faktor
Block Size Integer Anzahl aufeinanderfolgender Samples, die je Eingang vor dem Wechsel entnommen werden Standard 1 (echtes Sample-für-Sample-Interleaving); größere Werte gruppieren Blöcke statt einzelner Samples

5. Ein- und Ausgänge

Ein-/Ausgang Typ
Eingänge (in0in(N-1)) wie type, gleiche Abtastrate an allen Eingängen vorausgesetzt
Ausgang wie type, Abtastrate um Faktor $N$ erhöht
Gleiche Eingangsrate vorausgesetzt: Der Block geht implizit davon aus, dass an allen Eingängen im selben Takt neue Samples anliegen. Läuft ein Eingang langsamer oder liefert unregelmäßig Daten (z. B. eine Message-Quelle statt eines echten Streams), blockiert oder verzerrt sich die Verschränkung entsprechend — Interleave ist für synchron getaktete Stream-Eingänge gedacht, nicht für Daten unterschiedlicher Herkunftsraten.

6. Weitere wichtige Aspekte

Reihenfolge ist fix: Die Ausgabereihenfolge folgt strikt der Eingangsnummerierung (in0 vor in1 vor …) — eine andere Verschränkungsreihenfolge lässt sich nur durch entsprechende Verkabelung der Eingänge im Flowgraph erreichen, nicht über einen Parameter.

Verwandter Block: Deinterleave zum Rückgängigmachen der Verschränkung — teilt einen Strom wieder in $N$ separate Ausgänge auf.