|
|
OneBitSoundDieser Beitrag hat zum Ziel darzulegen, wie man einen einfachen Synthesizer baut, welcher auf dem Prinzip der Ein-Bit-Schwingungen basiert.
[Bearbeiten] Klangsynthese mit Sampletiefe von einem BitUm zu verstehen, was mit One Bit Sound (deutsch: Ein-Bit-Klang) gemeint ist muss man zuerst verstehen, was mit One Bit Sound nicht gemeint ist. Nicht gemeint sind:
Genaugenommen sind Rechteckschwingungen eine Unterart von Ein-Bit-Schwingungen. Bei den letzteren wechseln sich Einsen und Nullen dem Algorithmus entsprechend, bei den ersteren folgen zusammenhängende Gruppen von Einsen und Nullen mit gleicher Anzahl aufeinander.
Bei diesen Schwingungen folgt immer eine zusammenhängende Gruppe von Einsen einer zusammenhängenden Gruppe von Nullen. Bei den Ein-Bit-Schwingungen, wie schon bereits festgestellt, ist die Abfolge algorithmusbedingt. Außerdem haben ist die PWM-Frequenz höher als die maximal hörbare, dagegen haben die Ein-Bit-Schwingungen eine hörbare Frequenz. Ein-Bit-Schwingungen sind also rechteckige Schwingungen, deren Wert sich durch den Algorithmus beliebig ändert. [Bearbeiten] Ästhetik des Ein-Bit-KlangsMan stellt sich sicherlich die Frage nach der Zweckmäßigkeit der Ein-Bit-Synthese, wo doch die Rechenleistung des Controllers, welcher im Synthesizer One-Bit-Groovebox (http://web.media.mit.edu/~nvawter/projects/1bit/) benutzt wurde auch für den Synthesizer AVRSYN (http://www.jarek-synth.strona.pl/) mit der Sampletiefe vom 16 Bit ausreicht. Die negative Antwort hinsichtlich der Zweckmäßigkeit über "weniger" Möglichkeiten dieser Syntheseart ist hinreichend bekannt und wurde schon in den Achtzigern über die Monotonie der "Computermusik" geäußert. Dagegen sind die positiven Antworten interessanter:
Insbesondere die Stücke von Tristan Perich (Link s.u.) für Controller mit Orchester demonstrieren tatsächliche Möglichkeiten dieser Syntheseart.
Wie dieser Artikel im Software-Teil zeigt, ist unter Verzicht auf Effekte, MIDI- und Sequenzer-Teil ist es möglich, auch die kleinsten Mikrocontroller zu nutzen.
Die Klangerzeugung des Atari 2600 synthesiert Ein-Bit-Klänge, daher macht man mit der Nachbildung des Klangbausteins des Atari automatisch Ein-Bit-Musik. [Bearbeiten] Verwendung von Ein-Bit-SchwingungenDie bekannteste Anwendung von Ein-Bit-Schwingungen ist der Soundchip des Computers Atari 2600. Die Weiterentwicklung des Konzepts fand in der One-Bit-Groovebox von Noah Vawter (http://web.media.mit.edu/~nvawter/projects/1bit/index.html) statt. Im Bild ist der Nachbau der Groovebox auf einer Lochraster-Platine zu sehen. Die One-Bit-Groovebox ist ein auf Live-Performance ausgelegter Synthesizer. Er besitzt keinen Computeranschluss, weil dies den Musiker an den Computer fesseln würde, dafür aber einen eingebauten Sequencer. Die Erstimplementierung durch Noah Vawter läuft auf dem Mikrocontroller AVR Mega 32 mit der (maximalen) Taktfrequenz von 16 MHz. Das Gerät besitzt eine analoge Eingabe (Potentiometer, experimentierfreudige Musiker können diesen z. B. durch einen Fotowiderstand ersetzen) und zehn digitale Eingaben (Knopfschalter). Letztere sind in folgende Gruppen aufgeteilt: Record-Knöpfe (analoger Wert wird im Sequencer gespeichert), Jam-Knöpfe (analoger Wert wird vom Synthesizer unmittelbar übernommen), ein Knopf zur Auswahl des Audioeffekts und ein Knopf zum Einklopfen vom Tempo. Eine weitere Neuheit gegenüber dem Soundchip von Atari 2600 besteht in der Anwendung von digitalen Audioeffekten auf den durch den Synthesizer erzeugten Klang. Die Palette reicht vom Ring-Modulator bis zum Arpeggiator. Die Effekte verbrauchen aber nach der Aussage des Autors den größten Teil der Rechenleistung. Tristan Perich (http://www.tristanperich.com/) komponiert mit dem Ein-Bit-Klang komplette Musikstücke. Ausserdem benutzte er einen AVR Mega 8-Mikrocontroller als Musikmedium (analog zu einer CD) für seine Ein-Bit-Musikstücke. Die Gruppe "Loud Objects", deren Mitglied Tristan Perich ist, kombiniert den Ein-Bit-Klang mit dem Live-Zusammenlöten von Controllern, welche den Klang erzeugen. Auf deren Website (http://www.loudobjects.com/) ist es möglich, einen Kleinstsynthesizer namens Noise Toy entweder bereits zusammengebaut oder als Kit zu bestellen. Dazu gibt es auf der gleichen Seite verschiedene Beispiele für klangerzeugende Programme. Die in diesem Abschnitt vorgestellte Musiker und Entwickler gehen den Weg der meisten Möglichkeiten, der möglichst vielfältigen Klänge. Das führt zu einem mächtigen und komplexen Musikinstrument, dessen Fähigkeiten für einen Anfänger nur langsam erschließbar sind. Das Ziel dieses Beitrags ist aber der Bau eines kleinen, leicht verständlichen Synthesizers. Das Noise Toy von Loud Objects geht in diese Richtung, und kann auch als Hardwareplattform benutzt werden. Die im Beitrag präsentierte Algorithmen der Klangsynthese sind weitgehend hardwareunabhängig, dennoch sollten bei der Hardwareauswahl einige Aspekte berücksichtigt werden. [Bearbeiten] Hardware des SynthesizersDie Ansprüche an die Hardwareplattform sind minimal. Selbstverständlich muss die Rechenleistung für die Berechnungen ausreichen. Dasselbe gilt für die Speicherausstattung. Es müssen auch Pins für die Ein- und Ausgabe bereit stehen. Werden nur perkussive Klänge (d.h. Schlagzeug) gewünscht, ist die Stabilisierung der Taktfrequenz durch ein Quarz nicht erforderlich. Ansonsten besteht lediglich die Anforderung an den Entwickler, sich mit der Hardwareplattform auseinandergesetzt zu haben. Es ist von Vorteil, eine Möglichkeit zum Debugging zu haben. Ob diese sich im JTAG-Interface, UART-Ausgabe oder gar in einer einzigen LED erschöpft bleibt dem Entwickler überlassen. Bei der Wahl der Klangausgabe ist das Endergebnis zu berücksichtigen. Sind tiefe Frequenzen im Klang erwünscht, könnte zum Beispiel ein Piezo-Summer nicht ausreichen. Ein zusätzlicher Punkt, welchen es zu beachten gilt, ist die Leistung des resultierenden Klangs. Bei der Ausgabe auf Kopfhörer oder Verstärker hat sich folgender Schaltkreis bewährt: Bei Bedarf kann der Widerstand geändert oder durch einen Wechselwiderstand ersetzt werden. Der Klinkenstecker ist genauso anpassbar. [Bearbeiten] Software des SynthesizersDer Umstieg von der gewohnten 16-Bit oder 8-Bit- auf die Ein-Bit-Klangerzeugung beinhaltet einige Tücken, welche im folgenden Abschnitt ausgeräumt werden. [Bearbeiten] Theorie der Ein-Bit-KlangerzeugungDas Ergebnis der üblichen digitalen Klangerzeugung sind Amplitudenwerte aus einem Zahlenbereich, oft Bei der Ein-Bit-Klangerzeugung gibt es keine D/A-Wandlung, da die Ausgabewerte bereits als analog betrachtet werden. Daher kann man im Vergleich zu den 16 Bit breiten Werten sagen, dass 0 bei der Ein-Bit-Klangerzeugung für Man betrachte was mit einer Sinusschwingung geschieht, wenn diese mit einer Ein-Bit-Schwingung approximiert wird: Die Sinusschwingung wird hier also zu einer Rechteckschwingung mit Tastverhältnis 50:50. Dasselbe Ergebnis bekommt man allerdings auch bei der Approximation der Rechteckschwingung (trivial) und der Dreieckschwingung mit derselben Frequenz (im Bild). Man kann also sagen, dass die Ein-Bit-Schwingung die Nulldurchgänge der Amplitudenwerte nachbildet.
[Bearbeiten] Vom Klang zu AlgorithmusWie bereits erwähnt ist das Ziel des Artikels der Bau eines einfachen Synthesizers. Man könnte versuchen einen Klang mit vielen einstellbaren Parametern zu erzeugen, aber dies würde die Übersichtlichkeit des Projekts zunichte machen. Es bietet sich an einen vorhandenen Klang nachzubilden. Um das Ganze möglichst einfach zu gestalten und möglicherweise auch auf eine stabilisierte Taktfrequenzquelle zu verzichten bietet sich die Nachbildung des Klangs eines Schlaginstruments, im vorliegenden Fall einer Bass Drum, an. Zuerst muss man die Frequenzverteilung bestimmen. Dafür nutzen wir die Aufnahme einer gebeatboxten (d.h. mit menschlicher Stimme erzeugten) Bass Drum (Aufnahme). Mit dem Programm Sonic Visualiser (http://www.sonicvisualiser.org/) erzeugen wir ein Sonogramm der Aufnahme. Dieses sieht folgendermaßen aus: Es ist erkennbar, dass die dominierende Frequenz (die rote Linie im Bild) in den ersten 200 Millisekunden von Kleine Einstreuungen bei Somit ist auch der Algorithmus klar:
[Bearbeiten] ImplementierungBei der Implementierung wurde versucht, die Details wie die Syntax der Interruptspezifizierung möglichst frei zu halten, denn dies erleichtert die Portierung. Im Übrigen wurde es schon früher im Artikel auf eine gute Kenntnis der Werkzeuge, mit denen man arbeitet, hingewiesen. Die Implementierung wird nicht als zusammenhängendes Quelltext vorgestellt, sondern als einzelne Schritte mitsamt derer Erklärungen. Da die Spezifikationen des Hardwaresystems bisher sehr frei waren, geht die Software von den folgenden Annahmen aus:
Anmerkung: Es empfiehlt sich dennoch die Abtastfrequenz zu kontrollieren. Bei der Erstimplementierung der Ein-Bit-Klangerzeugung für eine Bass Drum wurde festgestellt, dass die Abtastfrequenz nur 880 Hertz betrug, statt der vermuteten 12000. Hardwarebedingt war eine Korrektur nicht möglich. Der Algorithmus funktionierte mit geringfügigen Anpassungen trotzdem. Zuerst definiert man häufig benötigte Konstanten. Mann macht es besser durch die Präprozessor-Konstanten als über const-Variablen, denn im letzteren Fall könnte der Compiler auf die Idee kommen, den Wert der Konstanten zur Laufzeit zu berechnen. Um Datentypen mit der vordefinierten Bitbreite zu nutzen, binden wir die Datei stdint.h ein:
Als erste Konstante benötigt man die Abtastfrequenz Fs. Mit dieser Frequenz wird eine Interruptroutine (mehr dazu weiter unten) von einem Timer aufgerufen.
Dann benötigen wir beide Randfrequenzen (in Hertz) des Klangs (siehe dazu voriges Abschnitt):
Es folgen die Definitionen der Phase 1 und Phase 2 des Algorithmus' (jeweils 200 Millisekunden, berechnet als ein Fünftel einer Sekunde und somit auch von 16000 Hertz):
Wir ändern die Klangfrequenz lieber über die Periodendauer der Frequenz, damit der Controller nicht bei jeder Änderung deren eine Division ausführen muss. Dazu brauchen wir die Periodendauer der Randfrequenzen:
Weiterhin benötigen wir die Dauer einer Frequenz beim Herunterlaufen von 200 zu 100 Hertz.
Und schließlich brauchen wir noch die Bezeichnung für den Port-Pin, auf dem die Klangausgabe stattfindet. Compiler- und controllerabhängig sind die Pinbezeichnungen entweder deren Stellen im Port-Wert oder Bitmasken. Man nehme hier an, dass die Bitstelle angegeben ist.
Dann definieren wir eine globale Statusvariable tbd. Diese bezeichnet den Zeitpunkt der Klanggenerierung. Damit die Sounderzeugung nicht bereits beim Einschalten des Systems losläuft, setzen wir den Anfangswert der Variable so, dass dieser die 200 + 200 Millisekunden des Klangs übersteigt.
Dazu definieren man den Zwischenspeicher für das resultierende Bit. Der Datentyp uint8_t wird verwendet, weil die bit-Datentypen nicht von allen Compilern sowie Controllerfamilien unterstützt wird.
Man benötigt noch eine Variable, in der die Periodendauer gespeichert wird. Man benötigt auch eine Laufvariable, welche zum Zählen der Zeiteinheiten pro Periodendauer gebraucht wird.
Zur Berechnung des Zeitpunktes für die Vergrößerung der Periodendauer brauchen wir eine zusätzliche Variable.
Wir kommen nun zu den Funktionen. Die erste Funktion ist die Interruptroutine, welche die Klangerzeugung startet. Dazu setzt diese die Zeitvariable tbd auf 0. Aufgerufen wird die Routine beim Port-Interrupt, d.h. bei einem Knopfdruck.
Die zweite Interruptroutine erzeugt den Klang. Dazu wird sie durch den entsprechend konfigurierten Timer aufgerufen.
Selbstverständlich sind die Initialisierungsroutinen für Interrupts sowie Konfiguration der Peripherieeinheiten ausgelassen worden. Aber deren Compiler- und Controllerabhängigkeit wurde bereits mehrfach erwähnt. [Bearbeiten] Verbesserung des KlangsDer resultierende Klang ist schon recht trommelähnlich, allerdings fehlt ihm die "Schärfe", die "Kantigkeit". Um dieses Problem zu beheben, denke man zuerst an das Erste, was beim Schlagen einer Trommel passiert: Der Stick, mit dem man schlägt, trifft die Membran der Trommel. Das Geräusch des Aufschlags lässt sich gut durch ein kurzes weißes Rauschen imitieren. Um weißes Rauschen zu erzeugen brauchen wir ein (Pseudo-)Zufallsgenerator. Eine effiziente Implementierung finden wir im Quelltext der bereits erwähnten One-Bit-Groovebox; diese basiert auf dem Prinzip des Linear Feedback Shift Register (LFSR). Zuerst fügen wir der Implementierung die Dauer des Rauschens (20 Millisekunden = ein Fünfzigstel Sekunde) hinzu:
Dann die Variablen für den Zufallsgenerator:
Danach die Funktion des Zufallsgenerators selbst:
Und schließlich den Funktionsaufruf, und zwar direkt vor die Klangausgabe:
Der Klang ist jetzt noch ein wenig authentischer. [Bearbeiten] FazitDie vorgestellte Art der Klangsynthese ist leicht zu implementieren und lädt zu Experimenten ein. Wie wird der Klang der Bass Drum sich anhören, wenn man ein Effekt darauf anwendet? Und wenn man die Effektparameter ändert? Die Möglichkeiten sind nicht unbegrenzt, aber sicherlich mehr, als dem Leser am Anfang dieses Artikels vorschwebte. Für weitere Experimente werden die Webseiten aus dem nächsten Abschnitt sehr hilfreich sein. [Bearbeiten] One Bit Musiker/Entwickler[Bearbeiten] Video zum Artikel[Bearbeiten] Siehe auch |