He tenido una fijación con el lenguaje Processing desde que mi amiga Martha Brinchi me presento el libro de Hartmut Bohnacker, Benedikt Gross, Julia Laub, y Claudius Lazzeroni llamado GENERATIVE DESIGN. Aquí se muestran mil formas de aplicar este lenguaje de código para generar texturas increíbles basándose en formulas matemáticas, sonido, o secuencias de lenguaje. Me parece fascinante que una secuencia de comandos o lenguaje de programación pueda responder a una imagen que toca nuestra sensibilidad pictórica, y aun mas cuando esto se complementa si esta imagen reacciona a una formula o un sonido.
Para Usar el lenguaje Processing simplemente debes ir a la pagina processing.org, descargar el programa que allí se ofrece y comenzar a escribir el código que desee.
En este caso, es mi placer mostrar el proceso de creación de este flyer para el evento de CONOSOUND, Mixtape Sessions Vol.1 que fue creado con la ayuda de este lenguaje junto con la inteligencia artificial de ChatGPT.
Paso 1
Importar a Processing una librería Minim para interpretar un archivo de audio: Dirígete al menú “Sketch” en Processing, selecciona “Importar Bibliotecas” y luego busca e instala la biblioteca “Minim”.
Paso 2
Añadir la pista de audio que quieres que se reproduzca junto con tu imagen y reaccione ante esta:
minim = new Minim(this); player = minim.loadFile("/Users/ungalaxylovinyeah/Documents/Processing/libraries/minim/src/navex_2.mp3"); player.play();
despues de esto ya le pedí a la inteligencia artificial que me ayudara a crear las formas que iban a reaccionar con la pista de audio, quería llegar a una textura muy similar a lo que se present en el album de Joy Division, Unknown Pleasures donde se ven las ondas de audio como picos de montaña seriada, ese era el objetivo.
muy contento por el resultado le pedí a la I.A. esto:
¡Genial! Ahora, usando ese parámetro de círculos, agrega algo con respecto a un entrono que simule profundidad o un entorno 3d obscuro y misterioso, porqueel archivo “/Users/ungalaxylovinyeah/Documents/Processing/libraries/minim/src/navex_2.mp3” es música electrónica, entonces quiero generar un ambiente obscuro de discoclub de Berlín, por favor.
me respondió asi:
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
AudioPlayer player;
FFT fft;
int numCircles = 50;
Circle[] circles;
void setup() {
size(800, 600, P3D);
background(0);
minim = new Minim(this);
player = minim.loadFile("/Users/ungalaxylovinyeah/Documents/Processing/libraries/minim/src/navex_2.mp3");
player.play();
fft = new FFT(player.bufferSize(), player.sampleRate());
circles = new Circle[numCircles];
for (int i = 0; i < numCircles; i++) {
circles[i] = new Circle(random(width), random(height), random(20, 100));
}
}
void draw() {
lights();
background(0);
// Ambient light
ambientLight(50, 50, 50); // Colores en tonos grises
// Point light
pointLight(255, 255, 255, width / 2, height / 2, 200);
// Analiza el espectro de frecuencia del audio
fft.forward(player.mix);
// Dibuja los círculos y actualiza su estado
for (Circle circle : circles) {
circle.update();
circle.display();
}
}
class Circle {
float x, y, z;
float diameter;
float growth = 0;
Circle(float x, float y, float diameter) {
this.x = x;
this.y = y;
this.z = random(-200, 200); // Z-coordinate for depth effect
this.diameter = diameter;
}
void update() {
float scale = map(player.position(), 0, player.length(), 0.2, 2);
growth = fft.getBand(1) * scale; // Modifica aquí para ajustar la reacción al audio
}
void display() {
noFill();
stroke(255);
strokeWeight(2);
pushMatrix();
translate(x, y, z);
ellipse(0, 0, diameter + growth, diameter + growth);
popMatrix();
}
}
Y así fui pidiéndole ajustes a la I.A. con diferentes colores o con diferentes formas que reaccionaran a la pista de diferentes formas dejandonos con varios resultados:
Hasta aquí todo lucía muy bien y este fue el ultimo requerimiento que le pedí a la I.A.
genial, usemos 5 colores más pero no uses colores naranja , amarillo o rojo, organiza esos colores más en orden de tono. esta parte del codigo: “for (int j = 0; j < numLines; j++) { float yOffset = yOffsetBase + j * 5;” dejala en 5 desde ahora porfavor muestrame todo el codigo entero
lo cual me respondió con este último código:
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
AudioPlayer player;
FFT fft;
int numPoints = 200; // Número de puntos que formarán la línea
float[] frequencies; // Array para almacenar las frecuencias
float[] amplitudes; // Array para almacenar las amplitudes
float yOffsetBase = 100; // Posición vertical inicial de la primera línea
float xOffset = 0; // Desplazamiento horizontal inicial de las líneas
float xSpacing; // Espaciado horizontal entre puntos
float moveSpeed = -5; // Velocidad de movimiento vertical
int numLines = 50; // Número de líneas
color[] lineColors = {
color(0, 255, 0),
color(0, 179, 0),
color(170, 0, 255),
color(119, 0, 179),
color(255, 153, 0),
color(168, 98, 234),
color(101, 69, 164),
color(234, 153, 98),
color(164, 107, 69),
color(176, 234, 98),
color(101, 255, 0),
color(101, 179, 0),
color(0, 255, 255),
color(153, 255, 0),
color(107, 179, 0)
}; // Colores brillantes
void setup() {
size(540, 960);
background(0);
minim = new Minim(this);
player = minim.loadFile("/Users/ungalaxylovinyeah/Documents/Processing/libraries/minim/src/navex_2.mp3");
fft = new FFT(player.bufferSize(), player.sampleRate());
frequencies = new float[numPoints];
amplitudes = new float[numPoints];
xSpacing = (float) width / (numPoints - 1);
player.play(); // Comienza la reproducción de la pista de audio
}
void draw() {
background(0);
fft.forward(player.mix);
// Ajusta el grosor del trazo aquí
strokeWeight(3); // Cambia el valor a lo que necesites
for (int j = 0; j < numLines; j++) {
float yOffset = yOffsetBase + j * 5; // Ajusta la posición vertical de cada línea
color lineColor = lineColors[j % lineColors.length]; // Obtiene el color actual
for (int i = 0; i < numPoints; i++) {
frequencies[i] = fft.getFreq(i); // Obtiene la frecuencia en la posición i
amplitudes[i] = fft.getBand(i) * 10; // Ajusta la amplitud
float y = yOffset - amplitudes[i];
float x = xOffset + i * xSpacing;
stroke(lineColor); // Usa el color generado
point(x, y);
}
noFill();
beginShape();
for (int i = 0; i < numPoints; i++) {
vertex(xOffset + i * xSpacing, yOffset - amplitudes[i]);
}
endShape();
}
// Mueve todas las líneas hacia arriba
yOffsetBase += moveSpeed;
// Reinicia la posición vertical de las líneas cuando llegan al borde superior
if (yOffsetBase < -50) {
yOffsetBase = height + 50;
}
}
Y este fué el último resultado:
Despues de esto lleve los archivos grabados a After Effects para crear la pieza publicada: