|

Theremin Glitch: proceso creativo y desarrollo

Theremin Glitch es una aplicación audiovisual interactiva que transforma la inclinación del dispositivo móvil en sonido y visuales generativos. El proyecto explora la relación entre gesto físico, síntesis sonora y representación visual en tiempo real, inspirándose en el funcionamiento del theremin tradicional, un instrumento que se toca sin contacto.

Repositorio de GitHub: https://github.com/dimecris/theremin-app

La app se puede probar en modo simulación moviendo el ratón.

Proceso de ideación

La idea del proyecto surgió a partir de la voluntad de trabajar con el movimiento del dispositivo como interfaz principal, evitando controles tradicionales como botones o sliders. El theremin apareció como una referencia clara, ya que plantea una relación directa entre gesto y sonido sin mediación física.

Desde el inicio se planteó la aplicación no como un instrumento musical preciso, sino como una experiencia experimental y sensorial. El objetivo era priorizar la exploración libre, donde cualquier gesto produjera una respuesta sonora y visual coherente, incluso imprevisible.

Proceso de diseño y prototipado

Antes de llegar a la versión final de la aplicación, se realizó una fase de exploración visual y funcional mediante bocetos y wireframes. El objetivo de esta etapa fue definir la relación entre la interfaz, el gesto físico del usuario y la respuesta audiovisual de la aplicación.

En una primera fase se trabajó con bocetos de baja fidelidad, centrados en la disposición de los elementos principales: botón de inicio, selección de tipo de onda y representación gráfica del sonido. Estos bocetos permitieron validar rápidamente la jerarquía visual y la claridad de la interacción sin entrar aún en decisiones estéticas.

Boceto inicial con exploración de ondas continuas y partículas como feedback visual.

 

Variación del boceto inicial, probando cambios en la densidad y posición de las partículas.

Posteriormente se desarrollaron wireframes más estructurados, en los que se definieron con mayor precisión los controles disponibles y su comportamiento. En esta fase se exploraron distintas representaciones de las ondas según el tipo de oscilador (senoidal, cuadrada, sierra y triangular), evaluando su legibilidad y coherencia visual.

Wireframe con representación de onda senoidal y controles básicos de interacción.

 

Wireframe con onda cuadrada, utilizado para evaluar diferencias visuales entre tipos de onda.

Este proceso de prototipado permitió tomar decisiones clave antes de la implementación final, como simplificar la interfaz para no interferir con la experiencia sonora; mantener el inglés, ya que la nomenclatura del tipo de onda era más precisa, corta y se adaptaba mejor a las dimensiones de la pantalla; mantener un número reducido de controles visibles y priorizar una estética minimalista y atmosférica que reforzara la relación entre gesto, sonido y visualización.

Desarrollo técnico y estructura

El desarrollo se basó en una arquitectura modular que separa claramente las responsabilidades del proyecto, facilitando la iteración y el mantenimiento del código. Cada módulo se encarga de una parte específica de la aplicación:

  • motion.js: lectura de los sensores de orientación mediante Capacitor
  • audio.js: síntesis sonora y cuantización musical
  • sketch.js: visualización generativa con p5.js
  • storage.js: persistencia de configuración con LocalStorage
  • main.js: módulo orquestador que coordina el flujo general

El proyecto se desarrolló con Vite como entorno de desarrollo y Capacitor como puente para acceder a funcionalidades nativas del dispositivo, como los sensores de movimiento y la vibración.

Stack tecnológico y plugins utilizados

La aplicación se desarrolló utilizando un stack basado en tecnologías web, priorizando herramientas ya trabajadas durante la asignatura y compatibles con el uso de sensores y audio en dispositivos móviles.

  • Vite: entorno de desarrollo y herramienta de build, utilizado por su rapidez y simplicidad en proyectos JavaScript modernos.
  • Capacitor: framework empleado para empaquetar la aplicación web como app nativa y acceder a funcionalidades del dispositivo.
  • @capacitor/motion: plugin oficial para la lectura de sensores de orientación e inclinación.
  • @capacitor/haptics: plugin utilizado para proporcionar feedback táctil mediante vibración.
  • p5.js: librería para la visualización generativa y el trabajo con canvas.
  • p5.sound: librería de síntesis sonora integrada en p5.js.

Este conjunto de tecnologías permitió desarrollar una aplicación experimental manteniendo una base web y extendiéndola a un contexto móvil sin necesidad de aprender un lenguaje nativo específico.

Proceso de desarrollo y workflow

El desarrollo del proyecto siguió un flujo de trabajo iterativo, alternando pruebas en navegador y pruebas en dispositivo móvil. Durante la fase de desarrollo se utilizó el servidor de desarrollo de Vite para iterar rápidamente sobre el código.

