Theremin Web · Documentación

Documento 03 · Especificación técnica

De píxeles a presión sonora

Inventario verificable del instrumento: adquisición de vídeo, estimación de manos, matemáticas de afinación, automatización continua, síntesis, dinámica, espacio, persistencia, captura y límites.

Sin backendMediaPipe 0.10.35AudioWorklet preferidoDo1–Do7La4 = 440 Hz

Alcance, versión y términos

Esta especificación describe el código de Theremin Web 3 en julio de 2026. Los valores indicados son constantes o comportamientos de la implementación, no objetivos de marketing.

Instrumento digital gestual

No hay osciladores RF ni medida de capacitancia. La cámara entrega coordenadas y Web Audio genera la señal.

Aplicación estática

HTML, CSS y JavaScript ES modules; sin framework, bundler, build, base de datos ni backend propio.

Históricamente informada

Los perfiles RCA/Rockmore modelan tendencias espectrales y registros; no son emulación circuital ni clon medido.

Definiciones operativas

  • Continuidad C0: la frecuencia no presenta saltos de valor entre objetivos; la pendiente puede cambiar entre rampas.
  • Libre: identidad exacta respecto al mapeo logarítmico, sin redondeo a MIDI.
  • Inercia: tiempo expresivo adicional aplicado al enlace de tono; no es el puente técnico mínimo entre frames.
  • Cabinet: ruta que aproxima amplificador, altavoz y caja. Una IR externa complementa esa cadena.
  • Latencia indicada: estimación del navegador para salida de audio; no incluye toda la cadena de visión.

Arquitectura de extremo a extremo

Separación modular

Responsabilidades de los módulos
MóduloResponsabilidadNo debe decidir
main.jsOrquestación, estado de sesión, modos, calibración, herramientas.Algoritmo DSP interno.
handTracking.jsCámara, MediaPipe, timestamps y asociación temporal.Frecuencias musicales.
mapping.jsLandmarks → frecuencia/volumen/velocidad.Forma de onda.
scale.jsConversión MIDI/nombre y atracción a escala.Adquisición visual.
pitchTrajectory.jsPuente exponencial continuo entre controles.Rango o escala.
thereminVoice.jsFuente, saturación, formantes, filtro, VCA y vibrato.Cámara o persistencia.
audioEngine.jsMezcla, cabinet, sala, eco, master y bus de grabación.Identidad de manos.
recorder.jsMediaRecorder y WAV PCM.Vídeo o micrófono.

El grafo Web Audio se crea después del gesto EMPEZAR. Las dos voces nacen una sola vez por sesión; los cambios de preset o cabinet usan automatización y crossfade, no destrucción inmediata de nodos.

Visión por computador y tracking

Modelo

MediaPipe Tasks Vision 0.10.35, Hand Landmarker float16, modo VIDEO, máximo dos manos. Umbrales de detección, presencia y tracking: 0,5.

Entrada solicitada

Cámara frontal por defecto, 1280×720 ideal, hasta 60 FPS, audio:false. Las restricciones son ideales: el navegador negocia lo disponible.

Delegación

Se intenta GPU. Si la creación falla, se reconstruye el modelo con CPU. Esto cambia rendimiento, no mapeo musical.

Bucle

requestVideoFrameCallback si existe; requestAnimationFrame como fallback. Se evita procesar dos veces el mismo video.currentTime.

Landmarks utilizados

  • Centro de palma: promedio 2D de muñeca y MCP 0, 5, 9, 13 y 17. Es más estable que una punta de dedo.
  • Pinza: distancia pulgar–índice, landmarks 4 y 8.
  • Escala de mano: distancia muñeca–MCP medio, landmarks 0 y 9, usada para normalizar la pinza.
  • Handedness: se conserva como metadato, pero los roles se asignan por trayectoria para resistir espejado y cruces.

Asociación y pérdidas

Con dos tracks previos se comparan asignación directa e intercambiada usando posición predicha por velocidad. Sin historial, las manos se ordenan por X teniendo en cuenta el espejo. Una sola mano se conecta al track cercano si la distancia es menor que 0,32; si no, se decide por mitad de imagen.

Una mano ausente conserva su último estado hasta 110 ms. Después la voz se silencia y se reinician mapeo y afinador. Un watchdog comprueba cada 100 ms si dejaron de llegar callbacks: su umbral nominal es 260 ms, por lo que el apagado efectivo puede caer aproximadamente entre 260 y 360 ms.

Límite geométrico

MediaPipe estima una mano visible; no recupera datos detrás de una oclusión completa. El seguimiento temporal reduce intercambios, pero no puede garantizar identidad si ambas manos desaparecen y reaparecen cruzadas.

Referencia externa: Hand Landmarker para Web y artículo de MediaPipe Hands.

Mapeo gestual y filtros

Tono vertical

El centro Y de la palma se filtra, se invierte —porque Y=0 está arriba—, se normaliza a la zona calibrada y se convierte a frecuencia:

Fórmula

p = clamp((1 − yFiltrada − inputLow) / (inputHigh − inputLow), 0, 1)
f = fMin × (fMax / fMin)p

El exponente hace que una distancia visual igual represente un intervalo igual en octavas/cents. X no entra en la fórmula; solo ayuda a identidad y dibujo.

Filtro One Euro

Parámetros de entrada
SeñalminCutoffbetadCutoffObjetivo
Posición1,80,321,2Estabilidad en reposo con respuesta al movimiento.
Apertura1,50,0101,0Dinámica menos nerviosa.
Velocidad2,501,0Decidir atracción a escala.

Volumen

En Dúo, la pinza normalizada se convierte así: silencio en ratio ≤0,18, máximo desde 1,05 y curva v1,3. En Clásico, la mano izquierda usa altura calibrada para emular la antena de volumen. La derecha mantiene el tono.

La VCA no aplica esa amplitud linealmente en los perfiles históricos: usa −48 × (1 − √amplitud) dB para ganar resolución expresiva en el tramo bajo.

Continuidad tonal, afinación y escalas

La cámara entrega objetivos discretos a 24–60 FPS; el audio trabaja normalmente a decenas de miles de muestras por segundo. Theremin Web no mantiene cada objetivo como escalón: programa el tramo que debe recorrer la frecuencia hasta el siguiente control.

Reglas de la trayectoria

  • El intervalo de control se estima y limita entre 1/120 y 1/12 s.
  • La rampa cubre al menos 1,15 × el intervalo estimado para solaparse con el siguiente frame.
  • El puente final se limita a 12–80 ms; la inercia elegida puede dominar dentro de ese margen.
  • exponentialRampToValueAtTime interpola geométricamente: lineal en octavas/cents, no en Hz.
  • cancelAndHoldAtTime retiene el valor exacto cuando llega un nuevo destino. Un fallback reconstruye matemáticamente la posición de la rampa en motores antiguos.
  • El Worklet desvanece cada armónico durante el 18 % previo al límite seguro de Nyquist; evita que aparezca/desaparezca como entero.
Qué garantiza

Continuidad de valor en la señal programada y un barrido Libre estrictamente monótono para una entrada monótona. No garantiza pendiente C1 ni elimina irregularidades de una detección visual errática.

Escalas y “afina al parar”

Definición de escalas en semitonos desde la tónica
EscalaIntervalosRespuesta
LibreIdentidad exacta; factor de atracción = 0.
Cromática0…11Atrae al semitono más próximo al detenerse.
Pentatónica mayor0, 2, 4, 7, 9Atrae a cinco grados por octava.
Mayor0, 2, 4, 5, 7, 9, 11Siete grados relativos a la tónica.
Menor natural0, 2, 3, 5, 7, 8, 10Siete grados relativos a la tónica.

Velocidad ≥1,6 unidades normalizadas/s produce factor libre; ≤0,25 produce atracción completa. Entre ambos se interpola. El factor usa constante temporal de 45 ms y la frecuencia final se mezcla geométricamente hacia la nota de temperamento igual, La4=440 Hz.

