Seite 1 von 2

HÜLLKURVEN

Verfasst: 22. Dezember 2013, 16:14
von herw
1 Einführung

Hüllkurven werden in der elektronischen Klangerzeugung zur Modulation von Verstärkern, Filtern und Oszillatoren benutzt.
Typisches und bekanntes Beispiel ist die ADSR-Kurve.
Bild 1.jpg
Derartige Hüllkurven sind in einzelne Zeit-Abschnitte unterteilt, in denen ein Wert - in der analogen Hardwarewelt der Synthesizer würde man hier Spannung sagen - linear oder exponentiell ansteigt bzw. fällt.
Die oben abgebildete Hüllkurve hat eine steigende Phase (attack) mit Rechtskrümmung, dann eine exponentiell (linksgekrümmte) fallende Kurve (decay), die sich einem Halteniveau (sustain) annähert und einen weiteren ähnlichen Abfall auf das Nullniveau.
In Softwareinstrumenten wird häufig eine lineare Kurve für die Attackphase oder sogar alle Phasen gewählt.
Bild 2.jpg
Denkbar wäre auch ein Vertauschen der Krümmung, …
Bild 3.jpg
... sogar für verschiedene Phasen auch unterschiedlich.
Um einen einfachen Einstieg in diese Art der Steuerung zu bekommen, kann ich das Projekt „lineare Steuerkurven” in unserem Forum empfehlen. Hier werden Grundlagen zu Zeitberechnung und grundsätzlichen Aspekten (Anfang und Ende einer Phase) beschrieben.
Weniges kann ich hier übernehmen, Vieles wird aber völlig neu sein, insbesondere mein mathematischer Ansatz wird hier zum ersten Mal veröffentlicht.
Am Ende dieses Projektes wird hoffentlich ein universell einsetz- und erweiterbares Makro stehen, so dass man sich seine „eigene” Hüllkurve basteln kann.
Dieses Projekt ist nunmehr drei Jahre alt und immer wieder unterbrochen und wieder neu angesetzt, so dass ich hoffe, endlich einmal das Ziel zu erreichen.

HÜLLKURVEN

Verfasst: 22. Dezember 2013, 17:03
von herw
2 Mathematischer Hintergrund

Ich benutze für die Darstellung und experimentelle Erforschung der Hüllkurven das frei verfügbare Programm GeoGebra.
Man findet im Netz Versionen für alle wichtigen Betriebssysteme unter der Adresse GeoGebra.org; allerdings kann ich die Version für das iPad noch nicht empfehlen.
Ich werde, wenn es sinnvoll ist, hier entsprechende Dateien hochladen, damit ihr selbst damit experimentieren könnt.
Allen Hüllkurven ist in der Hardwarewelt gemeinsam, dass sie zeitabhängig sind, in der REAKTOR-Welt bedeutet dies Abhängigkeit von der Samplerate. Somit liegt es nahe, die Audiocore-Ebene zu benutzen.
Ganz bewusst werde ich auch partials framework (Max Zagler) zur Einspeisung von Panelelementen benutzen, da dies dem programmiertechnischen aktuellen Stand entspricht.
Ich mache schon jetzt darauf aufmerksam, dass der mathematische Hintergrund Abiturwissen voraussetzt. Trotzdem möge man sich nicht scheuen, hier auch einfache Fragen zu stellen. Meistens lassen sich einzelne Aspekte dann doch mit normaler Mittelstufen-Mathematik klären.

HÜLLKURVEN

Verfasst: 22. Dezember 2013, 19:23
von herw
2.1 Lineare Steuerkurve

