Aprende a generar fácilmente un sonido de pitido (beep) con JavaScript en el navegador.

Cómo generar fácilmente un sonido de pitido (notificación) con JavaScript

Lo sé, lo sé, ¿sonidos en aplicaciones web? ¡Qué asco !. Ni siquiera consideres usar pitidos o cualquier otro sonido en aplicaciones comerciales serias a menos que sea estrictamente necesario, la mayoría de las veces un simple elemento de notificación en la ventana, como un pequeño modal, funcionará.

La mayoría de los usuarios condenarán su aplicación si decide implementar sonidos sin ningún motivo especial. Solo debería emitir algún sonido para notificar a los usuarios sobre mensajes, advertencias o errores de tu aplicación y definitivamente, esta no debería ser una característica obligatoria. El usuario debe saber que algo está sucediendo en segundo plano cuando no está prestando atención a la aplicación (es realmente útil en aplicaciones de tipo trading diario cuando se activa el stop-loss o take-profit), así que asegúrese de implementarlo como Bueno, una forma de deshabilitar los sonidos en su aplicación para su usuario cuando lo desee.

En caso de que necesite implementar un sonido similar a una notificación en su aplicación ocasionalmente sin demasiados problemas, le explicaré 2 formas de hacerlo en la web hoy en día usando JavaScript.

A. Usando el AudioContext del navegador

La primera opción para simular un sonido de Beep es generar audio con JavaScript simple gracias a la clase AudioContext del navegador (a través de la API de Web Audio). Esta interfaz representa un gráfico de procesamiento de audio construido a partir de módulos de audio conectados entre sí, cada uno representado por un AudioNode.

Según Mozilla Developer Network, un contexto de audio controla tanto la creación de los nodos que contiene como la ejecución del procesamiento o decodificación de audio. Debe crear un AudioContext antes de hacer cualquier otra cosa, ya que todo sucede dentro de un contexto. Se recomienda crear un AudioContext y reutilizarlo en lugar de inicializar uno nuevo cada vez, y está bien usar un único AudioContext para varias fuentes de audio y canalización diferentes al mismo tiempo.

En el caso de una implementación de "bip", la siguiente función le permitirá generar este sonido fácilmente con solo unas pocas líneas de código:

// El navegador limitará el número de contextos de audio concurrentes
// Así que asegúrate de reutilizarlos siempre que puedas
const myAudioContext = new AudioContext();

/**
 * Función auxiliar para emitir un pitido en el navegador mediante la API de Web Audio.
 * 
 * @param {number} duration - La duración del pitido en milisegundos.
 * @param {number} frequency - La frecuencia del pitido.
 * @param {number} volume - El volumen del pitido.
 * 
 * @returns {Promise} - Una promesa que se resuelve cuando termina el pitido.
 */
function beep(duration, frequency, volume){
    return new Promise((resolve, reject) => {
        // Establecer la duración predeterminada si no se proporciona
        duration = duration || 200;
        frequency = frequency || 440;
        volume = volume || 100;

        try{
            let oscillatorNode = myAudioContext.createOscillator();
            let gainNode = myAudioContext.createGain();
            oscillatorNode.connect(gainNode);

            // Establecer la frecuencia del oscilador en hercios
            oscillatorNode.frequency.value = frequency;

            // Establecer el tipo de oscilador
            oscillatorNode.type= "square";
            gainNode.connect(myAudioContext.destination);

            // Establecer la ganancia al volumen
            gainNode.gain.value = volume * 0.01;

            // Inicie el audio con la duración deseada
            oscillatorNode.start(myAudioContext.currentTime);
            oscillatorNode.stop(myAudioContext.currentTime + duration * 0.001);

            // Resuelve la promesa cuando se acabe el sonido.
            oscillatorNode.onended = () => {
                resolve();
            };
        }catch(error){
            reject(error);
        }
    });
}

Puedes usarlo así, proporcionando como primer argumento la duración del sonido en milisegundos, como segundo argumento la frecuencia del oscilador para simular una nota y finalmente el volumen del sonido:

// Bip simple
bip(
     // Establece la duración en 0,2 segundos (200 milisegundos)
     200,
     // Establece la frecuencia de la nota en A4 (440 Hz)
     440,
     // Establecer el volumen del pitido al 100%
     100
);

Puede generar un sonido de tono bajo o alto ajustando la frecuencia de la función a la nota que desee (puede utilizar el siguiente Cuadro de frecuencia de audio):

Audio Frecuency Chart

También puede crear "pitidos" encadenables ya que la implementación utiliza Promesas de JavaScript:

function delay(duration) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(), duration);
    });
}

// Emite una serie de pitidos
// para simular un Ready, Set, Go!
// Sonaria asi:
// (low pitch) Beep 
// (1 segundo de silencio) 
// (low pitch) Beep
// (1 segundo de silencio)
// (low pitch) Beep
// (1 segundo de silencio)
// (higher pitch) Beep!!!

Promise.resolve()
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep(200, 870));

Para obtener una explicación detallada sobre la frecuencia y el tono en AudioContext de JavaScript, le recomiendo que lea este artículo de Teropa . También puede cambiar el tipo de onda del nodo de audio:

  • seno
  • cuadrado
  • diente de sierra
  • triángulo

Otro tutorial interesante que puedes leer sobre las formas de onda es el artículo Waveforms de Josh W. Comeau .

Puede probar este pitido en el siguiente Fiddle:

B. Reproducción de un archivo de audio personalizado

La otra opción que tienes, en caso de que el sonido de tu "bip" deba ser mucho más sofisticado, como "You're Just a Chicken de Tommy Wiseau en The Room":

También puede hacerlo, ¡siéntase libre de hacer lo que quiera en su software !. Pero en serio, dependiendo de las necesidades de sus aplicaciones, los pitidos que puede crear con la API de Web Audio pueden no ser los mejores.

Si ya tiene un archivo de audio MP3 o WAV con el sonido de notificación, puede usar JavaScript simple para reproducirlo como un pitido. La siguiente función representa la lógica mencionada utilizando su propio archivo de audio personalizado:

/**
 * Función auxiliar para emitir un pitido en el navegador usando un archivo de audio.
 * 
 * @param {number} volume - El volumen del pitido.
 * 
 * @returns {Promise} - Una promesa que se resuelve cuando termina el pitido.
 */
function beep(volume){
    return new Promise((resolve, reject) => {
        volume = volume || 100;

        try{
            // estás a cargo de proporcionar un archivo de audio válido al que puede acceder su aplicación web
            let soundSource = "https://www.w3schools.com/html/horse.mp3";
            let sound = new Audio(soundSource);

            // Definir volumen
            sound.volume = volume / 100;

            sound.onended = () => {
                resolve();
            };

            sound.play();
        }catch(error){
            reject(error);
        }
    });
}

Esta implementación le permite crear una cadena al igual que la implementación de pitidos con la API de Web Audio:

function delay(duration) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(), duration);
    });
}

// ¡Emite 3 relinchos de caballo posteriormente!
Promise.resolve()
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep())
  .then(() => delay(1000))
  .then(() => beep());

Puede probar este pitido personalizado en el siguiente Fiddle:

Que te diviertas ❤️!


Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores