OSZILLATOREN [1] BASISWELLEN

Hier soll es ausschließlich um Arbeiten zu neuen und alten Ensembles gehen.

Moderator: herw

OSZILLATOREN [1] BASISWELLEN

Beitragvon Rampensau » Fr 14. Mai 2010, 13:37

Ziel

Der Selbstbau eines Oszillators, welcher die Grundwellenformen ausgibt. Hierbei möchte ich die gesamte Archtitektur einer gewöhnlichen Oszillator-Schaltung, sowie die Ableitung der Wellenformen aus der Phase behandeln und die Schaltung später zum Beispiel mit Hart-Synchronisation oder Antialiasing ausbauen.
Wobei ich darauf Wert lege, keinerlei Erfahrungen im Umgang mit den Strukturen in Reaktor vorauszusetzen, sodass sich auch der blutigste Anfänger daran versuchen kann, eigene Oszillatoren in Core zu basteln.

Das erste Zwischenziel ist ein, ähnlich dem im Corehandbuch beschriebener, gewöhnlicher Sägezahnoszillator, dessen Geschwindigkeit durch die Eingabe der Tonhöhe geregelt wird.
Abb.01.JPG
Abb.01.JPG (9.95 KiB) 8367-mal betrachtet

Um das Ensemble zu vereinfachen ist nur der Oszillator in Core realisiert. Der Rest- eine ADSR-Hüllkurve und das Oszilloskop und künftige Bedienelemente- spielt sich im Primary Level ab...
Zuletzt geändert von Rampensau am So 16. Mai 2010, 14:07, insgesamt 1-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Was ist Phase?!

Beitragvon Rampensau » Sa 15. Mai 2010, 05:21

Gewöhnlicher bzw trivialer Sägezahnoszillator

Die Phase ist das Signal, aus dem wir alle anderen Wellenformen "ableiten" wollen. Sie ist im Grunde schon das fertige Signal und hat die Form eines Sägezahns; wird in dem Zustand aber noch "Phase" genannt*, weil sie ohne weitere Bearbeitung unsauber klingt. Aber zu diesen hinzugewürfelten Harmonischen kommen wir noch. Ein erster Blick auf die Spektren der Signale zeigt, dass diese mehr oder weniger subtile Störung vorzugsweise zu unterbinden ist.
Abb.02.JPG
Abb.02.JPG (44.95 KiB) 8279-mal betrachtet

*Nun gut, das ist sicherlich nicht der einzige Grund. Die Phase gibt zudem zu jedem Zeitpunkt eine eindeutige Aussage über ihre Phasenlage. Man könnte es auch Sägezahn nennen. Aber um es später von dem "gesäuberten" Sägezahn zu unterscheiden, bezeichnen wir das triviale Sägezahnsignal als Phase.

Wenn wir einen ersten Blick auf die Struktur werfen, erscheint sie doch recht überschaubar.
Abb.03.JPG
Abb.03.JPG (14.04 KiB) 8281-mal betrachtet

Das ist nur eine (simple) Variante einen Oszillator aufzubauen. Diese Grundstruktur findet man so oder ähnlich in fast jedem corebasierten Oszillator. Wie bei vielen anderen Sachen, führen auch hier viele Wege nach Rom. Auf ein paar will ich eingehen.
Das rot markierte Modul gibt es so nicht, und ist nur ein leeres Rundungsmakro mit hübschem Icon.

Die Struktur ist super einfach zu verstehen und fast selbsterklärend. Ich werde mich dennoch in den folgenden Beiträgen dieser Struktur mit erklärenden Worten widmen.
Dateianhänge
Oszillator-a01.zip
(7.05 KiB) 321-mal heruntergeladen
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » So 16. Mai 2010, 14:47

Die Struktur kann man mit Hilfe von Reaktor-eigenen Macros sogar noch einfacher gestalten, was uns zugleich eine Art Gliederung der einzelnen Komponenten vorgibt.
Abb.04.JPG
Abb.04.JPG (15.29 KiB) 8285-mal betrachtet

Hierbei werden fast die selben Operationen durchgeführt, wie in Abb.03. Die Struktur ist bis auf die rot markierte Änderung dieselbe, sie sieht nur anders aus und stellt in der Form die wohl einfachste Form eines Phasengenerators mit logarithmischer Geschwindigkeits- bzw Tonhöhensteuerung dar. (Korrigiert mich, falls ich irre)

Das generierte Signal ist eine triviale Sägezahnschwingung, welche frei in dem Bereich von -0,5 bis +0.5 schwingt.(siehe Abb.01)

Core-Makros:
P2F: Standard Macro -> Convert ->...
1wrap: Expert Macro -> Math ->...
z^-1 ndc: Expert Macro -> Memory ->...

Core-Module:
/: Built-In Module -> Math ->...
+: Built-In Module -> Math ->...
Zuletzt geändert von Rampensau am Mo 17. Mai 2010, 13:57, insgesamt 1-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » Mo 17. Mai 2010, 13:53

Zählschleife
Abb.05.JPG
Abb.05.JPG (20.76 KiB) 8180-mal betrachtet

Die Schleife benötigt drei Komponenten, damit wir eine "fortlaufende" Phase erhalten:
- einen Speicher, der die akkumulierten Phasenwerte zwischenspeichert und wieder abruft.
- ein Additions-Modul, welches die aus dem Speicher abgerufenen Phasenwerte mit einer Erhöhungsrate, die sich aus der eingegebenen Tonhöhe errechnet (Inkremental), akkumuliert
- ein Wrap-Makro, das den akkumulierten Wert um 2*max abfallen lässt, wenn er max überschreitet, wobei max den gewünschten maximalen Amplitudenwert ausdrückt. In unserer Struktur ist max = 0.5, also 2*0.5=1.

Abb.05 zeigt, welche Module in der Zählschleife aus Abb.03 durch Reaktor-eigene Makros ersetzt wurden.
Die Schleife ist eigentlich nur ein Akkumulierer. Das heißt, jeder ankommende Wert wird auf den Speicher hinzuaddiert.
Ein normaler Akkumulierer ohne wrap-Makro würde theoretisch gen Unendlich zählen. Unsere Phase wird aber um 1 abfallen, sobald sie 0.5 übersteigt.


Samplerate Clock = SR.C
Der "Motor" der Oszillatorstruktur ist die Samplerate Clock SR.C. Ohne die SR.C-Verbindung würde dem Core-Oszillator kein brauchbares Audiosignal entfleuchen. Der Grundstein für den Oszillator ist also eine Audio-Core-Zelle.
Abb.06.JPG
Abb.06.JPG (19.02 KiB) 8186-mal betrachtet

SR.C-Verbindungen in Event-Core-Zellen haben keinen Zweck, da in einer Event-Core-Zelle keine Signale generiert werden können.
Die SR.C generiert pro Sample ein Event mit dem Wert 0. Die resultierende Impulsfolge hat also die Frequenz der eingestellten Samplerate und ihre Amplitude ist immer 0 (laut NI kann sich das in einer höheren Reaktorversion ändern), aber das ist erst einmal egal. Wir brauchen nicht den Amplitudenwert von der SR.C, sondern die Clock-Impulse (oder Ticks oder auch Gates), die jeweils ein Sample lang sind.
Abb.07.JPG
Abb.07.JPG (12.83 KiB) 8190-mal betrachtet

Aber was hat die Clock im Speicher verloren? (siehe Abb.05) :roll:
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » Mi 19. Mai 2010, 00:42

Speicher bzw z^-1 (ndc):