Ich beschränke mich in diesem und den nächsten Abschnitten zunächst einmal auf einen Wertebereich von [0; 1].
Lineare Steuerkurven basieren auf dem einfachen Prinzip, dass zu einem existierenden Wert in gleichen Abschnitten immer derselbe Wert addiert (steigender Funktionsgraph) bzw. subtrahiert (fallender Funktionsgraph) wird.
In der Mathematik wird eine solche Funktion beschrieben durch, ...
Bild 4.jpg
… wobei n der Startwert bei x=0 und m die Steigung (Änderungsrate) ist. In dieser Darstellung wird für jeden x-Wert mit Hilfe der Formel und zwei einfachen Grundrechenarten der jeweilige Funktionswert berechnet.
Es geht aber noch einfacher: ausgehend von einem Startwert n gibt die Steigung m an, um welchen Wert sich der aktuelle ändert, also nur eine einzige Rechenoperation pro Zeittakt, zudem noch nur eine Addition!
Es gilt, ...
Bild 5.jpg
… wobei der Index 0 die aktuellen Werte und der Index 1 die nächsten Werte für x und y bezeichnet. Nun, die x-Werte sind nichts anderes als die Taktungen durch die SampleRateClock SRC. Durch die SampleRate z.B. SR=44100 ist der zeitliche Abstand bestimmt und damit auch die Änderungsrate m durch die gewünschte Zeitdifferenz.
∆y=m·∆x ist dann der jeweilige Wert, der pro SampleRate-Tick addiert werden muss.
Nehmen wir mal den einfachsten Fall an: Anstieg von 0 auf 1 in 1 Sekunde, also m=1. Bei einer Samplerate von 44100 erhält man für ∆x=1/44100 auch ∆y=1/44100, d.h.bei jedem Samplerate-Tick steigt die Hüllkurve um den Wert ∆y=1/44100≈0,00000227 an. Nach 44100 SampleRate-Ticks hat die Hüllkurve den Wert 1 erreicht.
Für einen Anstieg in 2,5s dagegen erhält man m=1/2,5 und damit ∆y=1/2,5·1/44100=1/110250≈9,0702948≈0,000000907. Die Phase bricht ab, wenn der Wert 1 überschritten worden ist.

HÜLLKURVEN

Verfasst: 23. Dezember 2013, 06:34
von herw
2.2 Lineare decay-Kurve

Für eine fallende Hüllkurve ist der Wert ∆y einfach negativ zu wählen mit einem Startwert n=1.
Bild 6.jpg
Hier ist die passende GeoGebra-Datei:
decay_linear.ggb
Hüllkurven werden in der Regel durch einen Trigger angesteuert (z.B. velocityOn bei MidiGate). Aus dem gegebenen Parameter (Decay-Zeit) wird die Änderungsrate berechnet und danach wird alles durch die Samplerate-Ticks gesteuert.
Bleibt noch die Frage zu klären, wenn der Trigger nicht den Wert 1, sondern einen anderen Wert übergibt. Man muss sich nun entscheiden: will man die Phasenlänge beibehalten und damit die Steigung m ändern oder belässt man es bei derselben Änderungsrate?
Ich finde die Beibehaltung der Änderungsrate m „natürlicher”. Somit verkürzt sich die Phase entsprechend, wenn der Triggerwert kleiner als 1 (hier 0,6) ist.
Bild 7.jpg

HÜLLKURVEN

Verfasst: 23. Dezember 2013, 07:31
von herw
2.3 Exponentielle Steuerkurve

Exponentialfunktionen werden durch die Gleichung y=b^x beschrieben.
Alle Exponentialfunktionen haben die gemeinsame Eigenschaft, durch die Punkte (0|1) und (1|b) zu verlaufen:
Bild 8.jpg
Wir beobachten, dass der Graph umso steiler ist, desto größer die Basis b ist.
Für Basen b>1 sind die Graphen steigend, für 0<b<1 dagegen fallend:
Bild 9.jpg
Steigende und fallende Exponentialfunktionen sind zueinander symmetrisch zur y-Achse:
Bild 10.jpg
Für die fallende Funktion gilt:
Bild 11.jpg
Wir können also steigende, wie fallende Exponentialfunktionen auf dieselbe Klasse von Funktionen zurückführen; lediglich die Basis b bestimmt den Charakter des Graphen.

Bemerkung: Für diejenigen, die Schwierigkeiten haben, die Beispiele in GeoGebra eigenhändig einzugeben, gibt es auf dem Bildungsserver Baden-Württemberg Hinweise auf typische Eingabefehler.

Re: HÜLLKURVEN

Verfasst: 23. Dezember 2013, 11:07
von MvKeinen
::kaffee:: super! Ich bin in letzter Zeit durch sehr viele Envelopethreads gegangen und da ist es schwer und aufwändig die wichtigen Dinge rauszuziehen. Deswegen ist es genial hier erstmal die mathematischen Aspekte gebündelt zu haben.

HÜLLKURVEN

Verfasst: 23. Dezember 2013, 12:32
von herw
2.4 Exponentielle Decaykurve

