Uso dell'audio generato dinamicamente

Flash Player 10 e versioni successive, Adobe AIR 1.5 e versioni successive

Nota: la possibilità di generare audio in modo dinamico è disponibile a partire da Flash Player 10 e Adobe AIR 1.5.

Invece di caricare o eseguire lo streaming di un file audio esistente, potete generare i dati audio dinamicamente. Potete generare dati audio quando assegnate un listener di eventi per l'evento sampleData di un oggetto Sound. L'evento sampleData è definito nella classe SampleDataEvent del pacchetto flash.events. In questo ambiente, l'oggetto Sound non carica dati audio da un file, ma agisce da socket per i dati audio che riceve in streaming mediante l'uso della funzione che assegnate a questo evento.

Quando aggiungete un listener dell'evento sampleData a un oggetto Sound, l'oggetto richiede periodicamente dati da aggiungere al buffer audio che contiene i dati che devono essere riprodotti dall'oggetto Sound. Quando chiamate il metodo play() dell'oggetto Sound, viene generato l'evento sampleData quando vengono richiesti nuovi dati audio (questo è vero solo quando l'oggetto Sound non ha caricato dati mp3 da un file).

L'oggetto SampleDataEvent include una proprietà data . Nel listener di eventi, scrivete oggetti ByteArray in questo oggetto data . Gli array di byte che scrivete in questo oggetto vengono aggiunti ai dati audio memorizzati nel buffer che vengono riprodotti dall'oggetto Sound. L'array di byte nel buffer è un flusso di valori a virgola mobile compresi tra -1 e 1. Ogni valore a virgola mobile rappresenta l'ampiezza di un canale (sinistro o destro) di un suono campione. Il suono viene campionato a 44.100 campioni al secondo. Ogni campione contiene un canale sinistro e destro, interfogliato come dati a virgola mobile nell'array di byte.

Nella funzione di gestione, utilizzate il metodo ByteArray.writeFloat() per scrivere nella proprietà data dell'evento sampleData . Il codice seguente ad esempio genera una sinusoide:

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

Quando chiamate Sound.play() , l'applicazione inizia a chiamare il gestore di eventi richiedendo i dati del suono campione. L'applicazione continua a inviare eventi durante la riproduzione del suono fino a quando interrompete i dati audio o chiamate SoundChannel.stop() .

La latenza dell'evento varia da piattaforma a piattaforma e potrebbe cambiare nelle versioni future di Flash Player ed AIR. Non basatevi su una latenza specifica, ma calcolatela. Per calcolare la latenza, utilizzate la formula seguente:

(SampleDataEvent.position / 44.1) - SoundChannelObject.position

Inviate da 2048 a 8192 campioni alla proprietà data dell'oggetto SampleDataEvent (per ogni chiamata al listener di eventi). Per prestazioni ottimali, fornite il numero massimo di campioni possibili (fino a 8192). Più il numero di campioni è basso, maggiore è la possibilità che durante la riproduzione si verifichino rumori (clic e pop). Questo comportamento può essere diverso in base alla piattaforma e si può verificare in diverse situazioni, ad esempio se si ridimensiona il browser. Il codice che funziona in una piattaforma quando fornite solo 2048 campioni potrebbe non funzionare nello stesso modo se eseguito in una piattaforma diversa. Se necessitate della latenza più bassa possibile, è consigliabile che la quantità di dati sia selezionabile dall'utente.

Se fornite meno di 2048 campioni (per chiamata al listener dell'evento sampleData ), l'applicazione si interrompe dopo la riproduzione dei campioni rimanenti L'oggetto SoundChannel invia quindi un evento SoundComplete.

Modifica dell'audio da dati MP3

Con il metodo Sound.extract() potete estrarre dati da un oggetto Sound. Potete usare e modificare i dati per scrivere sul flusso dinamico di un altro oggetto Sound per la riproduzione. Il codice seguente, ad esempio, utilizza i byte di un file MP3 caricato e li passa attraverso una funzione filtro, 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; 
}

Limitazioni dei suoni generati

Quando usate un listener dell'evento sampleData con un oggetto Sound, gli unici altri metodi Sound attivati sono Sound.extract() e Sound.play() . La chiamata di altri metodi o proprietà causa un'eccezione. Tutti i metodi e le proprietà dell'oggetto SoundChannel rimangono attivati.