MIDI-Funktionen - Cinderella Dokumentation
Description: The user's guide to the Interactive Geometry Software Cinderella

Zum Inhalt

# MIDI-Funktionen

### Wie Cinderella-MIDI funktioniert

MIDI steht für Musical Instrumental Digital Interface. Es ist ein Standardprotokoll, das für die Kommunikation zwischen elektronischen Instrumenten und Computern verwendet wird. MIDI bietet Kontrolle über einzelne Töne, Tonfolgen, den Klang von Instrumenten, Polyphonie, Lautstärke und viele andere Dinge, die für die Wahrnehmung von Musik essentiell sind. Die CindyScript-MIDI-Schnittstelle bietet einen optimierten Satz von Anweisungen zum einfachen und flexiblen Erstellen von Musik und Soundeffekten. Bevor wir uns in die Details dieser Anweisungen vertiefen, geben wir einen kurzen Überblick über die Architektur und die Möglichkeiten von MIDI. Dies wird es einfacher machen, ihre Interaktion mit Cinderella zu verstehen. Soweit leicht möglich erwähnen wir auch, wie die MIDI-Anweisungen in CindyScript zugänglich sind.

### Noten, Kanäle und Instrumente

Grob gesagt ist die grundlegendste Funktionalität von MIDI, Informationen an einen Musiksynthesizer zu senden und ihm zu sagen, dass er eine Note spielen soll. In seiner einfachsten Form besteht diese Information einfach aus einer Zahl zwischen 0 und 127, die dem Synthesizer mitteilt, welche Note gespielt werden muss. In der Standard-MIDI-Kodierung stellt die Zahl 60 die Note C in der mittleren Oktave dar. Eine Erhöhung oder Verringerung dieser Zahl um eins entspricht einem Halbtonschritt. Somit entspricht 61 C#, 60 D und so weiter.

Die folgende Tabelle ordnet Noten und Zahlen für den Bereich von zwei Oktaven zu:

C | C# | D | D# | E | F | F# | G | G# | A | B | H | c | c# | d | e# | e | f | f# | g | g# | a | b | h | c'
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84

Die entsprechende CindyScript-Anweisung zum Abspielen eines Tons mit einer bestimmten Tonhöhe ist `playtone`. Versuchen Sie zum Beispiel `playtone(60)`.

Eine Note umfasst jedoch viel mehr als nur eine bestimmte Tonhöhe. Sie hat ein damit verbundenes Instrument, mit dem sie gespielt wird, eine Lautstärke, eine bestimmte räumliche Position und viele andere Eigenschaften. Einige davon sind eher statischer Natur (wie das Instrument) und ändern sich nicht von Ton zu Ton. Andere wie die Lautstärke sind eher dynamischer Natur und ändern sich häufig innerhalb eines Musikstücks. MIDI ermöglicht es Ihnen, alle diese Parameter auf eine Weise zu steuern, die den Merkmalen von Musik nahe kommt. Stellen Sie sich das Spielen eines Klaviers vor. Das Hauptmerkmal, das die Lautstärke eines Tons verändert, der durch das Drücken einer Taste erzeugt wird, ist die Anschlagsstärke, mit der die Taste gedrückt wird. Mit dieser Anschlagsstärke ändert sich nicht nur die Lautstärke, sondern auch die kompletten Klangcharakteristiken des Tons. MIDI modelliert nicht nur die Lautstärke, sondern auch (und vollständig automatisch) diese Änderung der Klangcharakteristiken. Aus diesem Grund wird der Parameter, der die Lautstärke steuert, Anschlagsstärke statt Lautstärke genannt. In Cinderella wird dieser Parameter durch einen Modifikator gesteuert, der von 0,0 bis 1,0 reicht. Mit `playtone(60,velocity->0.5)` erhalten Sie also ein C mit mittlerer Lautstärke.

In der Standardeinstellung von Cinderella wird solch eine Note von einem klavierähnlichen Instrument gespielt. Es gibt zwei weitere MIDI-Konzepte, die für das Verständnis der Klangerzeugung wesentlich sind: Instrumente und Kanäle. Ein einzelnes MIDI-Gerät ist in der Lage, die Instrumente einer ganzen Band mit 16 Spielern gleichzeitig zu spielen. Dafür bietet MIDI 16 Kanäle mit den Nummern 0 bis 15. Jeder von ihnen kann mit einem spezifischen Instrument verknüpft werden; die Instrumente sind von 1 bis 128 durchnummeriert und decken ein breites Spektrum von Musikerfahrungen ab (Blechbläser, Schlaginstrumente, Streicher, Klaviere, Akkordeons, Gitarren, Schlagzeug und vieles mehr). In CindyScript kann ein Instrument (z. B. 25, das ist eine Akustikgitarre) entweder durch `midichannel(3, intrument->25)` oder durch `instruments(25, channel->3)` einem Kanal (z. B. 3) zugeordnet werden. Der Standardkanal, in dem ein Ton durch `playtone(...)` gespielt wird, ist 0, aber er kann durch einen Modifikator geändert werden.

Der folgende Code

    midichannel(3,instrument->25); //guitar
    midichannel(2,instrument->12); //vibraphone
    playtone(60);
    playtone(64);
    playtone(67,channel->3);
    playtone(72,channel->2);

spielt einen C-Dur-Akkord, dessen zwei tiefste Töne vom Klavier gespielt werden und dessen höhere Töne von einem Vibraphon und einer Gitarre gespielt werden. Jeder Kanal kann völlig polyphon verwendet werden. Es ist daher kein Problem, dass das Klavier gleichzeitig zwei Noten spielt.

In der MIDI-Implementierung von CindyScript haben die 16 Kanäle vorgegebene Instrumente, um einen bequemen Zugriff auf wichtige Klänge zu ermöglichen. Die den Kanälen zugeordneten Instrumente sind in der folgenden Tabelle angegeben (die Zahlen hinter den Instrumenten geben die Instrumentennummern an):

0: Akustisches Großklavier (1) | 8: Synth. Rechteckwelle (81)
1: Glockenspiel (10) | 9: SCHLAGZEUG
2: Vibraphon (12) | 10: FX 3, Kristall (99)
3: Marimbophon (13) | 11: Glöckchen (113)
4: Xylophon (14) | 12: Flöte (74)
5: Holzblock (116) | 13: Akustischer Bass (33)
6: Pizzicato-Streicher (46) | 14: Perkussive Orgel (18)
7: Tremolo-Streicher (45) | 15: Alt-Saxophon (66)

Es gibt verschiedene weitere Merkmale (wie Hall, Balance, Druck usw.) von Tönen, auf die über Modifikatoren zugegriffen werden kann. Für eine vollständige Beschreibung verweisen wir auf die Erklärungen für die verschiedenen Anweisungen. Wir erwähnen hier nur die wichtigste: Dauer. Dieser Parameter steuert die Zeit (in Sekunden), nach der eine Note wieder freigegeben wird. So erzeugt `playtone(60,duration->0.1,velocity->1)` ein kurzes und lautes C. Der Standard für Dauer ohne expliziten Modifikator ist 1 Sekunde.

