3 Stimmen

Interpolation der Sinustabelle

Ich möchte ein SDR-System zusammenstellen, das zunächst AM, später FM usw. empfängt. Das System, das ich dafür verwenden will, wird eine Sinus-Lookup-Tabelle für die direkte digitale Synthese (DDS) haben. Um richtig abstimmen zu können, muss ich in der Lage sein, die Frequenz der Sinuswelle, die dem Mischer (in diesem Fall dem Multiplikator) zugeführt wird, genau zu steuern. Ich erwarte, dass eine lineare Interpolation nahe dran ist, denke aber, dass eine nicht-lineare Methode bessere Ergebnisse liefern wird.

Was ist eine gute und schnelle Interpolationsmethode für Sinustabellen? Multiplikation und Addition sind auf dem Zielsystem billig, Division ist kostspielig.

Bearbeiten: Ich plane, Konstanten mit Multiplikations-/Shift-Funktionen zu implementieren, um die Konstanten auf skalierte Ganzzahlen zu normalisieren. Zwischenwerte werden breite Additionen verwenden, und Multiplikationen werden 18 oder 17 Bits verwenden. Fließkomma-"Vorberechnungen" können verwendet werden, aber nicht auf der Zielplattform. Wenn ich sage "Division ist teuer", dann meine ich damit, dass sie mit Hilfe der Multiplizierer und einer Menge Code implementiert werden muss. Das ist nicht undenkbar, sollte aber vermieden werden. Echte IEEE-Fließkommamethoden würden jedoch auf dieser Plattform eine erhebliche Menge an Ressourcen sowie eine benutzerdefinierte Implementierung erfordern.

Jede SDR-Erfahrung wäre hilfreich.

8voto

Nick Dandoulakis Punkte 41402

Wenn Sie mit der linearen Interpolation keine sehr guten Ergebnisse erzielen, können Sie die trigonometrischen Beziehungen ausprobieren.

Formeln für Summe und Differenz

sin(A+B)=sinA*cosB + cosA*sinB
sin(A-B)=sinA*cosB - cosA*sinB
cos(A+B)=cosA*cosB - sinA*sinB
cos(A-B)=cosA*cosB + sinA*sinB

und Sie können vorberechnete sin- und cos-Werte für die Bereiche A und B haben, d. h.

A range: 0, 10, 20, ... 90
B range: 0.01 ... 0.99

4voto

Jason S Punkte 178087

Tabelleninterpolation für glatte Funktionen = ick hurl bleah. IMHO würde ich Tabelleninterpolation nur für wirklich seltsame Funktionen verwenden, oder wenn Sie unbedingt sicherstellen müssen, dass Sie Unstetigkeiten vermeiden (beachten Sie, dass die Ableitungen für interpolierte Tabellen allerdings unstetig sind). Bis Sie mit den Tabellenabfragen und dem erforderlichen Interpolationscode fertig sind, könnten Sie bereits ein oder zwei Polynome ausgewertet haben, zumindest wenn die Multiplikation Ihnen nicht zu viel Sodbrennen bereitet.

IMHO ist es viel besser, wenn Sie Tschebyscheff-Approximation für jedes Segment (z. B. -90 bis +90 Grad oder -45 bis +45 Grad und dann weitere Segmente der gleichen Breite) der Sinuswellenform und die Auswahl des Polynoms mit dem geringsten Grad, das den Fehler auf einen gewünschten Wert reduziert. Wenn das Segment klein genug ist, kann man mit einem quadratischen oder vielleicht sogar einem linearen Polynom auskommen; es gibt Kompromisse zwischen der Genauigkeit, der Anzahl der Segmente und dem Grad des Polynoms.

参照 mein Beitrag in dieser anderen Frage Das erspart Ihnen die Mühe, die Koeffizienten zu berechnen (zumindest wenn Sie meinen Berechnungen glauben).

(edit: falls das nicht klar war, machen Sie die Tschebyscheff-Approximation zur Entwurfszeit auf Ihrem bevorzugten Hochleistungs-PC, so dass Sie zur Laufzeit einen Drecksack-Mikrocontroller oder FPGA oder was auch immer mit einem einfachen Polynom von Grad 1-4 verwenden können. Gehen Sie nicht über Grad 4 hinaus, es sei denn, Sie wissen, was Sie tun; 3 oder darunter wäre besser).

4voto

Nosredna Punkte 78203

Warum ein Tisch? Diese sehr schnelle Funktion hat seine schlimmste Rauschspitze bei -90db, wenn das Signal bei -20db liegt. Das ist verdammt gut.

Für das Resampling von Audio verwende ich immer einen der Interpolatoren aus dem Elephant Paper. Dies wurde diskutiert in einem vorherige SO-Frage .

Wenn Sie einen Prozessor ohne fp haben, können Sie diese Dinge trotzdem tun, aber sie sind schwieriger. Ich habe das schon durchgemacht. Ich fühle Ihren Schmerz. Viel Glück! Früher habe ich zum Spaß Konvertierungen von fp in Integer gemacht, aber jetzt müsstest du mich dafür bezahlen :-)