Frecuencias, octavas y equivalencias instrumentales

Explorador de rango

Modifica el grave y la extensión para visualizar Do sucesivos. El cálculo limita el agudo a 5000 Hz, como la app.

Perfiles implementados

Rangos exactos del modo Clásico
PerfilMínimoMáximoOctavasUso
Concierto completo32,70319566 Hz · Do12093,004522 Hz · Do76Extremo medido del instrumento Rockmore restaurado.
RCA 1929123,47 Hz · ≈Si21396,91 Hz · Fa6≈3,5Especificación histórica aproximada.
Rockmore estable65,41 Hz · Do22093 Hz · Do75Registro de concierto prudente.
Webcam cómoda130,81 Hz · Do31046,5 Hz · Do63Mayor resolución espacial por semitono.

Equivalencias de registro — no de timbre

Cómo se sitúa Do1–Do7 frente a instrumentos acústicos
ReferenciaRegistro aproximadoRelación con Theremin Web
Piano de 88 teclasLa0–Do8Do1–Do7 cubre 72 semitonos: omite La0–Si0 y la última octava superior.
Contrabajo≈Mi1–Do5 sonandoLa zona grave del theremin solapa su fundamental, pero no su ataque ni caja.
VioloncheloDo2 hacia registros agudosDo2 es su cuerda grave; la riqueza RCA baja puede recordarlo perceptualmente.
Voces humanasConjunto aproximado Mi2–Do6El medio Rockmore puede sugerir una voz sostenida, sin formantes articulados ni texto.
ViolínSol3 hacia ≈La7Gran solapamiento superior; el theremin carece de arco, cuerda y resonancia de madera.
Flauta de conciertoDo4–Do7 y algo másLos agudos casi sinusoidales pueden evocar flauta o silbido, no simular su columna de aire.
ÓrganoMucho más amplio según registrosÓrbita puede resultar organístico por parciales estables; no modela tubos ni recinto.
Do1 exige transductor

El motor genera 32,7 Hz con sus armónicos; un teléfono o portátil puede dejar audible solo la estructura superior. La documentación de rango describe la señal, no la respuesta de tu altavoz.

Síntesis por voz y modelado tímbrico

Grafo común de una voz

Ruta preferida: AudioWorklet

  • frequency: a-rate, 16–5000 Hz.
  • detune: a-rate, −100…+100 cents.
  • timbreAmplitude: k-rate, 0…1; modula riqueza en perfiles históricos.
  • Fuente aditiva monofónica y determinista. Los perfiles históricos parten de pulso redondeado con duty/richness dependientes del registro.
  • RCA/Rockmore usan hasta 24 armónicos; Sci‑Fi solicita hasta 32, siempre limitados por frecuencia de muestreo.
  • Cambio de perfil con crossfade lineal de 50 ms y fase continua compartida.
  • Experimental suma fundamental, parciales 2/3/4/7/11, quinta 1,5× y octava 2,006×.

Fallback nativo

Si AudioWorklet no está disponible o su módulo no carga, se construyen OscillatorNode y PeriodicWave:

  • Siete ondas históricas ancladas en Do1…Do7, 32 armónicos, con riqueza decreciente y duty creciente.
  • Crossfade equal-power entre las dos anclas vecinas en log2(frecuencia).
  • PeriodicWave Sci‑Fi de hasta 40 armónicos y banco experimental con tres osciladores.
  • Ambas rutas comparten filtros, saturación, VCA, cabinet y efectos, pero no son bit-idénticas.

Saturación, formantes y filtro

La tabla de WaveShaper tiene 4096 puntos, drives positivo/negativo 1,55/1,22 y nivel negativo 0,91, con oversampling 4×. Rockmore realza 720 Hz +2,5 dB y 1450 Hz +1,7 dB; RCA +1,8/+1,1 dB. El filtro de salida se cierra al subir:

  • Rockmore: max(2450, 5100 − 690 × octavas sobre Do2) Hz.
  • RCA: max(2700, 5600 − 650 × octavas sobre Do2) Hz.
  • Sci‑Fi: 9200 Hz. Experimental: 7200 Hz.