Der Speicher ist sogesehen ein Puffer, der das Signal zwischenspeichert und es um einen Sample verzögert, bevor es in die Schleife tritt. Das ist eine Notwendigkeit, die Reaktor auch von sich aus in Corezellen einfügt, welche Schleifen bzw Rückkopplungen beherbergen. Grob gesagt: Da es in der digitalen Welt keine Rückkopplungen geben kann, erfordert die "Gleichzeitigkeit" in Core eine Verzögerung in der Schleife, um das Feedback aufzulösen.
Von daher können wir die Struktur noch einfacher aussehen lassen und das z^-1 -Makro einfach weglassen. Das orangefarbene "z" zeigt an, dass automatisch eine 1-Sample-Verzögerung, sprich ein z^-1-"Modul" erzwungen wurde. Dieses Verhalten kann man auch noch ändern, aber das benötigt man erst, wenn man es benötigt! :| Im Ernst, das ist eine sehr hilfreiche Funktion. Core-Anfänger sollten dem "solid"-Häkchen (Abb.10) erstmal keine Beachtung schenken.
Abb.08.JPG
Abb.08.JPG (8.36 KiB) 8133-mal betrachtet

Diese Struktur erscheint zwar höchst simpel und ist erst einmal genau, was wir benötigen, sieht aber eher unschön aus und außerdem kommen wir nicht mehr an den Phasen-Speicher ran, um ihn eventuell zu definierten Zeitpunkten zurückzusetzen (Hard-Sync), daher lassen wir das Makro drin und werfen mal ein kleinen Blick hinein.

Der Speicher besteht also aus einem Read- und einem Write-Modul, sowie der SR.C am Clock-Eingang des Read-Moduls.
Abb.09.JPG
Abb.09.JPG (8.21 KiB) 8128-mal betrachtet

Impulse am Clock-Eingang des Read-Moduls rufen die Werte aus dem Speicher ab. Impulse am Eingang des Write-Moduls schreiben ihre Werte in den Speicher.

Es wird in dem z^-1 -Makro also zu jedem Impuls der SR.C ein Wert aus dem Speicher gelesen. Und zwar der Wert, der zuletzt (vor dem Leseimpuls) über das Write-Modul in den Speicher geschrieben wurde.
Da die SR.C mit einem eingehenden Audio-Signal gleichgetaktet ist (nämlich in Samplerate), sollte man annehmen, ein Impuls liest genau den Sample, mit dem er gleichzeitig am Speicher "ankommt". Das geschieht hier aber nicht. Die grün dargestellte OBC-Verbindung sorgt genau dafür und ordnet den Signalfluss der Lese- und Schreibe-Hierarchie des Speichers.
Abb.10.JPG
Abb.10.JPG (28.34 KiB) 8124-mal betrachtet

Im Latch-Makro (Abb.10; untere Hälfte) ist das Write-Modul über den Slave-Ausgang mit dem Master-Eingang des Read-Moduls verbunden. Das sorgt eben dafür, dass immer das aktuelle Sample und nicht das davor aus dem Speicher gelesen wird. Speist man hier die SR.C als Leseimpulsfolge in den Clock-Eingang, läuft das Signal unverzögert durch das Lese- Schreibe- Netzwerk.

(Core-Makro: Latch: Expert Macro -> Memory -> ...)
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » Mi 19. Mai 2010, 02:07

Abb.11.JPG
Abb.11.JPG (12.71 KiB) 8111-mal betrachtet

Weil wir eine Schleife haben, und sich in dieser Schleife eine "Station" befindet, bei der das Signal erhöht wird (Akkumulierer), haben wir bei jedem Zyklus der Schleife, also mit jedem neuen Sample einen neuen Amplitudenwert.

Für unsere Schleife heißt das: Ein Sample wird durch die SR.C aus dem Speicher getriggert und durch den Akkumulierer mit einem bestimmten Wert (Inkremental) erhöht. Dieses Sample wird wiedergegeben und gespeichert, dabei wird das Ursprungs-Sample überschrieben. Ein SR.C-Impuls darauf wird dieses Sample getriggert und erneut erhöht und wiedergegeben, usw..

