SinianPoly ist ein polyphoner subtraktiver Synthesizer mit 16 Stimmen, der als Plugin in ein Host-Musikprogramm geladen werden kann.

Jede Stimme hat:

  • 3 Oszillatoren
  • 2 Noise-Generatoren
  • 2 Filter
  • 1 Amplituden-Envelope
  • 1 Filter-Envelope
  • 4 Modulations-Envelopes
  • 4 LFOs

Ausserdem besitzt SinianPoly einen globalen Delay-Effekt.

Durch die Kombination dieser Komponenten können mit SinianPoly neben traditionellen Synthesizer-Sounds wie Bässe, Pads und Leads auch Schlagzeug-Sounds wie Kick, Snare und Hi-Hats programmiert werden.

SinianPoly GUI

Demo-Video

Das Musikstück in diesem Demonstrations-Video verwendet als Instrumente nur SinianPoly-Instanzen. Ausserdem werden grob die verschiedenen Komponenten des Synthesizers erklärt.

Implementierung

Mit SinianPoly wollte ich einen Synthesizer kreieren, der einfach zu bedienen ist, aber trotzdem viele verschiedene Sounds generieren kann.

Den Audio-DSP-Code habe ich in reinem C++ implementiert.
Für das User-Interface, die Plugin-Schnittstelle und das Speichern und Laden der Presets verwende ich das JUCE-Framework.

Stimme
Signalfluss
Oszillator
Filter
Envelope
LFO
Delay
Presets
UI

Stimmenverwaltung

SinianPoly hat 16 Stimmen, das heisst es können bis zu 16 Töne gleichzeitig gespielt werden.

Wenn ein weiterer Ton gespielt werden soll, aber schon alle 16 Stimmen einen Ton spielen, wird die älteste Stimme gestohlen, um den neuen Ton zu spielen.
Dies muss nicht unbedingt heissen, dass 17 Keyboard-Tasten gleichzeitig gedrückt wurden; das Stehlen einer Stimme kann auch passieren, wenn beim Amp-Envelope eine lange Release-Zeit eingestellt ist.

Signalfluss

Signalfluss Diagramm

Oszillator

Die drei Oszillatoren stellen die klassischen analogen Wellenformen Sinus, Dreieck, Sägezahn und Rechteck zur Verfügung. Damit diese Alias frei sind, werden beim ersten Laden des Plugins pro MIDI-Note und für jede Wellenform durch Summieren von Sinuswellen ein Wavetable erzeugt.
Diese Wavetables werden von allen Oszillatoren und Instanzen des Plugins geteilt.

Filter

Die beiden Filter können als Tiefpass-, Hochpass-, Bandpass- und Bandstopp-Filter verwendet werden.
Die Implementierung als State-Variable-Filter basiert auf einem Filterdesign von Hal Chamberlin.

Envelope

Die Envelopes (oder Hüllkurven) sind ADSR-Envelopes und es kann zwischen linearen und exponentiellen Kurvensegmenten gewählt werden.

Envelope linear
linearer Envelope
Envelope exponential
exponentieller Envelope

LFO

Für die LFOs (Low Frequency Oscillators) habe ich die Wellenformen Triangle, Ramp up, Ramp down und Square implementiert.
Ein LFO kann mehrere Parameter gleichzeitig modulieren. Als Modulationsziele stehen die Parameter der Oszillatoren, die Parameter der Noise-Generatoren und die Parameter der Filter zur Verfügung.

Die Geschwindigkeit der LFOs kann entweder in Hertz angegeben werden, oder zum Tempo des Hosts synchronisiert werden.

Delay Effekt

Den Delay-Effekt habe ich als zirkulären Buffer implementiert, der die letzten fünf Sekunden des Audio-Signals aufzeichnet und verzögert wieder abgespielt. Feedback speist einen Anteil des verzögerten Signals wieder in diesen Buffer ein, sodass ein Echo Effekt entsteht.

Ist der Ping-Pong Modus eingeschaltet, wird das Input-Signal nur in den linken Buffer-Kanal geschrieben und die Feedback-Signale werden überkreuzt in die Buffer-Kanäle geschrieben. Dadurch wechselt jede Wiederholung des Echos die Seite, was an den Klang eines Ping-Pong-Spiels erinnert.

