Werken met dynamisch gegenereerde audio

Flash Player 10 of hoger, Adobe AIR 1.5 of hoger

Opmerking: De mogelijkheid om geluid dynamisch te genereren, is beschikbaar vanaf Flash Player 10 en Adobe AIR 1.5.

In plaats van een bestaand geluid te laden of te streamen, kunt u audiogegevens dynamisch genereren. U kunt audiogegevens genereren wanneer u een gebeurtenislistener toewijst voor de gebeurtenis sampleData van een Sound-object. (De gebeurtenis sampleData wordt gedefinieerd in de klasse SampleDataEvent in het pakket flash.events.) In deze omgeving laadt het Sound-object geen geluidsgegevens uit een bestand. Het fungeert als socket voor geluidsgegevens die ernaar worden gestreamd door het gebruik van de functie die u aan deze gebeurtenis toewijst.

Wanneer u de gebeurtenislistener sampleData toevoegt aan een Sound-object, vraagt het object regelmatig om gegevens die worden toegevoegd aan de geluidsbuffer. Deze buffer bevat gegevens die door het Sound-object worden afgespeeld. Wanneer u de methode play() van het Sound-object oproept, verzendt deze de gebeurtenis sampleData als nieuwe geluidsgegevens worden aangevraagd. (Dit is alleen van toepassing als het Sound-object geen MP3-gegevens heeft geladen uit een bestand.)

Het SampleDataEvent-object bevat de eigenschap data . In de gebeurtenislistener schrijft u ByteArray-objecten naar dit data -object. De bytearrays die u naar dit object schrijft, worden toegevoegd aan gebufferde geluidsgegevens die door het Sound-object worden afgespeeld. De bytearray in de buffer is een stream drijvende-kommawaarden van -1 tot 1. Elke drijvende-kommawaarde vertegenwoordigt de amplitude van één kanaal (links of rechts) van een geluidssample. Geluid wordt gesampled met 44.100 samples per seconde. Elke sample bevat een linker- en rechterkanaal en is interleaved als drijvende-kommagegevens in de bytearray.

In uw handlerfunctie gebruikt u de methode ByteArray.writeFloat() om de eigenschap data naar de gebeurtenis sampleData te schrijven. De volgende code genereert bijvoorbeeld een sinusgolf:

var mySound:Sound = new Sound(); 
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, sineWaveGenerator); 
mySound.play(); 
function sineWaveGenerator(event:SampleDataEvent):void 
{ 
    for (var i:int = 0; i < 8192; i++) 
    { 
        var n:Number = Math.sin((i + event.position) / Math.PI / 4); 
        event.data.writeFloat(n); 
        event.data.writeFloat(n); 
    } 
}

Wanneer u Sound.play() oproept, begint de toepassing de gebeurtenishandler op te roepen en gegevens met geluidssamples te vragen. De toepassing blijft gebeurtenissen verzenden terwijl het geluid wordt afgespeeld, totdat u stopt met het aanleveren van gegevens of totdat u SoundChannel.stop() oproept.

De vertraging van gebeurtenissen varieert per platform en kan veranderen in toekomstige versies van Flash Player en AIR. Het is verstandig niet uit te gaan van een specifieke vertraging, maar deze te berekenen. Gebruik de volgende formule om de vertraging te berekenen:

(SampleDataEvent.position / 44.1) - SoundChannelObject.position

Lever 2048 tot 8192 samples aan de eigenschap data van het SampleDataEvent-object (voor elke oproep van de gebeurtenislistener). U krijgt de beste resultaten als u zoveel mogelijk samples aanlevert (maximaal 8192). Hoe minder samples u aanlevert, des te groter de kans op ongewenste geluiden en onderbrekingen tijdens het afspelen. Dit gedrag verschilt per platform en kan in verschillende situaties optreden, bijvoorbeeld wanneer u de afmetingen van de browser wijzigt. Code die goed werkt op het ene platform wanneer u slechts 2048 samples aanlevert, kan mindere resultaten geven op een ander platform. Als u de kleinst mogelijke vertraging nodig hebt, kunt u overwegen om de hoeveelheid gegevens door de gebruiker te laten selecteren.

Als u minder dan 2048 samples aanlevert (per oproep van de gebeurtenislistener sampleData ), stopt de toepassing na het afspelen van de resterende samples. Het SoundChannel-object verzendt dan een SoundComplete-gebeurtenis.

Geluid wijzigen van MP3-gegevens

Met de methode Sound.extract() haalt u gegevens op van een Sound-object. U kunt deze gegevens gebruiken (en wijzigen) om te schrijven naar de dynamische stream van een Sound-object voor afspelen. In de volgende code worden bijvoorbeeld de bytes van een geladen MP3-bestand gebruikt en doorgegeven via de filterfunctie upOctave() :

var mySound:Sound = new Sound(); 
var sourceSnd:Sound = new Sound(); 
var urlReq:URLRequest = new URLRequest("test.mp3"); 
sourceSnd.load(urlReq); 
sourceSnd.addEventListener(Event.COMPLETE, loaded); 
function loaded(event:Event):void 
{ 
    mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound); 
    mySound.play(); 
} 
function processSound(event:SampleDataEvent):void 
{ 
        var bytes:ByteArray = new ByteArray(); 
        sourceSnd.extract(bytes, 8192); 
        event.data.writeBytes(upOctave(bytes)); 
} 
function upOctave(bytes:ByteArray):ByteArray 
{ 
    var returnBytes:ByteArray = new ByteArray(); 
    bytes.position = 0; 
    while(bytes.bytesAvailable > 0) 
    { 
        returnBytes.writeFloat(bytes.readFloat()); 
        returnBytes.writeFloat(bytes.readFloat()); 
        if (bytes.bytesAvailable > 0) 
        { 
            bytes.position += 8; 
        } 
    } 
    return returnBytes; 
}

Beperkingen betreffende gegenereerde geluiden

Als u de gebeurtenislistener sampleData gebruikt in combinatie met een Sound-object, worden alleen de volgende methoden van Sound ingeschakeld: Sound.extract() en Sound.play() . Als u andere methoden of eigenschappen oproept, resulteert dit in een uitzonderingsfout. Alle methoden en eigenschappen van het object SoundChannel blijven ingeschakeld.