1- Raspberry Pi Zero W: setting up speaker e microfono per Google Assistant

The real problem with the interface is that it is an interface
Don Norman

Language is the most powerful, useful, and effective communication technology ever, period.
Golden Krishna

Sin dalla loro introduzione  le interfacce grafiche (GUI) sono state un mezzo di interazione artificiale inventate per consentire all’utente di comunicare con il computer obbligandolo però ad  impararne le regole del linguaggio visivo (icone, puntatori, pulsanti, etc) per  potervi interagire.
La voce fornisce invece un mezzo di interazione naturale e nel 1962 l’IBM, molto prima di Watson, era stata la prima a proporre  all’esposizione universale un sistema di riconoscimento vocale chiamato ShoeBox, sviluppato dall’ingegnere William C. Dersch, ma questo riconosceva solo 16 parole in inglese: le cifre da 0 a 9 e altre 6 parole come le operazioni matematiche più, meno, totale.

Vocal user interface

Il cognitive scientist Steven Pinker scriveva nella suo saggio “L’istinto del linguaggio” (1998) che per interagire con i calcolatori dobbiamo ancora apprenderne il linguaggio, perché le macchine non sono abbastanza sveglie per apprendere il nostro.
Il linguaggio naturale è la nuova interfaccia utente? Rimuovendo l’interfaccia grafica e sostituendola con la voce, gli utenti si ritrovano in un contesto più familiare e oggi le macchine sono molto più sveglie e dai nostri smartphones è possibile interagire con un’assistente vocale (Siri, Cortana, Alexa o Google Assistant) per impostare promemoria, controllare il meteo o rispondere ad un messaggio in arrivo.
Le interfacce vocali (VUI) ci aiutano così a risparmiare tempo nelle attività di routine quotidiane.
Questo comporta una duplice sfida: da un lato, l’elaborazione e la  comprensione del linguaggio umano (NLP/NLU) da parte di una macchina,  dall’altro lato, si tratta di classificare l’intento (intents) con la quale un utente pronuncia una frase ed essere in grado di catturarne i dettagli (entity recognition).  Molte di queste operazioni sono possibili attraverso strumenti come DialogFlow ( in precedenza api.ai) che ci permette di realizzare apps per Google Assistant con Actions on Google.

Prima di poter installare Google Assistant e iniziare a sfruttarne le potenzialità di riconoscimento vocale dobbiamo configurare lo speaker e il microfono della Raspberry Pi Zero W.

Tech Stack

[1] Raspberry Pi Zero W
[2] Raspian, RD 2017-11-29, Kernel 4.9
[3] USB 2.0 mini microphone 
[4] Altoparlante audio, diametro 4 cm, 4 Ohm 3W
[5] Scheda Amplificatore Class D MAX98357A bus $${ I }^{ 2 }S$$

Step 1 – Audio speaker via $${ I }^{ 2 }S$$ digital audio

La scheda Raspberry Pi Zero non possiede un connettore audio dedicato perché fornito attraverso il connettore HDMI, ma a noi serve uno speaker esterno e l’unica porta USB per installarci il microfono. Quindi anche la soluzione di una USB sound card è da escludere.
Una possibile soluzione iniziale homebrew, spiegata in questo tutorial di Adafruit, è quella di impiegare due GPIO pins PWM (Pulse Width Modulation) e un filtro passa-basso. Un’altra potrebbe essere un circuito audio con il classico LM386. Entrambe le soluzioni sono praticabili, ma la qualità audio non è delle migliori.

Il segnale analogico audio della Pi Zero è troppo debole per pilotare un  speaker esterno, per farlo abbiamo bisogno di un amplificatore. Adafruit nel suo store ne vende diversi a basso costo alcuni utilizzano il protocollo di comunicazione seriale $${ I }^{ 2 }S$$ per l’audio digitale.

Ho scelto quindi  di impiegare un amplificatore con il bus seriale $${ I }^{ 2 }S$$ basato sul chip Maxim Integrated  983577A che offre in uscita 3W e consente di collegare un altoparlante da 4 ohm.

$${ I }^{ 2 }S$$: Inter-IC Sound

$${ I }^{ 2 }S$$ (“I-sqaured-S” o ” I-two-S) è un bus seriale per i dispositivi audio progettato per gestire due segnali audio indipendenti sulla stessa linea dati. Impiegato inizialmente nella progettazione dei lettori CD, riscosse un notevole successo e venne impiegato anche per convertitori (codecs) A/D e D/A, DSP, filtri, etc.
Le specifiche vennero definite da Philips (adesso NXP Semiconductors) nel febbraio del 1986 e revisionate dieci anni dopo a giugno.

Le specifiche per il bus $${ I }^{ 2 }S$$ prevedono che sia composto da tre segnali:
[1] Serial clock (SCK) o BCLK
[2] Word Select (WS) o LRCLK 
[3] Serial Data (SD) o SDATA

Succede spesso che gli altri produttori di circuiti integrati (IC) utilizzino altri nomi nei loro  data sheets. Per esempio WS viene sostituito con LRCLK ad  indicare left/right clock,  SCK con BCLK che sta bit clock o a volte con SCLK per serial clock.
I segnali Word Select (WS) e Serial Data (SD) sono sincroni al Serial Clock (SCK)  e cambiano stato al fronte di discesa (negative edge) del SCK come illustrato dal timing diagram:


