Rilevamento dell'input audio

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

La classe Microphone consente all'applicazione di connettersi a un microfono o a un altro dispositivo di input audio presente nel sistema dell'utente e di trasmettere l'input audio agli altoparlanti del sistema oppure di inviare i dati audio a un server remoto, quale Flash Media Server. Potete accedere ad audio raw dal microfono e registralo o elaborarlo; potete anche inviare l'audio direttamente agli altoparlanti del sistema o inviare audio compresso a un server remoto. Per i dati inviati a un server remoto potete utilizzare il codec Speex o Nellymoser. Il codec Speex è supportato a partire da Flash Player 10 e Adobe AIR 1.5.

Accesso a un microfono

La classe Microphone non contiene un metodo di costruzione. Per ottenere una nuova istanza Microphone si utilizza invece il metodo statico Microphone.getMicrophone() , come mostrato di seguito:

var mic:Microphone = Microphone.getMicrophone();

Una chiamata al metodo Microphone.getMicrophone() senza un parametro restituisce il primo dispositivo di input audio rilevato sul sistema dell'utente.

A un sistema può essere connesso più di un dispositivo di input audio. L'applicazione può utilizzare la proprietà Microphone.names per ottenere un array dei nomi di tutti i dispositivi di input audio disponibili. Quindi, chiama il metodo Microphone.getMicrophone() con un parametro index che corrisponde al valore di indice del nome di un dispositivo nell'array.

A un sistema può non essere connesso alcun microfono o dispositivo di input audio. Per verificare se l'utente ha installato un dispositivo di input audio, potete utilizzare la proprietà Microphone.names o il metodo Microphone.getMicrophone() . Se l'utente non ha installato alcun dispositivo, la lunghezza dell'array names è pari a 0 e il metodo getMicrophone() restituisce il valore null .

Quando l'applicazione chiama il metodo Microphone.getMicrophone() , Flash Player visualizza la finestra di dialogo Impostazioni di Flash Player, che richiede all'utente di consentire o negare a Flash Player di accedere alla videocamera e al microfono. Dopo che l'utente ha fatto clic sul pulsante Consenti o sul pulsante Nega in questa finestra di dialogo, viene inviato StatusEvent. La proprietà code di tale istanza StatusEvent indica se l'accesso al microfono è stato consentito o negato, come mostrato nell'esempio seguente:

import flash.media.Microphone; 
 
var mic:Microphone = Microphone.getMicrophone(); 
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus); 
 
function onMicStatus(event:StatusEvent):void 
{ 
    if (event.code == "Microphone.Unmuted") 
    { 
        trace("Microphone access was allowed."); 
    }  
    else if (event.code == "Microphone.Muted") 
    { 
         trace("Microphone access was denied."); 
    } 
}

La proprietà StatusEvent.code contiene “Microphone.Unmuted” se l'accesso è stato consentito oppure “Microphone.Muted” se l'accesso è stato negato.

la proprietà Microphone.muted viene impostata su true o false quando l'utente rispettivamente consente o nega l'accesso al microfono. Tuttavia, la proprietà muted non viene impostata sull'istanza Microphone fino a quando non viene inviato StatusEvent, pertanto l'applicazione deve anche attendere che venga inviato l'evento StatusEvent.STATUS prima di verificare la proprietà Microphone.muted .

Affinché Flash Player sia in grado di visualizzare la finestra di dialogo delle impostazioni, la finestra dell'applicazione deve essere sufficientemente grande per contenerla (almeno 215 x 138 pixel). In caso contrario, l'accesso viene automaticamente negato.

Il contenuto in esecuzione nella sandbox dell'applicazione AIR non richiede l'autorizzazione dell'utente per accedere al microfono. Pertanto, eventi status per la disattivazione e l'attivazione del microfono non vengono mai inviati. Il contenuto in esecuzione in AIR all'esterno della sandbox dell'applicazione non richiede l'autorizzazione dell'utente, pertanto questi eventi status possono essere inviati.

Instradamento dell'audio del microfono agli altoparlanti locali

L'input audio di un microfono può essere instradato agli altoparlanti del sistema locale chiamando il metodo Microphone.setLoopback() con un parametro con valore true .

Tuttavia, quando l'audio proveniente da un microfono locale viene instradato agli altoparlanti locali, si rischia di produrre un ciclo di feedback audio che può provocare dei suoni fortissimi e stridenti che possono danneggiare l'hardware audio. La chiamata al metodo Microphone.setUseEchoSuppression() con un parametro con valore true riduce (ma non elimina del tutto) il rischio di feedback audio. Adobe consiglia di chiamare sempre Microphone.setUseEchoSuppression(true) prima di chiamare Microphone.setLoopback(true) , a meno che non si sia certi che l'utente stia riproducendo l'audio mediante le cuffie o un dispositivo diverso dagli altoparlanti.

Il codice seguente mostra come instradare l'audio da un microfono locale agli altoparlanti del sistema locale:

var mic:Microphone = Microphone.getMicrophone(); 
mic.setUseEchoSuppression(true); 
mic.setLoopBack(true);

Modifica dell'audio del microfono

L'applicazione può modificare i dati audio provenienti da un microfono in due modi. Innanzi tutto, può modificare il guadagno dell'audio di ingresso, che moltiplica efficacemente i valori di input per una quantità specifica per ottenere un suono più forte o più tenue. La proprietà Microphone.gain accetta valori numerici compresi tra 0 e 100 (inclusi). Il valore 50 moltiplica per uno e specifica il volume normale. Il valore 0 moltiplica per zero e rende silenzioso il volume dell'audio in ingresso. I valori superiori a 50 specificano un volume superiore a quello normale.

L'applicazione può anche modificare la frequenza di campionamento dell'audio in ingresso. Le frequenze superiori aumentano la qualità del suono, ma producono flussi di dati più densi la cui trasmissione e memorizzazione richiede più risorse. La proprietà Microphone.rate rappresenta la frequenza di campionamento audio misurata in kilohertz (kHz). Il valore predefinito è 8 kHz. È possibile impostare la proprietà Microphone.rate su un valore maggiore di 8 kHz se il microfono lo supporta. Se ad esempio impostate la proprietà Microphone.rate sul valore 11, la frequenza di campionamento viene impostata su 11 kHz; se impostate questo valore su 22, la frequenza di campionamento viene impostata su 22 kHz e così via. Le frequenze di campionamento disponibili dipendono dal codec selezionato. Se utilizzate il codec Nellymoser, potete specificare come frequenza di campionamento 5, 8, 11, 16, 22 e 44 kHz. Se utilizzate il codec Speex (disponibile a partire da Flash Player 10 e Adobe AIR 1.5), potete utilizzare solo 16 kHz.

Rilevamento dell'attività del microfono

Per preservare larghezza di banda e risorse di elaborazione, Flash Player tenta di rilevare se non viene trasmesso alcun suono da un microfono. Quando il livello dell'attività del microfono rimane al di sotto della soglia del livello di silenzio per un determinato periodo di tempo, in Flash Player viene interrotta la trasmissione dell'input audio e viene inviato un semplice evento ActivityEvent. Se utilizzate il codec Speex (disponibile in Flash Player 10 o versione successiva e Adobe AIR 1.5 o versione successiva), impostate il livello di silenzio su 0 per garantire che l'applicazione trasmetta continuamente dati audio. Il rilevamento dell'attività vocale Speex riduce automaticamente la larghezza di banda.

Nota: un oggetto Microphone invia solo eventi Activity quando l'applicazione esegue il monitoraggio del microfono. Pertanto, se non chiamate setLoopBack( true ) , aggiungete un listener per gli eventi dati campione o collegate il microfono a un oggetto NetStream, non viene inviato nessun evento activity.

Tre proprietà della classe Microphone si occupano di monitorare e controllare il rilevamento dell'attività:

  • La proprietà di sola lettura activityLevel indica la quantità di suono che viene rilevata dal microfono, su una scala da 0 a 100.

  • La proprietà silenceLevel specifica la quantità di suono necessaria per attivare il microfono e inviare un evento ActivityEvent.ACTIVITY . Anche la proprietà silenceLevel utilizza una scala da 0 a 100, e il valore predefinito è 10.

  • La proprietà silenceTimeout descrive il numero di millisecondi per cui il livello dell'attività deve rimanere al di sotto del livello di silenzio, fino a quando viene inviato un evento ActivityEvent.ACTIVITY per indicare che il microfono è silenzioso. Il valore predefinito di silenceTimeout è 2000.

Sia la proprietà Microphone.silenceLevel che la proprietà Microphone.silenceTimeout sono di sola lettura, ma è possibile modificarne i valori utilizzando il metodo Microphone.setSilenceLevel() .

In determinati casi, il processo di attivazione del microfono quando viene rilevata una nuova attività può provocare un lieve ritardo. Tale circostanza può essere evitata mantenendo sempre attivo il microfono. L'applicazione può chiamare il metodo Microphone.setSilenceLevel() con il parametro silenceLevel impostato su zero per specificare a Flash Player di mantenere attivo il microfono e di continuare a raccogliere dati anche se non viene rilevato alcun suono. Al contrario, se si imposta il parametro silenceLevel su 100 si impedisce che il microfono venga attivato del tutto.

L'esempio seguente visualizza le informazioni sul microfono e genera un report sugli eventi activity e sugli eventi status inviati da un oggetto Microphone:

import flash.events.ActivityEvent; 
import flash.events.StatusEvent; 
import flash.media.Microphone; 
 
var deviceArray:Array = Microphone.names; 
trace("Available sound input devices:"); 
for (var i:int = 0; i < deviceArray.length; i++) 
{ 
    trace(" " + deviceArray[i]); 
} 
 
var mic:Microphone = Microphone.getMicrophone(); 
mic.gain = 60; 
mic.rate = 11; 
mic.setUseEchoSuppression(true); 
mic.setLoopBack(true); 
mic.setSilenceLevel(5, 1000); 
     
mic.addEventListener(ActivityEvent.ACTIVITY, this.onMicActivity); 
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus); 
     
var micDetails:String = "Sound input device name: " + mic.name + '\n'; 
micDetails += "Gain: " + mic.gain + '\n'; 
micDetails += "Rate: " + mic.rate + " kHz" + '\n'; 
micDetails += "Muted: " + mic.muted + '\n'; 
micDetails += "Silence level: " + mic.silenceLevel + '\n'; 
micDetails += "Silence timeout: " + mic.silenceTimeout + '\n'; 
micDetails += "Echo suppression: " + mic.useEchoSuppression + '\n'; 
trace(micDetails); 
 
function onMicActivity(event:ActivityEvent):void 
{ 
    trace("activating=" + event.activating + ", activityLevel=" +  
        mic.activityLevel); 
} 
 
function onMicStatus(event:StatusEvent):void 
{ 
    trace("status: level=" + event.level + ", code=" + event.code); 
}

Quando si esegue il suddetto esempio, parlare o produrre dei suoni nel microfono di sistema e osservare le istruzioni trace risultanti che vengono visualizzate sulla console o in una finestra di debug.

Invio di audio verso e da un server multimediale

Quando si utilizza ActionScript con un server per lo streaming di media audio e video come Flash Media Server (FMS) sono disponibili delle funzionalità audio aggiuntive.

In particolare, l'applicazione può associare un oggetto Microphone a un oggetto NetStream e trasmettere i dati direttamente dal microfono dell'utente al server. I dati audio possono anche essere inviati in streaming dal server a un'applicazione e riprodotti come parte di un oggetto MovieClip o utilizzando un oggetto Video.

Il codec Speex è disponibile a partire da Flash Player 10 e Adobe AIR 1.5. Per impostare il codec utilizzato per l'audio compresso inviato a Flash Media Server, impostate la proprietà codec dell'oggetto Microphone. Questa proprietà può essere associata a due valori, enumerati nella classe SoundCodec. Impostando la proprietà codec su SoundCodec.SPEEX si seleziona il codec Speex per la compressione dell'audio. Impostando la proprietà codec su SoundCodec.NELLYMOSER (valore predefinito) si seleziona il codec Nellymoser per la compressione dell'audio.

Per ulteriori informazioni, vedete la documentazione Flash Media Server in linea all'indirizzo www.adobe.com/go/learn_fms_docs_it .

Acquisizione dei dati audio di un microfono

In Flash Player 10.1. e AIR 2, o versioni successive, potete acquisire i dati audio dal microfono come un array di byte di valori a virgola mobile. Ogni valore rappresenta un esempio di dati audio monofonici.

Per ottenere i dati microfono, impostate un listener di eventi per l'evento sampleData dell'oggetto Microphone. L'oggetto Microphone invia eventi sampleData periodicamente man mano che il buffer del microfono viene riempito con campioni audio. L'oggetto SampleDataEvent dispone di una proprietà data che è un array di byte di campioni audio. I campioni sono rappresentati come valori a virgola mobile, ciascuno dei quali rappresenta un campione audio del microfono.

Il codice seguente acquisisce i dati audio del microfono in un oggetto ByteArray denominato soundBytes :

var mic:Microphone = Microphone.getMicrophone(); 
mic.setSilenceLevel(0, DELAY_LENGTH); 
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
function micSampleDataHandler(event:SampleDataEvent):void { 
    while(event.data.bytesAvailable)     { 
        var sample:Number = event.data.readFloat(); 
        soundBytes.writeFloat(sample); 
    } 
}

Potete riutilizzare i byte di esempio come audio di riproduzione per un oggetto Sound. In questo caso, dovete impostare la proprietà rate dell'oggetto Microphone su 44, che è la frequenza di campionamento utilizzata dagli oggetti Sound. (Potete anche convertire campioni microfono acquisiti a una frequenza inferiore a quella di 44 kHz richiesta dall'oggetto Sound.) Inoltre, tenete presente che l'oggetto Microphone acquisisce campioni monofonici, mentre l'oggetto Sound utilizza audio stereo; pertanto ogni byte acquisito dall'oggetto Microphone deve essere scritto nell'oggetto Sound due volte. Nell'esempio seguente vengono acquisiti 4 secondi di dati microfono, riprodotti utilizzando un oggetto Sound:

const DELAY_LENGTH:int = 4000; 
var mic:Microphone = Microphone.getMicrophone(); 
mic.setSilenceLevel(0, DELAY_LENGTH); 
mic.gain = 100; 
mic.rate = 44; 
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
 
var timer:Timer = new Timer(DELAY_LENGTH); 
timer.addEventListener(TimerEvent.TIMER, timerHandler); 
timer.start(); 
 
function micSampleDataHandler(event:SampleDataEvent):void 
{ 
    while(event.data.bytesAvailable) 
    { 
        var sample:Number = event.data.readFloat(); 
        soundBytes.writeFloat(sample); 
    } 
} 
var sound:Sound = new Sound(); 
var channel:SoundChannel; 
function timerHandler(event:TimerEvent):void 
{ 
    mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
    timer.stop(); 
    soundBytes.position = 0; 
    sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler); 
    channel.addEventListener( Event.SOUND_COMPLETE, playbackComplete ); 
    channel = sound.play(); 
} 
 
function playbackSampleHandler(event:SampleDataEvent):void 
{ 
    for (var i:int = 0; i < 8192 && soundBytes.bytesAvailable > 0; i++) 
    { 
        trace(sample); 
        var sample:Number = soundBytes.readFloat(); 
        event.data.writeFloat(sample); 
        event.data.writeFloat(sample); 
    } 
} 
 
function playbackComplete( event:Event ):void 
{ 
    trace( "Playback finished."); 
}

Per ulteriori informazioni sulla riproduzione di audio da dati di campionamento audio, vedete Uso dell'audio generato dinamicamente .