4.6 Klanganalyse

Voices and Piano (Peter Ablinger, seit 1998) (Website)
"Actually the piano part is the temporal and spectral scan of the respective voice, something like a coarse gridded photograph. Actually the piano part is the analysis of the voice. Music analyses reality."

Magnetosphere (flight404/Robert Hodgin, 2007)

1. Die minim-Library
Die Sound-Library von Processing bietet zwar einige Möglichkeiten zur Klangerzeugung und -wiedergabe, doch sind ihre Möglichkeiten zur Klanganalyse reduziert. Hier empfiehlt es sich wiederum auf die minim-Library zurückzugreifen.
2. Amplitude auslesen
Die Library importieren:
import ddf.minim.*;
import ddf.minim.analysis.*;
Soundfile laden:
minim = new Minim(this);
song = minim.loadFile("dot.mp3", 2048);
Beispiel 3-11

Minim minim;
AudioPlayer player;
float xPos = 0;
float yPos1 = 0;
float yPos2 = 0;
float lastX = 0;
float lastY = 0;
void setup() {
size(800, 600);
background(255);
fill(0);
minim = new Minim(this);
player = minim.loadFile("dot.mp3");
player.loop();
}
void draw() {
float ampLeft = abs(player.left.get(0));
float ampRight = abs(player.right.get(0));
float ampSum = ampLeft + ampRight;
println(ampSum);
yPos1 = height/2-(ampSum*height);
yPos2 = height/2+(ampSum*height);
ellipse(xPos, yPos1, 2, 2);
ellipse(xPos, yPos2, 2, 2);
line(xPos, yPos1, xPos, yPos2);
if (xPos < width){
xPos+=4;
}else{
fill(255, 230);
stroke(255);
rect(0,0,width, height);
fill(0);
stroke(0);
xPos = 0;
}
}
3. Fast Fourier Transformation

Zeit-basierte Darstellung (oben) und Frequenz-basierte Darstellung (unten) desselben Signals, wobei die untere Darstellung aus der oberen durch Fouriertransformation gewonnen werden kann. (Quelle: Wikipedia Commons)
Die minim-Library stellt ein FFT-Objekt bereit:
Minim minim;
AudioPlayer player;
FFT fft;
minim = new Minim(this);
player = minim.loadFile("dot.mp3");
player.loop();
fft = new FFT(player.bufferSize(), player.sampleRate());
Mit der Funktion logAverages teilt man dem FFT-Objekt mit was die unterste Frequenz sein soll und wieviele (Analyse-)Bänder pro Oktave verwendet werden soll.
fft.logAverages(55, 6); // Tiefster Ton: 55Hz (A1), 6 (Analyse-)Bänder pro Oktave
fft.forward(player.mix); // Analysiere den Stereo-Mix des zuvor erstellten AudioPlayers "player"
Nun lassen sich die einzelnen Frequenzbänder mit fft.getBand(); auslesen.
Beispiel 3-12

import ddf.minim.*; // import minim library
import ddf.minim.analysis.*;
Minim minim;
AudioPlayer player;
FFT fft;
int tonstufen = 24;
int cutHigh = tonstufen*6; // cut higher part of spectrum (6 Oktaves)
float x = 0;
int shape = 1;
void setup(){
size(1280,720, P3D);
pixelDensity(2);
background(0);
rectMode(CENTER);
minim = new Minim(this);
player = minim.loadFile("dot.mp3");
player.loop();
fft = new FFT(player.bufferSize(), player.sampleRate());
fft.logAverages(55, tonstufen); // Tiefster Ton: 55Hz (A1), 6 (Analyse-)Bänder pro Oktave
fft.forward(player.mix);
}
void draw(){
fill(255,6);
stroke(255,40);
fft.logAverages(55, tonstufen);
fft.forward(player.mix);
for (int i = 0; i < fft.specSize(); i++){
float value = fft.getBand(i);
float radius = map(value, 0, 10, 0, 6);
switch(shape){
case 1:
ellipse(x, height-(i*40), value, value);
break;
case 2:
rect(x, height-(i*40), value, value);
break;
case 3:
stroke(255,150);
line(x, height-(i*40), x+value, height-(i*40)+value);
break;
}
}
if (x
Beispiel 3-13

import ddf.minim.*; // import minim library
import ddf.minim.analysis.*;
Minim minim; //
AudioPlayer player;
FFT fft;
float lastX=0;
float lastY=0;
float radius = 200;
int tonstufen = 6;
int cutHigh = tonstufen*6; // cut higher part of spectrum (6 Oktaves)
float stepsize;
float rotation = 0;
float rSpeed = 0;
void setup(){
size(1280,720, P3D);
pixelDensity(2);
background(0);
minim = new Minim(this);
player = minim.loadFile("dot.mp3");
player.loop();
fft = new FFT(player.bufferSize(), player.sampleRate());
fft.logAverages(55, tonstufen); // Tiefster Ton: 55Hz (A1), 6 (Analyse-)Bänder pro Oktave
fft.forward(player.mix);
stepsize = 360/(fft.avgSize()-cutHigh);
}
void draw(){
fill(0,10);
rect(0,0,width, height);
rotation += rSpeed;
fft.logAverages(55, tonstufen); // Tiefster Ton: 55Hz (A1), 6 (Analyse-)Bänder pro Oktave
fft.forward(player.mix);
float totalAmp = 0;
int i =0;
for (int angle = 0; angle < 360; angle += stepsize ){
float radAng = radians(angle+rotation);
float value = fft.getBand(i);
totalAmp += value;
float xc = width/2 + cos(radAng)*(radius+(value*5));
float yc = height/2 + sin(radAng)*(radius+(value*5));
stroke (255, 100);
fill(255, 150);
if (i == 0){
line(xc, yc, width/2, height/2);
}
ellipse(xc,yc, 6, 6);
line(lastX, lastY, xc, yc);
lastX=xc;
lastY=yc;
i++;
}
if (totalAmp > 100){
rSpeed = randomGaussian() *2;
//rotation += randomGaussian()*30;
}
}