Tolle Online-Referenzen, die auf Ihr Problem zutreffen:

http://www.audiomulch.com/~rossb/code/sinusoids/

http://www.dattalo.com/technical/theory/sinewave.html


Edit: zusätzliche Gedanken aufgrund Ihrer Kommentare

Da du an einem kniffligen Prozessor arbeitest, solltest du dich vielleicht damit beschäftigen, wie du deine Sinustabelle so gestalten kannst, dass sie mehr Winkel hat, aber trotzdem klein bleibt.

Nehmen wir an, Sie teilen einen Quadranten in 90 Teile auf (in Wirklichkeit würden Sie wahrscheinlich 256 Teile verwenden, aber lassen wir es der Einfachheit und Klarheit halber bei 90). Kodieren Sie diese als 16 Bit. Das sind bis jetzt 180 Bytes der Tabelle.

Für jeden dieser Grade gibt es nun 9 (in Wirklichkeit wahrscheinlich 8 oder 16) Zwischenpunkte.

Nehmen wir als Beispiel den Bereich zwischen 3 Grad und 4 Grad.

sin(3)=0.052335956 //this will be in your table as a 16-bit number
sin(4)=0.069756474 //this will be in your table as a 16-bit number

Wir werden uns also sin(3.1) ansehen.

sin(3.1)=0.054978813 //we're going to be tricky and store the result
                     // in 8 bits as a percentage of the distance between
                     // sin(3) and sin(4)

Sie wollen herausfinden, wie sin(3.1) zwischen sin(3) und sin(4) passt. Wenn es auf halbem Weg dazwischen liegt, kodieren Sie es als ein Byte von 128. Wenn es ein Viertel des Weges dazwischen ist, kodiere es als 64.

Das sind zusätzliche 90 Bytes, und Sie haben ein Zehntelgrad in 16-Bit-Auflösung in nur 180+90*9 Bytes kodiert. Sie können nach Bedarf erweitern (vielleicht bis zu 32-Bit-Winkeln und 16-Bit-Tween-Winkeln) und dazwischen sehr schnell linear interpolieren. Um den Speicherplatz zu minimieren, machen Sie sich die Tatsache zunutze, dass aufeinanderfolgende Werte nahe beieinander liegen.


Edit 2: bessere Möglichkeit, die Zwischenwinkel in einer Tabelle zu kodieren

Ich habe mich gerade daran erinnert, dass ich bei dieser Arbeit sehr kompakt ausgedrückt habe Unterschied zwischen dem erwarteten Wert nach linearer Interpolation und dem tatsächlichen Wert. Dieser Fehler liegt immer in der gleichen Richtung.

Ich habe zunächst den maximalen Fehler im Bereich berechnet und dann die Skala darauf aufgebaut.

Hat super funktioniert. Ich habe das Gefühl, ich sollte den Code in einem Blogeintrag erläutern :-)

3voto

Sam Harwell Punkte 94511

Die Interpolation in einer Sinustabelle ist praktisch eine Neuabtastung. Natürlich können Sie perfekte Ergebnisse durch einen einzigen Aufruf von sin Was auch immer Ihre Lösung ist, sie muss besser sein als diese. Beim Resampling mit festem Filter steht Ihnen immer noch nur eine feste Anzahl von Punkten zur Verfügung (ein Upsampler von 3:1 bedeutet, dass zwischen jedem Punkt in Ihrer Tabelle 2 neue Punkte verfügbar sind). Wie teuer ist der Speicher auf dem Zielsystem? Meine erste Empfehlung ist, die Tabellenauflösung zu verbessern und lineare Interpolation zu verwenden. Damit erhalten Sie die gleichen Ergebnisse wie mit einer kleineren Tabelle und einem einfachen Upsampler, aber mit weniger Rechenaufwand.

2voto

Haben Sie in Erwägung gezogen, die Taylor-Reihe für die trigonometrischen Funktionen zu verwenden (gefunden aquí )? Dies beinhaltet Multiplikation und Division, aber je nachdem, wie Ihre Zahlen dargestellt werden, können Sie die Division in Multiplikation umwandeln (oder in Bitverschiebungen, wenn Sie viel Glück haben). Sie können so viele Terme der Reihe berechnen, wie Sie brauchen, und erhalten auf diese Weise Ihre Genauigkeit.

Wenn diese Sinuswelle irgendwann ein analoges Signal sein wird, können Sie alternativ auch eine Nachschlagetabelle verwenden und einen analogen Filter einsetzen, um die Abtastfrequenz aus der resultierenden Wellenform zu entfernen. Wenn die Abtastfrequenz das 100-fache der Sinusfrequenz ist, lässt sie sich leicht entfernen. Dazu benötigen Sie ein variables Filter. Ich habe so etwas noch nie gemacht, aber ich weiß, dass es digitale Potentiometer gibt, die eine binäre Zahl nehmen und ihren Widerstand ändern. Das könnte die Grundlage für einen variablen RC-Filter sein - wahrscheinlich mit einigen Operationsverstärkern für die Verstärkung usw.

Viel Glück!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X