### Timing und Sequenzierung

Bisher haben wir uns nur mit Tönen befasst, die alle auf einmal abgespielt werden. Es gibt zwei Möglichkeiten, um Melodien in Cinderella zu erstellen. Entweder erstellt man den Zeitplan explizit mit dem `wait(...)`-Befehl von CindyScript, oder man verwendet den integrierten MIDI-Sequenzer. Wir beschreiben zunächst kurz, wie die Methode funktioniert, die sich nicht auf den Sequenzer verlässt. Dafür müssen wir nur einzelne Noten durch wait-Befehle trennen.

    playtone(60,duration->3);     wait(500);
    playtone(64,duration->2.5);   wait(500);
    playtone(67,duration->2);     wait(500);
    playtone(72,duration->1.5);

Im obigen Beispiel ist der Zeitplan explizit vorgegeben, so dass alle Noten genau zum gleichen Zeitpunkt enden. Man kann diese Methode auch nutzen, um interessante Melodien (oder Jingles) programmgesteuert zu generieren. Probieren Sie das folgende Codebeispiel in CindyScript aus (es lohnt sich zu tippen):

    halftones=[61,63,66,68,70,73,75,78,80,82,85,87,90];
    forall(60..90,i,
      playtone(i,velocity->if(contains(halftones,i),1,0.6),
                 channel->if(contains(halftones,i),3,5));
      wait(100);
    );

Das Generieren von Noten auf diese Weise hat Nachteile. Erstens muss der Zeitplan detailliert durch den CindyScript-Code beschrieben werden. Zweitens wird während der `wait(...)`-Befehle die Ausführung von anderem CindyScript-Code blockiert, da CindyScript wartet. Aus diesem Grund (und mehreren anderen) ist es oft viel einfacher, den integrierten MIDI-Sequenzer zu verwenden.

Der MIDI-Sequenzer ist die zweite große Funktion von MIDI. Es ist eine Programmlogik, die es ermöglicht, MIDI-Ereignisse zeitlich abzuspeichern. Damit können beliebige Musikstücke beschrieben und abgespielt werden. Der MIDI-Sequenzer ordnet jedem MIDI-Ereignis einen Zeitstempel zu, der dem Synthesizer mitteilt, wann eine bestimmte Note abgespielt werden muss. In CindyScript können Sie auf den Sequenzer entweder über die `playmelody(...)`-Anweisung oder über die `midiaddtrack(...);midistart()`-Befehle zugreifen. Der erste ist einfacher und unmittelbarer, der zweite ist leistungsfähiger. Wir werden hier kurz die erste Methode beschreiben. Die Anweisung `playmelody(...)` erwartet einfach eine Liste von MIDI-Ereignissen. In ihrer grundlegendsten Form ist ein solches MIDI-Ereignis eine Liste, die einfach aus einer Zahl besteht, die die Note angibt, gefolgt von einer anderen Zahl, die die Dauer angibt. So kann ein gebrochener C-Dur-Akkord beispielsweise folgendermaßen codiert werden:

    playmelody([[60,1],[64,1],[67,1],[72,4]]);

Es ist auch möglich, auf die Noten über ihre Namen als Zeichenketten statt über die Zahlen zuzugreifen. Auf diese Weise spielt das folgende Codebeispiel:

    playmelody([
      ["c",1],["e",1],["f",1],["g",5],["c",1],["e",1],["f",1],["g",5],
      ["c",1],["e",1],["f",1],["g",2],["e",2],["c",2],["e",2],["d",5],
      ["e",1],["e",1],["d",1],["c",3],["c",1],["e",2],["g",2],["g",1],
      ["f",4],["f",1],["e",1],["f",1],["g",2],["e",2],["c",2],["d",2],
      ["c",5]
    ],speed->300,instrument->57)

eine sehr einfache Version von "Oh, when the saints". Wiederum kann die Anweisung durch verschiedene Modifizierer verziert werden. So wird hier das Instrument so gewählt, dass es ungefähr wie eine Trompete klingt (echte Trompeter mögen uns verzeihen). Die Geschwindigkeit ist auf 300 Schläge pro Minute eingestellt. Ein Schlag ist die grundlegende Zeiteinheit für den Sequenzer. Sie ist normalerweise einer Viertelnote zugeordnet und es gibt normalerweise vier Schläge pro Takt oder drei Schläge pro Takt (wenn Sie einen Walzer haben). Auch Bruchteile von Schlägen sind erlaubt. Sie können verwendet werden, um achte Noten, Triolen und ähnliches darzustellen.

Die Syntherella-Schnittstelle zum Sequenzer kann eine Menge musikalischer Inhalte auf einem ziemlich hohen Niveau ausdrücken. Details werden später erläutert.

### Schlagzeug

Cinderella verwendet das vordefinierte Setup namens General MIDI, das eine spezifische Sammlung von synthetisierten Instrumenten ist. Es gibt eine Konvention, die in General MIDI besonders ist (aber sehr nützlich). Kanal 10 spielt eine besondere Rolle. Er ist für Schlagzeuginstrumente reserviert und kann verwendet werden, um ein Schlagzeug zu implementieren. Daher müssen Sie sich bewusst sein, dass dieser Kanal eine besondere Bedeutung hat, wann immer Sie Kanal 10 verwenden. Die MIDI-Nummern, die normalerweise Noten darstellen, sind in diesem Fall spezifischen Schlagzeuginstrumenten zugeordnet (nicht alle 128 Tasten werden hier verwendet). Die folgende Tabelle gibt Ihnen einen Überblick über die den Tasten zugeordneten Instrumente.

35 Bass Drum 2 | 47 Mid Tom 1 | 59 Ride Cymbal 2 | 71 Short Whistle
36 Bass Drum 1 | 48 High Tom 2 | 60 High Bongo | 72 Long Whistle
37 Side Stick | 49 Crash Cymbal 1 | 61 Low Bongo | 73 Short Guiro
38 Snare Drum 1 | 50 High Tom 1 | 62 Mute High Conga | 74 Long Guiro
39 Hand Clap | 51 Ride Cymbal 1 | 63 Open High Conga | 75 Claves
40 Snare Drum 2 | 52 Chinese Cymbal | 64 Low Conga | 76 High Wood Block
41 Low Tom 2 | 53 Ride Bell | 65 High Timbale | 77 Low Wood Block
42 Closed Hi-hat | 54 Tambourine | 66 Low Timbale | 78 Mute Cuica
43 Low Tom 1 | 55 Splash Cymbal | 67 High Agogo | 79 Open Cuica
44 Pedal Hi-hat | 56 Cowbell | 68 Low Agogo | 80 Mute Triangle
45 Mid Tom 2 | 57 Crash Cymbal 2 | 69 Cabasa | 81 Open Triangle
46 Open Hi-hat | 58 Vibra Slap | 70 Maracas |

