Audio panner
Si el sonido se reproduce en dos canales audio decimos que se trata de sonido estereofónico. El sonido cuadrafónico se reproduce en cuatro canales audio, y hay también sonido hexafónico que se reproduce en seis canales auditivos distintos.
El panning es una técnica que permite redistribuir la señal de sonido entre los varios canales audio.
Para crear un nodo panner
estereo utilizamos el método StereoPannerNode
.
var pan = audioCtx.createStereoPanner(audioCtx);
Un ejemplo básico
En el siguiente ejemplo, en el HTML creamos un slider ( <input type="range"
) cuyo valor puede variar entre -1 ( min = "-1"
) y 1 ( max = "1"
), ya que la propiedad pan
del panner
puede tomar valores entre -1 ( el sonido se oye solo en el auricular izquierdo ) y 1 ( el sonido se oye solo en el auricular derecho ).
El paso del slider es de 0.01 ( step="0.01"
).
<div class="inputDiv">
<!--El valor del panControl es un número decimal entre -1 y 1 -->
<p><input id="panControl" type="range" min="-1" max="1" value="0.5" step="0.01" /></p>
</div>
También creamos un panner
estéreo y un oscilador
.
Conectamos el oscilador
( la fuente de sonido ) con el panner
, y el panner
con los dispositivos de salida.
El slider ( panControl
) es utilizado para cambiar el balance del sonido hacia la derecha o la izquierda.
Para que el oscilador
no sea molesto utilizamos el evento "mousedown
" para iniciar la oscilación y "mouseup
" para pararla.
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// crea un nuevo nodo audio panner
var pan = audioCtx.createStereoPanner(audioCtx);
// crea un nuevo oscildor,
// lo conecta con el panner y
// conecta el panner con los dispositivos de salida
crearOscilador();
// al arrastrar el boton del slider
panControl.addEventListener("input", function() {
// el balance cambia hacia la derecha o hacia la izquierda
pan.pan.value = this.value;
});
// inicia el oscilador al presionar el botón del ratón
panControl.addEventListener("mousedown", function() {
crearOscilador();
oscilador.start();
});
// para el oscilador al soltar el botón del ratón
panControl.addEventListener("mouseup", function() {
oscilador.stop();
});
function crearOscilador() {
// crea un nuevo oscilador
oscilador = audioCtx.createOscillator();
// establece la frequencia del oscilador
oscilador.frequency.value = 100;
// conecta el oscilador con el panner
oscilador.connect(pan);
// y el panner con los dispositivos de destino
pan.connect(audioCtx.destination);
}
Vea este ejemplo en codepen. Para una mejor experiencia por favor utilice auriculares.
See the Pen createStereoPanner* by Gabi (@enxaneta) on CodePen.
Crear un separador de canales
Si queremos manipular por separado los canales audio necesitamos un separador de canales ( channel splitter ).
Para crear un nuevo separador utilizamos el método createChannelSplitter
, que toma como argumento el número de canales que queremos generar. El valor por defecto es 6.
var splitter = audioCtx.createChannelSplitter(2);
El siguiente ejemplo utiliza como punto de partida un ejemplo anterior: Reproducir archivos de sonido.
Primero tenemos que declarar algunas variables globales:
// un separador de canales
var splitter = audioContext.createChannelSplitter(2);
// la ganancia para el auricular / altavoz izquierdo
var gainIzq = audioContext.createGain();
// la ganancia para el auricular / altavoz derecho
var gainDcha = audioContext.createGain();
// el panner para el auricular / altavoz izquierdo
var pannerIzq = audioContext.createStereoPanner();
// el panner para el auricular / altavoz derecho
var pannerDcha = audioContext.createStereoPanner();
También hay que modificar la función reproducirAudio()
. Ahora la fuente de reproducción se conecta con el splitter
fuenteDeReproduccion.connect(splitter);
Que a su turno se conecta con dos nodos de ganancia, uno para la izquierda y otro para la derecha. Observe por favor el segundo argumento del método connect()
que especifica el canal audio con cual conectarse.
splitter.connect(gainIzq, 0); splitter.connect(gainDcha, 1);
A continuación conectamos los nodos de ganancia, cada uno con el panner
correspondiente.
gainIzq.connect(pannerIzq); gainDcha.connect(pannerDcha);
Finalmente los panner se conectan con los dispositivos de destino. Es importante observar que el valor del panner izquierdo es -1 ( el sonido se oye solo en el auricular izquierdo )
pannerIzq.pan.value = -1;
mientras que el valor del panner derecho es 1 ( el sonido se oye solo en el auricular derecho )
pannerDcha.pan.value = 1;
function reproducirAudio() {
// fuenteDeReproduccion --> splitter --> gainIzq --> pannerIzq --> destination
// ↳ gainDcha --> pannerDcha --> destination
fuenteDeReproduccion = audioContext.createBufferSource();
fuenteDeReproduccion.loop = true;
fuenteDeReproduccion.buffer = audioBuffer;
fuenteDeReproduccion.connect(splitter);
splitter.connect(gainIzq, 0);
splitter.connect(gainDcha, 1);
gainIzq.connect(pannerIzq);
gainDcha.connect(pannerDcha);
pannerIzq.connect(audioContext.destination);
pannerIzq.pan.value = -1;
pannerDcha.connect(audioContext.destination);
pannerDcha.pan.value = 1;
fuenteDeReproduccion.connect(audioContext.destination);
fuenteDeReproduccion.start(audioContext.currentTime);
}
Vea este ejemplo en codepen. Para una mejor experiencia por favor utilice auriculares.
See the Pen createChannelSplitter by Gabi (@enxaneta) on CodePen.