Hacer música en un navegador: recrear Theremin con JS y Web Audio API

 

 

 


Índice
  1. La API de audio web
  2. Control del ratón
  3. Frecuencia y tono
    1. Otras lecturas

El sonido único del theremin resulta perfecto para bandas sonoras de ciencia ficción y Good Vibrations de los Beach Boys. El mundo es un mejor lugar. Con este tutorial, Stuart Memo espera que puedas ver lo sencillo que puede ser poner en marcha algo musical con bastante rapidez. Incluso puedes utilizar las siguientes técnicas para hacer un sintetizador. Stuart creó un pequeño teclado HTML llamado Qwerty Hancock para ayudarte a hacer esto. ¡Siéntete libre de mostrar tu propia creación!

 

Petrogrado, Rusia, 1920. En lo profundo de su laboratorio científico, un joven Léon Theremin se da cuenta accidentalmente de que el sonido procedente de uno de sus osciladores de alta frecuencia cambia de tono cuando mueve la mano. La cultura popular ha cambiado para siempre. El sonido único del theremin resulta perfecto para bandas sonoras de ciencia ficción y Good Vibrations de los Beach Boys. El mundo es un mejor lugar.

Durante casi un siglo, los músicos han estado esperando que una tecnología innovadora similar cambie nuevamente la forma en que creamos música. Estoy encantado de anunciar que ya ha llegado. Se llama Web Audio API.

La API Web Audio es una forma de alto nivel y alto rendimiento de crear y manipular sonido en el navegador. Así es, podemos hacer sonido en el navegador sin necesidad de ningún complemento o MP3 a la vista . Es más, te voy a mostrar cómo recrear el sorprendente invento de Léon Theremin con un poco de JavaScript .

La API de audio web

Actualmente, la API Web Audio es compatible con todos los principales navegadores excepto Internet Explorer , pero Microsoft Edge está solucionando ese problema . Imagínese un guitarrista eléctrico. Podrían tomar la ventaja de su guitarra, conectarla a un pedal de efectos y luego conectarla a un amplificador. Este concepto de encadenar cosas es fundamental para la API.

Para emitir un sonido, primero necesitaremos una página web simple con una referencia a un archivo JavaScript, algo como esto:

!doctype htmlhtml head meta charset="utf-8" / titleMy Theremin/title /head body h1My Theremin/h1 script src="theremin.js"/script /body/html

Luego, theremin.jscrearemos un AudioContext. Así AudioContextes como accedemos a los diversos métodos de la API de Web Audio. También querremos un oscilador que genere un tono continuo.

 

var context = new AudioContext(), oscillator = context.createOscillator();

Nota: La API Web Audio todavía tiene el prefijo en Safari 9.1 y se utiliza new webkitAudioContext()en lugar de new AudioContext().

Para continuar con nuestra analogía de la guitarra, necesitamos tomar una ventaja del oscilador y conectarlo a nuestros parlantes. Esto se hace usando el connectmétodo. Podemos acceder a nuestros altavoces usando context.destination.

oscillator.connect(context.destination);

Ahora que todo está conectado, necesitamos iniciar el oscilador para generar un tono. Esto es tan fácil como escribir lo siguiente:

oscillator.start(context.currentTime);

Puedes ver que hemos pasado context.currentTimepor aquí. Esto significa que le estamos diciendo al navegador que inicie el oscilador ahora. Para detenerlo simplemente decimos esto:

oscillator.stop(context.currentTime + 1);

Esto detendrá la reproducción del oscilador dentro de 1 segundo. Guarde y abra su página en el navegador para escuchar un hermoso tono de 440 Hz por un segundo. Hermoso.

Control del ratón

Ahora bien, un sonido que suena cuando cargamos la página es una cosa, pero si queremos convertirlo en un instrumento, tendremos que tener control sobre cuándo comienza y cuándo se detiene.

Hagamos de toda la página nuestra área de juego. Agregue algunos estilos simples a la página para asegurarse de que el bodyelemento cubra toda el área visible y que sea más interesante que el blanco simple.