Core-Module:
Read: Built-In Module -> Memory -> ...
Write: Built-In Module -> Memory -> ...
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » Mi 19. Mai 2010, 02:16

Wrap-Makro

Die Akkumulation ist mit einem Additionsmodul simpel realisiert (Abb.11). Aber ohne weiteres würde die Phase schnurstracks ins Unendliche rasen, wenn wir ein Inkrementalwert hätten und die Schleife jetzt schließen würden. Daher benötigen wir ein Makro, das den Wertebereich nach der Akkumulation "begrenzt". Es soll ihn aber nicht abbrechen, wie bei einer Steuerkurve, sondern so falten, dass der sich hebende Wertebereich in den gewünschten Bereich zurückfällt. Das erreicht man einerseits mit Vergleicher-Modulen und Routern, wie im Core-Handbuch beschrieben; ich finde jedoch die Methode mit dem Rundungsmakro praktischer. Jedenfalls für eine Phasen-Faltung nach der Schleife. Denn hier lassen sich auch weit höhere Werte in den gewünschten Zahlenbereich falten, als mit der Router-Methode. Aber auch dazu später.

Das Wrap-Makro hat auch nichts kryptisches an sich.
Abb.12.JPG
Abb.12.JPG (5.94 KiB) 8093-mal betrachtet

Das Round-Makro (rot markiert in Abb.03) ist auch hier nur ein leeres Makro, welches das Signal durchlässt. Der Ausgang des Makros ist vom Typ Integer. Das heißt, das Signal wird "immer" auf seine nächste ganze Zahl gerundet.
Das gerundete Signal wird nun vom eingehenden Signal abgezogen und man erhält von der akkumulierten Phase den gefalteten Zahlenbereich von -0.5 bis +0.5.
Abb.13.JPG
Abb.13.JPG (4.7 KiB) 8095-mal betrachtet

Bei Strukturen mit dem Round-Modul ist lediglich zu bemerken, dass die Rundung nicht mathematisch korrekt abläuft. Es wird immer zur nächsten ganzen Zahl gerundet. Was passiert nun, wenn diese Zahl mittig zwischen zwei ganzen Zahlen liegt, also x.5? Die Rundung ist nicht eindeutig definiert und läuft statistisch ab, also so, dass in 50% der Fälle entweder auf- oder abgerundet wird. Das ist in der Norm IEEE 754 festgelegt.
In dieser Norm ist außerdem festgelegt, dass eine konforme Implementierung der Rundung immer drei weitere Rundungsverhalten bereitstellen soll. Das tut Reaktor leider (noch?!) nicht.


Core-Makro:
round: Expert Macro -> Math -> ...

Core-Modul:
-: Built-In Module -> Math -> ...
Zuletzt geändert von Rampensau am Sa 22. Mai 2010, 17:10, insgesamt 2-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Die Zählschleife

Beitragvon Rampensau » Mi 19. Mai 2010, 04:02

Abb.14.JPG
Abb.14.JPG (23.26 KiB) 8083-mal betrachtet

Für welchen der beiden Stile man sich auch entscheidet, es läuft auf das selbe hinaus:

1) Die Samplerate Clock SR.C triggert ein Sample aus dem Speicher.
2) Das wird im Akkumulierer erhöht
3) und danach im Wrap-Netzwerk gefaltet.
4) Das gefaltete Sample wird wiedergegeben und
5) zurück in den Speicher gesamplet.
6) Der nächste Impuls der SR.C triggert jenes Sample, usw.

Die Schritte 1-5 sind dabei ein Rechenzyklus und finden "gleichzeitig" statt. Ab Schritt 6 wiederholt sich der Zyklus in einer Endlosschleife

Mit jedem SR.C-Impuls läuft der Phasenwert diesen Rechenzyklus durch.
Den Wert mit dem die Phase akkumuliert wird, bezeichnen wir als Inkremental.
Dieser Wert wird aus der eingegebenen Tonhöhe errechnet und repräsentiert den Wert, den unsere Phase mit jedem Schleifenzyklus steigen wird. Die Erhöhung pro Sample ist ebenso von max (maximaler Amplitudenwert) bzw vom Umfang des gefalteten Wertebereichs, wie auch von fSR (Samplerate) abhängig
Zuletzt geändert von Rampensau am Sa 22. Mai 2010, 21:47, insgesamt 1-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Grundstruktur

Beitragvon Rampensau » Mi 19. Mai 2010, 13:33

Inkremental
Abb.15.JPG
Abb.15.JPG (22.96 KiB) 8044-mal betrachtet

Abb.15 zeigt, welche Module zur Errechnung des Inkrementals aus der Ursprungsstruktur aus Abb.03 (grüner Rand) durch Reaktor-eigene Makros (gelber Rand) ersetzt wurden.

Die über Midi eingebene Tonhöhe ist logarithmisch in Halbtöne eingeteilt und wird im P2F-Konvertierer in eine lineare Frequenzeinteilung in Hertz gewandelt. Die Frequenz wird durch die Samplerate geteilt und ergibt dann den Inkrementalwert.

Die Erhöhung pro Sample ist unter Anderem anghängig von der Samplerate. Je öfter die SR.C pro Sekunde tickt, desto geringer muss der Inkrementalwert sein und vice versa, um die resultierende Oszillatorfrequenz bei Änderung der Samplerate nicht zu verschieben.
Eine stets aktuelle Information über die Samplerate (SR.R) liefert uns der Samplerate-Bus.
Außerdem muss max bekannt sein und auch in die Inkrementalberechnung einfließen.

Das Ganze ermittelt sich dann mit folgender Formel: inc = 2*max*f/fSR, wobei max der maximale Amplitudenwert der Phase (bzw den halben Werteumfang des gefalteten Zahlenbereichs), f die Frequenz des Oszillators in Hertz und fSR die Samplerate ausdrückt.

Nur wenn all diese Werte in die Inkrementalberechnung einfließen, wird der Oszillator in der korrekten Tonlage zählen.

Aber die Formel will irgendwie nicht zu ihrer Implementation in unserer Struktur passen und trotzdem wird die Tonlage "korrekt" wiedergegeben. Die Anzahl der Terme stimmt nicht überein.
Abb.16.JPG
Abb.16.JPG (5.51 KiB) 8025-mal betrachtet

Wer gut aufgepasst hat, wird auch gleich sehen, dass die Struktur so sehr richtig gedacht ist, wenn man einfach mal die gegebenen Werte in die Formel einsetzt:
geg: max = 0.5; fSR= SR.R

inc = 2 * 0.5 * f / SR.R = f/SR.R

So stimmt die Anzahl der Terme mit der Struktur überein. Zu beachten ist nur, dass der halbe Werte-Umfang des gefalteten Signals in der Zählschleife mit max übereinstimmt. Zur Erinnerung: das Faltungsmakro soll das Signal um 2*max abfallen lassen, wenn max überschritten wird.
Die Faltung hängt also unmittelbar mit der Inkrementalberechnung zusammen.

