Aurora Synth: un sintetizador wavetable, sampler y piano modelado gratuito con afinación makam, escrito en Rust
Tres motores en un solo instrumento: wavetables con mipmaps, un sampler SFZ y un piano modelado con cuerdas de guía de onda. Afinación makam en comas de Arel-Ezgi-Uzdilek, un coro sintetizado sin grabaciones, y kanun, oud, bağlama y ney construidos a partir de grabaciones CC0. VST3, CLAP y aplicación independiente para macOS y Windows.

Aurora son tres motores de sonido en un solo instrumento: un sintetizador de tablas de ondas (wavetable), un sampler SFZ y un piano de modelado físico. Los tres pasan por los mismos filtros, la misma matriz de modulación y el mismo rack de efectos, y trae afinaciones de makam y maqam integradas. Funciona en macOS y Windows como VST3, CLAP y aplicación independiente. Es gratuito; la página de descarga es aurorasynth.baltavista.com.
En este artículo miro por dentro: cómo evitan el aliasing los osciladores, cómo se calculan las cuerdas del piano, cómo se asignan a las teclas las comas de Arel-Ezgi-Uzdilek y cómo se sintetiza un coro sin una sola grabación. El código es Rust de arriba abajo: nih-plug en el lado del plugin y egui para la interfaz. En total, unas 15 mil líneas.

Cadena de señal
SYNTH : OSC 1/2/3 + Sub + Noise + Ring ─┐
SAMPLED: SFZ sampler ────────────────────┼→ Filter 1 ⇄ Filter 2 → Amp → FX chain → Master
MODELED: waveguide piano ────────────────┘
El motor se elige en el panel Master: SYNTH, MODELED o SAMPLED. Todo lo que viene después es común. Así, un kanun muestreado puede pasar por el mismo filtro ladder, la misma matriz de modulación y el mismo OTT que un lead de supersaw. Los 94 presets de fábrica se construyen sobre esta única arquitectura de voz; los ~245 parámetros se pueden automatizar desde el DAW y se guardan con el proyecto.
Osciladores y tablas de ondas
Las formas clásicas (seno, triángulo, sierra, pulso) se generan con PolyBLEP: se añade una pequeña corrección polinómica justo alrededor de cada esquina aguda de la forma de onda, lo que suprime la mayor parte de los armónicos que se desbordarían por encima de Nyquist.
Las tablas de ondas son más difíciles, porque la forma de onda es un único ciclo arbitrario que puede contener hasta 1024 armónicos. Aurora guarda cada tabla como un mipmap por octavas: el nivel m contiene solo los armónicos del 1 al 1024 >> m. El oscilador mira la frecuencia que está tocando y elige el nivel cuyo armónico más alto sigue por debajo de Nyquist. Las notas agudas leen de una copia con menos armónicos, y nada se repliega.
Hay seis tablas integradas (Classic, Harmonic, Vocal, FM, Sync, Fold) de 16 fotogramas cada una. WT position es un destino de la matriz de modulación, así que un LFO o una envolvente pueden recorrer la tabla. También puedes importar tablas como WAV: fotogramas de 2048 muestras de Serum con cabecera clm, tamaños de fotograma de 256/512/1024, o un solo ciclo.
Además: modos de deformación (Sync, Bend, Mirror, Squeeze/PWM, Quantize), FM por modulación de fase (2→1, 3→2), sincronía dura con OSC 1 y unísono de hasta 7 voces con desafinación y apertura estéreo.
Filtros
Los dos filtros se pueden conectar en serie o en paralelo (con un control de balance). Hay nueve modos:
- SVF: LP24, LP12, BP, HP, Notch. Un filtro de variable de estado de realimentación de retardo cero (ZDF) en la forma TPT de Simper/Zavalishin; dos etapas seguidas para 24 dB/oct.
- Ladder: un 4 polos saturante estilo Moog en ZDF.
- Comb+ / Comb−: filtros peine con realimentación positiva y negativa.
- Formant: un filtro de vocales que pasa de A-E-I-O-U según la frecuencia de corte.
El drive y los filtros no lineales pueden funcionar al doble de la frecuencia de muestreo (Off, Auto, Always). Auto solo lo activa cuando el drive está alto o se elige un filtro saturante como el ladder, de modo que un SVF limpio no gasta CPU.
El gráfico del filtro en la interfaz no es un dibujo: se calcula desde dentro del código del filtro, como la magnitud real de la función de transferencia digital. Haz clic y arrastra sobre él para cambiar la frecuencia de corte y la resonancia.
Modulación
Tres envolventes (filtro, amplificador y una envolvente de modulación aparte), dos LFO con cinco formas o una forma dibujable de 16 pasos, cuatro mandos macro, velocity, rueda de modulación, aftertouch, tecla y aleatorio pueden ser fuentes. Cada uno de los 8 slots de la matriz tiene además un escalador Via: "LFO 1 al tono, en la medida que indique la rueda de modulación". Cuando un parámetro está modulado aparece un anillo alrededor de su mando, que muestra a la vez el rango de modulación y el valor en vivo.
Las envolventes usan curvas exponenciales de estilo analógico y se editan arrastrando sus nodos. Las posiciones de envolvente y LFO de las voces que suenan se muestran en vivo sobre los gráficos.
El piano modelado
El motor MODELED no usa muestras. Cada tecla tiene de 1 a 3 cuerdas ligeramente desafinadas (una en el bajo profundo, dos en el registro medio, tres en los agudos). Cada cuerda es una guía de ondas digital: una línea de retardo y tres filtros que cierran el lazo.
- Filtro de pérdidas. Un paso bajo de un polo; los parciales agudos pierden un poco más en cada ida y vuelta, así que la nota se oscurece con el tiempo.
- Pasa todo de dispersión. Una cuerda de piano real es rígida, por lo que sus parciales no son múltiplos exactos sino que se estiran ligeramente hacia arriba. Una cadena de hasta cuatro pasa todo de primer orden imita ese estiramiento.
- Retardo fraccionario de Thiran. La línea de retardo tiene una longitud entera, pero una afinación precisa necesita una fraccionaria. Un pasa todo de Thiran cubre la fracción restante.
El detalle sutil: el filtro de pérdidas y los pasa todo también retrasan un poco la señal, y ese retardo depende de la frecuencia. Si se ignora, los agudos suenan claramente bajos de tono. Aurora calcula el retardo de fase de cada uno de estos filtros en la fundamental, por cuerda, y lo resta de la longitud de la línea de retardo:
let w = 2.0 * PI * f / sr;
let mut fixed = lp_delay(b, w);
for d in self.disp.iter_mut().take(n_disp) {
d.a = disp_a;
fixed += ap_delay(disp_a, w);
}
let total = sr / f - fixed;
let m = (total - 0.5).floor().max(2.0);
let frac = (total - m).clamp(0.1, 1.9);
self.thiran.a = (1.0 - frac) / (1.0 + frac);
El tiempo de decaimiento también cambia con la tecla: de ~16 segundos en el bajo profundo a ~1 segundo en el extremo agudo. Para que en las notas agudas el filtro de pérdidas no consuma por sí solo todo ese presupuesto, se suaviza hasta que su pérdida en la fundamental no supere la mitad del presupuesto.
El martillo que excita la cuerda es un pulso de medio seno que depende de la velocity: los golpes más fuertes dan un pulso más corto y, por tanto, más brillante. El pulso pasa por un filtro peine fijado por el punto donde el martillo golpea la cuerda (entre 1/16 y 1/5 de su longitud); esto imita cómo, en un piano real, faltan los parciales que tienen un nodo en el punto de golpe. Después vienen los apagadores (sin apagadores en la octava superior, como en un piano real), el pedal de sustain y un pequeño banco de resonadores para el color de la tabla armónica.
El sampler
El motor SAMPLED es un reproductor SFZ: regiones, capas de velocity, bucles con crossfade de bucle, disparadores de release con rt_decay, amp_veltrack, un paso bajo por región, round robin con lorand/hirand. Las muestras pueden ser WAV o FLAC; un SFZ que nombra x.wav también encuentra x.flac. Las carpetas sin SFZ, con nombres como A0v1.wav, se leen a partir de los nombres de archivo.
Resuelve dos problemas prácticos de forma automática:
- Volumen. Distintas librerías tienen niveles muy diferentes. Aurora mide el RMS de la ventana de 50 ms más fuerte del primer segundo de cada conjunto e iguala los conjuntos al piano Salamander. El enfoque de ventana es justo tanto con sonidos pulsados como con sonidos frotados.
- Memoria. Algunas librerías tienen 16 capas de velocity. Aurora las reduce a 6, se asegura de que todo el rango de velocity siga cubierto y solo carga los archivos que quedan.

