Um den originalen Thread nicht thematisch zu verbiegen: DH1AKF W. schrieb: > Entschuldigung, etwas O.T.: >... > Für W.S. (Gast) habe ich zu seinem Problem diesen Link: > https://forum.pjrc.com/threads/40590-Teensy-Convolution-SDR-(Software-Defined-Radio)?p=247147&viewfull=1#post247147 Vermutlich meinst du das da: "Ok Frank. I figured out how to make complex bandpass filters. After fruitless research and less-fruitless experimentation, it is actually embarrassingly trivial. I don't know why this information is so hard to find. I can't find any good reference material on complex filters - just a bunch of unhelpful info on fancy multi-stage decimating filters which we don't need because the Teensy handles the decimation. Maybe you know of a decent reference? Anyhow, here is how it is done: 1. Create a regular low-pass filter. 2. Create a vector of integers that run from 0:N, where N is the number of coefficients. 3. Take the low-pass numerator coefficients and scalar multiply the whole lot by e^(j*nFc*pi*(0:N)). Where: nFc is the normalized frequency shift that you desire and (0:N) is that vector you created in step 2. In Matlab the command is this: cpx_coeffs = coeffs .* exp(j*nFc*pi*(0:N)) This creates a center-frequency-tunable complex bandpass filter. If the low-pass filter you started with is minimum phase, then the complex filter is also minimum phase (from my experiments so far). I still need to figure out if any random low-pass filter will work. I don't know, but I suspect it may need a particular phase response to act the part of the Hilbert filter. I will do some more messing around tomorrow. 73, Bill WH7U" Kurz gesagt: ich kann's nicht nachvollziehen. Punkt 1 und 2 sind pillepalle, sie bedeuten ja lediglich daß man sich ein Array für den Realanteil und ein zweites Array für den Imaginäranteil macht und zuerst den Realteil mit einem berechneten Lowpaß füllt, den man anschließend quasi verschiebt. Punkt 3 mit der Formel "e^(j*nFc*pi*(0:N))" erscheint mir komplett falsch zu sein, aus folgenden Gründen: 1. sofern man das so versteht: for k:= 0 to N do tap[k].imaginär:= exp(0 + j*Eckfrequenz*pi*k); dann ist das vollständig unsymmetrisch, weil eigentlich k von -(N/2) bis +(N/2) laufen müßte. Also etwa so: tap[k].imaginär:= exp(0 + j*Eckfrequenz*pi*(k-N/2)); 2. der Exponent hat einen Realteil von 0 und einen Imaginärteil, der größer als 0 und proportional zu k ist. Mir fehlt da ein Minuszeichen. Und wenn ich mir das Bild beim Beitrag von WH7U vom 07-24-2020, 12:12 AM anschaue, dann kommen mir nochmal Zweifel. Bei der Phase erwarte ich eine Waagerechte, aber das kann auch vom Verständnis zum Referenzpunkt abhängen. Normalerweise ist das ja die Mitte des Filters. Und nein, Matlab hab ich nicht und ich hab mich auch in deren Notation nicht eingearbeitet. Abgesehen davon läuft das Ganze offenbar auf bandpass-shift hinaus, nicht jedoch auf phase-shift. Also Verschieben der Eckfrequenzen und nicht der Phase des Signals. Je mehr ich drüber nachdenke, desto mehr habe ich den Eindruck, daß der OM damit etwas ganz anderes vorhat als ich. W.S.
Hallo Wolfgang, leider war ich auf dem falschen Dampfer: Hier werden IIR- Filter benutzt, keine FIR's ... Vielleicht hilft Dir die Lektüre dieses Kapitels etwas weiter: https://www.intechopen.com/books/matlab-a-fundamental-tool-for-scientific-computing-and-engineering-applications-volume-1/digital-fir-hilbert-transformers-fundamentals-and-efficient-design-methods Es ist schwere Kost, wenn die Studienjahre schon etwas zurückliegen. Im Übrigen fand ich bei mehreren Projekten lediglich vorberechnete Filterkoeffizienten, keine direkt im Controller erzeugten: https://github.com/DD4WH/Teensy-ConvolutionSDR https://github.com/DD4WH/mchf-github/blob/active-devel/mchf-eclipse/drivers/audio/filters/iq_tx_filter.c
DH1AKF W. schrieb: > Im Übrigen fand ich bei mehreren Projekten lediglich vorberechnete > Filterkoeffizienten,... Ach, das ist langweilig. Natürlich kann man das so machen, also mehrere Filterkernel im Flash vorhalten. Früher hatte man ja auch nur die Auswahl zwischen den eingebauten Quarzfiltern. Aber es ist allemal wesentlich netter, auf sowas verzichten zu können und den Kernel ad hoc im µC zu berechnen. Und das von dir erwähnte Kapitel 19 hatte ich mEn schon mal vor geraumer Zeit gelesen. Jetzt, wo du es erwähnt hast, ist's mir wieder eingefallen. Mathe ist oftmals die reine Intuition - siehe Gauss: "Ich habe das Resultat, ich weiß nur noch nicht, auf welchem Wege ich es erreichen werde". Mein derzeitiger Gedanke dazu ist erstmal keine grandiose Intuition, sondern nur stur geradeaus: - Filter in real berechnen (FIR-Bandpaß auf Basis sin(x)/x mit Blackman oder Kaiser) - Imaginären Teil des Filters berechnen per Hilbert - für alle Taps des Filters jeweils den Re und Im als X und Y auffassen und damit nen cordic um 45° - der nun entstandene Realteil sollte dann der fertige Filterkernel sein. - für -45° braucht man ja bloß das Filter in der Mitte zu spiegeln, also paarweise tauschen: tap[0] <--> tap[N-1], tap[1]<-->tap[N-2], usw. W.S.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.