Laboratorio de Síntesis con SC

La serie se abre a la escala microtemporal

Esta tercera sesión conecta teoría, percepción y práctica: del grano como unidad mínima a los patches con GrainSin y GrainBuf, enlazando el cuaderno con la lectura de Roads.

Sesión 03 de 06 Curtis Roads + Fieldsteel Síntesis granular
Síntesis Granular

Teoría · Parámetros · SuperCollider

Anatomía de un Grano

Curtis Roads · The Computer Music Tutorial (2023)

Eli Fieldsteel · SuperCollider for the Creative Musician (2024)

Esta tercera sesión convierte el PDF de trabajo en una página navegable dentro del laboratorio: definición del grano, ley tiempo-banda, parámetros perceptivos y cuatro bloques de código que llevan la teoría de Roads a SuperCollider con GrainSin, GrainBuf y ProxySpace.

Base teórica: Curtis Roads, Gabor, Xenakis y la lectura práctica de Eli Fieldsteel.

Idea central: entender que la duración del grano modela el espectro tanto como la fuente interna.

Salida práctica: cuatro patches listos para explorar densidad, scatter, read pointer y slow morphing.

1. El Grano: Unidad Mínima de Sonido

La síntesis granular construye sonido a partir de partículas brevísimas llamadas granos. Un grano es un evento acústico de duración entre 1 ms y 100 ms, justo en el umbral de percepción auditiva.

< 1 ms → click subsimbólico. El oído no distingue ninguna propiedad.

1–100 ms → el grano. Cada partícula puede tener pitch, color y posición únicos.

> 100 ms → sonido normal. El paradigma granular deja de aplicarse.

Anatomía de un Grano

Gabor (1946):

Todo sonido puede representarse como una cuadrícula tiempo-frecuencia donde cada celda es un grano elemental de energía acústica.

Xenakis (1960):

Todo sonido continuo puede concebirse como un ensamblaje de una gran cantidad de sonidos elementales dispuestos adecuadamente en el tiempo.

2. La Ley Tiempo-Banda

Esta es la ley más importante de la síntesis granular. Proviene de la física de señales: cuanto más corto el grano, mayor su ancho de banda espectral.

Cuanto más corto el grano → mayor su ancho de banda espectral
Ley Tiempo-Banda
100 ms
Tono puro
20 ms
Formante
1 ms
Ruido banda ancha

Observación experimental: con GrainSin, grainDur 0.001 suena agudo y grainDur 0.009 suena grave. No estás escuchando la frecuencia interna de la sinusoide, sino la forma espectral de la envolvente del grano.

3. Parámetros del Grano

Roads distingue parámetros por grano, que afectan cada partícula individualmente, y parámetros de densidad, que operan como control global.

Formas de Envolvente del Grano

Gaussiana

Tukey

Expodec

Rexpodec

Triangular

Tabla de parámetros por grano

Parámetro Control SC Efecto perceptivo
Envolvente envbufnum: -1 Bell curve por defecto. Ángulos bruscos → artefactos espectrales.
Duración dur: 0.001–0.4 Control del ancho de banda según la ley tiempo-banda.
Forma de onda sndbuf: b Sinusoide en GrainSin o fragmento de audio en GrainBuf.
Frecuencia rate: ratio 1.0=original, 0.5=octava abajo, 2.0=octava arriba, -1=reverso.
Posición pos: 0.0–1.0 Read pointer en el buffer. 0=inicio, 1=fin.
Pan espacial pan: -1.0–1.0 Dispersión per-grano → morfología espacial vívida.
Sincronía Impulse / Dust Impulse=SGS periódico. Dust=AGS con jitter aleatorio.
Scatter LFNoise1.bipolar(s) Jitter de posición. 0=lineal, 0.4=scramble total.

Densidad y Fill Factor

FF = densidad × duración. FF < 0.5 → esparso. FF ≥ 1.0 → continuo.

Sincronía, Densidad y Fill Factor
Densidad (granos 25ms) Percepción
< 15 granos/s Secuencias rítmicas — cada grano se distingue.
15–25 granos/s Aleteo — el ritmo desaparece, emerge flutter.
25–50 granos/s Flujo granular — textura sin tempo perceptible.
50–100 granos/s Banda de textura continua.
> 100 granos/s Masa sonora — fusión total. Como reverb densa.