Die Herleitung der Inkrementalformel ist auch nicht schwer:
Wir wissen, dass die SR.C in unserem Beispiel 48000 also SR.R mal in der Sekunde tickt (Abb.07).
Ein Inkremental von inc = 1/SR.R bewirkt also grob gesagt, dass die Amplitude der Phase
auf dem ersten Tick A = 1/SR.R (= 1*inc),
und auf dem SR.R.ten (48000.) Tick A(ungefaltet) = SR.R/SR.R = 1 (= SR.R*inc) ist.
Die ungefaltete Amplitude der Phase erhöht sich in einer Sekunde von ihrem Minimum auf ihr Maximum, hat also eine Frequenz von f = 1Hz.
Also kann man sagen, dass der Inkremental 2*max/SR.R eine Frequenz von 1Hz ergibt. Dieser Inkremental ist jetzt einfach mit der gewünschten linearen Frequenzangabe zu multiplizieren. Es gilt also inc =2*max/SR.R * f, wobei wir einfach umgestellt wieder bei der oben genannten Formel inc = 2*max*F/SR.R sind.
Man kann max, entsprechend den Primary-Oszillatoren, mit A bezeichnen. Es steht ja für den maximalen Amplitudenwert. Von daher sagen wir ab jetzt max = A!
Also inc = 2*A*F/SR.R

Eine Division erfordert höhere Rechenleistung als andere arithmetische Rechnungen. Solange man Divisionen durch "komplexere" Zahlen vermeiden kann, dann macht man das. Um die CPU etwas zu entlasten wird der Divisionsterm auch hier "vereinfacht".

Anstatt die eingegebene (variable) Frequenz durch die Samplerate zu teilen, multipliziert man die Frequenz mit dem Kehrwert der Samplerate, und erreicht so eine konstante Division, sprich: (2*A/fSR) * f = (1 / SR.R) * F (für A=0.5)

P2F-Makro
Das P2F-Makro (Abb.15) beinhaltet eine Exponentialfunktion, welche die logarithmische Tonhöhenangabe in Halbtönen in eine lineare Frequenzangabe in Hertz umwandelt und lautet: (1.05946^P) * 8.17742 = F, wobei P die logarithmische Tonhöhenangabe ist.

~1.05946 ist die ungefähre 12. Wurzel aus 2 und beschreibt das Verhältnis der Frequenz zweier benachbarter Halbtöne.
Also A#3 : A3 = 466,1616377615... Hz : 440 Hz = 1.059463094... : 1

~8.17742 ist die ungefähre Frequenz bei P = 0. Und so birgt das Reaktor-Makro ein paar Rundungsfehler. Es sind nur ungefähre Werte und die Funktion ist nur eine vereinfachte Darstellung der Formel.
Abb.17.JPG
Abb.17.JPG (23.67 KiB) 7916-mal betrachtet

Abb.17: links die Formel zur nahezu exakten Umrechnung der Tonhöhe P(log) in die Frequenz F(lin)
rechts das "gerundete" Reaktor-eigene P2F-Makro


Die Basis in der Expontialfunktion und die Konstante als Faktor hinter exp(x) können nicht beliebig viele Nachkommastellen darstellen. Wenn einem höchste Tonhöhengenauigkeit wichtig ist, dann wählt man den Ausdruck mit der 2 als Basis, also F(P) = 2 ^ [(P - 69) / 12] * 440Hz


Core-Modul:
~exp(x): Built-In Module -> Math -> ...[/i]
Zuletzt geändert von Rampensau am Sa 22. Mai 2010, 18:55, insgesamt 10-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Revue: Die Phase

Beitragvon Rampensau » Sa 22. Mai 2010, 15:36

Die Grundsteine der Phasengeneration sollten jetzt erklärt sein. Jeder müsste im Stande sein, zumindest die Grundstruktur in anderen Oszillatoren erkennen, lesen und (rudimentär) modifizieren zu können und sich auch vollkommen selbstständig einen Phasengenerator zu basteln.

Ich will nur mal rekapitulieren:
Abb.18.JPG
Abb.18.JPG (17.17 KiB) 7905-mal betrachtet