Dadurch ist es relativ einfach, eine Rhythmusspur zu erstellen, die Ihre Musik begleitet. Die Schlagzeuginstrumente sind auch sehr nützlich, um Soundeffekte in anderen Cinderella-Anwendungen zu erstellen. Wenn Sie beispielsweise CindyLab verwenden, um ein Ping-Pong-Spiel zu erstellen, können Sie die Wood Blocks (Taste 76 und 77) verwenden, um Klickeffekte beim Treffen des Balls zu erzeugen.

Der folgende Code zeigt eine einfache Implementierung eines Rock-Rhythmus unter Verwendung des Sequencers. Beachten Sie, dass dieses Programm auch die `"goto"`-Anweisung in `playmelody(...)` verwendet, um die Spur zum Anfang zurückzuspulen.

    playmelody(channel->9,speed->500,loop->8,
     [[35,3],[35,3],[35,3],[35,6],[35,1],["goto",0], //bass drum
      [-1,2],[42,4],[42,4],[42,4],[42,2],["goto",0], //high-hat
      [-1,4],[38,8],[38,4],["goto",0],               //snare
      [59,4],[59,4],[59,4],[59,4],["goto",0],        //ride cymbal
      [-1,13],[76,1],[62,1],[-1,2],["goto",0]        //percussion
    ]);

Im obigen Code-Snippet werden mehrere Schlagzeuginstrumente in der gleichen „Melodie" überlagert und bilden ein komplexes rhythmisches Muster. Die Note `-1` wird als Pause verwendet.

### Spuren und Musikstücke

Wir beenden unsere kleine Einführungsreise, indem wir ein kleines Musikstück erstellen, das aus einem Melodieteil und einem Schlagzeugmuster besteht. MIDI kann viele verschiedene Spuren für den Sequencer akzeptieren. Jede Spur kann mit einem Spieler einer Band verbunden werden. CindyScript bietet eine Anweisung `midiaddtrack(...)`, die eine Spur stillschweigend zum Sequencer hinzufügt, ohne sie sofort abzuspielen. Alle hinzugefügten Spuren können durch Aufrufen des `midistart()`-Befehls abgespielt werden. Das folgende Code-Snippet zeigt, wie unser Rock-Rhythmus mit der Melodie „Oh, when the saints" kombiniert werden kann, um eine rockige Version dieses traditionellen Musikstücks zu geben. Es gibt einige Besonderheiten, die in einem Moment erläutert werden.

    midichannel(3,instrument->57);
    midiaddtrack(channel->3,track->1,
     [["c",1],["e",1],["f",1],["g",5],["c",1],["e",1],["f",1],["g",5],
      ["c",1],["e",1],["f",1],["g",2],["e",2],["c",2],["e",2],["d",5],
      ["e",1],["e",1],["d",1],["c",3],["c",1],["e",2],["g",2],["g",1],
      ["f",4],["f",1],["e",1],["f",1],["g",2],["e",2],["c",2],["d",2],
      ["c",5]
    ]);
    midiaddtrack(channel->9,track->2,stretch->1/2,offset->3,repeat->8,
     [[35,3],[35,3],[35,3],[35,6],[35,1],["goto",0], //bass drum
      [-1,2],[42,4],[42,4],[42,4],[42,2],["goto",0], //high-hat
      [-1,4],[38,8],[38,4],["goto",0],               //snare
      [59,4],[59,4],[59,4],[59,4],["goto",0],        //ride cymbal
      [-1,13],[76,1],[62,1],[-1,1]                   //percussion
    ]);
    midistart(speed->250);

Im Prinzip fügen wir also zwei Spuren zum Sequencer hinzu (eine für die Melodie und eine für den Rhythmus) und spielen sie mit `midistart()` ab. Es gibt einige kleinere Probleme bezüglich des Timings und der Positionierung, die durch die Verwendung von Modifiziern gelöst werden können. Zunächst nehmen wir die Spur „Oh, when the saints" aus dem vorherigen Beispiel wie sie ist. Wir verbinden sie mit Spur 1 des Sequencers. Das Hinzufügen des Rock-Rhythmusmusters aus dem anderen Beispiel zu Spur 2 wirft mehrere Probleme auf. Zunächst passt das Timing nicht. Die Schläge in der Melodie sind doppelt so lang wie die Schläge in der Rhythmusspur. Wir können dies anpassen, indem wir den Modifizierer `stretch->1/2` verwenden. Alternativ hätten wir die Positionsnummern der Rhythmusspur halbieren können. Zweitens hat „Oh, when the saints" einige Auftaktnoten (die ersten drei). Die Rhythmusspur sollte daher nicht sofort starten. Wir können dies beheben, indem wir `offset->3` verwenden. Schließlich benötigen wir insgesamt acht Wiederholungen des Rhythmusmusters. Wir tun dies, indem wir `repeat->8` sagen.

## Einzelne Töne

Wir beginnen zunächst mit den Anweisungen, die zum Generieren einzelner Töne verwendet werden. Einige Toncharakteristiken können über Modifizierer angesprochen werden.

#### Einen Ton abspielen: `playtone(<int>)`

Beschreibung: Dies ist die einfachste Möglichkeit, einen Ton zu erstellen. Es erstellt einen Ton, der unmittelbar nach dem Aufrufen dieser Anweisung abgespielt wird. Ohne Modifizierer wird der aktuelle Standard-Kanal mit seinem zugeordneten Instrument verwendet. Die Standard-Dauer beträgt 1 Sekunde. Die Standard-Velocity ist `0.5`.

Beispiel: Der folgende Code spielt einen gebrochenen C-Dur-Akkord ab.

    playtone(60);
    wait(1000);
    playtone(64);
    wait(1000);
    playtone(67);
    wait(1000);
    playtone(72, duration->4);

Modifizierer: Der Befehl hat mehrere Modifizierer, die meisten sind selbsterklärend.

Modifizierer | Parameter | Auswirkung
`velocity` | `0.0 ... 1.0` | die Lautstärke eines Tons (wie schnell eine Klaviertaste gedrückt wird)
`amp` | `0.0 ... 1.0` | identisch mit `velocity`
`duration` | `<real>` | Dauer des Tons in Sekunden
`channel` | `0..15` | Auswahl des Kanals, der abgespielt wird
`reverb` | `0.0 ... 1.0` | Halleffekt
`balance` | `-1.0 ... 1.0` | Links-/Rechts-Panorama des Tons
`bend` | `-2.0 ... 2.0` | Biegen eines Tons bis zu einer ganzen Note nach unten oder oben

Mit dem Modifizierer `bend` kann die Tonhöhe der Note um zwei Halbtöne nach oben oder unten geändert werden. Eine Einheit von `bend` entspricht einem Halbton.

Wenn die Dauer auf 0 (oder kleiner) gesetzt wird, wird der Ton auf unbestimmte Zeit beibehalten und nur durch die Anweisung `stoptone(...)` gestoppt.

#### Einen Ton stoppen: `stoptone(<int>)`

Beschreibung: Stoppt sofort den Ton der angegebenen Note. Dies kann nützlich sein, wenn ein Ton mit unbestimmter Länge gestartet wurde.

