Sintetizador modular en el navegador con React y Web Audio API

por | agosto 16, 2026
Photorealistic close-up of a modular synthesizer interface displayed on a computer screen, with colorful patch cables connecting modules, knobs and sliders, in a home studio environment.

Construir un sintetizador modular que corra en el navegador no es ningún misterio. Con React para la interfaz y la Web Audio API para generar y procesar el sonido, puedes montar un sistema completo con osciladores, filtros, envolventes y LFOs, todo conectado mediante cables virtuales. Aquí te explico cómo hacerlo paso a paso, sin rodeos.

Por qué React y Web Audio API encajan bien

La Web Audio API es un grafo de nodos: cada nodo genera o transforma audio. Tienes osciladores, filtros, ganancias, retardos… y los conectas entre sí. Eso es exactamente un modular. React, por su parte, te da componentes reutilizables para representar cada módulo y su panel de controles. La clave está en mantener el grafo de audio fuera del flujo normal de renderizado de React, para que los cambios de estado no interrumpan el sonido.

Paso 1: Prepara el proyecto

Lo primero: crea una app con Vite (o Create React App, aunque Vite es más rápido). No necesitas librerías extra de audio; la Web Audio API viene con el navegador. Para el estado global puedes usar React Context, o si prefieres algo más robusto, Zustand. En este ejemplo me quedo con Context y useReducer para mantenerlo simple.

Sintetizador modular en el navegador con React y Web Audio API

Paso 2: Crea el contexto de audio

El AudioContext debe ser único y crearse tras un gesto del usuario, porque los navegadores bloquean el autoplay. Puedes inicializarlo en un useEffect al montar el componente principal, pero es mejor esperar a que el usuario pulse un botón de arranque. Algo así:

const [audioContext, setAudioContext] = useState(null);
const iniciarAudio = () => {
  const ctx = new (window.AudioContext || window.webkitAudioContext)();
  setAudioContext(ctx);
};
<button onClick={iniciarAudio}>Encender audio</button>

Guarda el contexto en un Context para que todos los módulos puedan acceder.

Paso 3: Diseña el sistema de módulos

Cada módulo tendrá una representación en React (la interfaz) y una representación en el grafo de audio (los nodos Web Audio). Define un objeto base con propiedades como id, tipo, inputs, outputs y parámetros. Los tipos posibles: osc, filter, env, lfo. Los cables virtuales son conexiones entre la salida de un módulo y la entrada de otro. Puedes guardar estas conexiones en un array.

Paso 4: Implementa los módulos de audio

Aquí está el corazón. Para el oscilador: ctx.createOscillator(), ajustas frequency y type, y lo conectas a un GainNode que servirá como salida. El filtro: ctx.createBiquadFilter(), con frequency y Q. La envolvente es más complicada porque Web Audio no trae un nodo ADSR listo; tendrás que usar un GainNode y programar los cambios con setTargetAtTime o linearRampToValueAtTime al recibir un trigger. El LFO es otro oscilador, pero en lugar de conectarlo a un destino de audio, conectas su salida a un parámetro de otro nodo (por ejemplo, filter.frequency) usando lfo.connect(filter.frequency).

Paso 5: Conecta los nodos

La interconexión es la esencia del modular. En tu estado guardas las conexiones lógicas: { from: 'osc1', to: 'filter1', inputIndex: 0 }. Cuando algo cambia, recorres esas conexiones y llamas a connect() en los nodos correspondientes. Ojo: desconecta antes de volver a conectar para evitar acumulaciones. Puedes usar disconnect() sin argumentos para limpiar todas las conexiones de un nodo y luego reconectar.

Paso 6: Interfaz con controles y cables visuales

Para cada módulo crea un componente que renderice su nombre, sus controles (deslizantes, selectores) y sus puntos de entrada/salida. Los controles actualizan los parámetros de audio en tiempo real: por ejemplo, un slider de frecuencia cambia oscillator.frequency.value. Para visualizar las conexiones puedes usar SVG: dibuja líneas curvas entre los puntos de salida y entrada. Hay librerías que facilitan el drag and drop de cables, como React Flow, pero puedes empezar con algo más sencillo: dos selectores desplegables para elegir origen y destino.

Paso 7: Optimiza el rendimiento

El audio en tiempo real es sensible. No recrees nodos en cada render; crea los nodos una vez (en un useEffect con array vacío) y luego solo actualiza parámetros. Usa React.memo para los componentes de módulo y useCallback para los event handlers. Si tienes muchos módulos, considera usar requestAnimationFrame para actualizar visualizaciones, no para el audio. Y no olvides limpiar: al desmontar un módulo, desconecta y detén sus nodos.

Preguntas frecuentes

¿Necesito ser un experto en React?

No. Con conocimientos básicos de hooks y componentes puedes seguir esta guía. La parte de audio es más de lógica que de React avanzado.

¿Funciona en todos los navegadores?

Web Audio API está soportada en Chrome, Firefox, Safari y Edge. En móviles también, pero debes gestionar bien el gesto del usuario para desbloquear el audio.

¿Puedo exportar el sonido generado?

Sí, usando MediaRecorder con un MediaStreamAudioDestinationNode puedes grabar la salida del AudioContext y descargarla como archivo WAV o WebM. No es el objetivo de esta guía, pero es factible.

¿Hay alguna librería que ya haga esto?

Existen proyectos como Tone.js que simplifican la síntesis, pero construir tu propio modular te da control total y aprendizaje profundo.

Con estos cimientos tienes un sintetizador modular funcional y extensible. A partir de aquí puedes añadir más módulos: delay, reverb, secuenciador… El límite lo pones tú.