Principio acústico

Los graves históricos son ricos, asimétricos y comparables a un centro de violonchelo; al subir se pierden armónicos hasta una señal próxima a seno. “Comparable” describe percepción, no emulación de instrumento acústico.

Referencia sobre el entorno usado: AudioWorklet en MDN.

Presets sonoros: valores y finalidad

Configuración base de cada preset
PresetPerfilCabinetVibratoGlideReverbEco
RCA/RockmorercaNoNo12 ms4 %0
Rockmore conciertorockmoreNo10 ms12 %0
RCA + Cabinet 1929rcaNo12 ms10 %0
Ciencia ficciónscifiNo5,8 Hz · 34 ¢65 ms34 %16 %
Órbita prismáticaexperimentalNoNo36 ms30 %13 %

Envolvente

Rockmore define ataque 12 ms y release 24 ms. Los demás usan la constante de ganancia del perfil: RCA 18 ms, Cabinet 22 ms, Sci‑Fi 45 ms, Experimental 30 ms. La configuración interpretativa puede sustituir la respuesta de la voz derecha en Clásico.

Vibrato automático

Solo Sci‑Fi lo activa: comienza después de 450 ms de sonido audible y entra con constante de 240 ms. Rockmore, RCA y Experimental dejan el vibrato íntegramente a la mano.

Laboratorio XY

X mezcla de 0 a 1 hacia el perfil Experimental. Y añade hasta 0,42 de reverb y 0,18 de eco sobre la base; límites finales 0,72 y 0,34 respectivamente.

Cabinet 1929, espacio, eco y salida

Topología global

Cabinet modelado

Etapas del cabinet
EtapaValorFunción
Pasa-altos68 Hz · Q 0,72Limita excursión y subgrave.
Cuerpo+3,1 dB · 215 Hz · Q 0,82Resonancia de caja/grave.
Voz+2 dB · 860 Hz · Q 0,68Presencia media.
Pasa-bajos5000 Hz · Q 0,66Ancho de banda de altavoz antiguo.
SaturaciónWaveShaper asimétrico · 4×No linealidad moderada.
Compresión−15 dB · 2,2:1 · 18/95 msComportamiento mecánico aproximado.

Al activarse, la ruta directa va a 0 y cabinet a 0,92 mediante una constante de 55 ms. Una IR cargada se inserta después de filtros/saturación/compresión y sustituye la rama modelada final mediante crossfade de 80 ms; por tanto es una IR complementaria, no un “seco → IR” puro.

Sala de concierto

  • Convolver estéreo sintético de 1,6 s, decaimiento 2,35.
  • Ruido pseudoaleatorio determinista: mismo carácter para una misma frecuencia de muestreo.
  • Reflexiones tempranas a 11, 19, 31 y 47 ms con pequeño desplazamiento entre canales.
  • Rockmore: predelay 17 ms y damping a 4800 Hz.
  • El nivel seco se ajusta a 1 − wet × 0,22.

Eco y protección final

Sci‑Fi usa 158 ms / feedback 0,17; Experimental 243 ms / 0,27. El feedback pasa por LP 4800 Hz y el nivel visible se limita a 0,4. El compresor final actúa como limitador: umbral −1 dB, knee 1,5, ratio 20:1, ataque 2 ms, release 120 ms.

No es una IR histórica medida

La sala y el Cabinet 1929 son modelos diseñados. La app acepta una IR externa, pero todavía no incorpora una captura validada de un altavoz RCA 106 ni comparación espectral automatizada.

Latencia, cadencia y rendimiento

Estimador pedagógico

Suma media espera de captura, media rampa de enlace y latencia de salida que introduzcas. No incluye inferencia ni compositor del sistema; no sustituye una medida física extremo a extremo.

Qué muestra la interfaz

  • FPS: media exponencial 90/10 del reloj de callback.
  • Latencia: baseLatency + outputLatency cuando el navegador los expone.
  • No se mide fotón→landmarks, espera de scheduling, DAC, Bluetooth ni acústica.