4. UGens Granulares en SuperCollider

SuperCollider implementa la teoría de Roads en seis UGens. Todos comparten la misma arquitectura: fuente de audio, envolvente y trigger. Difieren en el tipo de fuente y en el grado de flexibilidad.

UGen Fuente Característica principal
GrainSin Sinusoide sintética Granular clásica tipo Gabor. Sin buffer. El pitch emerge de la duración.
GrainBuf Sample en buffer El más versátil. pos, rate, pan y envbufnum configurables.
TGrains Sample en buffer Como GrainBuf pero con centerPos en segundos y envolvente fija tipo bell.
Warp1 Sample en buffer numChannels toma los canales del buffer fuente. Sin pan.
GrainFM FM sintética FM dentro de cada grano. Gran riqueza espectral.
GrainIn Señal en vivo Granulación en tiempo real. Sin pos ni rate.

Regla crítica (Fieldsteel): GrainBuf, TGrains y Warp1 requieren un buffer mono. Granular un buffer estéreo produce silencio o distorsión sin aviso. Mezcla a mono antes de cargar.

5. Bloque 1 — GrainSin: Granular Clásica

Sinusoide dentro de cada grano. Este primer bloque permite explorar la ley tiempo-banda directamente sin necesidad de buffer.

// ▮▮ BLOQUE 1: GrainSin — granular clásica (Gabor) ▮▮▮▮▮▮▮▮▮▮▮▮
// Cada grano = sinusoide + envolvente gaussiana (bell curve por defecto)
(
~gran = {
    var trig, freq, sig;

    // DENSIDAD — Dust = asincrónico (AGS), Impulse = sincrónico (SGS)
    trig = Dust.kr(\density.kr(12));

    // FRECUENCIA — LFNoise1 introduce dispersión per-grano (banda de frec.)
    freq = \baseFreq.kr(220) * LFNoise1.kr(20).range(0.95, 1.05);

    sig = GrainSin.ar(
        numChannels: 2,
        trigger: trig,
        dur: \grainDur.kr(0.08),   // duración → color espectral
        freq: freq,
        pan: LFNoise1.kr(15)                  // dispersión espacial per-grano
    );
    sig * \amp.kr(0.3);
};
)
~gran.fadeTime_(8).play;

// Explorar la ley tiempo-banda:
~gran.set(\density, 50, \baseFreq, 440, \grainDur, 0.001);   // agudo/ruido
~gran.set(\density, 50, \baseFreq, 440, \grainDur, 0.009);   // grave
~gran.set(\density, 40, \baseFreq, 440, \grainDur, 0.02);    // tonal (≥20ms)

6. Bloque 2 — GrainBuf: Granular con Sample

El contenido de cada grano ya no es una sinusoide, sino un fragmento de audio leído desde un buffer. El parámetro pos se convierte en el eje compositivo central.

// ▮▮ BLOQUE 2: GrainBuf — granular con sample ▮▮▮▮▮▮▮▮▮▮▮▮▮▮
b = Buffer.read(s, Platform.resourceDir ++ "/sounds/a11wlk01.wav");

(
~gran = {
    var trig, sig;
    trig = Dust.kr(\density.kr(15));
    sig = GrainBuf.ar(
        numChannels: 2,
        trigger: trig,
        dur: \grainDur.kr(0.1),
        sndbuf: b,
        rate: \rate.kr(1.0),    // 1.0=original, 0.5=oct↓, 2.0=oct↑, -1=reverso
        pos: \pos.kr(0.5),      // 0=inicio buffer, 1=fin
        pan: LFNoise1.kr(20)
    );
    sig * \amp.kr(0.4);
};
)
~gran.set(\pos, 0.0);      // inicio del sample
~gran.set(\rate, -1.0);    // reproducción inversa

7. Bloque 3 — pos Dinámico: Tres Modos

Moviendo pos con un LFSaw lento y añadiendo scatter aleatorio emergen tres comportamientos clásicos: time-stretch, scrubbing y scramble.

TIME-STRETCH

SCRUBBING

SCRAMBLE