Die eingebene Tonhöhe P(log) ist logarithmisch in Halbtöne geteilt und wird mit Hilfe einer Exponentialfunktion (exp) in eine lineare Einteilung der Frequenz F(lin) in Hertz gerechnet. Die Frequenz wird mit Hilfe der Samplerate (fSR) und der Maximalamplitude (A) in einen Inkrementalwert inc(P) gerechnet.
Dieser Inkrementalwert (inc)gelangt in die Zählschleife und mit jedem Ticken der Samplerate Clock (SR.C) erfolgt ein Schleifenzyklus, welcher die Phase um den Inkrementalwert (inc) erhöht. Sobald die Phase den Maximalwert (A) überschreitet, fällt sie im Faltungsnetzwerk um 1 zurück. Die entstandene Phase wird nach dem Faltungsnetzwerk abgenommen und dem Ausgang zugeführt.

Die generierte Phase ist nun spielbar. Das Klangbild ist zwar etwas schräg, dennoch haben wir unser erstes Zwischenziel erreicht und auch die einzelnen Komponenten der Phase kennengelernt!
Abb.19.JPG
Abb.19.JPG (10.35 KiB) 7903-mal betrachtet

In der Struktur in Abb.19 sind die Exponentialfunktion und das Faltungsnetzwerk in jeweils eigene Makros verpackt.
Das P2F-Makro enthält nun die ungerundete Funktion zur Umrechnung und das Faltungs-Makro hat ein nettes Icon bekommen.
Dateianhänge
Oszillator-b.zip
(8.12 KiB) 338-mal heruntergeladen
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Wellenformen

Beitragvon Rampensau » Sa 22. Mai 2010, 23:14

Als nächsten wollen wir die Wellenformen aus der Phase gewinnen. Die Wellenformen lassen sich durch einfache arithmetische Operationen aus der Phase generieren. Der Sinus wird etwas komplizierter, deshalb führe ich die Parabel an.

Parabel
Abb.21.GIF
Abb.21.GIF (2.62 KiB) 7699-mal betrachtet

Die Parabel ist zwar nicht so CPU-hungrig wie der Sinus. Die Parabel hat jedoch Obertöne. Die Sinuswelle nicht.

Um eine Parabel zu erhalten, benötigen wir zunächst die Betragsfunktion der Phase. Das heißt, es zählen nur die Absolutwerte der Zahl, die Werte werden also vom Vorzeichen gelöst.
Der Betrag einer Zahl wird mit |x| bezeichnet.
Abb.22.GIF
Abb.22.GIF (4.17 KiB) 7702-mal betrachtet

Nun multiplizieren wir den Betrag mit der Phase.
Abb.23.GIF
Abb.23.GIF (4.39 KiB) 7702-mal betrachtet



Core-Modul:
|x|: Built-In Module -> Math -> ...
Zuletzt geändert von Rampensau am Mo 24. Mai 2010, 23:44, insgesamt 1-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Wellenformen

Beitragvon Rampensau » Sa 22. Mai 2010, 23:26

Den Betrag multiplizieren wir noch mit A*16 und ziehen ihn von A*8 ab und erhalten die Parabel.
Abb.24.GIF
Abb.24.GIF (5.25 KiB) 7702-mal betrachtet


Dreieck
Abb.25.GIF
Abb.25.GIF (2.61 KiB) 7702-mal betrachtet

Hierbei wird einfach der Betrag (Abb.22) der Phase genommen, und mit 2 multipliziert bzw verdoppelt, um die Maximalamplitude wiederherzustellen. Dann wird A vom Signal abgezogen, um den DC-Versatz zu entfernen.
Abb.26.GIF
Abb.26.GIF (4.86 KiB) 7701-mal betrachtet
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Wellenformen

Beitragvon Rampensau » So 23. Mai 2010, 02:30

Rechteck

Ein Rechteck kann man generieren, indem man die Phase mit ihrem invertierten und um 180° verschobenen Ebenbild mischt. Die Pulsweite lässt sich dann durch weitere Phasenverschiebung ungleich (180°) einstellen.
Nur wie verschieben die Phase auf der Zeitachse?
Durch Faltung der Phase!
Grob: die Faltung kompensiert eine Verschiebung auf der Amplitudenachse durch Verschiebung auf der Zeitachse bei dem Phasensignal.