Preset-Manager

Mit dem Preset-Manager können die Einstellungen des Synthesizers als XML-Datei exportiert und wieder geladen werden.

User-Interface

Das Design der verschieden Bedienelemente des User-Interfaces (Drehregler, Fader, Toggle-Buttons etc.) habe ich in Affinity Designer erstellt und dann in einer eigenen LookAndFeel-Klasse das Design der JUCE Standardelemente überschrieben.
Ausserdem habe ich Affinity Designer verwendet um ein gutes Layout der Regler innerhalb der Komponenten und der Komponenten selber zu finden.

JUCE Standard GUI
JUCE Standard UI-Elemente
Custom GUI
Eigene UI-Elemente

Die Komponenten

Oszillator

Oscillator

Type

Mit dem Type-Auswahlknopf kann die Wellenform des Oszillators gewählt werden. Es stehen die Wellenformen Sinus, Dreieck, Sägezahn und Rechteck zur Auswahl.

Tonhöhenregler

Mit den Octave-, Semi- und Detune-Reglern kann die Tonhöhe des Oszillators eingestellt werden.

Octave stellt die Oktave des Oszillators ein.

Mit dem Semitone-Regler kann die Tonhöhe in Halbtonschritten eingestellt werden. Zwölf Halbtöne entsprechen einer Oktave. So kann relativ zur gespielten Note ein Intervall eingestellt werden. Sollen zwei Oszillatoren zum Beispiel eine Quint bilden, muss einer der Oszillatoren um sieben Halbtöne transponiert werden.

Der Detune-Regler verstimmt die Tonhöhe in einem Bereich von ±100 Cent. 100 Cent entsprechen einem Halbton.

Key-Sync- und Bypass-Filters-Schalter

Ist Key-Sync eingeschaltet, beginnt der Oszillator den Wellenzyklus von vorne, sobald eine neue Note gespielt wird.
Wenn Key-Sync ausgeschaltet ist, beginnt die Schwingung an einer scheinbar zufälligen Position im Wellenzyklus, da der Oszillator auch weiter schwingt, wenn er nicht zu hören ist. Dadurch kann es zu Phasenverschiebungen unter den Oszillatoren kommen.

Das Signal des Oszillators umgeht bei eingeschaltetem Bypass-Filters-Schalter die beiden Filter und bleibt somit ungefiltert. Das kann zum Beispiel nützlich sein, wenn die beiden Filter einen der Rauschgeneratoren filtern, aber die Welle des Oszillators ungefiltert bleiben soll.

Oszillator-Synchronisation

Der Oszillator kann mit einem virtuellen Oszillator synchronisiert werden. Der nicht hörbare virtuelle Oszillator läuft mit der durch die Tonhöhenregler eingestellten Frequenz. Der hörbare Oszillator läuft mit einem Vielfachen der eingestellten Frequenz. Dieser Multiplikator wird mit dem Hard-Sync-Regler eingestellt. Wenn der virtuelle Oszillator eine Periode abschliesst, wird der Wellenzyklus des hörbaren Oszillators wieder neu gestartet. Die Oszillator-Synchronisation ermöglicht so die Erzeugung interessanter Klänge.

Lautstärke und Panning

Der Volume-Regler stellt die Lautstärke des Oszillators ein.

Mit dem Panning-Regler kann der Oszillator im Stereopanorama positioniert werden. Ist der Regler auf −1 eingestellt, ist der Oszillator nur auf dem linken Lautsprecher zu hören, ist er auf +1 gestellt, nur auf dem rechten.

Noise-Generator

Der Noise-Generator generiert weisses Rauschen. Das heisst, es werden zufällige Frequenzen im hörbaren Frequenzbereich generiert.

Noise Generator

Der Volume- und der Panning-Regler sowie der Bypass-Filters-Schalter des Noise-Generators haben die gleichen Funktionen wie die des Oszillators.

Filter

Filter

Type

Mit dem Type-Auswahlknopf kann die Art des Filters gewählt werden. Es stehen Tiefpass-, Hochpass-, Bandpass- und Bandstopp-Filter zur Auswahl.

Key-Tracking

