Acceso a datos de sonido sin formato

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

El método SoundMixer.computeSpectrum() permite que una aplicación lea los datos de sonido sin formato para la forma de onda que se reproduce en ese momento. Si se reproduce más de un objeto SoundChannel, el método SoundMixer.computeSpectrum() muestra los datos de sonido combinados de cada objeto SoundChannel mezclado.

Los datos de sonido se devuelven como un objeto ByteArray con 512 bytes de datos, cada uno de los cuales contiene un valor de coma flotante que oscila entre -1 y 1. Estos valores representan la amplitud de los puntos de la forma de onda del sonido en reproducción. Los valores se transmiten en dos grupos de 256; el primer grupo para el canal estéreo izquierdo y el segundo para el canal estéreo derecho.

El método SoundMixer.computeSpectrum() devolverá datos del espectro de frecuencias en lugar de datos de forma de onda si el parámetro FFTMode se establece en true . El espectro de frecuencias muestra la amplitud clasificada por la frecuencia de sonido, de menor a mayor. El algoritmo FFT (Fast Fourier Transform) se utiliza para convertir los datos de forma de onda en datos del espectro de frecuencias. Los valores resultantes del espectro de frecuencias oscilan entre 0 y 1,414 aproximadamente (la raíz cuadrada de 2).

En el siguiente diagrama se comparan los datos devueltos por el método computeSpectrum() cuando el parámetro FFTMode se establece en true y cuando se establece en false . El sonido cuyos datos se han utilizado para este diagrama contiene un sonido alto de contrabajo en el canal izquierdo y un sonido de batería en el canal derecho.
Ver gráfico a tamaño completo
Valores devueltos por el método SoundMixer.computeSpectrum()
A.
fftMode=true

B.
fftMode=false

El método computeSpectrum() también puede devolver datos que se han vuelto a muestrear a una velocidad inferior. Normalmente, esto genera datos de forma de onda o de frecuencia más suaves a expensas del detalle. El parámetro stretchFactor controla la velocidad a la que se muestrea el método computeSpectrum() . Cuando el parámetro stretchFactor se establece en 0 (valor predeterminado), los datos de sonido se muestrean a una velocidad de 44,1 kHz. La velocidad se reduce a la mitad en los valores sucesivos del parámetro stretchFactor, de manera que un valor de 1 especifica una velocidad de 22,05 kHz, un valor de 2 especifica una velocidad de 11,025 kHz, etc. El método computeSpectrum() aún devuelve 256 bytes en cada canal estéreo cuando se utiliza un valor stretchFactor más alto.

El método SoundMixer.computeSpectrum() tiene algunas limitaciones:

  • Puesto que los datos de sonido de un micrófono o de los flujos RTMP no pasan por el objeto SoundMixer global, el método SoundMixer.computeSpectrum() no devolverá datos de dichas fuentes.

  • Si uno o varios sonidos que se reproducen proceden de orígenes situados fuera del entorno limitado de contenido actual, las restricciones de seguridad harán que el método SoundMixer.computeSpectrum() genere un error. Para obtener más detalles sobre las limitaciones de seguridad del método SoundMixer.computeSpectrum() , consulte Consideraciones de seguridad al cargar y reproducir sonidos y Acceso a medios cargados como datos .

Sin embargo, en una aplicación de AIR, el contenido del entorno limitado de seguridad de la aplicación (contenido instalado con la aplicación AIR) no está limitado por estas restricciones de seguridad.

Creación de un visualizador de sonido sencillo

En el ejemplo siguiente se utiliza el método SoundMixer.computeSpectrum() para mostrar un gráfico de la forma de onda que se anima con cada fotograma:

import flash.display.Graphics; 
import flash.events.Event; 
import flash.media.Sound; 
import flash.media.SoundChannel; 
import flash.media.SoundMixer; 
import flash.net.URLRequest; 
 
const PLOT_HEIGHT:int = 200; 
const CHANNEL_LENGTH:int = 256; 
 
var snd:Sound = new Sound(); 
var req:URLRequest = new URLRequest("bigSound.mp3"); 
snd.load(req); 
 
var channel:SoundChannel; 
channel = snd.play(); 
addEventListener(Event.ENTER_FRAME, onEnterFrame); 
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 
 
var bytes:ByteArray = new ByteArray(); 
 
function onEnterFrame(event:Event):void 
{ 
    SoundMixer.computeSpectrum(bytes, false, 0); 
     
    var g:Graphics = this.graphics; 
     
    g.clear(); 
    g.lineStyle(0, 0x6600CC); 
    g.beginFill(0x6600CC); 
    g.moveTo(0, PLOT_HEIGHT); 
     
    var n:Number = 0; 
         
    // left channel 
    for (var i:int = 0; i < CHANNEL_LENGTH; i++)  
    { 
        n = (bytes.readFloat() * PLOT_HEIGHT); 
        g.lineTo(i * 2, PLOT_HEIGHT - n); 
    } 
    g.lineTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT); 
    g.endFill(); 
     
    // right channel 
    g.lineStyle(0, 0xCC0066); 
    g.beginFill(0xCC0066, 0.5); 
    g.moveTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT); 
     
    for (i = CHANNEL_LENGTH; i > 0; i--)  
    { 
        n = (bytes.readFloat() * PLOT_HEIGHT); 
        g.lineTo(i * 2, PLOT_HEIGHT - n); 
    } 
    g.lineTo(0, PLOT_HEIGHT); 
    g.endFill(); 
} 
 
function onPlaybackComplete(event:Event) 
{ 
    removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
}

En primer lugar, este ejemplo carga y reproduce un archivo de sonido, y luego detecta el evento Event.ENTER_FRAME que activará el método onEnterFrame() mientras se reproduce el sonido. El método onEnterFrame() se inicia llamando al método SoundMixer.computeSpectrum() , que almacena los datos de forma de onda del sonido en el objeto ByteArray bytes .

La forma de onda del sonido se representa con la API de dibujo vectorial. El bucle for recorre los primeros 256 valores de datos; representa el canal estéreo izquierdo y dibuja una línea desde un punto al siguiente con el método Graphics.lineTo() . Un segundo bucle for recorre el siguiente conjunto de 256 valores y los representa en orden inverso esta vez, de derecha a izquierda. Las representaciones de la forma de onda resultante pueden generar un interesante efecto de reflejo de imagen, tal como se muestra en la imagen siguiente.