Índice
- ¿Qué es MIDI?
- MIDI en el navegador
- Escenario del mundo real: construcción de una sala de descanso controlada por un teclado de piano
- Conclusión
¿Es posible utilizar instrumentos musicales digitales como entradas del navegador? Con la API Web MIDI, la respuesta es ¡sí! La mejor parte es que es bastante rápido y fácil de implementar e incluso crear un proyecto realmente divertido. En este artículo, Peter Anglea cubrirá los conceptos básicos de MIDI y la API Web MIDI para ver lo sencillo que puede ser crear una aplicación web que responda a la entrada musical utilizando JavaScript.
A medida que la web continúa evolucionando y siguen surgiendo nuevas tecnologías de navegador, la línea entre el desarrollo nativo y el desarrollo web se vuelve cada vez más borrosa. Las nuevas API están desbloqueando la capacidad de codificar categorías de software completamente nuevas en el navegador.
Hasta hace poco, la capacidad de interactuar con instrumentos musicales digitales se limitaba a aplicaciones de escritorio nativas. La API Web MIDI está aquí para cambiar eso.
En este artículo, cubriremos los conceptos básicos de MIDI y la API Web MIDI para ver qué tan simple puede ser crear una aplicación web que responda a la entrada musical usando JavaScript.
¿Qué es MIDI?
MIDI existe desde hace mucho tiempo, pero recientemente hizo su debut en el navegador. MIDI ( M usical Instrument D igital I nterface) es un estándar técnico que se publicó por primera vez en 1983 y creó los medios para que instrumentos digitales, sintetizadores, computadoras y varios dispositivos de audio se comunicaran entre sí . Los mensajes MIDI transmiten información musical y basada en el tiempo entre dispositivos.
Una configuración MIDI típica podría consistir en un teclado de piano digital que puede enviar mensajes que transmiten información como tono, velocidad (qué tan alto o suave se toca una nota), vibrato, volumen, panorama, modulación y más a un sintetizador de sonido que convierte eso. en un sonido audible. El teclado también podría enviar sus señales a un software de composición musical de escritorio o a una estación de trabajo de audio digital (DAW) que luego podría convertir las señales en notación escrita, guardarlas como un archivo de sonido y más.
MIDI también es un protocolo bastante versátil. Además de reproducir y grabar música, también se ha convertido en un protocolo estándar en aplicaciones de escenario y teatro, donde a menudo se utiliza para transmitir información de señales o controlar equipos de iluminación.
MIDI en el navegador
La API WebMIDI ofrece todas las utilidades de MIDI al navegador con un JavaScript bastante simple. Sólo necesitamos aprender sobre algunos métodos y objetos nuevos.
Introducción
Primero, está el navigator.requestMIDIAccess()
método. Hace exactamente lo que parece: solicitará acceso a cualquier dispositivo MIDI (entradas o salidas) conectado a su computadora. Puede confirmar que el navegador admite la API comprobando la existencia de este método.
if (navigator.requestMIDIAccess) { console.log('This browser supports WebMIDI!');} else { console.log('WebMIDI is not supported in this browser.');}
En segundo lugar, está el MIDIAccess
objeto que contiene referencias a todas las entradas disponibles (como teclados de piano) y salidas (como sintetizadores). El requestMIDIAccess()
método devuelve una promesa, por lo que debemos establecer devoluciones de llamada de éxito y fracaso. Y si el navegador logra conectarse a sus dispositivos MIDI, devolverá un MIDIAccess
objeto como argumento para la devolución de llamada exitosa.
navigator.requestMIDIAccess() .then(onMIDISuccess, onMIDIFailure);function onMIDISuccess(midiAccess) { console.log(midiAccess); var inputs = midiAccess.inputs; var outputs = midiAccess.outputs;}function onMIDIFailure() { console.log('Could not access your MIDI devices.');}
En tercer lugar, los mensajes MIDI se transmiten de un lado a otro entre entradas y salidas con un MIDIMessageEvent
objeto. Estos mensajes contienen información sobre el evento MIDI, como el tono, la velocidad (qué tan suave o fuerte se toca una nota), sincronización y más. Podemos comenzar a recopilar estos mensajes agregando funciones de devolución de llamada simples (oyentes) a nuestras entradas y salidas.
Profundizando
Profundicemos. Para enviar mensajes MIDI desde nuestros dispositivos MIDI al navegador, comenzaremos agregando un onmidimessage
oyente a cada entrada. Esta devolución de llamada se activará cada vez que el dispositivo de entrada envíe un mensaje, como al presionar una tecla en el piano.
Podemos recorrer nuestras entradas y asignar al oyente así:
function onMIDISuccess(midiAccess) { for (var input of midiAccess.inputs.values()) input.onmidimessage = getMIDIMessage; }}function getMIDIMessage(midiMessage) { console.log(midiMessage);}
El MIDIMessageEvent
objeto que recuperamos contiene mucha información, pero lo que más nos interesa es la matriz de datos. Esta matriz normalmente contiene tres valores (p. ej. [144, 72, 64]
). El primer valor nos dice qué tipo de comando se envió, el segundo es el valor de la nota y el tercero es la velocidad. El tipo de comando podría ser “nota activada”, “nota desactivada”, controlador (como inflexión de tono o pedal de piano) o algún otro tipo de evento exclusivo del sistema (“sysex”) exclusivo de ese dispositivo/fabricante.
A los efectos de este artículo, nos centraremos únicamente en identificar correctamente los mensajes de "nota activada" y "nota desactivada". Aquí están los conceptos básicos:
- Un valor de comando de 144 significa un evento de "nota activada" y 128 normalmente significa un evento de "nota desactivada".
- Los valores de las notas están en un rango de 0 a 127, de menor a mayor. Por ejemplo, la nota más baja en un piano de 88 teclas tiene un valor de 21 y la nota más alta es 108. Un “Do central” es 60.
- Los valores de velocidad también se dan en un rango de 0 a 127 (de más suave a más fuerte). La velocidad de “nota activada” más suave posible es 1.
- A veces se utiliza una velocidad de 0 junto con un valor de comando de 144 (que generalmente representa "nota activada") para indicar un mensaje de "nota desactivada", por lo que es útil verificar si la velocidad dada es 0 como una forma alternativa de interpretar un mensaje de “nota desactivada”.
Dado este conocimiento, podemos ampliar nuestro getMIDIMessage
ejemplo de controlador anterior analizando inteligentemente nuestros mensajes MIDI provenientes de nuestras entradas y pasándolos a funciones de controlador adicionales.
function getMIDIMessage(message) { var command = message.data[0]; var note = message.data[1]; var velocity = (message.data.length 2) ? message.data[2] : 0; // a velocity value might not be included with a noteOff command switch (command) { case 144: // noteOn if (velocity 0) { noteOn(note, velocity); } else { noteOff(note); } break; case 128: // noteOff noteOff(note); break; // we could easily expand this switch statement to cover other types of commands such as controllers or sysex }}
Compatibilidad del navegador y Polyfill
Al momento de escribir este artículo, la API Web MIDI solo está disponible de forma nativa en Chrome, Opera y Android WebView.
Para todos los demás navegadores que no lo admiten de forma nativa, la biblioteca WebMIDIAPIShim de Chris Wilson es un polyfill para la API Web MIDI, de la cual Chris es coautor. Simplemente incluyendo el script shim en su página habilitará todo lo que hemos cubierto hasta ahora.
script src="WebMIDIAPI.min.js"/scriptscriptif (navigator.requestMIDIAccess) { //... returns true/script
Desafortunadamente, esta corrección también requiere que Jazz-Plugin de Jazz-Soft.net funcione, lo que significa que es una buena opción para los desarrolladores que desean la flexibilidad de trabajar en múltiples navegadores, pero una barrera adicional para la adopción generalizada. Con suerte, con el tiempo, otros navegadores adoptarán la API Web MIDI de forma nativa.
Haciendo nuestro trabajo más fácil con WebMIDI.js
Realmente sólo hemos arañado la superficie de lo que es posible con la API WebMIDI. Agregar soporte para funciones adicionales además de los mensajes básicos de “nota activada” y “nota desactivada” comienza a volverse mucho más complejo.
Si está buscando una excelente biblioteca de JavaScript para simplificar radicalmente su código, consulte WebMidi.js de Jean-Philippe Côté en Github. Esta biblioteca hace un gran trabajo al abstraer todo el análisis de MIDIAccess
objetos MIDIMessageEvent
y le permite escuchar eventos específicos y agregar o eliminar oyentes de una manera mucho más sencilla.
WebMidi.enable(function () { // Viewing available inputs and outputs console.log(WebMidi.inputs); console.log(WebMidi.outputs); // Retrieve an input by name, id or index var input = WebMidi.getInputByName("My Awesome Keyboard"); // OR... // input = WebMidi.getInputById("1809568182"); // input = WebMidi.inputs[0]; // Listen for a 'note on' message on all channels input.addListener('noteon', 'all', function (e) { console.log("Received 'noteon' message (" + e.note.name + e.note.octave + ")."); } ); // Listen to pitch bend message on channel 3 input.addListener('pitchbend', 3, function (e) { console.log("Received 'pitchbend' message.", e); } ); // Listen to control change message on all channels input.addListener('controlchange', "all", function (e) { console.log("Received 'controlchange' message.", e); } ); // Remove all listeners for 'noteoff' on all channels input.removeListener('noteoff'); // Remove all listeners on the input input.removeListener();});
Escenario del mundo real: construcción de una sala de descanso controlada por un teclado de piano
Hace unos meses, mi esposa y yo decidimos construir una experiencia de “sala de descanso” en nuestra casa para entretener a nuestros amigos y familiares. Queríamos que el juego incluyera algún tipo de efecto especial para ayudar a mejorar la experiencia. Desafortunadamente, ninguno de nosotros tiene locas habilidades de ingeniería, por lo que construir cerraduras complejas o efectos especiales con imanes, láseres o cableado eléctrico estaba fuera del ámbito de nuestra experiencia. Sin embargo, conozco bastante bien el navegador. Y tenemos un piano digital.
Así nació una idea. Decidimos que la pieza central del juego sería una serie de códigos de acceso en una computadora que los jugadores tendrían que “desbloquear” tocando ciertas secuencias de notas en nuestro piano, al estilo Willy Wonka.
¿Suena genial? Así es como lo hice.
Configuración
Comenzaremos solicitando acceso WebMIDI, identificando nuestro teclado, adjuntando los detectores de eventos apropiados y creando algunas variables y funciones para ayudarnos a recorrer las distintas etapas del juego.
// Variable which tell us what step of the game we're on.// We'll use this later when we parse noteOn/Off messagesvar currentStep = 0;// Request MIDI accessif (navigator.requestMIDIAccess) { console.log('This browser supports WebMIDI!'); navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure);} else { console.log('WebMIDI is not supported in this browser.');}// Function to run when requestMIDIAccess is successfulfunction onMIDISuccess(midiAccess) { var inputs = midiAccess.inputs; var outputs = midiAccess.outputs; // Attach MIDI event "listeners" to each input for (var input of midiAccess.inputs.values()) { input.onmidimessage = getMIDIMessage; }}// Function to run when requestMIDIAccess failsfunction onMIDIFailure() { console.log('Error: Could not access MIDI devices.');}// Function to parse the MIDI messages we receive// For this app, we're only concerned with the actual note value,// but we can parse for other information, as wellfunction getMIDIMessage(message) { var command = message.data[0]; var note = message.data[1]; var velocity = (message.data.length 2) ? message.data[2] : 0; // a velocity value might not be included with a noteOff command switch (command) { case 144: // note on if (velocity 0) { noteOn(note); } else { noteOff(note); } break; case 128: // note off noteOffCallback(note); break; // we could easily expand this switch statement to cover other types of commands such as controllers or sysex }}// Function to handle noteOn messages (ie. key is pressed)// Think of this like an 'onkeydown' eventfunction noteOn(note) { //...}// Function to handle noteOff messages (ie. key is released)// Think of this like an 'onkeyup' eventfunction noteOff(note) { //...}// This function will trigger certain animations and advance gameplay// when certain criterion are identified by the noteOn/noteOff listeners// For instance, a lock is unlocked, the timer expires, etc.function runSequence(sequence) { //...}
Paso 1: presione cualquier tecla para comenzar
Para comenzar el juego, hagamos que los jugadores presionen cualquier tecla para comenzar. Este es un primer paso sencillo que les indicará cómo funciona el juego y también iniciará una cuenta regresiva.
function noteOn(note) { switch(currentStep) { // If the game hasn't started yet. // The first noteOn message we get will run the first sequence case 0: // Run our start up sequence runSequence('gamestart'); // Increment the currentStep so this is only triggered once currentStep++; break; }}function runSequence(sequence) { switch(sequence) { case 'gamestart': // Now we'll start a countdown timer... startTimer(); // code to trigger animations, give a clue for the first lock break; }}
Paso 2: reproduce la secuencia de notas correcta
Para el primer bloqueo, los jugadores deben tocar una secuencia particular de notas en el orden correcto. De hecho, he visto esto hecho en una sala de descanso real, solo que era con un piano vertical acústico conectado a una caja de seguridad. Recreemos el efecto con MIDI.
Por cada mensaje de "nota sobre" recibido, agregaremos el valor numérico de la nota a una matriz y luego verificaremos si esa matriz coincide con una matriz predefinida de valores de nota.
Supondremos que algunas pistas en la sala de descanso les han dicho a los jugadores qué notas tocar. Para este ejemplo, será el comienzo de la melodía de “Amazing Grace” en clave de fa mayor. Esa secuencia de notas se vería así.
Los valores de las notas MIDI en forma de matriz serían: [60, 65, 69, 65, 69, 67, 65, 62, 60]
.
var correctNoteSequence = [60, 65, 69, 65, 69, 67, 65, 62, 60]; // Amazing Grace in Fvar activeNoteSequence = [];function noteOn(note) { switch(currentStep) { // ... (case 0) // The first lock - playing a correct sequence case 1: activeNoteSequence.push(note); // when the array is the same length as the correct sequence, compare the two if (activeNoteSequence.length == correctNoteSequence.length) { var match = true; for (var index = 0; index activeNoteSequence.length; index++) { if (activeNoteSequence[index] != correctNoteSequence[index]) { match = false; break; } } if (match) { // Run the next sequence and increment the current step runSequence('lock1'); currentStep++; } else { // Clear the array and start over activeNoteSequence = []; } } break; }}function runSequence(sequence) { switch(sequence) { // ... case 'lock1': // code to trigger animations and give clue for the next lock break; }}
Paso 3: toca el acorde correcto
El siguiente bloqueo requiere que los jugadores toquen una combinación de notas al mismo tiempo. Aquí es donde entra en juego nuestro oyente de “nota desactivada”. Por cada mensaje de “nota activada” recibido, agregaremos ese valor de nota a una matriz; Por cada mensaje de "nota desactivada" recibido, eliminaremos ese valor de nota de la matriz. Por lo tanto, esta matriz reflejará qué notas se están presionando actualmente en cualquier momento. Luego, es cuestión de verificar esa matriz cada vez que se agrega un valor de nota para ver si coincide con una matriz maestra con los valores correctos.
Para esta pista, haremos que la respuesta correcta sea un acorde C7 en posición fundamental comenzando en el C central. Se ve así.
Los valores de notas MIDI correctos para este acorde son: [60, 64, 67, 70]
.
var correctChord = [60, 64, 67, 70]; // C7 chord starting on middle Cvar activeChord = [];function noteOn(note) { switch(currentStep) { // ... (case 0, 1) case 2: // add the note to the active chord array activeChord.push(note); // If the array is the same length as the correct chord, compare if (activeChord.length == correctChord.length) { var match = true; for (var index = 0; index activeChord.length; index++) { if (correctChord.indexOf(activeChord[index]) 0) { match = false; break; } } if (match) { runSequence('lock2'); currentStep++; } } break; }function noteOff(note) { switch(currentStep) { case 2: // Remove the note value from the active chord array activeChord.splice(activeChord.indexOf(note), 1); break; }}function runSequence(sequence) { switch(sequence) { // ... case 'lock2': // code to trigger animations, stop clock, end game stopTimer(); break; }}
¡Ahora todo lo que queda por hacer es agregar algunos elementos de interfaz de usuario y animaciones adicionales y ya tenemos un juego que funciona!
Aquí hay un vídeo de la secuencia completa del juego de principio a fin. Esto se ejecuta en Google Chrome. También se muestra un teclado MIDI virtual para ayudar a visualizar qué notas se están tocando actualmente. En un escenario normal de sala para grupos pequeños, esto puede ejecutarse en modo de pantalla completa y sin otras entradas en la sala (como un mouse o un teclado de computadora) para evitar que los usuarios cierren la ventana.
Si no tienes un dispositivo MIDI físico y aún quieres probarlo, existen varias aplicaciones de teclado MIDI virtual que te permitirán usar el teclado de tu computadora como entrada musical, como VMPK . Además, si desea analizar más a fondo todo lo que sucede aquí, consulte el prototipo completo en CodePen.
Vea la demostración de Pen WebMIDI Breakout Room de Peter Anglea ( @peteranglea ) en CodePen .
Conclusión
MIDI.org dice que “Web MIDI tiene el potencial de ser una de las [tecnologías] musicales más disruptivas en mucho tiempo, tal vez tan disruptiva como lo fue originalmente el MIDI allá por 1983”. Es una tarea difícil y un gran elogio.
Espero que este artículo y la aplicación de muestra te hayan entusiasmado sobre el potencial que tiene esta API para estimular el desarrollo de nuevos y emocionantes tipos de aplicaciones de música basadas en navegador. Con suerte, en los próximos años comenzaremos a ver más software de notación musical en línea, estaciones de trabajo de audio digital, visualizadores de audio, tutoriales de instrumentos y más.
Si desea leer más sobre Web MIDI y sus capacidades, le recomiendo lo siguiente:
- “ Making the Web Rock: Web MIDI ”, Chris Wilson, coeditor de Web MIDI (plataforma de diapositivas)
- “ Introducción a Web MIDI ”, Stuart Memo, Envato Tuts+
- “ Creación de aplicaciones de audio basadas en navegador controladas por hardware MIDI ”, Stéphane P. Péricat, Toptal
Y para mayor inspiración, aquí hay algunos otros ejemplos de la API Web MIDI en acción:
- Web Audio MIDI Synthesizer Una interfaz de usuario de sintetizador simple que se puede controlar a través de un dispositivo MIDI
- Web Audio Drum Machine Una aplicación divertida para crear tus propios loops de batería
- Noteflight Un software de notación musical en línea que utiliza Web MIDI como método de entrada potencial
Otras lecturas
- Diseño gráfico inspirador para el día a día
- 33 tentadores iconos de comercio electrónico gratis
- Saliendo de la caja: inspiración de diseño
- Movimientos de arte moderno para inspirar el diseño de su logotipo
(rb, ra, hj, il, mrn)Explora más en
- javascript
- API
- Aplicaciones
Tal vez te puede interesar:
- ¿Deberían abrirse los enlaces en ventanas nuevas?
- 24 excelentes tutoriales de AJAX
- 70 técnicas nuevas y útiles de AJAX y JavaScript
- Más de 45 excelentes recursos y repositorios de fragmentos de código
Primeros pasos con la API Web MIDI
¿Qué es MIDI?MIDI en el navegadorEscenario del mundo real: construcción de una sala de descanso controlada por un teclado de pianoConclusiónSmashingConf Fr
programar
es
2025-01-14
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