Factores dominantes

Exposición de cámara

En poca luz, la cámara puede alargar exposición y bajar FPS antes de que el código intervenga.

Inferencia

GPU suele mejorar cadencia; CPU es fallback funcional. Resolución, SoC y carga térmica importan.

Audio

latencyHint:"interactive" solicita baja latencia, pero el navegador y dispositivo eligen el buffer real.

Transporte

Bluetooth puede añadir decenas o cientos de milisegundos fuera del control Web Audio.

Objetivo manual de QA: tracking estable ≥24 FPS en móvil medio y ≥30 FPS en escritorio; audio cableado por debajo de 50 ms declarados cuando el sistema lo permita. No se afirma como garantía universal.

Configuración, calibración y persistencia

Estado de fábrica

Modo Clásico · Rockmore · Libre · Do · Concierto completo Do1–Do7 · reverb 0,12 · Cabinet activo · inercia 10 ms · volumen 18 ms.

Persistencia

Los ajustes se guardan en localStorage bajo theremin-web:settings:v5. Existe migración desde v4: conserva datos seguros, descarta calibración horizontal y valida el rango.

Qué se conserva al recargar
Se guardaNo se guarda
Sonido, perfil, modo, escala, tónicaPosición de sliders XY
Reverb, cabinet, cámara, entrenamientoEstado drone
Rango, octavas, inercia, volumenGestos en memoria
Calibración tono/volumenIR externa cargada

Calibración robusta

  • Cuatro poses: grave, agudo, silencio, forte.
  • Ventana de 340 ms y mínimo de seis muestras; estadístico mediana.
  • Recorrido de tono mínimo: min(0,55, max(0,22, octavas × 0,075)).
  • Separación mínima de volumen: 0,12.
  • Admite gestos normales o invertidos y normaliza sus extremos.

Grabación, WAV y datos de gestos

Audio

  • MediaStreamDestination recibe la mezcla después de efectos, limitador y master.
  • Orden de códec: WebM/Opus, WebM, Ogg/Opus, MP4, según MediaRecorder.isTypeSupported.
  • Se solicitan chunks cada 100 ms y se construye un Blob al detener.
  • La conversión WAV decodifica el Blob y escribe RIFF PCM entero de 16 bits con mismos canales, sample rate y número de frames.
  • Web Share es opcional; la descarga local sigue disponible si no existe.

Gestos

El formato JSON versión 1 registra eventos {t, frequency, amplitude, preset}, muestreados como máximo a 30 Hz. La importación limita a 18 000 eventos. La reproducción automatiza la voz derecha con requestAnimationFrame.

Entrenamiento

  • Cents respecto al semitono temperado más próximo.
  • Estabilidad: desviación estándar de cents en historial reciente.
  • Vibrato: cruces alrededor del promedio durante una ventana aproximada de 1,2 s; necesita al menos 0,5 s y tres cruces.

Privacidad, red y seguridad

Sin subida de vídeo

No hay llamadas propias fetch/XHR/WebSocket, analítica ni telemetría. Los frames pasan de video al modelo local.

Descargas de ejecución

El módulo y WASM llegan de jsDelivr; el modelo float16, de Google Storage. Sin esos recursos previamente cacheados no hay arranque offline completo.

Almacenamiento local

Preferencias y calibración no están cifradas. No contienen vídeo, pero cualquier script del mismo origen podría leerlas.

Archivos del usuario

IR, JSON y grabación permanecen en memoria/local hasta descarga o compartir. No se envían automáticamente.

Cabeceras de Vercel

  • Permissions-Policy: camera=(self), microphone=()
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin
  • Cache-Control: public, max-age=0, must-revalidate

No hay Content Security Policy, Subresource Integrity ni service worker. Añadir CSP requiere autorizar explícitamente jsDelivr, Google Storage, WebAssembly y las necesidades de MediaPipe.

Compatibilidad y matriz de fallbacks

