Uzyskiwanie dostępu do nieprzetworzonych danych dźwiękowych

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Metoda SoundMixer.computeSpectrum() umożliwia odczytywanie przez aplikację nieprzetworzonych danych dźwiękowych dla przebiegu fali obecnie odtwarzanej. Jeśli odtwarzany jest obecnie więcej niż jeden obiekt SoundChannel, metoda SoundMixer.computeSpectrum() pokazuje połączone dane dźwiękowe wszystkich zmiksowanych obiektów SoundChannel naraz.

Dane dźwiękowe są następnie zwracane w postaci obiektu ByteArray zawierającego 512 bitów danych, z których każdy zawiera wartość zmiennoprzecinkową z przedziału od -1 do 1. Wartości te reprezentują amplitudę punktów odtwarzanego przebiegu. Wartości są dostarczane w dwu grupach po 256; pierwsza grupa dla lewego, a druga grupa dla prawego kanału stereo.

Metoda SoundMixer.computeSpectrum() zwraca dane o rozkładzie częstotliwości, nie zaś dane przebiegu, jeśli parametr FFTMode jest ustawiony na wartość true . Rozkład częstotliwości ilustruje amplitudę według częstotliwości, od najniższej do najwyższej. Do konwersji danych przebiegu na dane rozkładu częstotliwościowego używana jest szybka transformacja Fouriera (FFT). Wynikowy zakres rozkładu częstotliwości waha się od 0 do około 1.414 (pierwiastek kwadratowy z 2).

Poniższy schemat stanowi porównanie danych zwróconych przez metodę computeSpectrum() po ustawieniu parametru FFTMode na wartość true oraz po ustawieniu na wartość false . Dźwięk, którego dane zostały użyte w tym schemacie, zawiera głośne basy w lewym kanale oraz uderzenia perkusji w prawym kanale.
Powiększ obraz
Wartości zwracane przez metodę SoundMixer.computeSpectrum()
A.
fftMode=true

B.
fftMode=false

Metoda computeSpectrum() może również zwracać dane ponownie spróbowane z niższą częstotliwością bitową. W ogólnym przypadku wynikiem jest gładszy przebieg lub rozkład częstotliwościowy o większej szczegółowości. Parametr stretchFactor steruje prędkością, z jaką próbkowane są dane metody computeSpectrum() . Po ustawieniu parametru stretchFactor na wartość 0 (domyślną) dane dźwiękowe są próbkowane z częstotliwością 44,1 kHz. Częstotliwość jest dzielona na dwa z każdą kolejną wartością parametru stretchFactor, tak że wartość 1 określa częstotliwość 22,05 kHz, wartość 2 określa częstotliwość 11,025 kHz itd. Metoda computeSpectrum() nadal zwraca 256 bitów na kanał stereo, jeśli używana jest wyższa wartość stretchFactor .

Metoda SoundMixer.computeSpectrum() ma pewne ograniczenia:

  • Ponieważ dane dźwiękowe z mikrofonu lub ze strumieni RTMP nie są przekazywane za pośrednictwem globalnego obiektu SoundMixer, metoda SoundMixer.computeSpectrum() nie zwróci danych z tych źródeł.

  • Jeśli jeden lub więcej odtwarzanych dźwięków pochodzi ze źródeł spoza bieżącego obszaru izolowanego, ograniczenia zabezpieczeń spowodują wyrzucenie błędu przez metodę SoundMixer.computeSpectrum() . Więcej informacji na temat ograniczeń zabezpieczeń dla metody SoundMixer.computeSpectrum() można znaleźć w sekcji Względy bezpieczeństwa podczas ładowania i odtwarzania dźwięków oraz Załadowane multimedia jako dane .

Jednak w aplikacji AIR zawartość obszaru izolowanego aplikacji (zawartość instalowana razem z aplikacją AIR) nie jest ograniczana przez te reguły zabezpieczeń.

Budowanie prostego mechanizmu wizualizacji dźwięków

Poniższy przykład ilustruje wykorzystanie metody SoundMixer.computeSpectrum() do pokazania schematu przebiegu dźwiękowego animowanego dla każdej klatki:

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

W niniejszym przykładzie przede wszystkim następuje załadowanie, a następnie odtworzenie pliku dźwiękowego i wykrycie zdarzenia Event.ENTER_FRAME , które wyzwoli metodę onEnterFrame() podczas odtwarzania dźwięku. Metoda onEnterFrame() rozpoczyna się od wywołania metody SoundMixer.computeSpectrum() , która zapisuje dane przebiegu dźwięku w obiekcie ByteArray bytes .

Przebieg fali dźwiękowej jest następnie wykreślany za pomocą modułu grafiki wektorowej API. W pętli for następuje przetworzenie pierwszych 256 wartości, reprezentujących lewy kanał stereo, a następnie wykreślenie linii od każdego z punktów do następnego metodą Graphics.lineTo() . W drugiej pętli for następuje przetworzenie drugiego zestawu 256 wartości i wykreślenie ich w przeciwnej kolejności, od prawej do lewej. Wynikowy przebieg fali dźwiękowej może utworzyć interesujący efekt obrazu lustrzanego, tak jak pokazano na poniższym obrazie.