Il SCK si calcola dal prodotto della frequenza di campionamento (sample rate) per il numero di bit per il numero dei canali impiegati. Per esempio, un CD Audio con sample rate standard di 44.1 kHz, con 16 bit e stereo avrà un clock di:

$$ 44.1kHz\quad x\quad 16bit\quad x\quad 2\quad =1.4112MHz\quad $$

L’interfaccia  $${ I }^{ 2 }S$$ permette di trasmettere due canali indipendenti sulla stessa linea dati e il  segnale WS indica se si sta trasmettendo sul canale 1 o il canale 2.
Le specifiche $${ I }^{ 2 }S$$ per la trasmissione stereo dichiarano che il canale audio sinistro viene impiegato durante lo stato logico 0 (Low) del WS mentre il canale destro durante lo stato 1 (High). I livelli logici sono quelli standard TTL quindi 0: < 0.8V e 1: > 2V.
Il WS clock è un segnale con duty cycle al 50% e ha la stessa frequenza della frequenza di campionamento.
I dati vengono codificati in complemento a due quindi il bit più significativo (MSB) risulta nella prima posizione di ogni cifra.

Collegamenti fra la Pi Zero e l’amplificatore

Dobbiamo collegare la Pi Zero alla scheda con l’amplificatore come mostrato nell’immagine seguente:

Playback hardware devices

Ora che la Pi Zero è collegata all’amplificatore possiamo modificare da terminale (con VIM o Nano) le impostazioni di config.txt che si trova nella cartella boot.
Per editare il file di testo preferisco utilizzare Leafpad.

Nel file config.txt alla riga 56 disabiliamo la voce dtparam=audio=on semplicemente commentandola con # all’inizio . Ora dobbiamo inserire due nuove righe:

Salviamo il file modificato e controlliamo se appare fra i dispositivi di riproduzione con il comando:

Ed eccone l’output con esito positivo:

Ricordardiamoci che a Card è associato il numero 0 e a Device numero 0, questi due parametri hardware ci serviranno per le impostazioni del file asound.conf

Step 2 – Microfono

La Pi Zero non ha un microfono integrato quindi ne ho acquistato uno mini da collegare alla porta USB.

 

Capture Hardware devices

Digitiamo da terminale  il seguente comando:

Ci verranno così mostrati i devices di acquisizione audio disponibili:

Come per l’amplificatore dobbiamo ricordarci i parametri hardware per Card 1 e a Device 0. 

Step 3 – Editing file: asound.conf

Ora che il microfono è collegato alla porta USB e la Pi Zero all’amplificatore possiamo creare e modificare il file asound.conf salvandolo nella cartella etc.

Sempre con Leafpad  iniziamo a dichiarare che avremmo come dispositivo di acquisizione il Microfono USB e di riproduzione lo Speaker (righe 1-5).
Nelle righe successive andremo invece a definire quali sono le proprietà di questi due dispositivi. Inserendo i corrispettivi parametri hardware associati di Card e Device in pcm.mic (righe 6-11) e pcm.speaker (righe 12-15).

Infine per per poter regolare comodamente il volume da alsamixer dobbiamo inserire anche le righe dalla 33 alla 45.

Step 4 – Test microfono e speaker

Ora dobbiamo regolare il volume da alxamixer impostandolo a un valore soddisfacente.

Non ci resta che testare il sistema microfono e audio registrando e riproducendo un file audio (raw) della durata di 5 secondi inserendo i parametri hardware del microfono (plughw:1,0). Utilizzando arecord dalla linea di comando digitiamo:

Ora non dobbiamo fare altro che riprodurre il file audio di test inserendo i parametri del nostro speaker (plughw:0,0).

Abbiamo  impostato la frequenza di campionamento (sample rate)  della sorgente audio a 16000 Hz perché dalla documentazione di Google Assitant risulta che i valori ideali per l’invio dei dati audio in tutti i messaggi dovrebbe essere in un range fra i  16000 e i 24000 Hz, con 16000 Hz come valore ottimale per coprire la gamma di frequenza della voce umana.

Bibliografia

[1] Steven Pinker, Istinto del linguaggio, Mondadori,1998
[2] Louis Frenzel, Handbook of Serial Communications Interfaces: A Comprehensive Compendium of Serial Digital Input/Output I/O) Standards, Newnes, 2015

Sitografia

Amplificatore
[1] PCM Input Class D Audio Power Amplifiers

Inter-IC Sound
[1] I2C-bus specification , Philips Semiconductor (adesso NXP Semiconductors)
[2] $${ I }^{ 2 }S$$, Wikipedia
[3] Common Inter-IC Digital Interfaces for Audio Data Transfer

Google Assistant SDK
[1] Configure and Test the Audio
[2] Audio In Config, Sample Rate Message

Audio Outputs
[1] How to Add Audio Outputs to your Pi Zero
[2] Pi Zero PWM Audio
[3] AudioSpoof with Raspberry Pi Zero, articolo che mostra l’utilizzo LM386

Amplificatore Mono Classe D Max98357 $${ I }^{ 2 }S$$
[1] Raspberry Pi Usage