Verschieben wir erst einmal auf der Amplitudenachse um A = 0.5
Abb.27.GIF
Abb.27.GIF (4.36 KiB) 7693-mal betrachtet

Nun falten wir das Signal
Abb.28.GIF
Abb.28.GIF (7.35 KiB) 7697-mal betrachtet

Die Phasenverschiebung durch Faltung funktioniert so nur mit dem Phasensignal.
Dasselbe invertiert
Abb.29.GIF
Abb.29.GIF (4.99 KiB) 7701-mal betrachtet


Core-Modul:
-x: Built-In Module -> Math -> ...
Zuletzt geändert von Rampensau am Fr 24. Feb 2012, 01:41, insgesamt 3-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Wellenformen

Beitragvon Rampensau » So 23. Mai 2010, 02:42

Und nun gemischt
Abb.30.GIF
Abb.30.GIF (5.13 KiB) 7697-mal betrachtet

Wie erwähnt, verändert eine zeitliche Verschiebung eines der beiden Phasenanteile die Pulsweite der entstehenden Rechteckwelle. Verändern wir also die Lage des zu faltenden Phasenanteils auf der Amplitudenachse, verschieben wir zeitlich und damit stellen wir die Pulsweite ein.
Abb.31.GIF
Abb.31.GIF (7.4 KiB) 7695-mal betrachtet

Eine Steuerung der Pulsweite erreichen wir also, indem wir einfach einen Versatz von PW <= |A| zur zu faltenden Phase addieren. Und um den DC-Versatz durch die Pulsweitenveränderung zu kompensieren, kann man PW zum Ausgang hinzumischen.
Abb.32.GIF
Abb.32.GIF (4.08 KiB) 7696-mal betrachtet
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Wellenformen

Beitragvon Rampensau » So 23. Mai 2010, 04:21

Sinus

Beim Sinus ist das leider nicht so trivial. Wenn man sich mal die mitgelieferte sin-Funktion anschaut, erschreckt man erst mal davor und es scheint mehr dahinterzustecken.
sinNI.jpg
sinNI.jpg (32.05 KiB) 7397-mal betrachtet

Das Problem ist: Die Funktionswerte der Sinusfunktion können nicht mit Hilfe einer uns bekannten Rechenart genau berechnet werden.
Man kann an einigen Stellen zwar genaue Aussagen über die Sinuswerte machen, dazwischen kann man aber nur noch schätzen...

...Oder annähern:

Der Taschenrechner muss schließlich auch erst lernen, wie er eine solche Funktion zu berechnen hat.

Wir wollen die Sinusfunktion durch einfache Rechenoperationen ausdrücken. Das können wir sogar beliebig genau treiben. Nur mit dem Grad [n] der Annäherung steigt auch die Anzahl der Rechenoperationen um den Faktor [n].

Die (lokale) Annäherung realisieren wir mit Hilfe der Taylor-Formel. Das ist ein relativ simpler Prozess und lässt sich an beliebigen (stetigen, differenzierbaren) Funktionen treiben. Wir schauen uns das nun anhand der Sinusfunktion an.


Das es auch anders geht zeigt folgender Sinus-Oszillator hier:
viewtopic.php?f=17&t=741&p=6244#p6244
Hier wird das Signal schon als Sinus generiert und nicht durch ein Polynom angenähert.
Oder hier mittels Chebyshev-Polynom
http://reaktor.approx.de/phpbb3/viewtop ... 6738#p6738
Zuletzt geändert von Rampensau am So 27. Feb 2011, 06:53, insgesamt 8-mal geändert.
Benutzeravatar
Rampensau
meister
 
Beiträge: 192
Registriert: So 6. Dez 2009, 20:32

Nächste

Zurück zu PROJEKTE

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron