Tra i requisiti di Windows Phone rientra la presenza sul dispositivo del microfono che può rivelarsi uno strumento molto utile in diverse tipologie di applicazioni che fanno uso della voce, musica, analisi e registrazioni.
Grazie alle API e la loro semplicità di utilizzo è possibile utilizzare il microfono in applicazioni XNA, ma anche in Silverlight, con un approccio misto che rientra tra le poche eccezioni consentite dalle policy di Microsoft. Come per tutte le tecnologie simili dedicate alla registrazione audio, il flusso arriva in buffer di byte che giungono attraverso un evento, nel quale è possibile salvare il buffer, elaborarlo oppure riprodurlo.
Tutto questo è possibile grazie alla classe Microphone, del namespace Microsoft.Xna.Framework.Audio, che cattura l'audio in un unico canale a 16bit. Questo significa che al secondo otteniamo 32000 byte e occorre perciò istruire il microfono di passarci il buffer ad intervalli regolari. Questo si traduce, una volta istanziata la classe e intercettato l'evento BufferReady, nell'impostare la proprietà BufferDuration con il tempo da catturare per ogni sample.
// Preparo il microfono microphone = Microphone.Default; microphone.BufferReady += microphone_BufferReady; // Durata del buffer microphone.BufferDuration = TimeSpan.FromMilliseconds(200); // Dimensiono il buffer in base alla dimensione int size = microphone.GetSampleSizeInBytes(microphone.BufferDuration); this.buffer = new byte[size];
Tramite questa durata si determina la dimensione del buffer, creando l'array che conterrà i byte. Poiché si hanno cinque campionature al secondo (32000 * 0.2) il buffer è di 6400 byte. La valorizzazione del BufferDuration è importante perché calibra il ritardo, l'utilizzo della CPU e della memoria nella fase di registrazione. Piccole campionature diminuiscono il ritardo e la memoria usata, ma intensificano l'uso della CPU. Campionature più lunghe aumentano il ritardo e la memoria usata, ma alleggeriscono la CPU. I 200 millisecondi proposti sono stati scelti in questo script come un valore medio appropriato per riprodurre quasi immediatamente la registrazione tramite l'output audio del dispositivo.
Per riprodurre l'audio si procede quindi, oltre alla preparazione del microfono, alla creazione della classe DynamicSoundEffectInstance che grazie al sample rate e al numero di canale resta in attesa di buffer audio da riprodurre.
// Attivo l'uscita audio in base alle caratteristiche dell'input this.dynamicSoundEffectInstance = new DynamicSoundEffectInstance(microphone.SampleRate, AudioChannels.Mono); this.dynamicSoundEffectInstance.Play(); // Avvio la registrazione this.microphone.Start();
A questo punto non serve fare altro che riempire il buffer dal microfono non appena scatta l'evento BufferReady per poi redirigere l'array alla periferica di output con il metodo SubmitBuffer.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Migrare una service connection a workload identity federation in Azure DevOps
Effettuare chiamate con versioning da Blazor ad ASP.NET Core
Sostituire la GitHub Action di login su private registry
Eseguire le GitHub Actions offline
Utilizzare la versione generica di EntityTypeConfiguration in Entity Framework Core
Elencare le container images installate in un cluster di Kubernetes
Load test di ASP.NET Core con k6
.NET Conference Italia 2023
Usare Refit e Polly in Blazor per creare client affidabili e fortemente tipizzati
Creazione di componenti personalizzati in React.js con Tailwind CSS
Ottimizzare il mapping di liste di tipi semplici con Entity Framework Core
Usare il versioning con i controller di ASP.NET Core Web API
I più letti di oggi
- Miglioramenti nelle performance di Angular 16
- Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
- HTML5 con CSS e JavaScript
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Ottimizzazione dei block template in Angular 17
- Disabilitare automaticamente un workflow di GitHub (parte 2)