Ist Key-Tracking eingestellt, passt sich die Grenzfrequenz der gespielten Note an. Dadurch bleibt der Klang des Synthesizers immer gleich, egal welche Note gespielt wird. Bei vollem Key-Tracking und einer eingestellten Grenzfrequenz von 440 Hz entspricht die angepasste Grenzfrequenz gerade der Frequenz der gespielten Note.

Cutoff

Der Cutoff-Regler stellt die Grenzfrequenz des Filters ein.

Envelope-Depth

Envelope-Depth besagt, wie stark die Grenzfrequenz des Filters vom Filter-Envelope im Lauf der Zeit verändert wird. Jede Erhöhung des Werts um 0.10 verdoppelt die maximal modulierte Grenzfrequenz.

Ist zum Beispiel eine Grenzfrequenz von 200 Hz eingestellt, ist bei einer Envelope-Depth von 0.10 die maximal modulierte Grenzfrequenz 400 Hz. Bei einer Envelope-Depth von 0.20 ist sie 800 Hz, bei −0.10 ist sie 100 Hz und bei −0.20 ist sie 50 Hz.

Resonance

Der Resonance-Regler bestimmt, wie stark die Frequenzanteile des Audio-Signals an der Grenzfrequenz verstärkt werden sollen.

Amplituden- und Filter-Envelope

Die Amplitudenhüllkurve bestimmt, wie sich die Lautstärke des generierten Klangs im Lauf der Zeit verändert, wenn eine Note gespielt wird.

Die Filterhüllkurve moduliert die Grenzfrequenz der beiden Filter entsprechend derer Envelope-Depth-Regler.

Amp Envelope

Attack, Decay, Sustain und Release

Der Attack-Regler bestimmt, wie lange es dauert bis der höchste Punkt der Kurve erreicht wird nachdem eine Keyboard-Taste gedrückt wurde. Der Decay-Regler bestimmt die Decay-Zeit, also wie lange es dauert, bis die Kurve auf das Sustain-Level fällt. Die Release-Zeit bestimmt, wie lange es dauert bis die Kurve wieder auf 0 sinkt, wenn die Taste wieder losgelassen wird.

Exponential-Schalter

Ist der Exponential-Schalter eingeschaltet, besteht die Hüllkurve aus exponentiellen Kurvensegmenten, ansonsten sind diese linear.

Velocity-Sensitivity

Mit dem Velocity-Sensitivity-Regler wird eingestellt, wie stark der maximale Modulationswert der Hüllkurve vom MIDI-Velocity-Wert der gespielten Note beeinflusst wird. Dadurch kann der Synthesizer auf die Anschlagdynamik der gespielten Noten reagieren. Bei schwach gespielten Noten erzeugt die Hüllkurve kleinere Modulationswerte, während stark gespielte Noten höhere Modulationswerte erzeugen.

Modulations-Envelope

Die Modulationshüllkurven sind Modulatoren und können deshalb Parameter des Synthesizers modulieren. Zusätzlich zu den normalen Reglern der anderen Hüllkurven besitzen die Modulationshüllkurven deshalb noch eine Modulationssektion.

Mod Envelope

Modulationssektion

Wird der Destinations-Auswahlknopf der Modulationshüllkurve gedrückt, wird eine Liste mit allen möglichen Modulationszielparametern angezeigt. Falls ein Zielparameter von dieser Hüllkurve moduliert wird, steht in Klammern die Modulationstiefe, mit der dieser Zielparameter von diesem Modulator moduliert wird. Wird einer der Modulationszielparameter in der Liste ausgewählt, kann mit dem Depth-Regler die Modulationstiefe des ausgewählten Modulationszielparameters eingestellt werden. Eine Modulationshüllkurve kann mehrere Zielparameter gleichzeitig modulieren.

Die möglichen Modulationsziele sind:

  • Cutoff der Filter
  • Resonanz der Filter
  • Tonhöhe (Pitch) der Oszillatoren in Halbtönen
  • Verstimmung (Detune) der Oszillatoren in Cents
  • Hard-Sync-Multiplikator der Oszillatoren
  • Lautstärke (Volume) der Oszillatoren und Noise-Generatoren
  • Stereo-Panning der Oszillatoren und Noise-Generatoren

LFO

Ein LFO ist ein Oszillator mit niedriger Frequenz, der als Modulationsquelle verwendet werden kann, um Parameter des Synthesizers zu modulieren. Der LFO kann entweder mit einer Frequenz relativ zum Tempo des Host-Programms oder mit einer Tempo-unabhängigen Frequenz oszillieren.

LFO

Geschwindigkeitssektion

Mit dem Rate-Regler wird die Frequenz des LFOs eingestellt.

Ist die ausgewählte Einheit "Hz", oszilliert der LFO Tempo-unabhängig. Alle anderen zur Auswahl stehenden Einheiten sind Notenlängeneinheiten. Wird eine Notenlängeneinheit gewählt, schwingt der LFO Tempo-abhängig. Mit dem Rate-Regler können dann Vielfache der ausgewählten Notenlängeneinheit gewählt werden. Es stehen ganze, halbe, Viertel-, Achtel-, Sechzehntel- und Zweiunddreissigstel-Noten zur Auswahl. Ausserdem können punktierte Varianten (mit Endung "D") und Triolen-Varianten (mit Endung "T") gewählt werden.

Key-Sync

Wenn Key-Sync aktiviert ist, startet der LFO jedes Mal neu, wenn eine neue Note gespielt wird.

Type, Bipolar und Phase

Bei dem Type-Auswahlknopf stehen die Wellenformen Dreieck, Ramp-Down, Ramp-Up und Rechteck zur Auswahl. Bei Ramp-Down geht die Welle linear von oben nach unten und sprint dann wieder hoch, Ramp-Up ist gerade umgekehrt.

Ist der LFO bipolar, wird der Zielparameter in positive und negative Richtung um den eingestellten Zielparameterwert herum moduliert. Wenn der LFO unipolar ist, wird der Zielparameter nur in eine Richtung moduliert, je nachdem, ob die Modulationstiefe positiv oder negativ ist.

Der Phase-Regler bestimmt, mit welchem Phasenoffset der LFO zu laufen beginnt, wenn er neu gestartet wird. Der LFO startet neu, wenn die Geschwindigkeit vom Tempo des Host-Programms abhängt und der Sequenzer des Hosts zu spielen beginnt oder wenn Key-Sync aktiviert ist und eine neue Note gespielt wird.

Modulationssektion

Die Modulationssektion der LFOs funktioniert so wie bei den Modulations-Envelopes. Auch ein LFO kann mehrere Zielparameter gleichzeitig modulieren.

Delay-Effekt

Delay Effect

Einheit

Der Unit-Auswahlknopf bestimmt, ob die Verzögerungszeit in Sekunden oder Tempo-abhängig eingestellt wird.

Ping-Pong Modus

Ist der Ping-Pong-Schalter aktiviert, wechseln sich die Wiederholungen im linken und rechten Lautsprecher ab. Die erste Wiederholung ist nur auf dem linken Lautsprecher zu hören, die zweite Wiederholung nur auf dem rechten Lautsprecher und so weiter.

Verzögerungszeit

Der Time-Regler bestimmt, wie lange der Delay-Effekt das Audio-Signal des Synthesizers verzögert.

Feedback

Bei einem Feedback-Wert von 0.0 gibt es keine Rückkopplung und somit nur eine verzögerte Wiederholung des Audio-Signals. Ist der Wert hingegen 0.5, wird die Hälfte des Signals rückgekoppelt. Das heisst, die Lautstärke jeder Wiederholung ist halb so laut wie die vorherige. Bei einem Wert von 1.0 fliesst das ganze verzögerte Signal wieder in den Delay-Effekt ein und wiederholt sich unendlich lange, ausser der Feedback-Wert wird wieder reduziert.

Mix

Der Mix-Regler bestimmt, wie viel vom Output-Signal des Delay-Effekts zum Synthesizer Audio-Signal dazugemischt wird. Ist der Wert 0.0, ist der Output des Delay-Effekts nicht zu hören. Bei einem Wert von 0.5 sind die Wiederholungen des Delay-Effekts gleich laut wie das Signal des Synthesizers. Bei Werten über 0.5 ist das Audio-Signal des Synthesizers leiser als das Signal des Delay-Effekts und bei einem Mix-Wert von 1.0 ist nur noch der Delay-Effekt zu hören.