// ▮▮ BLOQUE 3: pos dinámico — time-stretch / scrub / scramble ▮▮▮▮
(
~gran = {
    var trig, pos, sig;
    trig = Dust.kr(\density.kr(20));
    pos = LFSaw.kr(\stretchTime.kr(30).reciprocal, iphase: 0).range(0, 1);
    pos = (pos + LFNoise1.kr(30).bipolar(\scatter.kr(0.0))).clip(0, 1);
    sig = GrainBuf.ar(2, trig, \grainDur.kr(0.12), b, \rate.kr(1.0), pos,
        LFNoise1.kr(20));
    sig * \amp.kr(0.4);
};
)
~gran.set(\stretchTime, 30, \scatter, 0.0,  \grainDur, 0.12);  // TIME-STRETCH
~gran.set(\stretchTime, 15, \scatter, 0.05, \grainDur, 0.08);  // SCRUBBING
~gran.set(\stretchTime, 10, \scatter, 0.4,  \grainDur, 0.05);  // SCRAMBLE

8. Bloque 4 — ProxySpace con Slow Morphing

Integración en entorno de live coding. LFOs con periodos primos de 29, 41 y 67 segundos garantizan que los parámetros nunca se alineen: el sonido evoluciona sin repetición perceptible.

// ▮▮ BLOQUE 4: ProxySpace + slow morphing ▮▮▮▮▮▮▮▮▮▮▮▮
// Periodos primos: 41s, 29s, 67s — nunca se sincronizan → evolución infinita
(
~gran = {
    var trig, pos, scatter, density, rate, sig;

    density = LFNoise1.kr(1/41).range(8, 35);          // 41s
    scatter = LFNoise1.kr(1/29).range(0.0, 0.25);      // 29s
    rate = LFNoise1.kr(1/67).range(0.85, 1.15);        // 67s

    trig = Dust.kr(density);
    pos = LFSaw.kr(\stretchTime.kr(40).reciprocal, iphase: 0).range(0, 1);
    pos = (pos + LFNoise1.kr(30).bipolar(scatter)).clip(0, 1);

    sig = GrainBuf.ar(
        numChannels: 2,
        trigger: trig,
        dur: \grainDur.kr(0.12),
        sndbuf: b,
        rate: rate,
        pos: pos,
        pan: LFNoise1.kr(20)
    );

    // Reverb integrado
    sig = FreeVerb2.ar(sig[0], sig[1], mix: 0.35, room: 0.85, damp: 0.5);
    sig * \amp.kr(0.3);
};
)
~gran.play;

// Performance en vivo — solo dos parámetros mueven todo el espacio:
~gran.xset(\stretchTime, 60, \grainDur, 0.15);  // time-stretch suave
~gran.xset(\stretchTime, 10, \grainDur, 0.04);  // nube densa
Densidad → Textura (Fill Factor)

FF=0.2 esparso
5 granos/s

FF=1.0 umbral
20 granos/s

FF=3.6 continuo
60 granos/s

9. Mapa: Teoría Roads → SuperCollider

Concepto Roads Parámetro SC Rango de interés
Trigger / densidad Impulse.kr(n) / Dust.kr(n) 8–100 granos/s
Duración del grano dur: 0.001 – 0.4 s
Envolvente envbufnum: -1 Bell curve gaussiana por defecto
Fuente / forma de onda sndbuf: b Buffer mono obligatorio
Read pointer pos: 0.0–1.0 0=inicio, 1=fin buffer
Pitch shift rate: ratio 0.5=oct↓ 1.0=orig 2.0=oct↑
Pan espacial pan: -1.0–1.0 LFNoise1 para dispersión per-grano
Scatter / jitter pos LFNoise1.bipolar(s) 0.0=lineal 0.4=scramble

Seguir en el laboratorio

Laboratorio de Síntesis con SC Volver al archivo principal de sesiones y al cuaderno técnico del laboratorio. Sesión 02 · Sistema de live coding rítmico Cruzar este estudio granular con la sesión centrada en reloj de servidor, secuenciación y envíos auxiliares. Descargar patch de la sesión 03 Versión consolidada con los cuatro bloques y comentarios listos para ejecutar en SuperCollider.