このアプリは、音声入力から音声データを取得し、波形と周波数スペクトルの可視化、および円形のパターンを描画するプログラムです。 Processing Sound Libraryを使用しています。 ウィンドウには、3Dボックス、波形、円形のパターン、現在の時間が表示されています。円形のパターンは、音声入力から取得した音量に応じて変化します。円の位置、サイズ、回転速度、および周波数帯域幅などがランダムに生成されます。波形は、左右の音声入力から得られた波形を表示します。現在の時刻は、Helvetica Neueフォントで表示されます。
import processing.sound.*;
AudioIn audioInput;
Waveform leftWaveform, rightWaveform;
Circle[][] circles;
int numCircles = 120;
int minDist = 50;
int maxDist = 400;
int samples = 512;
void setup() {
size(720, 300, P3D);
frameRate(120);
noStroke();
ambientLight(0, 0, 0);
initializeAudio();
initializeTextFont();
initializeCircles();
}
void initializeAudio() {
audioInput = new AudioIn(this, 0);
audioInput.start();
leftWaveform = new Waveform(this, samples);
leftWaveform.input(audioInput);
audioInput = new AudioIn(this, 1);
audioInput.start();
rightWaveform = new Waveform(this, samples);
rightWaveform.input(audioInput);
}
void initializeTextFont() {
PFont font = createFont("HelveticaNeue-BoldItalic", 6);
textFont(font);
textAlign(CENTER, CENTER);
textMode(SHAPE);
}
void initializeCircles() {
circles = new Circle[numCircles / 10][10];
for (int i = 0; i < numCircles; i++) {
circles[i / 10][i % 10] = new Circle();
}
}
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //
void draw() {
background(0, 107, 130);
drawTimeText();
draw3DBox();
drawWaveforms();
drawCircles();
}
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //
void drawTimeText() {
pushMatrix();
translate(0, 0, 200);
String text = getCurrentTimeString();
int margin = 320;
float totalTextWidth = textWidth(text) + (margin * 2);
float letterSpacing = (width - totalTextWidth) / (text.length() - 1);
float x = margin;
float y = height / 2;
fill(255);
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
float charWidth = textWidth(c);
text(c, x + (charWidth / 2), y);
x += charWidth + letterSpacing;
}
popMatrix();
}
String getCurrentTimeString() {
int hour = hour();
int minute = minute();
int second = second();
return nf(hour, 2) + ":" + nf(minute, 2) + ":" + nf(second, 2);
}
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //
void draw3DBox() {
pushMatrix();
translate(width / 2, height / 2, 50);
rotateX(frameCount * 0.002);
rotateY(frameCount * 0.005);
noStroke();
fill(0, 206, 206);
box(100);
popMatrix();
}
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //
void drawWaveforms() {
stroke(0, 206, 206);
strokeWeight(4);
noFill();
leftWaveform.analyze();
drawWaveform(leftWaveform, 0, width / 2);
rightWaveform.analyze();
drawWaveform(rightWaveform, width / 2, width);
}
void drawWaveform(Waveform waveform, float startX, float endX) {
beginShape();
for (int i = 0; i < samples; i++) {
vertex(
map(i, 0, samples, startX, endX),
map(waveform.data[i], -1, 1, 0, height)
);
}
endShape();
}
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //
void drawCircles() {
translate(width / 2, height / 2);
for (Circle[] row : circles) {
for (Circle circle : row) {
circle.display();
}
}
}
class Circle {
float x, y;
float size;
float smoothSize;
float angle;
float angleSpeed;
Circle() {
angle = random(TWO_PI);
x = cos(angle) * random(minDist, maxDist);
y = sin(angle) * random(minDist, maxDist);
size = random(10, 60);
smoothSize = size;
angleSpeed = map(size, 10, 60, 0.0002, 0.0004);
}
void display() {
float volume = getVolume();
smoothSize = lerp(smoothSize, size * volume, 0.1);
strokeWeight(1);
smooth();
ellipse(x, y, smoothSize, smoothSize);
angle += angleSpeed;
x = cos(angle) * dist(x, y, 0, 0);
y = sin(angle) * dist(x, y, 0, 0);
}
}
float getVolume() {
float leftVolume = max(abs(min(leftWaveform.data)), abs(max(leftWaveform.data)));
float rightVolume = max(abs(min(rightWaveform.data)), abs(max(rightWaveform.data)));
float volume = (leftVolume + rightVolume) * 5;
return volume;
}