Dann wird
im <body> der Seite
ein Container mit einer eindeutigen id mithilfe von DIV-Tags angelegt,
in dem alles angezeigt werden soll. Dies geschieht via
<DIV id="p5container"></DIV>
über
Style-Eigenschaften kann man diesen noch weiter im Aussehen verändern,
z.B.
Darunter
wird mit Hilfe von <select>...</select>
eine Auswahl mit der id "auswahl"
angelegt, in der man zwischen verschiedenen Wellenformen für die
Klangsynthese wählen kann. Über den Befehl onchange
kann die Funktion wechselwelle();
aufgerufen werden (s.u.), der mit Hilfe von this.value
die jeweils ausgewählte Wellenform übergeben wird:
Bevor im
<script>...</script>-Bereich
mit dem eigentlichen Sript angefangen wird, werden zwei Arrays (Listen)
mit MIDI-Notenwerten und den dazugehörenden Tonhöhennamen definiert:
var midinoten = [48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
67, 68, 69, 70, 71, 72]; // Liste mit den
MIDI-Notenwerten
var tonhoehen = ['C3','C#3', 'D3', 'D#3','E3','F3','F#3', 'G3', 'G#3',
'A3', 'Bb3', 'B3','C4','C#4', 'D4', 'D#4','E4','F4','F#4', 'G4', 'G#4',
'B4', 'Bb4', 'B4','C5']; // Liste mit den
dazugehörenden Tonhöhennamen
Dann werden
in der Funktion setup() die
Grundkomponenten festgelegt:
function setup(){
var container = createCanvas(800,400); //
Canvas erstellen
container.parent('p5container'); // an
DIV-Container anhängen
container.mousePressed(playSound); // rufe
bei einer gedrückten Maus die Funktion
// playSound() auf (s.u.)
container.mouseReleased(stopSound); //
rufe bei einer losgelassenen Maus die Funktion
// stopSound() auf (s.u.)
osc = new p5.Oscillator('sine'); // Erstelle
einen Oszillator mit einer Sinus-Welle als Wellenform und weise ihn der
Variablen osc zu.
env = new p5.Envelope(); // erstelle eine
Hüllkurve für den Pegel des Oszillators und weise sie der Variablen
env zu.
env.ramp(osc, 0, 0.5, 0); // gib der Hüllkurve
env eine Rampenfunktion, die sich auf den Oszillator bezieht und gib dieser
eine auf- (0 bis 0,5) und eine absteigende Kurve (0,5 bis 0).
osc.freq(440); // stelle die Frequenz des
Oszillators auf 440 Hz ein
osc.amp(0) // stelle den Pegel des Oszillators
auf 0 ein
fft = new p5.FFT();//
Fouriertransformation des Signals ermöglichen
}
Daraufhin
wird in der Funktion draw()
beschrieben, was im Canvas dargestellt werden soll:
function draw(){
background(255, 255, 255); //zeichne weißen
Hintergrund
cursor(HAND); // zeige den Cursor als Hand
//
zunächst werden Trennlinien für die einzelnen Tonhöhenbereiche
gezeichnet:
faktor=round(width/midinoten.length);
// Über die Weite des Canvas geteilt
durch die
// Anzahl der Töne im Array midinoten wird der Abstand der Trennlinien
ermittelt und der Variblen
// faktor zugeordnet.
for (var i = 0; i < midinoten.length; i++){ //
hole in einer Schleife in der Länge
// des Arrays midinoten jeden einzelnen Wert i aus dem Array
line(i*faktor, 0, i*faktor, height); //
zeichne für jeden Wert eine Linie von oben
// nach unten in einem Abstand von i multipliziert mit dem vorher ermittelten
Faktor für den
// Abstand
stroke(225,225,225); // gib der Linie die
Strichfarbe hellgrau.
}
//
dann wird die Tonhöhe aus der Mausposition über den Trennlinien
ermittelt:
ton = round(map(mouseX,
width, 0, midinoten.length, 0)); // skaliere
den Wert
// der X-Koordinaten der Maus, der zwischen der Weite des Canvas und 0
liegt, so, dass er zwischen
// der Anzahl der verfügbaren MIDI-Notenwerte und 0 liegt, runde
diesen zu einer ganzen Zahl und
// weise ihn der Variablen ton zu.
note = round(midiToFreq(midinoten[ton])); //
nimm die Variable ton als index
// (= Positionsanzeiger) für das Array midinoten und ermittle via
midiToFreq() die Frequenz des
// gewählten Tons und gib den auf ganze Zahlen gerundeten Wert der
Frequenz in die Variable note.
osc.freq(note); // stelle über die
Variable note die Frequenz für den Oszillator ein.
notenname = tonhoehen[ton]; // nimm die
Variable ton als index (= Positionsanzeiger) für
// das Array tonhoehen und gebe die darüber gefundene Tonhöhenbezeichnung
in die Variable
// notenname.
dynamik = map(mouseY, height, 0, 0, 1); //
skaliere den Wert der Y-Koordinaten
der
// Maus, der zwischen der Höhe des Canvas und 0 liegt, so, dass er
zwischen 0 und 1 liegt und weise
// ihn der Variablen dynamik zu.
osc.amp(dynamik); // stelle die Amplitude
(amp) des Oszillators mit der Variablen dynamik
// ein.
fill(188, 48, 47, 255); //
Dunkelrot als Füllfarbe
text('Tonhöhe: ' + notenname + ' ('+note+' Hz)', 20, 20); //
gebe die Tonhöhe
// mit Notenname und Frequenz aus.
text('Dynamik: ' + dynamik, 20, 40); //
gebe den Pegel aus.
//
Schließlich wird der jeweilige Pegel mit der Größe der
Kreisfläche ausgegeben
var waveform = fft.waveform();
// hole aus dem Klang alle Pegelwerte und
schreibe sie
// ins Array waveform
for (var i = 0; i < waveform.length; i++){ //
hole in einer Schleife in der Länge
// des Arrays waveform jeden einzelnen Wert i aus dem Array
var y = map( waveform[i], -1, 1, 0, height); //
skaliere jeden Wert aus dem
// Array waveform, der zwischen -1 und 1 liegt, so, dass er zwischen 0
und der Höhe des Canvas
// dargestellt wird, und weise ihn dem Wert y zu (Durchmesser des Kreises)
noStroke();
// keine Strichfarbe = keinen Rand für
den Kreis
fill(188, 48, 47); // Dunkelrot als
Füllfarbe
ellipse(mouseX,
mouseY, y-190, y-190);// Zeichne einen
Kreis an der Mausposition
// (x,y) und lasse seinen Durchmesser vom ermittelten Pegel (y) bestimmen.
}
}
Schließlich
wird mit der Funktion playSound()
und stopSound()
beschrieben, was passieren soll, wenn die Maus auf dem Canvas gedrückt
oder losgelassen wird:
function playSound()
{
osc.start(); // Starte den Oszillator
}
function stopSound() {
osc.stop(); // Stoppe den Oszillator
}
Mit den Audio-Bausteinen
von P5.sound lässt sich ein kompletter
Synthesizer auf Javascript-Basis erstellen.
Insgesamt
sieht das Script dann folgendermaßen aus:
function setup(){
var container = createCanvas(800,400);
container.parent('p5container');
container.mousePressed(playSound);
container.mouseReleased(stopSound);
osc = new p5.Oscillator('sine');
env = new p5.Envelope();
env.ramp(osc, 0, 0.5, 0);
osc.freq(440);
osc.amp(0)
fft = new p5.FFT();
}
function wechselwelle(id){
osc.setType(id);
}
function draw(){
background(255, 255, 255);
cursor(HAND);
faktor=round(width/midinoten.length);
for (var i = 0; i < midinoten.length; i++){
line(i*faktor, 0, i*faktor, height);
stroke(225,225,225);
}