#### Einen Ton mit angegebener Frequenz abspielen: `playfrequency(<real>)`

Beschreibung: Diese Anweisung ist sehr ähnlich wie `playtone`. In diesem Fall wird jedoch die Frequenz (in Hz) explizit durch einen reellen Parameter gegeben. Manchmal kann es nützlich sein, stattdessen die stärker physikalisch orientierte Funktion `playsin(...)` zu verwenden.

Beispiel: `playfrequency(440)` spielt einen Ton von 440 Hz mit dem aktuell ausgewählten Kanal und Instrument ab. Die Anweisung `playfrequency` ist besonders interessant für die Simulation von Skalen nicht-europäischer Kulturen, die zum Beispiel in indischen Ragas oder javanischer Gamelan-Musik benötigt werden.

Modifizierer: Die Modifizierer sind identisch mit `playtone(...)`. Der Modifizierer `bend` hat jedoch hier keine Auswirkung.

## Melodien

Die Cinderella-MIDI-Schnittstelle bietet eine umfangreiche Menge von Anweisungen zum Verarbeiten der Wiedergabe von sequenzierten Musiknoten. Im Prinzip ist jede Note (oder allgemeiner jedes MIDI-Ereignis) mit einem bestimmten Zeitstempel verknüpft, der dem Sequenzer mitteilt, wann diese Note abgespielt werden soll. Die abzuspielenden Noten werden als Elemente einer CindyScript-Liste hinzugefügt. Jede Note ist selbst eine kleine Liste, die aus der ganzen Zahl oder einer Zeichenkette besteht, die die abzuspielende Note und ihre Dauer darstellt. Auch Kontrollereignisse wie der Wechsel eines Instruments oder eine Lautstärkeänderung sind Elemente dieser Melodieliste. Sie sind ebenfalls mit einem Zeitstempel verknüpft. Da alle CindyScript-Funktionen zur Melodieverarbeitung auf dieselbe Beschreibung von Melodien durch Listen von Ereignissen verweisen, erklären wir diese Melodiebeschreibungssprache zunächst.

### Beschreibung von Melodien

Melodien in CindyScript werden durch Listen von Ereignissen beschrieben. Jedes Ereignis entspricht entweder einer Note, die gespielt werden muss, einem Steuerbefehl (wie der Auswahl des gewählten Instruments) oder einem Positionierungsbefehl, der beschreibt, wo das nächste Ereignis hinzugefügt wird. Die einfachste Form, in der eine Melodie auftreten kann, ist eine Sequenz von Tönen. Das folgende Code-Stück zeigt den Aufruf einer einfachen C-Dur-Tonleiter:

    playmelody([["C",1],["D",1],["E",1],["F",1],
                ["G",1],["A",1],["H",1],["c",5]])

Alternativ könnte die gleiche Tonleiter auch durch Beschreibung der Noten mit Hilfe der entsprechenden MIDI-Ganzzahlen statt Namen ausgedrückt werden:

    playmelody([[60,1],[62,1],[64,1],[65,1],[67,1],[69,1],[71,1],[72,5]])

Die zweite Zahl in der kurzen Liste, die eine einzelne Note beschreibt, ist ihre Dauer. Die Längen der Dauern werden in Schlägen gemessen. Standardmäßig wird die Melodie mit einer Geschwindigkeit von 60 Schlägen pro Minute gespielt. Falls nötig, kann dies durch einen Modifikator des `midispeed(...)`-Befehls geändert werden.

Intern passiert ungefähr Folgendes, wenn eine Melodie gespielt wird. Wenn die Melodie startet, wird der Sequenzer auf seine Startposition gesetzt. Die erste Note wird gespielt und die Position des Sequenzers rückt um die mit der Note verbundene Dauer vor. Dann wird die nächste Note gespielt, der Sequenzer rückt um die Dauer der zweiten Note vor und so weiter. Intern wird jeder Schlag in viele Mikroschritte unterteilt, die eine präzise Positionierung jeder Note ermöglichen. Tatsächlich wird der Schlag in 240=5*4*2*2*2 Mikroschritte unterteilt. Dies ermöglicht die genaue Positionierung von Achteln, Sechzehnteln, Zweiunddreißigsteln, Triolen und Quintolen. Für alle praktischen Anwendungen sind diese Mikroschritte so fein, dass man sie einfach als Kontinuum betrachten kann. Daher kann eine Dauer einfach durch eine reelle Zahl ausgedrückt werden. Die Annäherung an die Mikroposition erfolgt automatisch. Im folgenden Code-Stück wird für jeden Ton der Tonleiter immer noch ein ganzer Schlag verwendet. Allerdings werden die Noten wiederholt, indem jeder Schlag unterteilt wird.

    playmelody([["C",1],
                ["D",1/2],["D",1/2],
                ["E",1/3],["E",1/3],["E",1/3],
                ["F",1/4],["F",1/4],["F",1/4],["F",1/4],
                ["G",1/6],["G",1/6],["G",1/6],["G",1/6],["G",1/6],["G",1/6],
                ["A",1/8],["A",1/8],["A",1/8],["A",1/8],
                ["A",1/8],["A",1/8],["A",1/8],["A",1/8],
                ["H",1],["c",5]])

Wir werden nun die verschiedenen Elemente der Melodiebeschreibungssprache beschreiben.

Töne und Akkorde: Wie wir bereits gesehen haben, können Töne sowohl als Ganzzahlen als auch als Zeichenkettennamen codiert werden. Das Spielen einer einzelnen Note hat das Format `[<key>,<duration>]`, wobei `<key>` die Note angibt (als Ganzzahl oder Zeichenkette) und `<duration>` ihre Dauer durch eine positive reelle Zahl. Die folgende Tabelle beschreibt, wie Namen den Tönen der mittleren Oktave zugeordnet werden.

C | Cis | Des | D | Dis | Es | E | F | Fis | Ges | G | Gis | As | A | Ais | B | H | c
48 | 49 | 49 | 50 | 51 | 51 | 52 | 53 | 54 | 54 | 55 | 56 | 56 | 57 | 58 | 58 | 59 | 60

Die nächst höhere Oktave entspricht:

c | cis | des | d | dis | es | e | f | fis | ges | g | gis | as | a | ais | b | h | c'
60 | 61 | 61 | 62 | 63 | 63 | 64 | 65 | 66 | 66 | 67 | 68 | 68 | 69 | 70 | 70 | 71 | 72

Töne der tieferen Oktave können durch Anhängen eines Apostrophs um eine weitere Oktave erniedrigt werden. Beispielsweise entspricht `C''` der MIDI-Note 24. Ähnlich können Töne der höheren Oktave durch Anhängen eines Apostrophs um eine Oktave erhöht werden. So entspricht `c'''` 96.

Es ist auch möglich, Akkorde statt Einzelnoten zu spielen. Dazu müssen die Tasten der Noten in einem Akkord in einer Liste gesammelt werden. Das Format eines Akkords ist `[[<key1>,<key2>,<key3>,...],<duration>]`. Das folgende Beispiel zeigt eine Melodieliste, die Akkorde zunehmender Komplexität spielt.

    playmelody([["C",1],
                [["C","E"],1],
                [["C","E","G"],1],
                [["C","E","G","c"],5] ] )

Schließlich kann man die Zahl `-1` oder die Zeichenketten `"P"` oder `"p"` als Pause verwenden.

Dynamik und Phrasierung: Es gibt auch eine Reihe von Melodieereignissen, die verwendet werden können, um die Dynamik oder Phrasierung der folgenden Noten zu beeinflussen. Sie entsprechen entweder einer einzelnen Zeichenkette oder einer Liste mit einem Schlüssel/Wert-Paar. Die folgenden Anweisungen sind derzeit implementiert:

- `"ppp"`: piano-pianissimo
- `"pp"`: pianissimo
- `"p"`: piano
- `"mp"`: mezzo-piano
- `"mf"`: mezzo-forte
- `"f"`: forte
- `"ff"`: fortissimo
- `"fff"`: forte-fortissimo
- `">"`: Akzent auf der nächsten Note
- `"staccato"` oder `"st"`: Spielen Sie die folgenden Noten sehr kurz (Staccato-Stil)
- `"legato"` oder `"le"`: Spielen Sie die folgenden Noten sehr lange (Legato-Stil)
- `["velocity",<real>]`: Lautstärke einstellen. `<real>` liegt zwischen 0,0 und 1,0.

Das folgende Code-Stück spielt eine Tonleiter, die im pianissimo Staccato beginnt und mit lautem Legato endet:

    playmelody([["st"],["pp"],["C",1],["D",1],["E",1],["F",1],["le"],
                ["f"],["G",1],["A",1],["H",1],["c",5]])

Positionierung: Der Sequenzer hat intern einen Zeiger, der die Position angibt, an der eine Note hinzugefügt wird. Normalerweise rückt der Zeiger um die Dauer einer Note vor, wenn eine Note hinzugefügt wird. Es gibt jedoch auch Anweisungen, die es ermöglichen, den Zeiger direkt zu positionieren und dadurch den Zeitstempel zu beeinflussen, bei dem die nächste Note hinzugefügt wird. Wenn eine Spur hinzugefügt wird, wird der Zeiger auf Position 0 gesetzt. Durch zwei Anweisungen `"goto"` und `"gorel"` kann der Zeiger zu einer absoluten Position bewegt oder relativ verschoben werden. Die genaue Syntax ist wie folgt:

- `["goto",<real>]`: Setzen Sie den Zeiger auf die Position `<real>`, gemessen vom Anfang der Melodie. Negative absolute Positionen sind nicht erlaubt.
- `["gt",<real>]`: dasselbe wie `"goto"`.
- `["gorel",<real>]`: Setzen Sie den Zeiger auf die Position, die relativ durch einen Versatz von `<real>` zur aktuellen Position berechnet wird. Das `<real>` kann negativ sein. Allerdings sind Versätze, die zu negativen absoluten Positionen führen, nicht erlaubt.
- `["gr",<real>]`: dasselbe wie `"gorel"`.

Das folgende Code-Stück fügt eine (leiser) zweite Stimme hinzu, indem die `goto(...)`-Anweisung verwendet wird.

    playmelody([
       ["c",1],["e",1],["g",1],["a",1],["c'",4],["goto",0],["vel",0.3],
       ["g",1],["a",1],["c'",1],["e'",1],["a'",4],
    ],speed->100)

Es gibt auch fortgeschrittenere Möglichkeiten, das Timing von hinzugefügten Noten zu steuern. Sie sind näher an der üblichen Musiknotation. Es gibt vier Anweisungen:

- `["||:"]`: Anfang eines da capo.
- `[":||"]`: Ende eines da capo.
- `["1."]`: Erste Klammer.
- `["2."]`: Zweite Klammer.

Mit diesen Befehlen ist es leicht möglich, Notenblätter mit Wiederholungen direkt zu übertragen. Die folgende Zeile aus „Oh, Susanna"

kann auf folgende Weise als Melodie in CindyScript codiert werden:

    playmelody([
       ["c",.5],["d",.5],
       ["||:"],["e",1],["g",1],["g",1.5],["a",.5],
               ["g",1],["e",1],["c",1.5],["d",.5],
       ["1."],["e",1],["e",1],["d",1],["c",1],["d",3],
               ["c",.5],["d",.5],[":||"],
       ["2."],["e",1],["e",1],["d",1],["d",1],["c",4]
    ],speed->200)

Instrumentensteuerung:

Schließlich gibt es noch einige Anweisungen, um den Klang und die Auswahl eines Instruments innerhalb einer Melodie zu beeinflussen. Dadurch ist es möglich, das Instrument zu wechseln, während die Melodie abgespielt wird, indem Steuerbefehle in der Melodieliste verwendet werden. Die Befehle sind wie folgt:

- `["channel",<int>]`: Wechselt den Kanal (0...15), der derzeit für die Melodie verwendet wird.
- `["ch",<int>]`: dasselbe wie `channel`.
- `["instrument",<int>]`: Wechselt das Instrument (1...128), das dem Kanal zugeordnet ist.
- `["inst",<int>]`: dasselbe wie `instrument`.
- `[<int>,<int>,<int>,<int>]`: Diese Anweisung (bestehend aus einfach vier Ganzzahlen) gibt Zugriff auf andere MIDI-Steuerungen von Instrumenten (konsultieren Sie ein MIDI-Handbuch für Details). Die erste Zahl codiert den Controller, die zweite den Kanal, auf den sie angewendet wird, die letzten zwei sind Datenbytes.

Wenn eine Spur neu gestartet wird, werden die Instrumente auf ihre ursprünglichen Werte zurückgesetzt.

Die MIDI-Steuerungssprache, die wir oben beschrieben haben, bildet nun die Grundlage aller anderen MIDI-Funktionen.

#### Eine Melodie spielen: `playmelody(<list>)`

Beschreibung: Wir haben `playmelody(...)` bereits in allen bisherigen Beispielen der Melodiesprache verwendet. Es ist der direkteste Weg, eine Melodie zu spielen, die sofort startet. Es wird angenommen, dass die Liste eine in der Melodiesprache beschriebene Melodie ist. Das Aufrufen von `playmelody(...)` fügt die Liste dem Sequenzer hinzu und spielt sie sofort ab. Es ist wichtig zu wissen, dass wenn die Melodie aufgerufen wird, alle anderen Spuren aus dem Sequenzer gelöscht werden.

Modifizierer: Zusätzlich hat die Anweisung Modifizierer zur globalen Einstellung von Kanal, Instrument, Geschwindigkeit usw.

Modifizierer | Parameter | Effekt
`channel` | `0..15` | Auswahl des abzuspielenden Kanals
`instrument` | `1 ... 123` | Auswahl eines bestimmten Instruments
`speed` | `<real>` | Geschwindigkeit in Schlägen pro Minute
`loop` | `0,1,2,3,4 ...` | Wiederholung der Melodie
`start` | `<real>` | Startposition (in Schlägen)

Der Modifizierer loop teilt dem Sequenzer mit, nach dem Ende der Melodie zu spulen und neu zu starten. Die Zahl in diesem Modifizierer gibt an, wie oft ein Spulen durchgeführt wird. So hat `loop->3` den Effekt, dass die Melodie vier mal abgespielt wird. Das Setzen von `loop->-1` wird als Endlosschleife interpretiert. Wenn dies aufgerufen wurde, muss die Melodie durch das Hinzufügen einer neuen (vielleicht leeren) Melodie gestoppt werden: `playmelody([])`. Alternativ kann der `midistop()`-Befehl verwendet werden.

#### Eine Spur zum Sequenzer hinzufügen: `midiaddtrack(<list>)`

Beschreibung: Im Gegensatz zu `playmelody(...)` fügt diese Anweisung eine Melodie zum Sequenzer hinzu, spielt sie aber nicht sofort ab. Dadurch ist es möglich, erste eine komplexere Komposition zu erstellen, indem mehrere Stimmen hinzugefügt werden und diese später zu spielen, wenn die Komposition vollständig ist. Das Starten des Sequenzers erfolgt über den `midistart()`-Befehl. Wenn eine Spur hinzugefügt wird, während der Sequenzer bereits läuft, wird der Sequenzer nicht neu gestartet. Die Spur wird stillschweigend durch die neue Spur ersetzt. Dies macht es möglich, Szenarien zu erstellen, in denen sich die abgespielten Melodien je nach bestimmten algorithmischen Prozessen ändern. Darüber hinaus hat der Befehl mehrere Modifizierer, die es ermöglichen, das Timing der hinzugefügten Spur relativ zum Timing des Sequenzers zu ändern. Dadurch können Melodien gestreckt, verkleinert oder verschoben werden. Details werden unten erläutert.

Modifizierer: Die Funktion unterstützt die folgenden Modifizierer:

Modifizierer | Parameter | Effekt
`channel` | `0..15` | Auswahl des abzuspielenden Kanals
`instrument` | `1 ... 123` | Auswahl eines bestimmten Instruments
`speed` | `<real>` | Geschwindigkeit in Schlägen pro Minute
`track` | `0..10` | Auswahl der Spur des Sequenzers
`start` | `<real>` | Startposition (in Schlägen)
`mode` | `"add", "replace", "append"` | Der Modus, in dem die Spur hinzugefügt wird
`stretch` | `<real>` | Ein Faktor, der die Schlaglänge im hinzugefügten Melodieteil erweitert (relativ zum Sequenzer)
`offset` | `<real>` | Ein Versatz, der den hinzugefügten Melodieteil relativ zum Sequenzer verschiebt.
`repeat` | `<real>` | Wie oft die Melodie hinzugefügt wird

Ein paar Modifizierer benötigen etwas weitere Erklärung. Cinderella erlaubt insgesamt 16 Spuren mit den Nummern 0 bis 15. Jede Spur ähnelt einer einzelnen unabhängigen Stimme. Die Spur, zu der eine Melodie hinzugefügt wird, kann durch den `track`-Modifizierer ausgewählt werden.

Wenn Sie eine Spur hinzufügen, gibt der `mode`-Modifizierer an, ob die aktuelle Spur durch die neue Spur ersetzt wird, ob sie an die bereits vorhandene Spur angehängt wird oder zu der vorhandenen Spur hinzugefügt wird (mit Überlagerung von Zeitstempeln).

Das Timing der neuen Melodie kann relativ zur bereits vorhandenen Spur im Sequenzer angepasst werden. Durch den `stretch`-Modifizierer kann eine Zahl angegeben werden, die als Faktor für alle Schlagangaben in der Melodie dient. Das Setzen von `stretch->0.5` spielt die Spur mit ihrer doppelten Originalgeschwindigkeit ab. Ähnlich kann `offset` die Position angeben, an der die neue Spur hinzugefügt wird. Das Setzen von `offset->8` zeigt an, dass die Spur nach den ersten acht Schlägen des Sequenzers startet. Schließlich gibt `repeat` an, wie oft die Spur nacheinander hinzugefügt wird. Die Verwendung von `stretch`, `offset` und `repeat` kann sehr hilfreich sein, wenn ein Schlagzeugmuster zu einer vorhandenen Melodie hinzugefügt wird.

#### Den Sequenzer starten: `midistart()`

Beschreibung: Dieser Befehl startet den MIDI-Sequenzer. Spuren müssen zuvor durch den `midiaddtrack(...)`-Befehl hinzugefügt worden sein.

Modifizierer: Modifizierer ähneln denen des `playmelody(...)`-Befehls. Die folgenden Modifizierer sind erlaubt.

Modifizierer | Parameter | Effekt
`speed` | `<real>` | Geschwindigkeit in Schlägen pro Minute
`loop` | `0,1,2,3,4 ...` | Wiederholung der Melodie
`start` | `<real>` | Startposition (in Schlägen)

#### Den Sequenzer stoppen: `midistop()`

Beschreibung: Dieser Befehl stoppt den MIDI-Sequenzer sofort.

#### Die Geschwindigkeit des Sequenzers einstellen: `midispeed(<real>)`

Beschreibung: Mit diesem Befehl kann die Abspielgeschwindigkeit des Sequenzers geändert werden. Die Geschwindigkeit wird durch eine reelle Zahl angegeben, die die Schläge pro Minute darstellt. Standardmäßig ist die Geschwindigkeit auf 60 eingestellt, was einem Schlag pro Sekunde entspricht (dies ist für die meisten Musikstücke viel zu langsam). Der Geschwindigkeitswert kann auch geändert werden, wenn der Sequenzer bereits läuft. Dadurch ist es beispielsweise möglich, die Geschwindigkeit mit der Position eines Punktes zu verbinden, der die Geschwindigkeit steuert.

#### Die Geschwindigkeit des Sequenzers abfragen: `midispeed()`

Beschreibung: Diese Anweisung gibt die aktuelle Geschwindigkeit des Sequenzers zurück.

#### Die Position des Sequenzers einstellen: `midiposition(<real>)`

Beschreibung: Mit diesem Befehl kann die Position des Sequenzers auf eine bestimmte Position gesetzt werden. Dadurch kann ein CindyScript-Programm beispielsweise die Eingangsposition einer abgespielten Komposition explizit steuern.

#### Die Position des Sequenzers abfragen: `midiposition()`

Beschreibung: Dieser Befehl gibt die aktuelle Position des Sequenzers zurück. Wenn der Sequenzer läuft, ändert sich dieser Wert kontinuierlich.

## Klangcharakteristiken

Mit den folgenden CindyScript-Anweisungen können Sie die Standardinstrumente auswählen, sie Kanälen zuordnen und deren Klangcharakteristiken beeinflussen.

#### Instrument auswählen: `instrument(<int>)`

