
Vediamo come si possono processare i file audio WAV in sistemi embedded. Un po' di tempo fa mi è stato chiesto di creare un piccolo circuito basato su un microcontrollore e un convertitore analogico/digitale che avrebbe prodotto vari suoni corrispondenti a diversi stimoli.
Questi stimoli sarebbero stati comandi ricevuti dal microcontrollore embedded tramite un ricevitore-trasmettitore asincrono universale e l'uscita dei suoni avrebbe stimolato un interruttore,una porta chiusa o altri suoni provenienti da un ambiente di lavoro. Costruire l'hardware del circuito non era difficile - si veda la Figura 1 per il diagramma a blocchi (anche se ho dovuto fare notevoli sforzi per mantenere il costo del BOM il più basso possibile), ma era la prima volta che mi sono trovato di fronte al suono emesso! Così ho dovuto imparare nuove cose.

Come processare file audio WAV in sistemi embedded
Il primo ostacolo che ho incontrato consisteva nel determinare in che modo la produzione dei suoni sarebbe apparsa. La descrizione "Ho bisogno di un suono che simula la pressione di un pulsante" è abbastanza sufficiente, ma ... come si fa a renderlo realmente? Per fortuna, ci sono molti siti web che forniscono file WAV per applicazioni in un PC. Mi sono imbattuto in questi accidentalmente ma ero felice di trovare vari suoni che ben si adattavano alla descrizione: Soundjay, Pachd, Soundsnap.
Solo una volta ho trovato i suoni "digitali" che mi servivano e ho capito che il problema principale era la mancanza di memoria. Tutti i suoni su questi siti sono relativamente di buona qualità, il che significa che vengono campionati a 44.1 kHz e ogni campione è codificato con 16 o 32 bit. Naturalmente, questo non pone alcun problema per un PC che ha molta memoria disponibile, ma purtroppo per il mio povero "sistema embedded", mi sono reso conto che per un breve audio di buona qualità della durata di circa 200 ms (44,1 kHz con 16 bit /campione) io avevo bisogno di ... 17640 byte di ROM sul chip. A causa dei costi sono stato costretto a non utilizzare alcun chip di memoria esterna per il microcontrollore, ma un unico suono ha preso più di tutto il programma di memoria disponibile (16kbyte)!
Chiaramente doveva essere creata un’alternativa. Quello che ho capito subito era che per suoni semplici, che sono lontani dall’essere musica o addirittura discorso, non vi era alcuna necessità di buona qualità. E mi sono reso conto che invece di 44,1 kHz di frequenza di campionamento potevo richiedere di meno. E anche 16bit/campione mi sembrava troppo, ero sicuro di poter abbassare ancora di più (il mio obiettivo era 8bit/ campione).
Facendo di nuovo i calcoli, ero felice nel rendermi conto che le nuove condizioni mi permettevano un suono a 200ms campionato a 20kHz con 8bit/campione da memorizzare con soltanto 4000 byte ... il che significava che la mia memoria di programma a 16kbyte era sufficiente per tre suoni e il programma stesso. Ma finora tutto questo è solo teoria. Tutto quello che avevo erano questi calcoli e alcuni file WAV. La vera sfida (almeno per me che non sono uno sviluppatore di software ma un ingegnere di hardware), è stato a sua volta un file WAV in una array di C da utilizzare nel programma in esecuzione sul microprocessore, qualcosa del tipo:
unsigned char campione suoni [4000]={ 55, 66, 81, 83, 76, 66, 63, 62, 66, 62, 62, 82, 91, 85, 77, 70, 67, 68, 75, 80, 77, 79, 76, 74, 70, 63, 67, 70, 67, 65, 73, 71, 71, 72, 70, 61, 64, 59, 54, 62, 71, 73, 67, 67, 76, 81, 81, 70, …55, 43}
Avevo anche bisogno di tradurre i file WAV da un segnale con doppia polarità centrato su 0V in un segnale positivo, con il valore più piccolo del campione corrispondente a 0V. Descriverò a seguire il procedimento necessario per effettuare questa operazione che consta di due fasi:
Passo I – Processare il file WAV
In primo luogo ho dovuto convertire il file WAV da 44,1 kHz a 20 kHz e per questo ho usato uno degli strumenti disponibili on-line chiamato Cool Edit. Ci sono diverse versioni di prova disponibili, ma quelli più recenti non consentono di salvare il file modificato, per cui ho preferito una versione precedente di questo strumento, denominato Cool Edit 2000. Uno strumento open source che potrebbe consentire di eseguire lo stesso procedimento, in caso di necessità, è Audacity, disponibile all'indirizzo: Audacity.Sourceforge

Affrontiamo in dettaglio l'utilizzo di questi strumenti, in quanto è piuttosto semplice: avviare lo strumento, aprire il file WAV, tagliarlo a 200 ms, convertirlo da stereo a mono, modificare la frequenza di campionamento (dal menù in alto scegliere Brani e nella casella di testo che si apre scrivere la nuova frequenza di campionamento di cui si ha bisogno - 20 kHz nel mio caso) e poi salvare il nuovo file wav. Se si riproduce il nuovo file WAV sul PC, potrete osservare una piccola degenerazione della qualità del suono. Una volta che questo passo è stato completato, ho creato il file WAV come lo volevo, ora era necessario estrarre i campioni!
Passo II – Estrarre i campioni di suono dal file WAV
Questo è stato un vero problema, soprattutto perché non vi è alcun strumento a disposizione per farlo (o meglio, che io non conosco). Così ho dovuto istruire il mio software su cosa fare e ho dovuto fare qualche correzione sul formato del file WAV. Fortunatamente nessuno di questi compiti riguarda la scienza missilistica. Il formato del file WAV è piuttosto semplice:

I primi 44 byte del file WAV contengono una grande quantità di informazioni ma che non sono di alcuna utilità per noi adesso. Fondamentalmente questi primi 44 byte formano un header indicando (tra gli altri): la frequenza di campionamento (ma lo sappiamo già: 20 kHz), il numero di bit per campione (sappiamo anche questo: 16bit/campione), la lunghezza della sezione "Dati" - che vuol dire quanti campioni sono nel file (ma conosciamo anche questo: 4000 campioni, perché ho tagliato il file a 200m con lo strumento di editing nel passo I). Ciò di cui ho veramente bisogno da questo file sono i dati (tutti i 4000 campioni), che si trovano dal 44esimo byte nel file successivo. Per questo ho dovuto scrivere il mio codice usando il linguaggio di programmazione C #, con un compilatore gratis (e anche open source!) noto come Sharpdevelop e disponibile sotto: Codeplex
Anche se non sono un programmatore professionista, C # permette di manipolare facilmente il testo e i file binari. Il programma che ho scritto [vedi allegato] prende un file wav come input generando l’array di C di cui ho bisogno. Legge ogni campione dal file WAV, aggiunge un importo fisso per ogni campione (in modo che tutti i campioni diventino numeri positivi), lo scala da 16 bit a 8 bit (una semplice divisione per 256) e poi crea un file di testo che contiene l'array nel formato standard di C:
unsigned char campione suoni [4000]={ 55, 66, 81, 83, 76, 66, 63, 62, 66, 62, 62, 82, 91, 85, 77, 70, 67, 68, 75, 80, 77, 79, 76, 74, 70, 63, 67, 70, 67, 65, 73, 71, 71, 72, 70, 61, 64, 59, 54, 62, 71, 73, 67, 67, 76, 81, 81, 70, …55, 43}
L'effetto di questa trasformazione può essere illustrato con un grafico di Excel, con il suono del segnale prima della trasformazione e il suono del segnale dopo l'elaborazione. Il grafico mostra in blu i campioni in modalità raw (centrato su 0) e in giallo i campioni tradotti in un intervallo (con l'aggiunta di un importo fisso).
Quindi, dopo aver diviso i campioni tradotti da 256 (per la conversione a 8 bit/campione ) il programma C # semplicemente genera un file di testo contenente l’array di C.
Produrre il suono dell’altoparlante
Una volta completata questa elaborazione sono pronto per integrare questo array nel programma in C che ho scritto per il microcontrollore. Finora ho fatto solo la teoria e la trasformazione del computer. Ma dovevo sentire un suono dall’altoparlante del sistema embedded. Il programma del microcontrollore non era così difficile da scrivere, poiché avevo familiarità con questo dispositivo. La frequenza di campionamento a 20 kHz richiedeva che ogni campione dovesse essere inviato al DAC ogni 50us. Questo lasso di tempo è più che sufficiente per scrivere uno o due byte tramite SPI (frequenza di clock a 8 MHz) e dopo un breve sforzo mi ha fatto piacere sentire il suono dagli altoparlanti che simulavano il "premere un pulsante"!
Vai in Download e scarica WAV_Extract.zip
Leggi la versione Inglese: How to process audio WAV files in embedded systems

grazie per aver condiviso questa tua esperienza. lettura a mio parere molto utile! 🙂
proprio oggi ho avuto problemi a decodificare un file audio che con GoldWave non sono riuscito a decodificare.
a me mi piacerebbe realizzare una cosetta simile con la scheda Arduino.
Ma la cosa interessante sarebbedi esportare anche il dato della lunghezza del file così da potere mettersi qualsiasi campione sonoro.
Dire che questo articolo è interessante mi sembra davvero riduttivo. Mi ha aperto gli occhi ad un mondo di applicazioni nuove. Mi serviva proprio una base da cui partire per supportare dell’audio con un Pic micro. Grazie mille!
Molto utile questo articolo! Se dovrò realizzare un sistema embedded, saprò dove andare a trovare informazioni!
Come funziona il DAC? Gli invii un byte e lui commuta l’uscita su quel livello oppure ha un buffer interno e va programmato per dirbgli periodo e bit?
Avevo pensato di costruirmi un generatore di seganli, sinusoidale, triangolare, quadra ecc. Si siesce a generare una sinusoide a 20kHz con distorsione sufficientemente bassa?
Ciao, ho letto con interesse l’articolo, ti chiedo di aiutarmi, devo far uscire da un pic 18f alla pressione di un pulsante un suono di buona qualita quindi ho bisogno di una memoria esterna, purtoppo non so quale usare e come programmarla per includergli il file audio, per cortesia mi dai qualche dritta?
Grazie.