3-dimensionale Soundvisualisierung in p5.js
3-dimensionale Animation – durch Soundeingabe beeinflussbar
Ziel der Übung
Dieses Tutorial zeigt, wie eine animierte, dreidimensionale Netzstruktur erzeugt wird. Optional kann dabei ein automischer Farbwechsel ergänzt werden. Im weiteren Verlauf wird die Form durch eine eigene Soundeingabe beeinflussbar.
Setup()-Funktion
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
angleMode(DEGREES)
//Aussehen
background(40)
noFill()
strokeWeight(1.5)
stroke(255)
}
In der setup()
-Funktion wird ein responsives Canvas erstellt. Durch windowWidth
und windowHeight
passt sich die Zeichenfläche automatisch der Fenstergröße an. Der Modus (angleMode
) wird auf Grad (DEGRESS
) gestellt und gibt damit an, wie der Winkel interpretiert wird.
Der Hintergrund wird durch background(40)
in ein sehr dunkles Grau eingefärbt. Für das Aussehen der Linien wird durch noFill()
und strokeWeight(1.5)
definiert, dass diese keine Füllung und eine Strichstärke von 1,5 aufweisen.
Draw()-Funktion
function draw() {
//Perspektive der Scheibe
rotateX(60)
for(var i=0; i<50; i++){
//Dreidimensionalität
beginShape()
for(var j=0; j<360; j+=60){
var rad = i * 7
var x = rad * sin(j)
var y = rad * cos(j)
var z = sin(i* 5) * 50
vertex(x,y,z)
}
endShape(CLOSE)
//Drehung
rotate(frameCount/20)
}
}
Als nächstes wird die draw()
-Funktion erstellt, die sobald das Programm gestartet wird, wiederholt abläuft.
Das Tutorial teilt sich in zwei Bereiche auf, die Generierung der Animation und die anschließende Soundeingabe.
Im ersten Schritt wird die Animation programmiert.
Begonnen wird mit einer for-Schleife mit der Variable i, die verantwortlich für die Anzahl (50) der Sechsecke ist. Die zweite for-Schleife, die sich innerhalb der ersten Schleife befindet, setzt die Ankerpunkte jedes einzelnen Sechseckes und zeichnet diese. Die 360 ist dafür da, damit die Form geschlossen ist, die 60 bestimmt die Form. Optional kann durch den Wert 10 anstelle von 60 die Form eines Kreises erzeugt werden.
In der Variable rad
wird das jeweilige Sechseck (i) mit dem gleichen Faktor multipliziert. Dadurch werden die Sechsecke, die hochgezählt werden, proportional größer.
Dabei definieren x, y und z die Ankerpunkte des jeweiligen Sechseckes.
Mit vertex(x, y, z)
werden die Sechsecke gezeichnet.
Durch das rotateX(60)
wird die Form an der X-Achse rotiert, wodurch eine Dreidimensionalität erzeugt wird.
Das rotate(frameCount/20)
ist dazu da, dass sich die Form dreht, damit interessante Muster entstehen.
Durch die interne Variable frameCount
werden die Sechsecke kontinuierlich und dynamisch animiert.
Automatischer Farbwechsel
//in der äußere Schleife i hinzufügen
var r = map(sin(frameCount/ 2), -1, 1, 100, 200)
var g = map(i, 0, 50, 100, 200)
var b = map(cos(frameCount), -1, 1, 200, 100)
stroke(r, g, b)
Um die bisher weißen Linien einzufärben werden drei Variablen (r, g, b)
erstellt. Mit diesen werden die Farbwerte festgelegt.
Im Folgenden wird das Codefragment: map(value, start1, stop1, start2, stop2)
näher erklärt.
Durch den Value frameCount
in map
wird erreicht, dass der Farbwechsel kontinuierlich abläuft, solange das Programm läuft. Damit die Farben sich ändern, werden die untere und obere Grenze des aktuellen Wertebereichs und des Zielbereichs festgelegt.
Mit stroke (r, g, b)
werden den Linien die Farbwerte zugewiesen.
Soundeingabe
//über die Setup()-Funktion schreiben
var mic
var easing = 0.05
var vol = 0
Zunächst werden Variablen (var) deklariert.
Die Variable mic
wird für die Audioeingabe benötigt.
Den Variablen easing
und vol
werden bei der Initialisierung Grundwerte zugewiesen, damit die Animation später flüssiger abläuft.
//in die Setup()-Funktion ergänzen
//Mikrofon starten und aufnehmen
mic = new p5.AudioIn()
mic.start()
Um eine Audioeingabe zu tätigen, wird die p5.sound library genutzt.
p5.AudioIn()
nimmt das Audio eines Eingabegerätes auf und weist dieses der Variable mic
zu.
Mit der Methode start()
wird die Aufnahme begonnen.
//in die Draw()-Funktion ergänzen
//Variable aus Mikro Lautsärke
var sound = mic.getLevel()*20
var diff = sound - vol
vol = vol + (diff * easing)
//in die Draw()-Funktion nach der for-Schleife
//Mikrofon-Werte werden in Console angezeigt
console.log(sound)
Durch mic.getLevel()
wird die Lautstärke der Audioeingabe in Zahlenwerte umgewandelt und in der neuen Variable sound
gespeichert. Zusätzlich werden diese mit 20 multipliziert, um die Werte zu erhöhen und die visuelle Veränderung deutlicher zu machen.
Zur Überprüfung können die Werte mit console.log(sound)
auf die Konsole ausgegeben werden.
Die Variable diff
beinhaltet die Differenz zwischen dem aktuell aufgenommenen Lautstärkewert(sound) und dem Wert von vol
(am Anfang 0).
Im Anschluss wird zu dem Wert von vol
die Differenz (sound und vol) mal 0.05 (easing) addiert.
Das bedeutet, dass in jedem folgenden Durchlauf die Differenz und dadurch auch
der Wert vol
direkt abhängig vom vorherigen Durchlauf ist.
Der Wert von easing
beeinflusst die Stärke der Abhängigkeit.
Durch diesen dauerhaften Bezug zu vorherigen Werten werden Ausschläge der Animation ›geglättet‹
Kombination Animation und Spracheingabe
//Dreidimensionalität
...
var z = sin(i* 5) * 50 * vol
...
Um die Animation durch Sprache zu beeinflussen, wird die Variable vol
zusätzlich mit der bereits vorhandenen Variable z
multipliziert.
Dies bewirkt, dass die Netzstruktur bei Audioeingabe nach oben ausschlägt. Durch die entstehende Dreidimensionalität erhält der Nutzer positives Feedback.
Optional kann vol
auch an anderen Stellen ergänzt werden, z.B. bei x, y
oder zu dem Farbwechsel. Somit können andere Wirkungen in der Animation durch die Soundeingabe erzeugt werden.
Quellcode
Hier findest du den gesamten Quellcode.
Die Animation ist inspiriert von Colorful Coding.
Die Soundeingabe ist inspiriert von The Coding Train.
Musik: Go With You Darlin' by All Good Folks.