Beschreibung: Mit diesem Befehl können Sie ein Instrument einem Kanal zuordnen. Wenn kein Kanal angegeben ist, wird der Standardkanal verwendet. Jedes Instrument wird durch eine ganze Zahl im Bereich 1...128 identifiziert. Die Korrelation zwischen Instrumenten und den ganzen Zahlen wird im nächsten Abschnitt zu `instrumentnames()` erläutert. Wenn ein expliziter Kanal durch einen Modifizierer angegeben wird, wird das Instrument des entsprechenden Kanals geändert.

Modifizierer: Diese Funktion unterstützt verschiedene Modifizierer, die die Klangcharakteristiken des Instruments beeinflussen.

Modifizierer | Parameter | Auswirkung
`velocity` | `0.0 ... 1.0` | die Lautstärke eines Tons (wie schnell eine Klaviertaste gedrückt wird)
`duration` | `<real>` | Dauer des Tons in Sekunden
`bend` | `-2.0 ... 2.0` | Biegen eines Tons um bis zu einer ganzen Note nach unten oder oben
`channel` | `0..15` | Auswahl des zu spielenden Kanals
`reverb` | `0.0 ... 1.0` | Hall-Effekt
`balance` | `-1.0 ... 1.0` | Links/Rechts-Panorama des Tons

Hier beeinflussen die Modifizierer `velocity` und `duration` die Standard-Geschwindigkeit (Lautstärke) und Dauer, mit der ein Ton gespielt wird (zum Beispiel durch `playtone(...)`).

Beispiel: Das folgende Codesegment spielt einen sanften c auf einem Glockenspiel, dann einen lauten und kurzen auf einer Trompete und schließlich einen langen (mit mittlerer Lautstärke) auf einem Klavier ab:

    instrument(10,velocity->0.2);
    playtone(96);
    wait(1000);
    instrument(57,duration->0.1,velocity->1);
    playtone(60);
    wait(1000);
    instrument(1,duration->2,velocity->.5);
    playtone(60);

#### Verfügbare Instrumente abrufen: `instrumentnames()`

Beschreibung: Diese Anweisung gibt eine Liste aller auf Ihrem Computer verfügbaren Instrumentnamen zurück. In der General MIDI-Datenbank (die wahrscheinlich auf Ihrem Computer vorinstalliert ist) haben Sie die folgenden Instrumente zur Verfügung.

Klavier: | Bass: | Blattinstrumente: | Synth-Effekte:
1 Akustischer Konzertflügel | 33 Akustischer Bass | 65 Sopransaxophon | 97 FX 1 (Regen)
2 Helles akustisches Klavier | 34 Elektrischer Bass (Finger) | 66 Altsaxophon | 98 FX 2 (Filmmusik)
3 Elektrischer Konzertflügel | 35 Elektrischer Bass (Pick) | 67 Tenor-Saxophon | 99 FX 3 (Kristall)
4 Honky-Tonk-Klavier | 36 Bundloser Bass | 68 Bariton-Saxophon | 100 FX 4 (Atmosphäre)
5 Elektrisches Klavier 1 | 37 Slap Bass 1 | 69 Oboe | 101 FX 5 (Helligkeit)
6 Elektrisches Klavier 2 | 38 Slap Bass 2 | 70 Englischhorn | 102 FX 6 (Goblins)
7 Cembalo | 39 Synth Bass 1 | 71 Fagott | 103 FX 7 (Echos)
8 Clavi | 40 Synth Bass 2 | 72 Klarinette | 104 FX 8 (Science-Fiction)
Chromatische Schlagzeuge: | Streicher: | Blasinstrumente: | Ethnische Instrumente:
9 Celesta | 41 Violine | 73 Piccolo | 105 Sitar
10 Glockenspiel | 42 Bratsche | 74 Flöte | 106 Banjo
11 Spieluhr | 43 Cello | 75 Blockflöte | 107 Shamisen
12 Vibraphon | 44 Kontrabass | 76 Panflöte | 108 Koto
13 Marimba | 45 Tremolo-Streicher | 77 Geblasene Flasche | 109 Kalimba
14 Xylophon | 46 Pizzicato-Streicher | 78 Shakuhachi | 110 Dudelsack
15 Röhrenglockenspiel | 47 Orchester-Harfe | 79 Pfeife | 111 Fidel
16 Dulzimer | 48 Pauken | 80 Ocarina | 112 Shanai
Orgel: | Ensemble: | Synth-Bleiinstrumente: | Perkussiv:
17 Orgel | 49 String Ensemble 1 | 81 Lead 1 (Quadrat) | 113 Klingel-Glocke
18 Perkussive Orgel | 50 String Ensemble 2 | 82 Lead 2 (Sägezahn) | 114 Agogo-Glocken
19 Rock-Orgel | 51 Synth Strings 1 | 83 Lead 3 (Calliope) | 115 Stahltrommeln
20 Kirchenorgel | 52 Synth Strings 2 | 84 Lead 4 (Chiff) | 116 Holzblock
21 Rohrorgel | 53 Stimme Aahs | 85 Lead 5 (Charang) | 117 Taiko-Trommel
22 Akkordeon | 54 Stimme Oohs | 86 Lead 6 (Stimme) | 118 Melodischer Tom
23 Mundharmonika | 55 Synth-Stimme | 87 Lead 7 (Quinten) | 119 Synth-Trommel
24 Tango-Akkordeon | 56 Orchester-Hit | 88 Lead 8 (Bass + Lead) | 120 Umgekehrte Becken
Gitarre: | Blech: | Synth Pad: | Soundeffekte:
25 Akustische Gitarre (Nylon) | 57 Trompete | 89 Pad 1 (New Age) | 121 Gitarrensaitenlärm
26 Akustische Gitarre (Stahl) | 58 Posaune | 90 Pad 2 (Warm) | 122 Atemgeräusch
27 Elektrogitarre (Jazz) | 59 Tuba | 91 Pad 3 (Polysynth) | 123 Meeresrauschen
28 Elektrogitarre (Clean) | 60 Gedämpfte Trompete | 92 Pad 4 (Chor) | 124 Vogelzwitschern
29 Elektrogitarre (gedämpft) | 61 Französisches Horn | 93 Pad 5 (Bogenspiel) | 125 Telefonklingeln
30 Übersteuerte Gitarre | 62 Blechbläser-Sektion | 94 Pad 6 (Metallisch) | 126 Hubschrauber
31 Verzerrgitarre | 63 Synth Brass 1 | 95 Pad 7 (Heiligenschein) | 127 Applaus
32 Gitarren-Harmoniken | 64 Synth Brass 2 | 96 Pad 8 (Sweep) | 128 Schuss

#### Kanal wählen: `midichannel(<int>)`

Beschreibung: Dieser Befehl wählt den aktuellen Standardkanal aus, der für die Wiedergabe von Tönen mit `playmelody(...)` oder `playtone(...)` verwendet wird. Über Modifizierer ist es möglich, die Instrumente und Toncharakteristiken des ausgewählten Kanals zu ändern.