Afinación de makam
Toca makam, no solo doce notas. Elige un makam y una tónica, y todos los motores (sintetizador, sampler, piano) se reafinan según los intervalos de ese makam. El teclado en pantalla muestra la desviación de cada tecla respecto a 12-TET en cents.
Los makams turcos están en sus posiciones según la teoría de Arel-Ezgi-Uzdilek: la octava se divide en 53 comas de Holder (1 coma ≈ 22.64 cents) y cada makam se define por las posiciones en comas de sus grados sobre la tónica:
const KOMA: f32 = 1200.0 / 53.0;
5 => &[5, 17, 22, 31, 40, 44], // Hicaz: Hicaz tetrachord + Rast pentachord
3 => &[9, 17, 22, 31, 40, 48], // Rast: Rast tetrachord + Rast pentachord
Cada grado se convierte a cents y se coloca en la tecla más cercana del teclado; la diferencia es cuánto se desplaza esa tecla. En Hicaz sobre re, por ejemplo, mi♭ se mueve +13 cents, fa♯ −15 cents y si +6 cents. El resultado es una tabla de 128 entradas con un desplazamiento de tono para cada nota MIDI, que los motores suman a sus notas.
Además de Rast, Uşşak, Hicaz, Hicazkar, Saba, Hüseyni, Nihavend y Kürdi, hay Bayati y Rast árabes de cuartos de tono, entonación justa de 5 límites y afinación pitagórica. Si eso no basta, también se cargan archivos Scala .scl: 53-EDO, 24-EDO o la escala que quieras, con cualquier número de notas por octava.
Un coro sin grabaciones
El coro "Elven" y la soprano solista del pack Voices no contienen ninguna grabación; se generan por completo con síntesis aditiva en un script de Python. Cada nota es un conjunto: una fuente armónica de tipo glotal por cantante, cada una con su propia desafinación, vibrato, deriva de tono y ruido de aliento.
El detalle que lo hace convincente es cómo se aplican los formantes. Los formantes de la vocal (para "aah", por ejemplo 850, 1220 y 2810 Hz) se evalúan en la frecuencia instantánea de cada armónico. A medida que el vibrato acerca y aleja un armónico del pico de un formante, el nivel de ese armónico cambia con él; de ahí viene el brillo de una voz real. Un filtro estático no te da eso.
Instrumentos turcos y árabes
El kanun, la bağlama, el ud, el ney, la darbuka y el def proceden de grabaciones CC0, pero esas grabaciones no son conjuntos de muestras ya hechos: una escala cromática en un kanun, una improvisación de ney. Otro script de Python las convierte en instrumentos: encuentra las notas por detección de ataques en los instrumentos pulsados y siguiendo tramos de tono estable en el ney, mide el tono de cada nota, elige la mejor toma para cada semitono y corrige la desafinación restante con tune en el SFZ. Estos presets también vienen en versiones afinadas por makam: Rast en sol, Uşşak, Hicaz y Hüseyni en la, Bayati en re.
Efectos y el resto
La cadena de efectos está hecha de chips que se arrastran para reordenar: drive, bitcrusher, phaser, flanger, chorus, delay ping-pong sincronizado al tempo, EQ de 3 bandas, compresor, compresión multibanda OTT y una reverb FDN. La reverb tiene cuatro pasa todo de difusión tras el predelay y ocho líneas de retardo con una matriz de realimentación de Householder, cada línea con su propia amortiguación y una modulación suave.
También hay un arpegiador sincronizado al tempo con seis modos; poli de 16 voces, mono y legato con glide; un osciloscopio, un analizador de espectro FFT y medidores estéreo; y puedes tocar desde el teclado en pantalla o desde el del ordenador.
En un DAW y sin él

El plugin se construye como VST3 y CLAP con nih-plug; el MIDI llega desde el DAW con temporización exacta a la muestra, y el arpegiador y los LFO siguen el tempo del DAW. Se ha probado en Ableton Live 12; en la sesión de arriba cada pista es una Aurora: cuerdas muestreadas, clavecín y capas de sintetizador sonando a la vez. Todavía no hay versión AU, así que Logic y GarageBand no pueden cargarlo; para ellos está la aplicación independiente.
En la aplicación independiente el audio viene de cpal, el MIDI de midir, y hay un reproductor de archivos MIDI integrado: arrastra un .mid a la ventana, elige qué partes suenan, cambia el tempo y toca encima con el teclado. En archivos con varias partes la melodía principal se elige automáticamente. Ambas funciones tienen un vídeo en el sitio.
El paquete de macOS es universal para Apple Silicon e Intel (unido con lipo); el de Windows se compila de forma cruzada desde macOS con mingw-w64. Los packs de muestras son FLAC e iguales para ambos sistemas: Piano (Salamander Grand y Upright KW, ~93 MB), Orchestral (cuerdas, maderas, metales y clavecín de VSCO 2 CE, ~255 MB), World (~32 MB) y Voices (~22 MB). Los presets de sintetizador no necesitan ningún pack; los presets que sí lo necesitan están marcados en el explorador.
Pruébalo
Puedes descargar Aurora en aurorasynth.baltavista.com. Un buen punto de partida: abre un preset de kanun afinado en Hicaz de la categoría Turkish & Arabic y mira las desviaciones en cents sobre las teclas del teclado en pantalla.