Jetzt ist zwar geklärt, wie man zu steigenden und fallenden Kurven kommt, doch wie schafft man es, dass eine vorgegebene Zeit für die Phase eingehalten wird? Bei linearem Verlauf ist es eindeutig geklärt: irgendwann fällt der Funktionsgraph unter Null und beendet damit eindeutig die Phase. Fallende Exponentialfunktionen nähern sich zwar der x-Achse beliebig nah an, erreichen bzw. unterschreiten die x-Achse niemals. Im Gegensatz zur linearen Funktion, die sich um einen festen Betrag ändert, gilt für Exponentialfunktionen, dass sich der Wert in gleichen Abschnitten um denselben Faktor verändert. Beispielsweise halbiert sich der Wert der Funktion y=0,5^x mit jedem ganzzahligen x-Wert auf die Hälfte, bleibt also immer positiv. Die in den herkömmlichen REAKTOR ADSR-Kurven angegeben Zeiten für decay und release sind Zeiten, die sich auf das Absinken auf einen bestimmten Bruchteil beziehen.
Ich will dagegen auf eine eindeutige Zeitlänge hinaus. Also subtrahiere ich zunächst den für x=1 berechneten Wert für die ursprüngliche Funktion :
Bild 12.jpg
Die Grafik zeigt ein Beispiel für b=4:
Bild 13.jpg
Jetzt startet die Hüllkurve aber nicht mehr bei 1 sondern bei 0,75. Also muss der Graph noch gedehnt werden:
Bild 14.jpg
Somit bekommen wir einen exponentiellen Verlauf, der wieder eine eindeutige Abbruchbedingung durch die x-Achse erfährt.
Bild 15.jpg
::kaffee:: alles klar? Ich hoffe; dies alles hört sich so an, als wenn man es mal eben aus der Tasche zieht, doch die Idee ist zunächst mal das Entscheidende :)

HÜLLKURVEN

Verfasst: 23. Dezember 2013, 14:03
von herw
2.5 Krümmungen

Ab diesem Zeitpunkt schlägt natürlich das mathematische Forscherherz! Man spielt mit dem Parameter b!
Für b=8 erhält man schon eine stärkere Krümmung, ...
Bild 16.jpg
..., für b=1024 wesentlich stärker ...
Bild 17.jpg
... und für b=1,072 ?!!!
Bild 18.jpg
Erstaunlich linear. D.h. wir haben allein durch Änderung des Parameters b die Möglichkeit die Krümmung beliebig anzupassen, sogar bis zu einer (annähernd) linearen Funktion!
Entscheidend für alle Funktionen ist, dass mit Sicherheit 0 unterschritten wird.

HÜLLKURVEN

Verfasst: 24. Dezember 2013, 06:55
von herw
2.6 Rechts- und Linkskrümmungen

Hier ist mal ein Video (MausKlick auf „Gebe Quicktime-Datei wieder”):
Leider funktioniert die Wiedergabe nicht auf einem iPad :(
krümmung.mov
Wenn man für b auch Zahlen zwischen 0 und 1 zulässt, bekommt man rechtsgekrümmte Hüllkurven :)
Wer es selbst ausprobieren möchte, kann auch die GeoGebra-Datei laden:
decay_exponentiell.ggb

HÜLLKURVEN

Verfasst: 24. Dezember 2013, 17:13
von herw
2.7 attack-Kurve

Die Umwandlung einer fallenden decay-Kurve in eine steigende attack-Kurve ist nur ein Kinderspiel:
Bild 21.jpg
Bild 19.jpg
Bild 20.jpg
Damit ist grundsätzlich der mathematische Hintergrund gegeben. Ich denke, dass dieser mathematische Ansatz mit einer einzigen Funktionenklasse für exponentielle und lineare sowohl für steigende als auch fallende Steuerungen wohl völlig neu ist.
Nun geht es an die Umsetzung in REAKTOR. Wenn es erforderlich ist, werde ich bei der Entwicklung der Makros nochmals die Mathematik einflechten (müssen).

::kaffee::

HÜLLKURVEN

Verfasst: 26. Dezember 2013, 08:46
von herw
3 decay
3.1 ein Display

3.1.1 das Panel

Wenn man sich mit Hüllkurven, insbesondere zusammengesetzten Hüllkurven beschäftigt, taucht unweigerlich die Unanschaulichkeit von bloßen Regler-Parametern auf. Natürlich kann man sich die Zeitdauer einer Hüllkurve vorstellen, aber der zeitliche Verlauf der Hüllkurvenwerte, insbesondere bei unterschiedlichen Krümmungen ist doch schon schwieriger. Also muss in jedem Fall ein Display her.
Wenn man sich die Darstellungen der REAKTOR-Makros für Hüllkurven, Steuerkurven und Filter ansieht, dann gewinnt man den Eindruck, dass sie auch nur als unabdingbares Übel angesehen wurden (und werden) und nur einen sehr groben und zum Teil auch falschen Eindruck hinterlassen.
Daher beginne ich mal, mit diesem Übel aufzuräumen.
Ich orientiere mich dabei an Geogebra. Ähnlich wie bei den dort benutzten Schiebereglern, soll sich die Darstellung unmittelbar erneuern und zwar in Abhängigkeit der Krümmung und der eingestellte Zeitdauer.
Hier bietet sich eine Iteration als Lösung an, die das Durchlaufen der Zeitspanne simuliert.
Bild 22.jpg
Das Display wird durch eine Event-Tabelle erzeugt. Als Einstellparameter stehen die Kurvenform (curve), die Zeitdauer (time) und der Eingangswert (level) zur Verfügung. Jede Änderung baut das Bild unmittelbar wieder neu auf.
Ich trenne GUI, Verarbeitung und Display streng in drei Makros:
Bild 23.jpg
Das Panel besteht aus den drei Reglern, deren Werte über einen Eventbus (partials framework) an das Makro val (Werteberechnung) übergeben werden, und erzeugt zugleich auch die notwendige Iteration, die die Darstellung im eigentlichen display, der Event-Tabelle, startet. Das Display selbst ist zur Veranschaulicheng relativ groß gewählt. In der Entfassung soll es selbstverständlich kleiner sein.
Bild 24.jpg
Die Werteberechnung im Makro val benutzt genau die Überlegungen, die ich in der obigen mathematischen Betrachtung verwende:
Bild 25.jpg
Im Zentrum der Berechnung steht ein Speicher mit dem jeweils aktuellem Hüllkurvenwert.
Bild 26.jpg
Wichtigster Bestandteil ist der Multiplikationsoperator, mit dem aus dem vorangegangenen Wert der neue bestimmt wird. Vor und hinter der Multiplikation wird zur eigentlichen Exponentialfunktion transformiert. Man möge mit den Funktionen im Abschnitt 2 vergleichen. Es wird jeweils durch eine Addition und Multiplikation transformiert; vergleiche mit der in einer späteren Post hochgeladenen REAKTOR-Datei.
Der Rest dient zur Bereitstellung der Eingabe- und Ausgabewerte. Wie man schon dem ersten Video entnehmen konnte, wird die Basis b der Exponentialfunktion nicht unmittelbar eingestellt, da der Wertebereich ebenfalls exponential ansteigt. D.h. der Krümmungsparameter k legt nur einen Exponenten fest, so dass die Basis im Bereich von 1/1024 bis 1024 liegen kann.

HÜLLKURVEN

Verfasst: 26. Dezember 2013, 18:04
von herw
3.1.2 decay level
Interessant ist auf der linken Seite der Einstiegswert level für den Speicher. Bisher war die decay-Kurve für einen Anfangswert 1 festgelegt. Da ich das decay-Makro universeller gestalten will, so dass es für jede Hüllkurvenphase benutzt werden kann, muss ich berücksichtigen, dass es ja auch andere Anfangs- und Zwischenwerte gibt.
Ich habe im Abschnitt 2.1 schon erwähnt, dass ein niedriger Anfangswert automatisch auch die Phasendauer verkürzt. Dieser Umstand war für mich bei der Betrachtung der entstehenden Kurven auf dem Display äußerst verwirrend und hat mich auch lange zögern lassen, mich mit einem gescheiten Display zu beschäftigen. Denkt man aber über die Konsequenzen der Darstellung nach, dann ist es völlig logisch:
Bild 27.jpg
Ich vergleiche die Darstellung im unteren Display mit dem level 1 und dem oberen Display mit level=0,7. Die Länge dieser Hüllkurve wird bestimmt durch den Zwischenwert 0,7 im unteren Display. Man erkennt sehr schön, dass der Ausschnitt ab 0,7 die verkürzte Hüllkurve festlegt.
Hier noch ein weiteres Beispiel mit dem Level 0,3:
Bild 28.jpg
Um das mal für die Praxis zu übersetzen: ein leichter Tastenanschlag (velocity als level-Festlegung) verkürzt die Hüllkurvenlänge. Steuert man damit einen Verstärker so bleibt das Abklingverhalten eines Klangs dabei völlig identisch, d.h. es muss kein neuer Algorithmus gewählt werden.
Wenn mehrere Phasen hintereinander ablaufen, wie zum Beispiel bei einer ADSR-Kurve, dann kann derselbe Berechnungsalgorithmus gewählt werden, lediglich die Parameter sind neu zu wählen. Nach demselben Prinzip funktioniert auch das Core-Modul zum ADSR (das Makro loop), allerdings wird dort eine andere Funktion benutzt., nämlich ein Gemisch aus einer linearen und exponentiellen Änderungsrate.

