Verwenden von dynamisch generierten Audiodaten

Flash Player 10 und höher, Adobe AIR 1.5 und höher

Hinweis: Die Möglichkeit, Audio dynamisch zu generieren, ist ab Flash Player 10 und Adobe AIR 1.5 verfügbar.

Anstatt einen vorhandenen Sound zu laden oder zu streamen, können Sie Audiodaten auch dynamisch generieren. Sie können Audiodaten erzeugen, wenn Sie einen Ereignis-Listener für das Ereignis sampleData eines Sound-Objekts zuweisen. (Das Ereignis sampleData wird in der SampleDataEvent-Klasse im Paket „flash.events“ definiert.) In dieser Umgebung lädt das Sound-Objekt keine Sounddaten aus einer Datei. Es fungiert stattdessen als Socket für Sounddaten, die zum Objekt gestreamt werden. Das Streamen erfolgt mittels einer Funktion, die Sie diesem Ereignis zuweisen.

Wenn Sie einen sampleData -Ereignis-Listener zu einem Sound-Objekt hinzufügen, fordert das Objekt in bestimmten Abständen Daten zum Hinzufügen zum Soundpuffer an. Dieser Puffer enthält die Daten, die das Sound-Objekt abspielt. Nachdem Sie die play() -Methode des Sound-Objekts aufgerufen haben, löst es beim Anfordern neuer Sounddaten das sampleData -Ereignis aus. (Dies gilt nur, wenn vom Sound-Objekt keine MP3-Daten aus einer Datei geladen wurden.)

Das SampleDataEvent-Objekt enthält eine data -Eigenschaft. In Ihrem Ereignis-Listener schreiben Sie ByteArray-Objekte in dieses data -Objekt. Die Byte-Arrays, die Sie in dieses Objekt schreiben, fügen zu dem gepufferten Sound weitere Daten hinzu, die vom Sound-Objekt abgespielt werden. Das Byte-Array im Puffer ist ein Stream von Gleitkommawerten von -1 bis 1. Jeder Gleitkommawert stellt eine Amplitude eines Kanals (rechts oder links) eines Soundsamples dar. Die Sounddaten werden mit einer Rate von 44.100 Samples pro Sekunde abgetastet. Jedes Sample enthält einen linken und einen rechten Kanal, die als Gleitkommadaten in einem Byte-Array mit Interleave arrangiert werden.

In Ihrer Prozedurfunktion verwenden Sie die Methode ByteArray.writeFloat() , um in die Eigenschaft data des Ereignisses sampleData zu schreiben. Der folgende Code erzeugt zum Beispiel eine Sinus-Kurve.

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

Wenn Sie Sound.play() aufrufen, beginnt die Anwendung, die Ereignisprozedur aufzurufen und fordert Soundsample-Daten an. Die Anwendung fährt damit fort, Ereignisse zu senden, während der Sound solange abgespielt wird, bis Sie keine Daten mehr zur Verfügung stellen oder Sie SoundChannel.stop() aufrufen.

Die Wartezeit des Ereignisses unterscheidet sich von Plattform zu Plattform und kann sich in zukünftigen Versionen von Flash Player und AIR ändern. Machen Sie sich nicht von einer bestimmten Wartezeit abhängig; berechnen Sie sie stattdessen selbst. Berechnen Sie die Wartezeit anhand der folgenden Formel:

(SampleDataEvent.position / 44.1) - SoundChannelObject.position

Stellen Sie zwischen 2048 und 8192 Sample für die Eigenschaft data des SampleDataEvent-Objekts zur Verfügung (für jeden Aufruf an den Ereignis-Listener). Um die beste Leistung zu erzielen, stellen Sie so viele Sample wie möglich (bis zu 8192) zur Verfügung. Je weniger Sample Sie zur Verfügung stellen, desto wahrscheinlicher ist es, dass während des Abspielens Klick- und Popupfenster eingeblendet werden. Dies kann von Plattform zu Plattform unterschiedlich sein und in verschiedenen Situationen auftreten, zum Beispiel wenn die Größe des Browsers verändert wird. Code, der auf einer Plattform problemlos läuft, wenn nur 2048 Samples zur Verfügung gestellt werden, tut dies auf einer anderen Plattform möglicherweise nicht. Wenn Sie die geringst mögliche Wartezeit benötigen, überlegen Sie sich, ob Sie die Menge der Daten vom Benutzer auswählen lassen.

Stellen Sie weniger als 2048 Samples (pro Aufruf an den sampleData -Ereignis-Listener) zur Verfügung, stoppt die Anwendung nach dem Abspielen der verbleibenden Samples. Das SoundChannel-Objekt löst dann ein SoundComplete-Ereignis aus.

Modifizieren von Sound von mp3-Daten

Sie verwenden die Methode Sound.extract() , um Daten aus einem Sound-Objekt zu extrahieren. Sie können diese Daten so verwenden (und modifizieren), dass für die Wiedergabe in den dynamischen Stream eines anderen Sound-Objekts geschrieben wird. Der folgende Code verwendet zum Beispiel die Bytes einer geladenen MP3-Datei und übergibt sie über eine Filterfunktion, 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; 
}

Einschränkungen bei der Erzeugung von Sound

WEnn Sie einen sampleData -Ereignis-Listener mit einem Sound-Objekt verwenden, sind als weitere Sound-Methoden nur noch Sound.extract() und Sound.play() aktiviert. Das Aufrufen anderer Methoden oder Eigenschaften verursacht eine Ausnahme. Alle Methoden und Eigenschaften des SoundChannel-Objekts sind nach wie vor aktiviert.