Получение необработанных аудиоданных

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Метод SoundMixer.computeSpectrum() позволяет приложению считывать необработанные аудиоданные для отображения воспроизводимой в данный момент звуковой волны. Если одновременно воспроизводится несколько объектов SoundChannel, метод SoundMixer.computeSpectrum() показывает комбинированные аудиоданные для всех смикшированных вместе объектов SoundChannel.

Аудиоданные возвращаются в виде объекта ByteArray, содержащего 512 байтов данных, каждый из которых содержит значение с плавающей запятой в диапазоне от -1 до 1. Эти значения представляют амплитуду точек воспроизводимой звуковой волны. Значения передаются двумя группами, по 256 в каждой: первая группа предназначена для левого стереоканала, а вторая — для правого.

Если параметр FFTMode имеет значение true, метод SoundMixer.computeSpectrum() возвращает данные спектра частот, а не формы волны. Спектр частот показывает амплитуду по частоте звука: от самой низкой до самой высокой. Алгоритм быстрого преобразования Фурье (FFT) используется для преобразования данных звуковой волны в данные спектра частот. Полученные значения спектра частот находятся в диапазоне от 0 приблизительно до 1,414 (квадратный корень из 2).

На примере следующих графиков сравниваются данные, возвращенные методом computeSpectrum() с параметром FFTMode в значении true и в значении false. Звук, данные которого представлены на графиках, содержит громкий бас в левом канале и удар барабана в правом канале.
Просмотр полноразмерных изображений
Значения, возвращенные методом SoundMixer.computeSpectrum()
A.
fftMode=true

Б.
fftMode=false

Метод computeSpectrum() может также возвращать данные, преобразованные с использованием более низкой скорости передачи битов. Как правило, это приводит к сглаживанию данных звуковой волны или частоты за счет их прореживания. Параметр stretchFactor управляет частотой дискретизации, используемой для данных метода computeSpectrum(). Когда параметр stretchFactor имеет значение 0 (по умолчанию), для звука используется частота дискретизации 44,1 кГц. Эта частота уменьшается вдвое для каждого последующего значения параметра stretchFactor, поэтому значению 1 соответствует частота 22,05 кГц, а значению 2 — 11,025 кГц и т.д. Метод computeSpectrum() все равно возвращает по 256 байтов для каждого стереоканала, когда используются более высокие значения для параметраstretchFactor.

Метод SoundMixer.computeSpectrum() имеет некоторые ограничения.

  • Так как аудиоданные с микрофона или с RTMP-сервера не проходят через глобальный объект SoundMixer, метод SoundMixer.computeSpectrum() не возвращает данных из этих источников.

  • Если один или несколько из воспроизводимых звуков находятся за пределами текущей изолированной программной среды содержимого, метод SoundMixer.computeSpectrum() выдаст ошибку из-за ограничений по безопасности. Дополнительные сведения об ограничениях по безопасности для метода SoundMixer.computeSpectrum() см. в разделах «Безопасность при загрузке и воспроизведении звуков» и «Получение данных загруженного мультимедийного содержимого».

Однако в AIR эти ограничения по безопасности не распространяются на содержимое в изолированной программной среде приложения (содержимое, установленное с приложением AIR).

Создание простого визуализатора звука

В следующем примере используется метод SoundMixer.computeSpectrum() для отображения зрительного образа звука с анимацией каждого кадра.

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); 
}

Сначала код загружает аудиофайл и запускает его воспроизведение, а затем прослушивает событие Event.ENTER_FRAME, которое запускает метод onEnterFrame() во время воспроизведения звука. Метод onEnterFrame() вызывает метод SoundMixer.computeSpectrum(), который сохраняет данные звуковой волны в объекте ByteArray с именем bytes.

Зрительный образ звука отображается с использованием API-интерфейса векторного рисования. Первый цикл for считывает первые 256 значений (левый стереоканал) и рисует линию от одной точки к другой с помощью метода Graphics.lineTo(). Второй цикл for считывает следующие 256 значений и рисует линию, но на этот раз в обратном порядке, справа налево. Полученные зрительные образы звука могут дать интересный эффект зеркального отражения, как показано на следующем рисунке.