html, body { background: darkmagenta; height: 100%;}

A continuación, agregaremos algunos detectores de eventos de clic al bodyelemento:

document.body.addEventListener('mousedown', function () { // Mouse has been pressed});document.body.addEventListener('mouseup', function () { // Mouse has been released});

Quizás esté pensando: "Está bien, dejemos la startllamada en mousedowny stopen mouseup". Es un poco más complicado que eso. Los osciladores, por diseño, sólo pueden iniciarse y detenerse exactamente una vez. Piense en ellos como una especie de extraños fuegos artificiales de audio. En realidad, esto es mejor para el rendimiento, porque significa que no permanecerán en la memoria esperando a ser utilizados cuando no sea necesario. Afortunadamente, los osciladores son baratos y fáciles de fabricar, por lo que crearemos uno cada vez que el usuario mantenga presionado el botón del mouse.

var context = new AudioContext(), oscillator = null;document.body.addEventListener('mousedown', function () { oscillator = context.createOscillator(); oscillator.connect(context.destination); oscillator.start(context.currentTime);});document.body.addEventListener('mouseup', function () { oscillator.stop(context.currentTime); oscillator.disconnect();});

Tenga en cuenta que para detener el oscilador que hemos creado en el mousedowndetector de eventos, debemos mantener una referencia a él fuera del alcance de la función, para que mouseupsepa detener ese oscilador exacto.

 

Además, para estar seguros, debemos verificar que el oscilador realmente se haya creado antes de llamarlo stop. Si bien es poco común tener un mouseupevento sin mousedownprecedente, es una buena práctica de programación verificar que un objeto existe antes de realizar operaciones en él.

document.body.addEventListener('mouseup', function () { if (oscillator) { oscillator.stop(context.currentTime); oscillator.disconnect(); }});

¡Actualice el navegador para sorprenderse con el sonido que se reproduce en respuesta a los clics del mouse! ¡Siéntete decepcionado cuando te des cuenta de que todo lo que puedes hacer es escribir un código morse incomprensible! Arreglemos eso.

Frecuencia y tono

Un theremin cambia de tono cuando cambia la posición de la mano del jugador. El tono es qué tan alto o bajo es una nota, que técnicamente es la velocidad a la que vibra el instrumento que produce la nota. La frecuencia de estas vibraciones se mide en hercios y, afortunadamente, la API de Web Audio nos permite especificar la frecuencia de un oscilador para cambiar el tono exactamente de esta manera.

Justo después de la línea en la que creamos el oscilador, cambia la frecuencia así:

oscillator.frequency.value = 600;

Ahora podrás hacer tapping en un tono diferente. Sin embargo, lo que queremos hacer es alterar el tono dependiendo de en qué parte de la pantalla se encuentre el mouse, sin hacer clic repetidamente.

Nuestro mousedowndetector de eventos nos pasa el evento del mouse en la devolución de llamada, que etiquetaremos e. Podemos obtener la coordenada x de esto usando la clientXpropiedad.

document.body.addEventListener('mousedown', function (e) { console.log(e.clientX);});

Entonces, ¿qué tenemos que hacer para convertir esta coordenada en una frecuencia adecuada para un theremin? Comencemos creando una calculateFrequencyfunción que tome la coordenada x y devuelva una frecuencia.

var calculateFrequency = function (mouseXPosition) {};

La coordenada x del extremo izquierdo de la ventana del navegador es 0, mientras que la coordenada del extremo derecho es el ancho del navegador en píxeles. Sin hacer nada, este es en realidad un rango bastante bueno. El rango de audición humana va de 20 a 20.000 Hz, aunque las cosas empiezan a ponerse desagradables alrededor de los 2.000 Hz, por lo que no queremos ir más allá de eso. Dicho esto, no podemos usar este rango tal cual porque limitaría los dispositivos pequeños a producir notas bajas en frecuencias bajas. En su lugar, deberíamos usar la relación entre el ancho desde el lado izquierdo de la pantalla hasta donde se produce el clic del mouse. Calefactor electrico

Primero, establecemos nuestras frecuencias mínima y máxima.

var minFrequency = 20, maxFrequency = 2000;

Para calcular la proporción, dividimos mouseXPositionpor el ancho de la ventana del navegador. Luego, para obtener la frecuencia, multiplica esta relación por la frecuencia máxima. Esto nos da una frecuencia de 0 a 2000 Hz. 0 Hz es inaudible, por lo que simplemente agregaremos 20 para superar el umbral del oído humano.

 

var calculateFrequency = function (mouseXPosition) { var minFrequency = 20, maxFrequency = 2000; return ((mouseXPosition / window.innerWidth) * maxFrequency) + minFrequency;};

A continuación, reemplace la frecuencia codificada en nuestra mousedownfunción con esto:

oscillator.frequency.value = calculateFrequency(e.clientX);

Esto calculará la frecuencia en función de la posición del clic del mouse, pero lo hará de manera bastante abrupta. Queremos que nuestro theremin se deslice suavemente entre frecuencias. Para hacer esto, utilizamos los métodos de automatización de Web Audio API. Estos métodos nos permiten programar dichos cambios en algún momento futuro, pero, lo que es más importante para nosotros, harán la transición de la frecuencia a su nuevo valor sin problemas . Para automatizar el cambio de frecuencia, eliminamos nuestra línea anterior y escribimos esto:

oscillator.frequency.setTargetAtTime(calculateFrequency(e.clientX), context.currentTime, 0.01);

Lo que estamos diciendo aquí es hacer una transición suave de la frecuencia del oscilador a lo largo del tiempo. El primer parámetro es la frecuencia a la que cambiar el oscilador, el segundo dice cuándo hacerlo (ahora) y el tercero es la velocidad a la que debe cambiar. Para este valor, queremos que la transición se produzca rápidamente, por lo que es apropiado un valor pequeño.

Pruébelo en su navegador haciendo clic en diferentes áreas para escuchar el cambio de tono.

Una característica distintiva del sonido del theremin es la forma en que se desliza de una nota a otra. Podemos lograr este mismo efecto rastreando la posición del mouse y actualizando la frecuencia a medida que se mueve. Usaremos el mousemoveevento y configuraremos un oyente de la misma manera que los demás. En él, estableceremos la frecuencia del oscilador como antes.

document.body.addEventListener('mousemove', function (e) { oscillator.frequency.setTargetAtTime(calculateFrequency(e.clientX), context.currentTime, 0.01);});

Sin embargo, este código provocará un error porque mousemovese activará incluso si no se presiona el mouse. Esto significa que es posible que el oscilador especificado aquí ni siquiera exista todavía. Podemos asegurarnos de que un oscilador acepte activamente valores de frecuencia realizando un seguimiento de si se ha hecho clic con el mouse.

var context = new AudioContext(), mousedown = false, oscillator;var calculateFrequency = function (mouseXPosition) { var minFrequency = 20, maxFrequency = 2000; return ((mouseXPosition / window.innerWidth) * maxFrequency) + minFrequency;};document.body.addEventListener('mousedown', function (e) { mousedown = true; oscillator = context.createOscillator(); oscillator.frequency.setTargetAtTime(calculateFrequency(e.clientX), context.currentTime, 0.01); oscillator.connect(context.destination); oscillator.start(context.currentTime);});document.body.addEventListener('mouseup', function () { mousedown = false; oscillator.stop(context.currentTime); oscillator.disconnect();});document.body.addEventListener('mousemove', function (e) { if (mousedown) { oscillator.frequency.setTargetAtTime(calculateFrequency(e.clientX), context.currentTime, 0.01); }});

Eso ya está resuelto. Pero el theremin tiene otra característica que lo hace tan expresivo. El intérprete puede alterar el volumen del instrumento simplemente moviendo la otra mano hacia arriba o hacia abajo para hacerlo más alto o más bajo. Podemos añadir esta funcionalidad a nuestro theremin web con bastante facilidad acercando el volumen de forma similar a la frecuencia.

 

Primero, necesitaremos agregar un archivo gainNode. ¿Recuerdas la analogía de la guitarra? Un nodo de ganancia es un efecto simple que podemos agregar a nuestra cadena para cambiar el volumen de una señal entrante. Lo crearemos en la parte superior con nuestras otras variables.

var gainNode = context.createGain();

Ahora necesitamos agregarlo a la posición correcta en nuestra cadena. Elimine la línea que conecta el oscilador context.destinationy en su lugar escriba lo siguiente:

oscillator.connect(gainNode);gainNode.connect(context.destination);

Aquí, tomamos la conexión del oscilador a nuestro nodo de ganancia y luego la conectamos a nuestros parlantes.

A continuación, duplique la calculateFrequencyfunción y cambie el nombre de la copia a calculateGain. En cambio, esta función aceptará la posición y del cursor como su único argumento. Y en lugar de una frecuencia mínima y máxima, estos valores representarán una ganancia. La ganancia es el valor por el cual desea multiplicar el volumen de la señal entrante. Entonces, si estableces la ganancia en 0,5, eso sería la mitad del volumen de nuestro oscilador. No queremos que nuestro instrumento suene más fuerte de lo que ya es, por lo que el valor mínimo será 0 y el máximo 1. El último ajuste de la función será restar nuestro cálculo de 1. Esto significa que el volumen aumentará en la parte superior de la pantalla y más silencioso en la parte inferior. La función final se ve así:

var calculateGain = function (mouseYPosition) { var minGain = 0, maxGain = 1; return 1 - ((mouseYPosition / window.innerHeight) * maxGain) + minGain;};

¡Excelente! Ahora todo lo que tenemos que hacer es establecer la ganancia a medida que se mueve el mouse. Nuevamente, duplique las dos líneas que especifican las frequency.setTargetAtTimelíneas y actualice la copia para hacer referencia a ellas gainNode. Ah, y recuerda usar la posición y del cursor.

gainNode.gain.setTargetAtTime(calculateGain(e.clientY), context.currentTime, 0.01);

¡He aquí nuestro encantador theremin ! Si miras el código fuente de mi versión, verás que también agregué oyentes para eventos táctiles, lo que significa que puedes molestar a otros en el transporte público mientras realizas tu obra maestra del theremin.

Hermoso. Léon Theremin estaría orgulloso: un instrumento musical en el navegador sin ningún complemento a la vista.

Este tutorial solo ha abordado la API de Web Audio, pero espero que le muestre lo sencillo que puede ser poner en marcha algo musical con bastante rapidez. Incluso puedes usar las técnicas que hemos aprendido aquí para hacer un sintetizador. He creado un pequeño teclado HTML llamado Qwerty Hancock para ayudarte a hacer esto mismo. No dudes en mostrar tu propia creación en los comentarios o enviarme un tweet . Me encantaría ver lo que haces.

Otras lecturas

  • Directrices para diseñar con audio
  • Cómo crear una caja de ritmos responsiva de 8 bits
  • Cómo aumentar el flujo de trabajo y reducir el estrés con sonidos de la naturaleza
  • Listas de reproducción de Spotify para impulsar sus sesiones de codificación y diseño

(rb, ml, al, il, mrn)Explora más en

  • Codificación
  • CSS
  • javascript
  • audio web





Tal vez te puede interesar:

  1. ¿Deberían abrirse los enlaces en ventanas nuevas?
  2. 24 excelentes tutoriales de AJAX
  3. 70 técnicas nuevas y útiles de AJAX y JavaScript
  4. Más de 45 excelentes recursos y repositorios de fragmentos de código

Hacer música en un navegador: recrear Theremin con JS y Web Audio API

Hacer música en un navegador: recrear Theremin con JS y Web Audio API

Índice La API de audio web Control del ratón

programar

es

https://aprendeprogramando.es/static/images/programar-hacer-musica-en-un-navegador-recrear-theremin-con-js-y-web-audio-api-894-0.jpg

2024-05-20

 

Hacer música en un navegador: recrear Theremin con JS y Web Audio API
Hacer música en un navegador: recrear Theremin con JS y Web Audio API

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Top 20