Hier ist nun die Datei, mit der man selbst die Steuerung ausprobieren kann:
decay-display1.ens

HÜLLKURVEN

Verfasst: 29. Dezember 2013, 15:18
von herw
3.2 Taktungen
Nachdem eine erste grobe Darstellung möglich ist - denkbar ist noch ein Zoom - soll in diesem Abschnitt durch Taktung ein zeitabhängiger Verlauf erzeugt werden.
Es bieten sich hier zwei Lösungen an: eine Taktung im Audiobereich also mit der SampleRate (z.B. 44100 Hz) oder durch die Ressourcen sparende ControlRate (z.B. 400 Hz). Beide Algorithmen werden identisch aufgebaut sein, der Unterschied liegt lediglich im Multiplikationsfaktor!
Dazu ersetze ich die Zählvariable WX im Display, die durch eine Iteration erzeugt wird durch eine entsprechende Clock.
Bild 29.jpg
Die Hüllkurve wird durch einen GateOn-Trigger gestartet.

HÜLLKURVEN

Verfasst: 29. Dezember 2013, 17:39
von herw
3.2.1 Taktung durch die ControlRate CR
Beginnen wir mit der ControlRate CR: ich zeige zuerst mal im Video, wie sich der Ausgabewert ändert. Ich stelle die Zeitdauer auf etwa 4 Sekunden ein und variiere die Kurvenform. Man erkennt, wie die eingestellte Hüllkurve (links) in einer EventTable über die Taktung aufgebaut wird (MausKlick auf „Gebe Quicktime-Datei wieder”) :
decay_ControlRate.mov
Natürlich habe ich nicht die Absicht, das ControlRate-getaktete Display zu verwenden, aber es sollte die Verarbeitung veranschaulichen.
Bild 30.jpg
Die ControlRate CR und die Zeitdauer t bestimmen die Anzahl der Multiplikationen bis die Hüllkurve innnerhalb von t abgeschlossen ist. Das Potenz-Modul berechnet die entsprechende Wurzel und bestimmt damit, mit welchem Faktor der (normierte) Speicher multipliziert werden soll.
Der Speicher wird in diesem Fall durch den Trigger trg (GateOn) auf das Startlevel gesetzt.
Oben rechts erkennt man den Zähler für die Eventtabelle. In diesem Fall ist die Anzeige auf 10s (entspricht t=80) beschränkt. Aber, wie schon oben erwähnt, dient diese Anzeige hier nur zur Kontrolle.
Der CPU-Verbrauch ist, wie zu erwarten, sehr gering, wenn überhaupt messbar. Bei 8 Voices wurden nur zeitweise 0,1% für das SystemInfo-Modul angezeigt.

Re: HÜLLKURVEN

Verfasst: 31. Dezember 2013, 10:08
von herw
3.2.2 Taktung durch die SampleRate SR.R
Nun ersetzen wir die ControlRate durch die SampleRate …
Bild 31.jpg
... und siehe da, es klappt (Display rechts unten) …
Bild 32.jpg
ABER, was ist das? …
Bild 33.jpg
... und das?
Bild 34.jpg
Das AudioRate-Makro berechnet falsche Werte, wenn der curve-Regler nahe 0 (linearer Verlauf) und lange Zeitdauern time=80 (entspricht 10s) gewählt werden! Die Ursache klären wir im nächsten Kapitel.