Requisitos mínimos

  • HTTPS o localhost para cámara.
  • JavaScript ES modules, dynamic import y WebAssembly.
  • getUserMedia y Web Audio.
  • MediaRecorder solo para la función de grabación.
Degradación controlada
Capacidad preferidaFallbackDiferencia observable
MediaPipe GPUCPUPosible reducción de FPS / mayor consumo.
requestVideoFrameCallbackrequestAnimationFrameMenor sincronía con frames reales; se evita duplicación.
AudioWorkletOscillatorNode + PeriodicWaveTimbre aproximado, no bit-idéntico.
cancelAndHoldAtTimeReconstrucción de trayectoriaMisma intención continua en motores antiguos.
MediaRecorder WebM/OpusWebM, Ogg o MP4Contenedor depende del navegador.
Conversión WAVArchivo comprimido originalWAV puede no generarse si el códec no se decodifica.
Web ShareDescargaSin panel de compartir del sistema.

Navegadores objetivo de QA

Chrome y Edge en Windows; Firefox; Safari en macOS e iOS/iPadOS; Chrome en Android. La sintaxis y las pruebas unitarias no sustituyen una sesión HTTPS con cámara/audio real en cada plataforma.

Límites conocidos y afirmaciones que no se hacen

Modelo, no clon

RCA/Rockmore y Cabinet 1929 son modelos perceptivos basados en tendencias documentadas. No reproducen cada válvula, transformador, bobina, antena, distorsión del altavoz ni interacción eléctrica del cuerpo.

  • No existe todavía una IR medida y validada de RCA 106 incluida de fábrica.
  • Worklet y fallback nativo no son espectralmente idénticos.
  • No hay medida automatizada de latencia cámara→altavoz ni compensación de Bluetooth.
  • No hay pruebas OfflineAudioContext de barridos completos ni comparación espectral contra grabaciones de referencia.
  • La cámara 2D no mide distancia real, capacitancia, profundidad ni orientación completa.
  • Los extremos Do1/Do7 pueden ser poco útiles según altavoz, FPS, campo calibrado y técnica.
  • Una IR importada no tiene límite explícito de duración/tamaño y pasa después de parte del modelado.
  • Grabaciones largas permanecen en memoria; no hay streaming a disco.
  • No existe backend, colaboración en tiempo real, MIDI, OSC, PWA ni funcionamiento offline completo.
  • Las escalas ofrecen atracción tonal, no garantía de afinación durante cada gesto.
  • La asociación de manos no puede resolver oclusiones completas indefinidas.

Prioridades técnicas futuras

  1. Medición de cabinet/altavoz histórico y banco de comparaciones espectrales.
  2. Pruebas de audio offline con jitter, dropouts, cambios de registro y límites de Nyquist.
  3. Medida física extremo a extremo mediante flash/clic o loopback.
  4. Validación y límites de IR/JSON, gestión de Object URL y grabación larga.
  5. QA pública completa en la matriz de navegadores y dispositivos.

Mapa del código y referencias externas

Archivos de implementación
ArchivoConceptos clave
src/config.jsVersiones, filtros, rangos, presets, escalas y referencia 440 Hz.
src/handTracking.jsMediaPipe, cámara, landmarks, asociación y FPS.
src/oneEuro.jsFiltro adaptativo de posición, apertura y velocidad.
src/mapping.jsNormalización vertical, ecuación logarítmica y pinza.
src/scale.jsTemperamento igual, nombres españoles y atracción dinámica.
src/pitchTrajectory.jsEstimación de frame y automatización continua compatible.
src/theremin-worklet.jsFuente aditiva a-rate, perfiles y antialias gradual.
src/thereminVoice.jsFallback, filtros, saturación, VCA y vibrato.
src/audioEngine.jsCabinet, convolver, eco, limitador y salida.
src/settings.jsEsquema v5, migración, validación y calibración.
src/recorder.jsMediaRecorder, Blob y codificador WAV.

Estándares y documentación base

Para el uso cotidiano vuelve al manual; para entender por qué estas decisiones importan consulta la historia documentada.