Modifizierer: Die Modifizierer hier sind sehr ähnlich den `instrument`-Modifizierern.

Modifizierer | Parameter | Auswirkung
`velocity` | `0.0 ... 1.0` | die Lautstärke eines Tons (wie schnell eine Klaviertaste gedrückt wird)
`duration` | `<real>` | Dauer des Tons in Sekunden
`bend` | `-2.0 ... 2.0` | Biegen eines Tons um bis zu einer ganzen Note nach unten oder oben
`instrument` | `0..15` | Auswahl des zu spielenden Instruments
`reverb` | `0.0 ... 1.0` | Hall-Effekt
`balance` | `-1.0 ... 1.0` | Links/Rechts-Panorama des Tons

#### Einstellen der Lautstärke eines Kanals: `midivolume(<real>)`

Beschreibung: Durch diese Anweisung wird die Gesamtlautstärke des MIDI-Klangs eines Kanals gesteuert. Der Parameter ist eine reelle Zahl im Bereich 0,0...1,0. Normalerweise wirkt sich diese Anweisung auf die Lautstärke des Standardkanals aus. Mit Modifizierern kann man jedoch den betroffenen Kanal auswählen.

Modifizierer:

Modifizierer | Parameter | Auswirkung
`channel` | `0 ..15` oder `"all"` | der ausgewählte Kanal.

Die Kanalnummer wird entweder explizit angegeben, oder durch die Verwendung von `"all"` können alle Kanäle beeinflusst werden.

#### Einstellen eines Controllers eines Kanals: `midicontrol(<int>,<int>)`

Beschreibung: Damit kann ein spezifischer MIDI-Controller eines Kanals eingestellt werden. Der erste Parameter gibt die Nummer des Controllers an (0..127), der zweite Parameter (0..127) gibt die Daten an, die dem Controller gesetzt werden. Controller können Charakteristiken wie Hall, Balance und andere instrumentspezifische Charakteristiken beeinflussen. Die Datenwerte werden im Bereich 0..127 genommen. Weitere Details finden Sie in einem Handbuch zur General MIDI.

Modifizierer: Die Modifizierer-Verwendung ist ähnlich wie bei `midivolume`.

## Drei kleine Stücke

In diesem abschließenden Abschnitt über MIDI möchten wir die Verwendung von CindyScript MIDI in drei kleinen, aber fortgeschrittenen Beispielen demonstrieren. Der Benutzer wird eingeladen, diese Beispiele als Ausgangspunkt für weitere eigene Experimente zu verwenden.

### Ein Keyboard-Piano

In diesem Beispiel möchten wir ein Piano programmieren, das durch das Drücken der Tasten der Computertastatur gespielt werden kann. Dazu muss man einfach den folgenden Code in das Timer Tick-Event des CindyScript-Code-Fensters einfügen, die Play-Schaltfläche drücken, die in der Cinderella-Ansicht angezeigt wird, und spielen.

    pairs=[[65,60],[83,62],[68,64],[70,65],[71,67],[72,69],[74,71],
           [75,72],[76,74],[59,76],[222,77],[92,79],[87,61],[69,63],
           [84,66],[90,68],[85,70],[79,73],[80,75],[93,78]];

    l=keydownlist();
    forall(pairs,p,
      if(contains(l,p_1)&!contains(ol,p_1),
          playtone(p_2,duration->-1,velocity->0.5));
      if(contains(ol,p_1)&!contains(l,p_1),stoptone(p_2));
    );
    ol=l;

Der Code nutzt den CindyScript-Operator `keydownlist()`. Dieser Operator gibt eine Liste aller (computerinternen) Tastencodes der in diesem Moment gedrückten Tasten. Die Liste `pairs` ordnet die Tastencodes den zu spielenden Noten zu. Die `forall`-Schleife prüft für jede möglicherweise betätigte oder losgelassene Taste und schaltet die mit dieser Taste verbundene Note speziell ein oder aus, indem `playtone` und `stoptone` verwendet werden. Auf einem modernen Computer ist dieser Code sehr latenzfrei und kann als echtes Instrument verwendet werden.

### Ping Pong mit Sound

Unser nächstes Beispiel ist wirklich sehr klein und verwendet nur eine `playtone(...)`-Anweisung an der richtigen Stelle. Wir möchten ein Ping-Pong-Spiel mit Soundeffekten erstellen. Mit Hilfe der Physik-Simulationsmöglichkeiten von CindyLab ist es sehr einfach, einen physikalisch angemessenen interaktiven Ping-Pong-Tisch zu konstruieren. Die Grenze des Tisches wird durch physikalische Bouncer erzeugt. Im Inspector kann jeder dieser Bouncer mit einem Skript verknüpft werden, das in dem Moment ausgeführt wird, wenn eine Masse auf den Bouncer trifft. Dort müssen wir einfach eine `playtone`-Anweisung platzieren, die einen "Click"-Sound erzeugt. Das war's.

### Let it Groove!

Abschließend exemplifiziert unser letztes Beispiel die Genauigkeit des Sequencer-Timings. Es spielt einfach den Anfang des berühmten Charlie Parker Jazz-Stücks Ornithology (Charlies Spitzname war Bird und dieser Titel bezieht sich auf seinen Spitzname). Ein typisches Merkmal des Jazz ist sein grooviges Timing, das Swing-Gefühl. Dies kommt von einer bestimmten sinnvollen Verschiebung der Noten in Bezug auf den Grundbeat. Im folgenden Beispielcode wird die Variable `g` als „Swing-Parameter" verwendet. Sie verschiebt den Anfang jeder zweiten Note in Bezug auf den Grundbeat. Es ist lehrreich, `g` mit einem verschiebbaren Punkt im Bereich von 0,0 bis 1,0 zu verknüpfen. Auf diese Weise kann man die Menge an Swing-Gefühl, die das Stück verwendet, sehr leicht anpassen (in einem Bereich zwischen 0,5 und 0,7 klingt es ziemlich angemessen).

    g=.6;
    mel=[[62,2-g],[67,2+g],[69,2-g],[71,2+g],[72,2-g],[74,2+g],
         [71,2-g],[72,2+g],[74,2-g],[71,2+g],[67,3],[-1,9],
         [62,2-g],[67,2+g],[69,2-g],[70,2+g],[72,2-g],[74,2+g],
         [76,4],[77,4],[67,2-g],[69,2+g],[70,8],[74,2-g],
         [72,2+g],[69,4],[65,2-g],[70,2+g],[68,2-g],[69,2+g],
         [65,13],[-1,3]
    ];

    drum=44;
    beat=[[-1,2-g]];
    apply(1..11,beat=beat++[[-1,4],[drum,4]]);
    beat=beat++[[-1,4],[drum,4-2+g]];
    midiaddtrack(mel ,channel->2,track->2);
    midiaddtrack(beat,channel->9,track->1,velocity->.5);
    midistart(speed->700);

Diese Seite wurde automatisch mit KI (Claude) übersetzt und wartet noch auf Überprüfung. → Alle KI-übersetzten Seiten