Una vez alcanzada una versión funcional, la aplicación se compiló y sincronizó con Capacitor para su ejecución en Android, siguiendo el flujo recomendado:

npm run build

npx cap sync

npx cap open android

Este proceso permitió comprobar el comportamiento real de los sensores, el audio y el rendimiento de la aplicación en un entorno nativo (Medium Phone API 36.1, Android 16 “Backlava” arm64), detectando diferencias respecto al comportamiento en escritorio.

La separación entre entorno de desarrollo (navegador) y entorno de ejecución (dispositivo móvil) fue clave para entender las limitaciones y particularidades del desarrollo web aplicado a apps móviles.

Decisiones técnicas relevantes

Durante el desarrollo surgió la duda de si gestionar el audio directamente con la Web Audio API o utilizar la librería  de p5.sound. Aunque la Web Audio API ofrece un control muy detallado y es perfectamente válida si se prefiere no añadir dependencias externas, finalmente se optó por p5.sound para mantener coherencia con el stack propuesto en el tutorial base y facilitar la integración con p5.js.

También se probó la librería Tone.js propuesta por el profesor, que es una opción moderna y muy potente para síntesis y manipulación de audio en la web. Tone.js destaca por su flexibilidad, su API orientada a músicos y su integración sencilla con proyectos JavaScript modernos. Sin embargo, para este proyecto concreto, se usó p5.sound que ya había trabajado en otras asignaturas.

Cabe destacar que la importación de p5.sound como módulo puede generar conflictos con sistemas de bundling como Vite. Por ello, se siguió la estrategia recomendada en el tutorial: cargar p5.js y p5.sound desde la carpeta public/ y acceder a ellas como variables globales. Esta solución evitó problemas de compilación y aseguró un comportamiento estable tanto en navegador como en la app empaquetada con Capacitor.

Consultas externas y documentación

A lo largo del proyecto se realizaron consultas a documentación externa y ejemplos de código para validar el uso de sensores, la gestión del audio en dispositivos móviles y el comportamiento de la aplicación en distintos entornos.

La documentación oficial de Capacitor fue especialmente relevante para comprender el funcionamiento del plugin Motion y las diferencias de comportamiento entre plataformas, especialmente en lo relativo a permisos en iOS frente a Android.

Pruebas, problemas y mejoras

Uno de los principales problemas detectados en las primeras versiones fue el carácter poco armónico del sonido al mapear directamente valores continuos de inclinación a frecuencia. Para solucionarlo, se implementó un sistema de cuantización a una escala pentatónica mayor, que permitió obtener un resultado más musical sin perder expresividad.

Otro reto importante fue poder desarrollar y depurar la aplicación sin depender constantemente de un dispositivo móvil. Para ello se incorporó un modo de depuración en escritorio que simula la inclinación del dispositivo mediante el ratón.

La parte visual también se fue refinando progresivamente. El sistema inicial de partículas resultaba demasiado errático, por lo que se ajustaron parámetros como la fricción, el uso de ruido Perlin y la sensibilidad al movimiento, logrando un comportamiento más orgánico y controlado.

La app se ha probado en IOS (con Xcode y con un dispositivo real) pero sin éxito. Incluso en el navegador Safari se probó, pero no funciona correctamente. Se detectó un error: se pasaba un NaN a la frecuencia en audio.js. Queda pendiente para su implementación y prueba en IOS en siguientes fases.

Funcionamiento e interacción

La interacción principal de la aplicación se basa en la inclinación del dispositivo móvil, que actúa como interfaz gestual. El usuario no manipula controles tradicionales, sino que modifica el sonido y la visualización a través del movimiento físico del teléfono.

En dispositivo móvil, el sistema interpreta la orientación del terminal en dos ejes principales:

  • Inclinación horizontal (eje X): controla la frecuencia del tono generado por el oscilador.
  • Inclinación vertical (eje Y): controla el brillo del sonido mediante un filtro pasa-bajos.

El inicio de la experiencia se realiza mediante un botón de activación que pone en marcha tanto los sensores como el audio. Este paso es necesario para cumplir con las políticas de los navegadores y sistemas operativos móviles, que requieren una interacción explícita del usuario para activar el AudioContext.

La aplicación permite detener el sonido en cualquier momento, pausando la síntesis sin perder el estado visual ni la configuración actual.

La configuración del sistema, como el tipo de onda o la sensibilidad del movimiento, se almacena localmente mediante LocalStorage. De este modo, la aplicación conserva las preferencias del usuario entre sesiones sin necesidad de configuración adicional.

Mapeo sensor–audio

El mapeo entre los sensores y los parámetros sonoros se diseñó de forma intencionadamente simple y legible, facilitando una relación directa entre gesto y resultado auditivo.

// Eje X (izquierda / derecha) → Frecuencia (200–1000 Hz)
tiltX → frequency (cuantizada a escala pentatónica mayor)

// Eje Y (adelante / atrás) → Filtro
tiltY → filterFrequency (400–1400 Hz)

La cuantización a escala pentatónica mayor permite evitar disonancias extremas y facilita que cualquier movimiento produzca un resultado sonoro coherente, manteniendo el carácter experimental de la aplicación.

Aprendizajes y conclusiones

El proyecto ha permitido comprender mejor las particularidades del desarrollo web aplicado a dispositivos móviles, especialmente en lo referente a sensores, permisos y restricciones de audio. También ha reforzado la importancia de una buena organización del código y de tomar decisiones técnicas coherentes con el contexto del proyecto.

Como conclusión, Theremin Glitch demuestra que es posible crear experiencias audiovisuales ricas utilizando tecnologías web estándar. La combinación de sensores, sonido y visualización generativa abre un amplio campo de experimentación artística e interactiva, con múltiples posibilidades de evolución futura.


Anexo técnico: instalación y despliegue

Este anexo recoge los pasos técnicos necesarios para crear el proyecto desde cero y desplegarlo en Android. Se incluye como referencia futura y como apoyo para comprender el entorno de desarrollo utilizado durante el proyecto.

Instalación desde cero

1. Verificación del entorno

Antes de iniciar el proyecto, es necesario comprobar que Node.js y npm están correctamente instalados:

node -v
npm -v

2. Creación del proyecto con Vite

El proyecto se crea utilizando Vite con el template vanilla, tal como se propone en el enunciado de la práctica:

npm create vite@latest theremin -- --template vanilla

cd theremin
npm install

3. Instalación e inicialización de Capacitor

Una vez creado el proyecto base, se instala Capacitor y se inicializa indicando el directorio de salida del build:

npm install @capacitor/core @capacitor/cli --save

npx cap init "Theremin" "com.theremin.app" --web-dir dist

Build y despliegue en Android

4. Añadir la plataforma Android

npm install @capacitor/android
npx cap add android

5. Instalación de plugins de Capacitor

Para acceder a los sensores de movimiento y al feedback háptico se instalan los siguientes plugins oficiales:

npm install @capacitor/motion @capacitor/haptics

6. Compilación y prueba en Android Studio

Una vez completado el desarrollo web, el proyecto se compila y se sincroniza con Capacitor para su ejecución en Android Studio:

npm run build

npx cap sync

npx cap open android

Este flujo permite ejecutar la aplicación en un emulador o dispositivo físico y comprobar el comportamiento real de los sensores, el audio y la visualización en un entorno nativo.


Nota metodológica sobre el uso de herramientas de inteligencia artificial

Durante el desarrollo del proyecto se utilizaron herramientas de asistencia basadas en inteligencia artificial como apoyo al proceso de aprendizaje y resolución de problemas técnicos.

En concreto, se empleó GitHub Copilot como herramienta de ayuda para la revisión de código y la generación de sugerencias durante la fase de desarrollo, y ChatGPT como soporte para la resolución de dudas conceptuales, técnicas y de documentación relacionadas con el stack tecnológico utilizado.

Bibliografía

  • Capacitor. (s. f.-a). Introducción a Capacitor. Disponible en: https://capacitorjs.com/docs (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-b). Instalando Capacitor. Disponible en: https://capacitorjs.com/docs/getting-started (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-c). Configuración del entorno. Disponible en: https://capacitorjs.com/docs/getting-started/environment-setup (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-d). Guía de desarrollo para Android. Disponible en: https://capacitorjs.com/docs/android (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-e). Vibración (Haptics) — Capacitor Plugin API. Disponible en: https://capacitorjs.com/docs/apis/haptics (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-f). Acelerómetro y giroscopio (Motion) — Capacitor Plugin API. Disponible en: https://capacitorjs.com/docs/apis/motion (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-g). Cámara (Camera) — Capacitor Plugin API. Disponible en: https://capacitorjs.com/docs/apis/camera (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-h). Almacenamiento local (Preferences) — Capacitor Plugin API. Disponible en: https://capacitorjs.com/docs/apis/preferences (Consultado el: 23 de diciembre de 2025).
  • Capacitor. (s. f.-i). Conceptos web/nativos (Development Workflow). Disponible en: https://capacitorjs.com/docs/basics/workflow (Consultado el: 23 de diciembre de 2025).
  • GitHub. (s. f.). GitHub Copilot. https://github.com/features/copilot
  • OpenAI. (s. f.). ChatGPT. https://chat.openai.com/
  • Tone.js. (s. f.). https://tonejs.github.io/

Publicaciones Similares

Deja una respuesta