UNIVERSITÀ POLITECNICA DELLE MARCHE
FACOLTÀ DI INGEGNERIA
Corso di Laurea Specialistica in Ingegneria delle Telecomunicazioni
Algoritmi per Applicazioni Multimediali
Implementazione in Nu-Tech di un VAD
in tempo reale basato sulle statistiche di
ordine superiore e sull’algoritmo EM
Online
Titolare del corso: Chiar.mo
Prof. FRANCESCO PIAZZA
Tesina di:
Relatore:
Giovanni Pelliccioni
Marco Malatesta
Prof. STEFANO SQUARTINI
Anno Accademico 2008-2009
Abstract
In questo lavoro è stato studiato e implementato un nuovo metodo per la
realizzazione di un Rilevatore di Attività Vocale (Voice Activity Detection, VAD) in
tempo reale. Il lavoro deriva dall’analisi proposta nell’articolo Voice Activity Detection
Based on High Order Statistics and Online EM Algorithm [1] il quale viene presentato,
integrato con nozioni teoriche e ampliato nella parte riguardante la decisione nel
capitolo 1 e 2.
Il metodo proposto è basato su un parametro denominato caratteristica (feature),
ricavato dalle Statistiche di Ordine Superiore (High Order Statistics, HOS) e, per
migliorare la sua robustezza ai rumori non gaussiani, dai picchi di autocorrelazione
normalizzata. La caratteristica è anche finalizzata alla distinzione tra il segnale vocale in
campo lontano e in campo vicino, ovvero il parlatore situato rispettivamente lontano e
vicino al microfono.
A differenza dei classici approcci VAD, questo non si basa esclusivamente sul livello
di energia. La classificazione tra segnale vocale e ciò che è considerato rumore, tra cui il
parlato in campo lontano, è incentrata su una modifica dell’algoritmo EM affinché sia
utilizzabile in tempo reale (EM Online).
È stato aggiunto un criterio di decisione per integrare lo studio presentato dagli autori
dell’articolo al fine di ottenere un’implementazione del VAD più efficiente.
Vengono forniti e confrontati in MATLAB e in C, sfruttando la piattaforma NuTech, i risultati ottenuti dalle implementazioni dell’algoritmo.
Indice
INDICE ........................................................................................................................................................3 CAPITOLO 1 ..............................................................................................................................................5 INTRODUZIONE ......................................................................................................................................5 1.1 RILEVATORE DI ATTIVITÀ VOCALE ..................................................................................................5 1.2 PRESENTAZIONE DEL METODO ........................................................................................................6 CAPITOLO 2 ..............................................................................................................................................8 STRUTTURA DEL VAD BASATO SULLE STATISTICHE DI ORDINE SUPERIORE E
SULL’EM ONLINE ...................................................................................................................................8 2.1 ANALISI LPC E CALCOLO DEL RESIDUO ..........................................................................................9 2.1.1 Linear Predictive Coding ......................................................................................................9 2.1.2 Calcolo del residuo LPC .....................................................................................................11 2.2 ESTRAZIONE DEL PICCO DI AUTOCORRELAZIONE ..........................................................................12 2.3 STATISTICHE DI ORDINE SUPERIORE PER LA RILEVAZIONE DEL PARLATO: LA KURTOSI ................13 2.3.1 Proprietà del segnale vocale nei casi vicino e lontano dal microfono ...............................13 2.3.2 Definizione delle Statistiche di Ordine Superiore (HOS) ...................................................15 2.3.3 La kurtosi e la forma della distribuzione ............................................................................16 2.3.4 Calcolo della feature ..........................................................................................................18 2.4 EM ONLINE...................................................................................................................................21 2.4.1 Apprendimento con variabili nascoste: l’algoritmo EM.....................................................21 2.4.2 Approccio teorico all’EM Online: apprendimento non controllato....................................24 2.4.3 Realizzazione real time dell’algoritmo EM: l’EM Online ..................................................28 2.5 RISULTATI SPERIMENTALI DELL’ARTICOLO DI RIFERIMENTO.........................................................30 2.5.1 Struttura di valutazione ......................................................................................................30 2.5.2 Valutazione su dati autoprodotti .........................................................................................31 2.5.3 Valutazione sul database CENSREC-1 ...............................................................................33 2.6 IL CUORE DEL VAD: LA DECISIONE ...............................................................................................35 CAPITOLO 3 ............................................................................................................................................45 RISULTATI SPERIMENTALI...............................................................................................................45 3.1 PARAMETRI E RISULTATI IN MATLAB .........................................................................................45 3.2 RISULTATI SULLA PIATTAFORMA NU-TECH ..................................................................................55 3.2.1 Risorse di calcolo impiegate dall’algoritmo .......................................................................60 3.3 CONFRONTO TRA MATLAB E NU-TECH ......................................................................................62 3.4 TEMPI DI CONVERGENZA DEI PARAMETRI DEL VAD .....................................................................65 3.5 PRESTAZIONI DELL’ALGORITMO VAD PER DIVERSI SNR ..............................................................70 3.5.1 Ulteriore miglioramento dell’algoritmo per bassi SNR......................................................91 CAPITOLO 4 ............................................................................................................................................96 CONCLUSIONI........................................................................................................................................96 APPENDICE .............................................................................................................................................99 LISTATI DELL’ALGORITMO .............................................................................................................99 A. B. LISTATO IN MATLAB ..................................................................................................................99 LISTATO IN C ..............................................................................................................................107 BIBLIOGRAFIA ....................................................................................................................................119 4
Capitolo 1
Introduzione
1.1 Rilevatore di attività vocale
Il VAD (Voice Activity Detection) rileva automaticamente le parole dai segnali
audio, è un problema classico nell’elaborazione del segnale vocale. Ad esempio, è
spesso usato come un’interfaccia per il riconoscimento automatico delle parole (ASR)
[2]. È stata data recentemente attenzione al problema perché l’efficacia dell’interfaccia
VAD è cruciale per le prestazioni del riconoscitore vocale negli ambienti rumorosi;
quando il rumore di sottofondo è alto, il numero degli errori di inserzione diventano
maggiori [3], e avere un VAD immune ai rumori ambientali può significativamente
ridurre il rate delle parole errate (WER: Word Error Rate). Il VAD è utile anche in altri
impieghi come la codifica del parlato e il riconoscimento del parlatore.
Il lavoro qui descritto tratta dell’individuazione del parlato nel contesto di interazione
uomo-uomo. Questa situazione pone molte sfide principalmente perché alcune delle
assunzioni solitamente fatte per l’ASR o per la codifica vocale, come il segnale che
contiene parlato per la maggior parte del tempo, non sono verificate nell’interazione
uomo a uomo. Perciò un algoritmo VAD deve fare i conti con questa poca densità
temporale (sparsity). Inoltre quando molte persone sono coinvolte dovrebbe essere in
grado di distinguere i diversi parlatori. Una soluzione a questo problema è quella di
usare un array di microfoni [4]. Se fosse possibile usare registrazioni fatte con microfoni
vicino ai parlatori, la distinzione tra chi indossa il microfono e le altre persone sarebbe
possibile qualora si trovasse una caratteristica il cui comportamento fosse diverso a
seconda che il parlato sia vicino o lontano al microfono. Il lavoro qui presentato segue
proprio questo approccio. Infatti anche quando la registrazione del parlato da vicino è
disponibile, la semplice strategia basata sull’energia dà risultati insoddisfacenti [5],
principalmente a causa della sovrapposizione di più voci nello stesso canale e della
variazione delle condizioni di rumore.
1.2 Presentazione del metodo
Il metodo di cui si parla nell’articolo [1] alla base di questo lavoro contiene una
nuova caratteristica incentrata sulle statistiche di alto ordine (HOS) per distinguere tra il
parlato in campo lontano e in campo vicino, e uno schema di classificazione online non
controllato basato sull’algoritmo Online EM (Expectation Maximization) per far fronte
alla variazione della condizione di rumore e il cambiamento della proporzione del
parlato. Le HOS possono essere definite dai momenti di una variabile aleatoria, e danno
l’informazione che è assente dai più comuni momenti usati che sono media e varianza.
L’utilizzo delle HOS per il VAD è stato suggerito per esempio in [6], la cui strategia è
stata raffinata in [7]. È stato mostrato in [6] che l’HOS del residuo LPC è una funzione
crescente del numero di armoniche nel segnale, usando un modello sinusoidale del
parlato [8]. Siccome le HOS sono immuni al rumore gaussiano, possono essere usate
per il VAD in alcuni ambienti rumorosi, come quelli gaussiani. Ad ogni modo le HOS
sono sensibili ad altri tipi di rumori come i rumori transitori (i rumori che hanno
un’energia elevata e sono ben localizzati nel tempo, che possono capitare per esempio
quando c’è un contatto fisico con il microfono). Nell’articolo [1] le HOS sono
combinate con un’altra metrica, derivata dall’autocorrelazione normalizzata, per
migliorare la loro robustezza ai rumori di tipo non gaussiani. Delle HOS così migliorate
sarà studiata l’efficacia nel distinguere il parlato in campo vicino e in campo lontano.
Verrà proposto anche un nuovo schema per la classificazione in tempo reale attraverso
l’uso dell’EM online. Questo metodo ha il vantaggio di stimare in tempo reale il rumore
e il livello del parlato contemporaneamente alla classificazione, senza dipendere da uno
schema di stima del SNR indipendente come quello usato nel VAD G.729B [9]. La
Figura 1 visualizza lo schema a blocchi di principio presentato in [1]: come prima cosa
6
il segnale vocale viene suddiviso in frames i quali sono pre-processati e passano
attraverso l’analisi LPC, il residuo della quale è usato come ingresso al resto del
metodo. La kurtosi e l’autocorrelazione normalizzata, il cui picco principale viene
estratto, sono calcolate, combinate tra loro e usate come ingresso dell’algoritmo EM
online, che fa la classificazione e l’aggiornamento del modello simultaneamente.
Speech signal
LPC analysis
Autocorrelation
Kurtosis
Peak Picking
Online EM
Result
Figura 1. Schema dell’algoritmo proposto nell’articolo [1]
7
Capitolo 2
Struttura del VAD basato sulle
Statistiche di Ordine Superiore e
sull’EM Online
In questo capitolo si entra nel merito della teoria e della procedura che permette la
realizzazione del VAD in questione. In Figura 2 è visibile il suo schema a blocchi
completo, cioè con la parte relativa alla decisione aggiunta con questo lavoro.
Concettualmente il VAD può essere suddiviso in 5 grandi sezioni:
•
l’analisi LPC per il calcolo del residuo;
•
l’autocorrelazione del residuo LPC per l’estrazione del picco;
•
il calcolo della kurtosi del residuo LPC e la feature;
•
l’algoritmo EM Online;
•
la decisione.
Speech signal
LPC analysis
Autocorrelation
Kurtosis
Peak picking
Online EM
Decision
VAD
Figura 2. Schema a blocchi completo del VAD.
2.1 Analisi LPC e calcolo del residuo
2.1.1 Linear Predictive Coding
La codifica di predizione lineare (Linear Predictive Coding) è un efficiente e pratico
metodo per ottenere voce artificiale. La sua efficienza è dovuta alla velocità
dell’algoritmo di analisi e al basso requisito di banda per i segnali codificati. La sua
efficacia è legata all’intelligibilità del segnale vocale decodificato.
L'idea alla base dell'analisi predittiva è che un campione di parlato è rappresentabile
come combinazione lineare dei campioni ad esso precedenti, ovvero:
1
̂
2
‐
rappresenta il campione vero all’ n-esima posizione, mentre ̂
dove
1
rappresenta
la sua stima, combinazione lineare dei campioni precedenti.
Viene poi indicato con
l’errore di predizione corrispondente ad un predittore
di ordine P e cioè realizzato con P coefficienti:
‐
̂
La determinazione dei coefficienti
2
viene fatta in modo ottimo, minimizzando il
valore atteso del quadrato dell’errore:
|
|
‐
‐
3
quindi basterà minimizzare rispetto ad essi il valore dell’errore quadratico medio e
dunque imporre che
|
|
2
1, … ,
‐
:
1
‐
‐
2
‐
0 4
Queste equazioni corrispondono alla condizione di ortogonalità. Se l’errore di
predizione è minimo, deve essere incorrelato con i dati utilizzati per calcolarlo; infatti,
se ci fosse correlazione, si contraddirebbe l’ipotesi che l’errore sia minimo, in quanto i
dati potrebbero essere utilizzati meglio per ridurre ancora di più l’errore. Le equazioni
(4) vengono dette equazioni di Yule-Walker, dai ricercatori che per primi le
utilizzarono, e potrebbero essere riscritte in questo modo:
9
‐
dove, ignorando l’operatore di coniugio essendo
con
0,
1, … ,
5
reale, si ha che:
0, … ,
–1
6
è l’autocorrelazione del segnale. Le equazioni di Yule-Walker possono essere viste
anche in forma matriciale, considerando la simmetria dell’autocorrelazione di un
segnale reale:
7
Per risolvere questo sistema, si usa solitamente un algoritmo dai costi computazionali
molto contenuti, l’algoritmo di Levinson-Durbin [22].
L’analisi spettrale autoregressiva fornisce un metodo per calcolare un filtro tutti poli
che, applicato ad un rumore bianco, ne sagomi lo spettro in modo da riprodurre quello
della sequenza esaminata. La predizione lineare non fa altro che applicare gli stessi
metodi per il procedimento inverso, ovvero sbiancare il segnale tramite un filtro a media
mobile. Quindi i parametri
trovati conterranno l’informazione spettrale del segnale in
ingresso e, riprodotti in un filtro IIR alimentato da rumore gaussiano bianco,
riporteranno al segnale precedente, a patto che l’ordine della predizione sia
sufficientemente alto. In Figura 3 viene mostrato questo ragionamento, si può
dimostrare che, nel caso in cui
,
sarà statisticamente uguale
e quindi
l’errore di predizione sarà bianco. È possibile quindi scrivere:
‐
dove
8
è un segnale gaussiano bianco.
Ora si può passare ad analizzare l’implementazione della codifica vera e propria.
Dall’equazione (2) si nota che l’errore di predizione è l’uscita di un sistema la cui
funzione di trasferimento è il seguente polinomio monico:
1
‐
9
10
1
sn sequenza colorata
sequenza
bianca
errore di
predizione
equazioni di Yule-Walker
parametri
del filtro
Figura 3. Schema di predizione.
Comparando l’equazione (9) con la (8), è possibile affermare che se il segnale vocale
obbedisce esattamente al modello dell’equazione (8), allora
di predizione
. Così il filtro
sarà un filtro inverso per il sistema di produzione del parlato, ad
esempio:
10
dove g è una costante moltiplicativa opportuna.
L’ipotesi principale per applicare l’analisi LPC al parlato è il fatto che questo si
mantenga all’incirca stazionario per un periodo di tempo; si può dimostrare che, avendo
in ingresso un segnale campionato a 8 KHz, la stazionarietà sarà mantenuta per circa
128-256 campioni, ovvero 16-32 ms. Quindi, una volta segmentato il segnale in
intervalli verrà applicata a ciascun frame un’analisi di predizione lineare, con un
numero di coefficienti
solitamente variabile tra 8 e 14, lo standard LPC-10 ne
utilizza 10 poiché per il tratto vocale umano P=10 è una buona stima dei gradi di libertà
che sono necessari per rappresentare la maggior parte delle espressioni.
2.1.2 Calcolo del residuo LPC
Nella trattazione attuale, seguendo quanto fatto nell’articolo [1], viene utilizzato
come segnale d’ingresso al VAD un segnale vocale campionato a 8KHz. Come
mostrato in Figura 4, questo viene elaborato in frames da 256 campioni (32 ms) con un
11
overlap del 50%. Su ogni frame si effettua l’analisi LPC descritta in generale nel
paragrafo precedente con N=P. Vengono restituiti i coefficienti
che permettono di
costituire il seguente filtro A’(z) che sintetizza la voce:
‐
.
11
Infatti per continuare con lo studio deve essere calcolato il residuo eseguendo la
differenza tra il segnale originale e quello artificiale. Si ricostruisce il segnale sintetico
ponendo in ingresso al filtro i 256 campioni del segnale originale; essi rappresentano la
miglior eccitazione per il filtro di sintesi.
frame vocale
(256 campioni)
frame
ricostruito
equazioni di Yule-Walker
+
-
∑
residuo
LPC
parametri
del filtro
Figura 4. Schema del blocco LPC analysis.
2.2 Estrazione del picco di autocorrelazione
Il residuo LPC segue due percorsi paralleli, uno di questi è il calcolo della sua
autocorrelazione normalizzata con in cascata l’estrazione del picco.
1
Infatti l’autocorrelazione normalizzata,
1
0
2
, fatta sui N=256
campioni di residuo, fornisce valori compresi tra -1 e 1, ove 1 è il massimo ottenuto per
un ritardo k nullo.
12
Ai fini dell’algoritmo il picco significativo non è quello a ritardo nullo, ma quello più
elevato tra tutti gli altri. Questo picco, denominato mx, verrà prelevato e
successivamente abbinato ad un altro parametro del sistema per proseguire nello studio
del VAD.
2.3 Statistiche di Ordine Superiore per la rilevazione
del parlato: la kurtosi
2.3.1 Proprietà del segnale vocale nei casi vicino e lontano dal
microfono
Molte caratteristiche sono state proposte per il VAD, ad esempio l’energia,
l’autocorrelazione, i picchi di cepstrum [11], e MFCC [12]. L’obiettivo è trovare una
caratteristica la cui distribuzione fondamentale è diversa per il segnale vocale e per
quello non vocale. Inoltre l’obiettivo è quello di rilevare solamente il parlato in campo
vicino perciò la caratteristica deve essere anche in grado di distinguere tra campo vicino
e campo lontano. La proprietà più ovvia per individuare il parlato in campo vicino e in
campo lontano sarebbe l’energia, ma questa non si comporta come ci si aspetterebbe; le
principali cause di deterioramento delle prestazioni negli algoritmi che si basano
semplicemente sull’energia si identificano [5] nella sovrapposizione vocale in un canale
e nelle variazioni delle condizioni di rumore. Inoltre, come notato in [13], la
normalizzazione della caratteristica per quanto riguarda l’energia è molto importante per
il VAD online. Per queste ragioni ci si concentra sulle caratteristiche indipendenti
dall’energia.
Si riporta in Figura 5 il residuo LPC del parlato in campo vicino e in campo lontano,
poiché è noto essere legato con l’eccitazione glottale. Il segnale è stato registrato con
due microfoni, uno in campo vicino e l’altro in campo lontano, e viene mostrato
l’estratto da entrambi i microfoni sincronizzato nel tempo. In entrambi i casi,
l’inviluppo spettrale (colonna in mezzo) è simile, e gli impulsi corrispondenti alle
variazioni del flusso d’aria così come la loro periodicità sono visibili nel residuo LPC
(colonna a destra). Ma nel caso del parlato in campo vicino, il residuo LPC non è
13
relativamente disturbato dal rumore e gli impulsi hanno un’ampiezza molto più forte
sulla media. Così, nel parlato in campo vicino, l’ampiezza del segnale x(t) è o fuori il
range [-σ, σ] o circa 0 (ad esempio | |
). Nell’altro caso, per il parlato in campo
lontano, l’ampiezza è più probabile che sia nell’intorno di σ (ad esempio| |
).
Figura 5. Paragone tra parlato lontano (in alto) e vicino (in basso). Le due registrazioni appartengono allo
stesso segnale. La colonna a sinistra mostra lo spettrogramma di circa un secondo di segnale,
quella in mezzo mostra lo spettro e quella a destra riporta il residuo LPC di un particolare
estratto della registrazione. La linea tratteggiata rappresenta la deviazione standard del segnale.
Ci sono diverse spiegazioni per questa differenza: primo perché l’SNR è più basso
per voci distanti e in quanto tale è incluso nel rumore, e inoltre, a causa della
riverberazione, la distribuzione del suo residuo LPC è più somigliante ad una gaussiana.
Un’altra possibile spiegazione per questa differenza potrebbe essere l’effetto di
prossimità del microfono. La maggior parte dei microfoni per il campo vicino sono
direzionali, e poiché quelli direzionali usano due diaframmi, ciò causa l’effetto di
prossimità di questi microfoni. Questo effetto aumenta lo spettro di bassa intensità del
segnale ricevuto per i segnali vicini (pochi centimetri distanti dal microfono).
In conclusione, la distribuzione del residuo LPC è più probabile che abbia valori
estremi (lontani dalla media, o vicini alla media) nel caso di campo vicino piuttosto che
nel caso di campo lontano. Seguendo questa proprietà, la distinzione tra parlato in
campo vicino e in campo lontano si riduce alla distinzione tra una distribuzione con un
picco e coda alta e una distribuzione con un elevato medio-range. La kurtosi, che è una
delle HOS, è una statistica standard usata per questo intento.
14
2.3.2 Definizione delle Statistiche di Ordine Superiore (HOS)
Come accennato nel paragrafo 1.2, per stimare la kurtosi, che è uno dei pilastri della
procedura per la realizzazione del VAD, viene utilizzato il residuo LPC dal quale la si
ricava attraverso media e varianza. Prima di approfondire l’analisi della kurtosi però,
viene definita la famiglia da cui deriva cioè le High Order Statistics.
Le HOS, anche chiamate cumulanti, di variabili casuali X sono definite dalla
funzione generatrice dei cumulanti Ψ:
Φ t
!
12
cioè, la funzione generatrice dei cumulanti è definita come il logaritmo della funzione
generatrice dei momenti Φ, e il cumulante di ordine n,
Kn,
è l’n-esimo coefficiente
dell’espansione di Taylor diviso per n!. C’è una relazione diretta tra i cumulanti di una
variabile casuale X e i suoi momenti centrali. Per i primi quattro cumulanti queste
relazioni sono:
0
13
14
15
3
16
Il cumulante di ordine 2 è semplicemente la varianza. Le statistiche di alto ordine più
comuni, la skewness sX e la kurtosi kX, sono definite come la versione normalizzata dei
cumulanti rispettivamente di ordine 3 e 4, con il fattore di normalizzazione σn, dove σ è
la deviazione standard e n l’ordine delle statistiche:
⁄
⁄
⁄
⁄
17
3
18
Un motivo per questa definizione è la proprietà di additività per le variabili casuali
indipendenti, che è una diretta conseguenza della proprietà della funzione generatrice
dei momenti per le variabili casuali indipendenti. Un’altra diretta conseguenza è che
tutti i cumulanti di ordine n ≥ 3 sono 0 per le variabili casuali gaussiane, poiché la
funzione generatrice dei cumulanti di una variabile gaussiana è un polinomio di ordine
2.
15
2.3.3 La kurtosi e la forma della distribuzione
La kurtosi è stata usata a lungo in letteratura statistica come una misura di nongaussianeità, come una misura di forma a picchi o a code per una variabile casuale [14],
[15]. Infatti la kurtosi nel linguaggio della statistica indica un allontanamento dalla
normalità distributiva, rispetto alla quale si verifica un andamento più piatto e a code
ampie (distribuzione platicurtica) o un andamento più appuntito e con code piccole
(distribuzione leptocurtica). Una distribuzione con la stessa kurtosi della distribuzione
normale è chiamata mesocurtica.
Si ricorda che la più nota misura della kurtosi è l'indice di Fisher (19), ottenuto
facendo il rapporto tra il momento centrale di ordine 4 e la varianza al quadrato (o
deviazione standard alla quarta). Il valore della kurtosi kx corrispondente alla
distribuzione normale (gaussiana) è 0 qualora si utilizzi, come nell’articolo [1] e di
conseguenza anche in questo lavoro, la formula (20) in cui si sottrae 3 all’indice di
Fisher.
4
4
19
3
20
Schematicamente, se il coefficiente di kurtosi è:
•
> 0 la curva si definisce leptocurtica, cioè più "appuntita" di una normale.
•
< 0 la curva si definisce platicurtica, cioè più "piatta" di una normale.
•
= 0 la curva si definisce normocurtica o mesocurtica, cioè "piatta" come una
normale.
Un esempio grafico è dato dalla Figura 6 in cui sono rappresentate due distribuzioni
con la stessa varianza, con approssimativamente la stessa asimmetria ma con differenze
marcate nell'indice di kurtosi.
Figura 6. Esempio grafico dei due tipi di distribuzione: leptocurtica e platicurtica.
16
Dato che il primo e il secondo momento di una variabile casuale X possono essere
visti semplicemente come un parametro di traslazione e di scala, rispettivamente, le
HOS contengono informazione sulla forma della distribuzione. La kurtosi misura sia il
picco che la coda delle variabili casuali, e entrambe queste caratteristiche devono essere
tenute in considerazione quando si confrontano due variabili casuali [14]. Più
formalmente, per due variabili casuali simmetriche X e Y di uguale media e varianza, se
ci sono a e b tali che
,| |
| |
,
21
mentre
,
| |
,
22
allora il momento di quarto ordine di X è più alto di quello di Y (vedi [15] per una
dimostrazione). Presa una variabile casuale gaussiana come riferimento, un esempio di
distribuzione che ha code più pesanti e che è più appuntita rispetto a una gaussiana è la
distribuzione di Laplace, come raffigurato in Figura 7. Laddove una gaussiana ha una
kurtosi uguale a 0, la distribuzione di Laplace ha una kurtosi uguale a 3 (sia la
distribuzione di Laplace che la gaussiana hanno una kurtosi che è indipendente dai loro
parametri).
Figura 7. Paragone tra la distribuzione più appuntita e con coda più pesante (Laplace) rispetto alla
gaussiana. Entrambe hanno stessa media(0) e varianza(1), sono simmetriche, ma Laplace ha
kurtosi 3 rispetto a 0 della gaussiana. L’area riempita sottolinea i ranges in cui i valori sono più
probabili per Laplace.
17
2.3.4 Calcolo della feature
Seguendo le discussioni sopra, ci si aspetta che la kurtosi sia un candidato in grado di
distinguere tra parlato in campo vicino e in campo lontano. Per l’esempio in Figura 5 la
kurtosi è 15,4 per il parlato in campo vicino, e 0.4 per il parlato in campo lontano. Ad
ogni modo, come già notato in [6], usare direttamente le HOS per il VAD non è
efficace, per parecchie ragioni; gli stimatori standard per la kurtosi, basati su uno
stimatore a campione di momenti, convergono lentamente sul vero valore e sono
sensibili alle deviazioni estreme; inoltre, i rumori non-gaussiani potrebbero non avere
un basso valore di kurtosi. Infatti, i rumori tipici in condizioni di campo vicino come i
rumori di contatto, che sono di natura altamente transitoria, hanno una kurtosi grande.
Figura 8. Campione di registrazione autoprodotta del segnale vocale con rumore naturale. Lo
spettrogramma(in alto), l’energia(la seconda), la log-kurtosi(la terza) e la caratteristica
proposta(la quarta). Le aree evidenziate sono parlato che deve essere individuato.
Questo è osservato in Figura 8 la quale rappresenta un estratto di 37 secondi registrati
con un microfono in campo vicino: il segnale contiene per lo più parlato che inizia
18
attorno ai 17 secondi, ma tutto l’inizio del segnale contiene voce di sottofondo, le cui
basse linee spettrali di frequenza possono essere viste sullo spettrogramma. Lo
spettrogramma contiene anche rumori transienti attorno ai 9-10 secondi, che sono
visibili sia sullo spettrogramma che sul grafico dell’energia. La Figura 8 mostra inoltre
che la kurtosi si comporta in maniera differente per il parlato in campo lontano e quello
in campo vicino: è principalmente a basso valore e stabile per il parlato lontano, invece
ha alti valori per il parlato vicino. Comunque la kurtosi ha alcuni spikes, in particolare
per i rumori transienti attorno ai 9 secondi.
Per migliorare la proprietà sopra, viene proposto un metodo per potenziare la kurtosi
contro i rumori transienti lasciando inalterato il suo comportamento desiderato per
distinguere il parlato in campo lontano dal parlato in campo vicino; questa viene
combinata con il picco di autocorrelazione normalizzata. L’autocorrelazione è un buon
segnale per indicare il tono, ed è abbastanza robusto ai rumori transitori; per queste
ragioni è stato spesso usato per il VAD (per esempio in [16]). Per migliorare l’immunità
alla variazione dell’energia del segnale si usa l’autocorrelazione normalizzata a[k] per
un frame X = (xt) = {x0 , … , xN-1} data dalle seguente formula:
1
1
0
23
2
Per segnali periodici in T campioni l’autocorrelazione ha massimi per ritardi multipli
di T. Si rileva un picco se il suo valore è molto più grande dei suoi vicini più prossimi
da entrambi i lati (scartando il primo picco a
0, che è sempre uguale a 1 per
definizione di autocorrelazione normalizzata). A causa del processo di normalizzazione,
i picchi per rumori a bassa energia possono sembrare avere uno spettro marcato (un
esempio di tale rumore è il rumore del motore). Inoltre non può essere usato da solo per
rilevare le parole del parlatore principale dalle voci di sottofondo. Comunque, in questo
studio, il motivo per cui si usa l’autocorrelazione è che i suoi picchi hanno una bassa
ampiezza per i rumori transitori, i quali sono i rumori più problematici quando si usano
le HOS.
Dunque la combinazione del picco di autocorrelazione mx con la kurtosi kx del
residuo LPC permette di ottenere la nuova caratteristica (feature) fx come segue:
log 1
24
19
Si impiega il logaritmo della kurtosi per dare un comportamento più gaussiano alla
caratteristica, questo sarà più utile per la classificazione, e inoltre compensa alti valori
che possono capitare per frames in campo vicino di voci forti. La kurtosi migliorata è
mostrata in Figura 8, dove il miglioramento sulla kurtosi originale è evidente. Infatti ha
ancora bassi valori per il parlato in campo lontano ed è più stabile per frames rumorosi.
Un altro esempio, preso dal set di dati CENSREC-1, è mostrato in Figura 9, dove è
possibile osservare le stesse caratteristiche. In particolare si nota che la kurtosi
migliorata è più robusta ai rumori che si manifestano nei primi 5 secondi (essi
corrispondono a rumori di passi di qualcuno che cammina); il miglioramento
confrontato con la kurtosi semplice è anche evidente sulla seconda e sulla quinta
sezione del parlato.
Figura 9. Campione di segnale vocale da CENSREC-1 (alto SNR). Lo spettrogramma(in alto),
l’energia(la seconda), la log-kurtosi(la terza) e la caratteristica proposta(la quarta).
20
2.4 EM Online
2.4.1 Apprendimento con variabili nascoste: l’algoritmo EM
Reti Bayesiane, variabili latenti, miscugli gaussiani, algoritmo EM
Una rete bayesiana è un modo di rappresentare un problema attraverso ragionamenti
probabilistici, essa modella relazioni tra i vari nodi della rete attraverso distribuzioni
congiunte di probabilità.
Molti problemi reali hanno variabili nascoste, talvolta chiamate anche variabili
latenti, che non sono osservabili nei dati, ma si possono apprendere. Ad esempio, le
cartelle mediche spesso includono i sintomi osservati, le terapie applicate e talvolta i
risultati ottenuti, ma molto raramente è inclusa anche l’osservazione diretta della
malattia stessa.
2
2
2
2
Dieta
Fumo
2
2
Esercizio
Fumo
Dieta
Esercizio
Sintomo3
54
Sintomo1
Sintomo2
Sintomo3
Malattia Cardiaca
6
Sintomo1
6
6
Sintomo2
486
162
(a)
(b)
Figura 10. Esempio di modello diagnostico immaginario per le malattie cardiache.
Se la malattia non è osservabile, perché non costruire un modello che non tenga
conto di essa? Si può fare il seguente esempio per chiarire il concetto: nella Figura 10
viene riportato un piccolo modello diagnostico immaginario per le malattie cardiache.
Ci sono tre fattori di predisposizione alla malattia osservabili e tre sintomi osservabili.
Si suppone che ogni variabile possa assumere 3 possibili valori: nessuno, moderato e
severo. Rimuovere la variabile nascosta dalla rete (a) dà come risultato la rete (b);
21
appare evidente che il numero di parametri aumenta drasticamente. Così le variabili
latenti possono ridurre drasticamente il numero di parametri necessari per specificare
una rete bayesiana. Questo a sua volta riduce drasticamente le quantità di dati necessari
per apprendere i parametri.
Le
variabili
nascoste
sono
importanti,
ma
effettivamente
complicano
l’apprendimento. Nella Figura 10(a) ad esempio, non è chiaro come apprendere la
distribuzione condizionata di Malattia Cardiaca dati i suoi genitori, perché non se ne
conoscono i valori nei vari casi; lo stesso problema si ha per l’apprendimento delle
distribuzioni dei sintomi. L’algoritmo Expectation - Maximization, o EM, risolve questo
problema in un modo molto generale. Esso è usato in una grande varietà di problemi di
apprendimento.
Clustering non supervisionato: apprendere miscugli di gaussiane
Il problema del clustering non supervisionato consiste nel discernere categorie
multiple in una collezione di oggetti. Il problema è non supervisionato perché le
etichette delle categorie non sono date. Ad esempio si può ipotizzare di registrare gli
spettri di centomila stelle: è possibile chiedersi se tali spettri identificano tipi diversi di
stelle, e se fosse così, quanti sono e quali sono le loro caratteristiche. Sono conosciuti da
tutti i termini quali “gigante rossa” e “nana bianca”, ma le stelle non hanno un cartellino
identificativo; per distinguere tali categorie gli astronomi hanno dovuto eseguire un
clustering non supervisionato.
Il clustering non supervisionato parte dai dati. Dall’insieme di dati si deve cercare di
capire quale distribuzione di probabilità potrebbe aver generato quei dati. Il clustering
presume che i dati siano generati da una distribuzione miscuglio P. Tale distribuzione
ha k componenti, ognuno dei quali è una distribuzione. Un dato si ottiene scegliendo per
prima cosa uno dei componenti e quindi generando un campione da esso. Sia C la
variabile casuale che denota il componente con valori 1,…,k; la distribuzione miscuglio
è data da
|
25
22
in cui x si riferisce ai valori degli attributi per un determinato dato. Nel caso di dati
continui, una scelta naturale per le distribuzioni dei componenti è la gaussiana
multivariata, che genera la famiglia di distribuzioni nota come miscuglio di gaussiane.
I parametri di un miscuglio di gaussiane sono
(il peso di ogni
(la media di ogni componente) e Σ
componente),
(la covarianza di ogni
componente).
Il problema del clustering non supervisionato quindi è ricostruire un modello a
miscuglio partendo dai dati.
Se si conoscesse il componente che genera ogni dato sarebbe facile ricostruire le
gaussiane costituenti il miscuglio: basterebbe selezionare tutti i dati derivati da ogni
componente e adattare i parametri della distribuzione. Sapendo i parametri di ogni
componente si potrebbe, almeno in senso probabilistico, assegnare ogni dato ad un
preciso componente. Il problema sta nel fatto che non si conoscono né gli assegnamenti
né i parametri.
L’idea base dell’EM è fingere di conoscere i parametri del modello e quindi inferire
la probabilità che ogni dato appartenga a ogni componente.
Fatto ciò è possibile riadattare ciascun componente all’intero insieme di dati, dopo
aver pesato ogni punto in base alla probabilità che esso appartenga effettivamente a tale
componente. Il processo itera fino alla convergenza. Essenzialmente quello che si fa è
“completare” i dati inferendo distribuzioni di probabilità sulle variabili nascoste (il
componente a cui appartiene ogni dato) in base al modello corrente. Per un miscuglio di
gaussiane si inizializzano arbitrariamente i parametri del modello a miscuglio,
dopodiché si iterano i seguenti passi.
1.
, la probabilità che il
sia stato generato dal componente i. Per la regola di Bayes,
dato
|
nel punto
. Il termine
|
è semplicemente la probabilità
della i-esima gaussiana e il termine
esima gaussiana. Viene definito
2.
|
Passo E: viene calcolata la probabilità
è il peso della i-
.
Passo M: si calcola la nuova media, covarianza e peso dei componenti come
segue:
23
Σ
26
Il passo E da expectation, può essere visto come il calcolo dei valori attesi
indicatori nascosti
, dove ogni
vale 1 se il dato
degli
è stato generato dall’i-esimo
componente e 0 in caso contrario. Il passo M da maximization, calcola i nuovi valori dei
parametri che massimizzano la verosimiglianza logaritmica dei dati in base ai valori
attesi degli indicatori nascosti.
2.4.2 Approccio teorico
controllato
all’EM
Online:
apprendimento
non
Alcuni algoritmi VAD fanno la soglia della caratteristica, con una soglia il cui valore
è generalmente calcolato dal livello di rumore di sottofondo stimato; la classificazione
del frame, parlato o non-parlato, è poi convertita nei limiti del segnale vocale attraverso
una macchina-stato (anche chiamata hangover); per un algoritmo VAD non controllato
è la via più diretta per la classificazione (per esempio [17]). Qui viene proposto uno
schema di classificazione non controllata ma senza basarsi direttamente su una soglia, la
quale richiederebbe una stima del livello di rumore.
Supponendo che ogni classe (parlato e non parlato) abbia una distribuzione
probabilistica, un’ottima decisione potrebbe essere quella di scegliere la classe che
massimizza p(class|X); questa è una classificazione di massimo a posteriori (MAP). Qui
p(X|class) è modellata come un densità parametrica p(.;θ), e si prova a stimare il
parametro stabilito θ. Il metodo che si usa è un raggruppamento parametrico, come
rappresentato in Figura 11. Scegliendo una distribuzione gaussiana per p(.;θ), il modello
è una semplice mescolanza binaria di gaussiane, dove ogni componente della
mescolanza rappresenta una classe (una per il parlato, una per il non-parlato).
24
L’algoritmo di massimizzazione del valore atteso (EM) [18] stima modelli
parametrici con variabili latenti basato sul principio di massima verosimiglianza. In
questo caso, la variabile latente è la classe di appartenenza C.
Figura 11. Istogramma della kurtosi migliorata per lo stesso estratto di Figura 8 e un semplice modello di
miscuglio a 2 componenti stimato dall’algoritmo EM standard (la variabile latente ha due stati,
parlato o non parlato).
L’algoritmo EM è un algoritmo iterativo e ogni iterazione i richiede due passi: il
passo E, dove il valore atteso condizionato del logaritmo della probabilità per il dato
completo (X,C) ottenuto dal dato osservato X è calcolato così:
, ;
27
| ;
e il passo M, dove J è massimizzata rispetto a θ per dare un nuovo set di parametri
stimati per il passo i
28
La chiave dell’algoritmo EM è che lo schema sopra garantisce che il logaritmo della
probabilità per il dato osservato X al punto θi è più alto che al punto θi-1, e che J ha una
forma chiusa per un’ampia classe di modelli, inclusi i miscugli finiti dei modelli
esponenziali, come i modelli di miscuglio gaussiano. Nel caso di miscugli finiti, e date
T osservazioni Indipendenti e Identicamente Distribuite (IID) X = {Xt} = {X1, . . . , XT},
il calcolo di
è ridotto al calcolo di
| ;
per tutti t e c, dove
Ct è la variabile latente corrispondente a Xt e c è una scelta di appartenenza. Il nuovo
25
parametro θi può poi essere calcolato da ζ e dalle statistiche che dipendono direttamente
dai dati; nel caso di modelli di miscugli gaussiani, loro sono Xt e Xt2. In altre parole (ζti,
Xt, Xt2) sono Statistiche Sufficienti (SS) per θi-1.
Per quanto riguarda la classificazione online, questa non può essere usata
direttamente perché il passo E richiede l’intero insieme dei dati X. Per esempio, nell’EM
standard, la media del componente c al passo i μi(c) è data da:
29
Invece, deve essere trovato un metodo per aggiornare μt (e altri parametri del modello)
al frame t dai dati osservati Xt e dai precedenti parametri stimati θt-1. Come notato in
[19], ci sono stati diversi approcci a questo problema.
Viene adottato lo stesso schema proposto in [19] e [20]; le quantità di interesse per il
passo E sono sostituite da un approssimazione stocastica e il passo M viene mantenuto
uguale. Nell’EM online, si sostituisce ogni statistica mediata su ζ con la sua
approssimazione stocastica, la quale è aggiornata ogni volta che un nuovo frame è dato
in pasto all’algoritmo. Per quanto riguarda la media, la statistica ∑
rimpiazzata da
è
, che è aggiornato ad ogni nuovo frame:
30
1
Da notare che il suffisso i per ζ è stato tolto, mentre il passo e l’indice del frame
rimangono gli stessi per l’EM online; inoltre, le statistiche approssimate ora dipendono
da c tramite ζt(c). Questa approssimazione è poi inserita dentro lo stimatore della media
dato dall’EM standard (equazione 29):
̂
31
Così, invece di mediare le statistiche ζt · Xt per tutte le t in una volta, l’EM online media
successivamente tra il frame corrente e il frame precedente, e il termine
può essere visto come l’errore di approssimazione della procedura [21]. Le
condizioni sulla sequenza γt tali che la procedura sopra converga sono date in ([19],
1
La notazione che verrà introdotta dal prossimo paragrafo, per essere più chiara ed aderente al codice,
subirà le seguenti variazioni:
;
;
_;
. I parametri relativi al frame
precedente qui indicati con t-1 saranno poi indicati con il suffisso _p.
26
[20]); una revisione più completa della teoria che sta dietro questo tipo di procedure è
data in [21].
Come per lo standard EM, c’è bisogno di inizializzare l’algoritmo. Sono possibili
diverse strategie. La strategia più semplice, usata anche in questo lavoro, è di
inizializzare usando valori casuali; un’altra soluzione, adottata nell’articolo [1], è basata
su un algoritmo k-mean per inizializzare le medie, con i pesi per una distribuzione
cluster equiprobabile. Viene poi calcolata la varianza per ogni cluster. L’algoritmo kmean è eseguito su un piccolo sottoinsieme di dati per ogni segnale: il primo secondo di
ogni segnale vocale elaborato. Per dare un’idea riguardo l’adattamento online dell’EM,
vengono graficati in Figura 12 i parametri delle due componenti.
Figura 12. Lo spettrogramma del segmento audio(la prima), la kurtosi migliorata(la seconda), le medie(la
terza), le varianze(la quarta), e i pesi(la quinta) dei componenti come stimato dall’EM online
(la linea tratteggiata per il parlato, la linea piena per il rumore).
Sebbene le due medie abbiano un valore quasi uguale nei tre secondi iniziali, dove il
parlato non è presente, è possibile osservare che il modello effettivamente si adatta al
segnale quando è presente nel segnale stesso qualche voce in campo vicino. Il parlato è
sempre supposto essere il componente con la media più alta.
27
Per quanto riguarda il costo computazionale, lo standard EM può essere diviso in tre
parti (per ogni iterazione i): calcolare le responsabilità ζit (c), calcolare le Statistiche
Sufficienti (ζit, Xt, Xt2), e aggiornare il modello a miscuglio (equazione 29 e la sua
equivalente per le matrici dei pesi e della covarianza). Solo il calcolo delle SS è
differente nell’EM online (equazione 30), ma la differenza è trascurabile in termini di
quantità di calcolo. Il costo d’esecuzione dell’EM online su un certo insieme di dati è
quindi circa uguale a quello di una iterazione dell’EM. Poiché l’EM online è un
algoritmo ricorsivo, e le caratteristiche sono calcolate frame dopo frame, esso ha una
latenza di un frame una volta che è stato inizializzato.
2.4.3 Realizzazione real time dell’algoritmo EM: l’EM Online
Considerando il caso della trattazione in esame, occorre distinguere due classi c: una
che indica il parlato e l’altra che indica il non parlato. Ognuna di esse ha una
distribuzione probabilistica di verificarsi per ogni frame del segnale vocale in ingresso.
Ogni frame, come detto sopra, è caratterizzato dalla sua feature fx. Come anticipato,
attraverso una distribuzione di probabilità gaussiana, il modello è un semplice miscuglio
binario di gaussiane (Figura 13) e il problema è quello di massimizzare tale densità a
seconda della classe di appartenenza: p(Xt|classe), dove Xt è la feature stimata, è
ricavata dalla distribuzione al passo precedente.
Figura 13. Miscuglio binario di gaussiane derivato da uno dei file di test usato per provare l’algoritmo.
28
Essendo gaussiana, la densità è caratterizzata dai parametri media
e varianza
,
sono proprio questi che devono essere aggiornati, quindi stimati, e massimizzati.
In generale la procedura seguita dall’algoritmo può essere rappresentata dal
diagramma a stati di Figura 14.
P(Xt |classe=1)
Classe
1
P(classe=1|fx)
fx
P(classe=2|fx)
Classe
2
P(Xt |classe=2)
Figura 14. Diagramma a stati dell’EM On-line.
Per ogni valore della caratteristica fx generato dalla trama corrente esiste una
probabilità di appartenere a una classe o all’altra. Per le due classi vengono generate due
stime con le quali è possibile aggiornare i parametri di interesse, medie e varianze.
Tutto ciò si traduce matematicamente nei passi sottostanti ricavati dal [20] pag. 413.
La feature stimata è data da
_
_
dove
_
32
_
è la probabilità P(classe=c|fx) espressa dal rapporto tra il valore della
gaussiana considerata con i parametri relativi ad una classe, corrispondente a fx, e la
somma dei valori di entrambe
_
_
33
con
_
2
,
e
1
_
1
_
2
2
_
2
2
34
,
_
36 dedotto dal riferimento [19] con 0.5
35
1.
29
È necessario stimare anche la probabilità
_
per poter aggiornare la media e la
varianza ottenendo così la probabilità stimata
_
_
_
.
37
La media quindi è così calcolata:
38
.
, stimato
Prima di calcolare la varianza bisogna ottenere un ulteriore parametro
come segue:
_
_
_
,
39
a questo punto si desume la varianza:
.
40
Grazie alla media e alla varianza appena ricavati si può passare allo step riguardante
la decisione della classe di appartenenza, trattata in dettaglio nel paragrafo 2.6. Inoltre i
parametri attuali permettono il passaggio alla successiva iterazione dell’algoritmo EM
Online.
2.5 Risultati sperimentali dell’articolo di riferimento
2.5.1 Struttura di valutazione
È stato valutato il metodo proposto ed è stato confrontato con diversi algoritmi.
Vengono usati 2 set di prove. Un insieme di dati autoprodotti che consistono in
registrazioni da vicino fatte in un luogo all’aperto. Con l’intenzione di fare un
confronto, è stato anche usato il database CENSREC-1-C [10]. Per entrambi i set di
prova il segnale vocale è suddiviso in frames vocali di 32 ms con un overlap di 16ms
(ad esempio 256 campioni ad un rate di campionamento di 8kHz, 50% di overlap), e
esattamente lo stesso algoritmo (ad esempio nessuna sintonia per il sistema hangover).
Come una misura di valutazione, si usano gli errori di classificazione a livello del
frame, cioè:
•
False Rejection Rate (FRR), definita come
30
N° di frames del parlato persi
N° di frames del parlato
•
False Alarm Rate (FAR), definito come
N° di frames del parlato non rilevati correttamente
N° di frames non parlato
•
Global Error Rate (GER), definito come
N° di frames persi
quelli non rilevati correttamente
N° di frames
2.5.2 Valutazione su dati autoprodotti
I dati prelevati nel luogo all’aperto sono stati registrati nelle seguenti condizioni: le
persone sono state dotate di cuffie equipaggiate con un microfono (headset). Parlavano
con altre persone di presentazioni del poster. I dati audio sono stati registrati su un altro
dispositivo embedded simile ad un PC, portato da ogni persona (il flusso del suono è
stato convertito in digitale ed è stato registrato sull’hard disk del dispositivo). I dati
contengono diversi tipi di rumore (aria condizionata, altre persone, auto che viaggiano
sulla strada, ecc.). Il set della prova contiene circa 45 minuti di dati audio, divisi in circa
30 files di uguale lunghezza. I files sono differenti per parlatori, sesso, linguaggio
(principalmente Giapponese ma anche Inglese), densità di parlato e SNR (compreso tra
10 e 25dB). Per ogni file del set di prova l’algoritmo online EM proposto è stato
inizializzato con i dati del primo secondo. L’obiettivo di questa valutazione è di stabilire
se il metodo proposto può adattarsi al diverso SNR e alle condizioni di bassa densità di
parlato (sparsity). Il rapporto di frames vocali in questi dati varia dal 10 al 90%, con in
media il 33% di parlato. Viene confrontato il metodo proposto con metodi che
rimpiazzano la kurtosi migliorata con altre caratteristiche: l’energia e la kurtosi. I
risultati sono riassunti nella Tabella 1.
Tabella 1. Frame Error Rates per l’algoritmo proposto (prima riga), usando l’EM online sull’energia
(seconda), e usando l’EM online sulla kurtosi (terza).
31
La kurtosi migliorata ottiene un significativo miglioramento di FAR e GER, mentre
ha un valore leggermente peggiore di FRR rispetto all’energia. Viene anche mostrato
che la kurtosi da sola non è efficace.
Figura 15. Risultati dell’algoritmo VAD proposto(a sinistra) in funzione del rapporto parlato/non parlato,
confrontato con il metodo basato sull’energia (a destra). Le linee tratteggiate mostrano la
deviazione standard di ogni criterio, e la linea solida mostra la media su tutti i files del
database.
Per avere un’idea più precisa della robustezza dello schema di classificazione
proposto nei confronti della sparsity, viene fornito in Figura 15 il Frame Error Rates in
funzione della percentuale del parlato (ad esempio il rapporto parlato/non-parlato) per
ogni file. Dal momento che il metodo proposto e il metodo basato sull’energia si
comportano in modo simile per segnali dove il parlato è dominante, il FAR aumenta
significativamente per l’algoritmo basato sull’energia nel caso di segnali meno densi di
parlato. Inoltre la linea tratteggiata, che rappresenta la deviazione standard dell’error
rate sull’insieme completo di dati, mostra che il metodo proposto è meno sensibile alla
variazione della densità, perciò dà risultati più stabili.
32
Si confronta anche l’efficienza dell’EM online rispetto all’algoritmo standard EM.
Entrambi usavano la kurtosi migliorata come una caratteristica. I risultati sono riassunti
nella Tabella 2. Si trova che l’EM online dà prestazioni simili all’EM offline.
Tabella 2. Paragone tra l’EM online e lo standard EM.
2.5.3 Valutazione sul database CENSREC-1
Con l’intenzione di fare un confronto, viene anche testato il metodo proposto su un
database pubblico, il CENSREC-1 [10]. Questo database consiste di enunciazioni in
Giapponese di cifre contigue rumorose. Le registrazioni sono state fatte in due tipi di
ambienti rumorosi (strada e ristorante), e alto (SNR>10dB) e basso rapporto segnalerumore (-5≤SNR≤10dB). Per ognuna di queste condizioni sono disponibili le
registrazioni da vicino e da lontano [10]. L’algoritmo usato è esattamente lo stesso della
sezione precedente, e l’online EM è stato inizializzato con il primo secondo per ogni file
del database.
Per primo, i risultati delle registrazioni da vicino per molte condizioni di rumore
sono date in Tabella 3. Ogni caso ha una lunghezza totale approssimativamente di 30
minuti. Dalla Tabella 3 si osserva che le figure sono quasi uguali per basso e alto SNR
in entrambi gli ambienti, ristorante e strada, nel caso di registrazione da vicino. Sembra
essere più importante il tipo di rumore che la condizione di SNR.
Tabella 3. Frame error rates per il metodo proposto su registrazioni da vicino del CENSREC-1-C.
33
Inoltre si confronta il metodo proposto con un metodo che usa come caratteristica
l’energia invece della kurtosi migliorata. I risultati sono riportati in Tabella 4, la quale
conferma che la kurtosi migliorata dà prestazioni migliori rispetto all’energia.
Tabella 4. Frame error rates per il metodo basato sull’energia su registrazioni da vicino del CENSREC-1C.
Infine, come suggerito dagli sviluppatori del CENSREC, è mostrato un confronto
con la linea base assieme alla sua ROC per registrazioni da lontano, nonostante questo
metodo sia indirizzato alla condizione di parlato da vicino. La ROC è calcolata per la
media tra basso e alto SNR, ed è graficata in Figura 16.
Figura 16. ROC della linea base rispetto a quella del metodo proposto, in condizioni di registrazioni da
lontano (mediato su basso e alto SNR).
34
La linea base usa un semplice algoritmo basato sull’energia [10]. Si può notare che
questo metodo della linea base è un algoritmo offline e la classificazione è fatta a
posteriori conoscendo l’intero segnale. Questo dà alla linea base un vantaggio, ad ogni
modo l’algoritmo proposto supera in prestazione la linea base.
2.6 Il cuore del VAD: la decisione
Dall’articolo emerge che la classe che identifica il parlato è quella a media maggiore
ma non viene esplicitamente fatta menzione sul criterio di scelta frame per frame della
classe. Si intuisce solamente che il VAD vero è proprio viene realizzato attraverso il
confronto tra le due probabilità che si attribuiscono di volta in volta alle classi. Infatti
inizialmente la strada battuta per l’implementazione è stata quella di inserire la feature
nell’argomento della gaussiana calcolata con i parametri (media e varianza) attuali, cioè
appena stimati, e ricavare le probabilità come descritto nella (33). Questa valutazione
conduce però ad un scelta non ottima, in effetti si è verificato attraverso opportune
prove che il parlato non veniva riconosciuto adeguatamente perché, nello spazio di
tempo che esso occupava, la decisione tendeva ad essere troppo “frastagliata”, ovvero si
presentavano, anche se non consecutivamente, numerosi frames di parlato persi che
rendevano non intellegibile il discorso. Mentre per quanto riguarda il non-parlato la
scelta poteva ritenersi accettabile, in quanto la maggior parte dei frames considerati
non-parlato venivano correttamente riconosciuti (Figura 17).
Il frastagliamento osservabile in Figura 17 è dovuto al continuo alternarsi delle
probabilità delle due classi (Figura 18). Nella Figura 19 è inoltre riportato l’andamento
delle medie associate al parlato (in verde) e al non-parlato (in rosso).
Si è così deciso di trovare altre soluzioni che implementassero la scelta coinvolgendo
i vari parametri dello studio: confrontare le probabilità delle due classi con soglie
differenti (una per il parlato una per il non-parlato), confrontare la media maggiore
(quella del parlato) con una soglia mobile, valutare l’andamento crescente o decrescente
(che sembrava monotono) della media, della feature stimata e delle chi, perché questi
andamenti corrispondono al parlato e al non-parlato anche se non in maniera monotona,
35
tutte soluzioni che avevano in comune lo stesso difetto del frastagliamento riscontrato
nella decisione di riferimento.
segnale vocale x (blue), feature fx (magenta), vad (black)
2
1.5
1
0.5
0
-0.5
0
10
20
30
40
50
Tempo [s]
60
Figura 17. Decisione (VAD: 1 per il parlato, 0 per il non-parlato), in nero, fatta in base al confronto tra
le probabilità delle due classi su un segnale vocale (blu) con un SNR=30dB. La feature del
segnale è rappresentata in magenta.
feature fx (magenta), prob1(red) e prob2(green)
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
Numero iterazioni
2500
3000
3500
Figura 18. Andamento delle probabilità delle due classi, in questo caso il verde indica il parlato e
il rosso il non parlato per lo stesso segnale vocale di Figura 17. In magenta la feature.
36
feature fx (magenta), media1(red) e media2(green)
2
1.5
1
0.5
0
-0.5
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 19. Andamento delle medie delle due classi, in questo caso il verde indica il parlato, essendo
maggiore, e il rosso il non parlato, per lo stesso segnale vocale di Figura 17. In magenta la
feature.
Quindi si è cercato di agire sulla elevata variabilità della decisione stessa proponendo
un metodo di scelta a maggioranza su una finestra dispari di frames, passando poi come
diretta conseguenza a una scelta basata sulla media delle decisioni di ogni frame. Queste
soluzioni miglioravano un po’ la variabilità del VAD ma l’intelligibilità del segnale
vocale rimaneva ancora scarsa.
Da qui si è tornati ad analizzare le probabilità e ad applicare ad esse una soglia (per il
parlato) dopo aver effettuato un filtraggio per stabilizzarle. Questa soglia, essendo sulla
probabilità, ha un range di valori compreso tra 0 e 1, dove 0 indica l’incertezza che un
frame sia parlato, ovvero qualsiasi frame viene considerato parlato e quindi non viene
fatta alcuna distinzione tra le due classi, e 1 indica la certezza che il frame sia parlato,
tuttavia ciò è massimamente discriminante nel senso che vengono considerati parlato
solo i frames di cui si è sicuri che siano parlato.
Come filtro si è pensato sempre ad una media su n probabilità precedenti e la
decisione veniva fatta confrontandola con una soglia opportuna. In particolare il numero
n di probabilità che è stato adottato è pari a 4, ovvero si è implementato un filtro FIR di
questo tipo:
37
1
2
3 ⁄4
41
si riporta in Figura 20 l’andamento dell’ampiezza della risposta in frequenza realizzata
tramite il pacchetto FDATool del MATLAB. Chiaramente l’operazione di media è un
filtraggio passa - basso.
Il tutto ha condotto a discreti risultati rendendo meno frastagliate le probabilità
(Figura 21) e di conseguenza la decisione (Figura 22), ma ancora il segnale vocale
parlato rimaneva non del tutto intelligibile.
Il frastagliamento comunque dipende fortemente dalla caratteristica fx che, se in una
visione globale distingue bene tra parlato e non-parlato (come è possibile osservare
dalle Figura 8, Figura 9 e Figura 12), è evidente che è molto variabile nella finestra
temporale individuata dal parlato. Per cui risulta difficile trovare una scelta real time
corretta in queste condizioni, dato che probabilità e feature sono ovviamente correlate
dall’algoritmo EM online.
Una buona decisione può essere ottenuta migliorando la caratteristica fx in questa
maniera: nella finestra temporale che indica il parlato dovrebbero essere innalzati quei
valori di fx che per ampiezza si abbassano al livello del non-parlato.
Figura 20. Filtro passa - basso FIR del terzo ordine usato per mediare le probabilità.
38
feature fx (magenta), probFIR1(red) e probFIR2(green)
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 21. Andamento delle probabilità delle due classi dopo il filtraggio FIR, come sopra il verde
indica il parlato e il rosso il non parlato per lo stesso segnale vocale di Figura 17. In
magenta la feature.
segnale x(blue), feature fx(magenta), vad(black)
2
1.5
1
0.5
0
-0.5
0
10
20
30
40
50
Tempo [s]
60
Figura 22. Decisione (VAD: 1 per il parlato, 0 per il non-parlato), in nero, fatta sulla probabilità
calcolata dalla feature fx e filtrata con il FIR.
Così si è iniziato a filtrare la feature dapprima con lo stesso filtro usato per le
probabilità, poi con un filtro mediano, ma in entrambi i casi il VAD non era pronto,
39
ovvero era affetto da una piccola latenza che faceva perdere la parte iniziale di una
frase. Il giusto compromesso tra media e prontezza è stato raggiunto con un filtro IIR.
Di seguito si riportano le figure dei 3 filtri IIR testati:
Figura 23. Filtro IIR del primo ordine.
Figura 24. Filtro IIR del secondo ordine.
40
Figura 25. Filtro IIR del terzo ordine.
I filtri riportati sono rispettivamente del primo, del secondo e del terzo ordine. Per
quanto riguarda il primo filtro dall’equazione alle differenze
⁄2
1
42
è possibile ricavare la sua funzione di rete
1
1
2
1
2
1
43
.
Per il secondo ordine invece
yn 2
yn
2
yn 1
xn
44
2
la funzione di rete risulta essere
1
1
1
4
2
1
4
1
2
45
.
Mentre per il terzo ordine
3
2
2
2
1
46
2
la funzione di rete diventa
1
1
1
4
1
2
1
8
2
1
8
3
.
47
41
feature fx(magenta) e feature migliorata fxp(cyan)
2
1.5
1
0.5
0
-0.5
0
500
1000
1500
2000
Numero iterazioni
2500
3000
3500
Figura 26. Differenza tra la feature originale(magenta) e quella filtrata con l’IIR(cyan) relativa al
segnale vocale di Figura 17.
Alla fine la scelta è ricaduta sul filtro IIR del terzo ordine e la differenza tra la feature
originale e quella filtrata è apprezzabile in Figura 26 dove si nota la minor oscillazione
della caratteristica migliorata.
feature migliorata fxp(cyan), prob1(red) e prob2(green)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
Numero iterazioni
2500
3000
3500
Figura 27. Probabilità calcolate con la feature migliorata fxp e senza il filtraggio FIR.
42
È inoltre evidente il fatto che tra parlato e non parlato vi è una maggior distinzione
tra i valori più alti della feature che ne indicano il non parlato e quelli più bassi che ne
indicano il parlato.
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
Numero iterazioni
2500
3000
3500
Figura 28. Probabilità calcolate con la feature migliorata fxp e filtrate FIR.
segnale x(blue), feature migliorata fxp(cyan), vad(black)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
Tempo [s]
60
Figura 29. Decisione (VAD: 1 per il parlato, 0 per il non-parlato), in nero, fatta sul segnale vocale di
Figura 17. In cyan la caratteristica migliorata.
43
Questa nuova caratteristica, data in pasto alla decisione fatta con il filtraggio FIR
delle probabilità, permette la realizzazione di un VAD con ottime prestazioni. A tal
proposito si vuol far osservare in Figura 27 le probabilità calcolate con la feature
migliorata fxp e senza il filtraggio FIR. In Figura 28 si può notare il miglioramento
definitivo apportato alle probabilità delle due classi da entrambi i filtraggi. Infine, come
si può vedere nella Figura 29, viene riportata la decisione elaborata sul file oggetto degli
esempi citati. L’unica incertezza nella decisione è nella parte iniziale tra il secondo 1 e 2
in quanto l’algoritmo non ha ancora iniziato la convergenza poiché ancora non è iniziato
il parlato. Proprio il tema della convergenza verrà approfondito in seguito nel paragrafo
3.4.
44
Capitolo 3
Risultati sperimentali
In questo capitolo si vuole evidenziare, attraverso alcuni grafici, l’andamento di tutti
i parametri e tutti i risultati dell’algoritmo esaminato. Inoltre si vogliono valutare le
prestazioni relative all’algoritmo e alla sua implementazione.
3.1 Parametri e risultati in MATLAB
Viene preso in esame un file wave audio standard di parlato maschile a 8KHz che è
stato opportunamente modificato aggiungendo silenzi di diversa durata per ricreare le
condizioni suggerite nell’articolo [1], cioè la condizione di sparsity che descriverebbe
adeguatamente un segnale vocale riferito ad un individuo in una conversazione tra più
persone.
Al file audio è stato aggiunto rumore AWGN tale che il rapporto segnale rumore
risulti di 60dB ed è stato processato come descritto nei capitoli precedenti, qui vengono
riportati i vari parametri caratterizzanti l’algoritmo.
La media è uno dei parametri più importanti perché indica la classe del parlato: si
ribadisce infatti che il parlato è quello che ha la media maggiore. Questa viene calcolata
attraverso i parametri feature stimata (X_t) e probabilità stimata (chi). I tre andamenti
sono osservabili rispettivamente in Figura 30, Figura 31 e Figura 32 per il file audio
descritto sopra.
feature fx(magenta), mu1(red) e mu2(green) con alpha=0.9
2
1.
1
0.
0
0
500
100
150
200
250
300
350
Numero Iterazioni
Figura 30. Andamento delle medie associate alle due classi per il file audio con un SNR=60dB.
feature fx(magenta), Xt1(red) e Xt2(green) con alpha=0.9
2
1.
1
0.
0
0
500
100
150
200
250
300
350
Numero Iterazioni
Figura 31. Andamento delle features stimate associate alle due classi per il file audio con un
SNR=60dB.
46
feature fx(magenta), chi1(red) e chi2(green) con alpha=0.9
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 32. Andamento delle probabilità stimate associate alle due classi per il file audio con un
SNR=60dB.
feature fx(magenta), variance1(red) e variance2(green)
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 33. Andamento delle varianze associate alle due classi per il file audio con un SNR=60dB.
Alpha=0.9.
47
feature fx(magenta), Xt1quadro(red) e Xt2quadro(green)
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 34. Andamento delle features quadro stimate associate alle due classi per il file audio con
un SNR=60dB. Alpha=0.9.
Un ulteriore importante parametro per la modellazione delle gaussiane nel miscuglio
binario è la varianza, questa e il parametro feature stimata quadro (X_t_quadro) da cui
si ricava sono riportate in Figura 33 e Figura 34.
Si vuole fare notare ora come agisce il parametro di convergenza alpha sui parametri
media, probabilità stimata e varianza. Nelle figure sopra, l’elaborazione è stata eseguita
con un alpha pari a 0.9. Si può osservare come per un alpha pari a 0.6 (Figura 35, Figura
36, Figura 37) questi parametri tendono ad essere meno separati e meno stabili, di
conseguenza la decisione risulta essere più variabile.
Al contrario ponendo alpha = 0.98 (Figura 38, Figura 39, Figura 40) si verifica un
solo distacco che tende a mantenere una maggiore separazione per tutte le iterazioni e di
conseguenza c’è una maggiore stabilizzazione dei parametri.
Per quanto riguarda la decisione invece occorre tener conto del parametro soglia.
Infatti la soglia agisce sulla probabilità filtrata relativa al parlato e migliora
l’intelligibilità del segnale vocale in presenza di rumori più elevati (più bassi SNR).
Questo avviene ovviamente, essendo le due probabilità parlato/non-parlato in relazione
48
tra loro, a spese di un più che accettabile incremento di errore nel riconoscimento del
non-parlato. Le prestazioni relative verranno presentate nel paragrafo 3.5 dove si
confronta il VAD in condizioni di diversi SNR.
feature fx(magenta), mu1(red) e mu2(green) con alpha=0.6
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 35. Andamento delle medie per alpha=0.6 per il file audio con un SNR=60dB.
feature fx(magenta), chi1(red) e chi2(green) con alpha=0.6
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 36. Andamento delle probabilità stimate per alpha=0.6 per il file audio con un SNR=60dB.
49
feature fx(magenta), variance1(red) e variance2(green) con alpha=0.6
2
1.
1
0.
0
0
50
100
150
200
250
300
350
Numero Iterazioni
Figura 37. Andamento delle varianze per alpha=0.6 per il file audio con un SNR=60dB.
feature fx(magenta), mu1(red) e mu2(green) con alpha=0.98
2
1.
1
0.
0
0
50
100
150
200
2500
3000
3500
Numero Iterazioni
Figura 38. Andamento delle medie per alpha=0.98 per il file audio con un SNR=60dB.
50
feature fx(magenta), chi1(red) e chi2(green) con alpha=0.98
2
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 39. Andamento delle probabilità stimate per alpha=0.98 per il file audio con un
SNR=60dB.
feature fx(magenta), variance1(red) e variance2(green) con alpha=0.98
2
1.
1
0.
0
0
50
100
150
200
2500
3000
3500
Numero Iterazioni
Figura 40. Andamento delle varianze per alpha=0.98 per il file audio con un SNR=60dB.
51
Per chiarire graficamente il discorso sulla decisione vengono riportate in Figura 41,
Figura 42 e Figura 43 le probabilità filtrate FIR su cui si effettua la scelta della classe di
appartenenza.
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.6
1.2
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 41. Andamento delle probabilità filtrate FIR delle due classi per alpha=0.6 per il file audio
con un SNR=60dB. In cyan la feature migliorata.
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.9
1.2
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 42. Andamento delle probabilità filtrate FIR delle due classi per alpha=0.9 per il file
audio con un SNR=60dB. In cyan la feature migliorata.
52
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.98
1.2
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
2500
3000
3500
Numero Iterazioni
Figura 43. Andamento delle probabilità filtrate FIR delle due classi per alpha=0.98 per il file
audio con un SNR=60dB. In cyan la feature migliorata.
Infine i risultati delle prove per i diversi alpha con una soglia pari a 0.5 sono riportati
nelle seguenti figure (Figura 44, Figura 45, Figura 46).
segnale x(blue), feature migliorata fxp(cyan), vad(black) con alpha=0.6
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
0
10
20
30
40
50
Tempo
60
Figura 44. VAD con un alpha=0.6 applicato al file audio con SNR=60dB.
53
segnale x(blue), feature migliorata fxp(cyan), vad(black) con alpha=0.9
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
0
10
20
30
40
50 Tempo [s]
Figura 45. VAD con un alpha=0.9 applicato al file audio con SNR=60dB.
60
segnale x(blue), feature migliorata fxp(cyan), vad(black) con alpha=0.98
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
0
10
20
30
40
50 Tempo [s] 60
Figura 46. VAD con un alpha=0.98 applicato al file audio con SNR=60dB.
La freccia rossa in Figura 44 vuole indicare l’instabilità che già si presenta nel VAD
con un alpha pari a 0.6 applicato al file audio con rumore pressoché inesistente
(SNR=60dB).
54
3.2 Risultati sulla piattaforma Nu-Tech
In questo paragrafo si riportano i risultati dell’implementazione vera e propria: quella
realizzata in C e riprodotta utilizzando il framework Nu-Tech. Tale piattaforma
permette di elaborare in tempo reale il flusso dei dati in ingresso alla scheda audio del
PC su cui è installato. Oltre a ciò permette di processare anche dati in maniera off-line.
In questo caso infatti, per provare la congruenza con quanto scritto in MATLAB, si
propone per prima cosa una prova off-line utilizzando lo stesso file wave con
SNR=60dB testato nel MATLAB (paragrafo 3.1). Per questo motivo nella voce Driver
della finestra Settings del Nu-Tech si sono impostati i valori necessari alla scheda audio
per l’elaborazione del file, cioè frequenza di campionamento pari a 8KHz e Frame Size
uguale a 1024. Tale Frame Size è il minimo valore di campioni che la scheda audio
usata può supportare a quella frequenza di campionamento per far in modo che questo
algoritmo sia il più possibile in tempo reale (si ha la minima latenza tra ingresso e
uscita). Qui di seguito vengono visualizzate le impostazioni del driver della scheda
audio (Figura 47), il setup della prova off-line (Figura 48) e i suoi risultati (Figura 49).
Figura 47. Impostazione della frequenza di campionamento e della dimensione del frame di lavoro del
Nu-Tech. È visibile anche il nome della scheda audio utilizzata per i tests.
55
Figura 48. Setup utilizzato per le prove offline. Il nome del blocco NUT che implementa l’algoritmo è
VADonHOS.
Figura 49. Prova off-line del VAD con alpha=0.9 e soglia=0.5 applicato al file audio con SNR=60dB. In
questo caso l’uscita del VAD è stata registrata utilizzando il blocco FileWrite anziché essere
ascoltata.
Per quanto riguarda la prova in tempo reale il suo setup in Nu-Tech è stato realizzato
come in Figura 50.
56
Figura 50. Setup utilizzato per le prove real time.
Si è usata una cuffia headset con microfono (stesso strumento usato nell’articolo [1]),
il microfono è stato inserito in ingresso alla scheda audio Realtek AC97 Audio e le
cuffie poste nella sua uscita. Il notebook utilizzato è dotato di processore Intel Pentium
4 2.8GHz con 512Mbyte di memoria RAM. Le impostazioni software sono le stesse
della prova off-line con la differenza che in ingresso al blocco VAD ora c’è il flusso
audio proveniente dal microfono invece che dal blocco FileRead. Inoltre a monte del
VAD è stato inserito un filtro passa-alto per eliminare la fastidiosa componente
continua intrinseca nell’hardware utilizzato. Questo bias provoca un innalzamento della
feature fx nella parte che indica il non parlato avvicinando così i valori della X_t relativi
alle due classi. Ciò compromette tutti gli altri parametri tra cui media e varianza, le
quali generano due gaussiane vicine e simili tra loro rendendo meno distinguibili le due
classi. Questo fenomeno può essere spiegato considerando che la kurtosi, che agisce su
fx, dipende dalla media del residuo LPC, la quale in caso di rumore biased è maggiore
del caso unbiased. Siccome la media del residuo LPC per la voce è più alta di quella che
riguarda il non-parlato, nel caso di presenza della componente continua di fondo tale
differenza si abbassa. Il filtro passa-alto usato è il NUT disponibile nel Nu-Tech
denominato Filter, i cui parametri sono stati impostati come visibile nella Figura 51. è
un filtro FIR in frequenza di lunghezza 10 con frequenza di taglio a 20Hz. I risultati
della prova real time invece sono riportati nella Figura 52.
57
Figura 51. Impostazione del filtro passa-alto in ingresso al VAD.
Figura 52. Prova real time del VAD con alpha=0.98 e soglia=0.5 dopo 11 minuti e 20 secondi circa di
conversazione.
Si è voluto effettuare un’ulteriore prova per testare la bontà dell’algoritmo anche per
qualità più elevate, cioè si è innalzata la frequenza di campionamento a 32KHz.
Inizialmente (Figura 53) si è lasciata l’implementazione dell’algoritmo uguale al caso
8KHz ma la latenza era troppo elevata. Per diminuire il ritardo ingresso-uscita si è
58
dovuto modificare la lunghezza del buffer di lavoro raddoppiandola, passando cioè ad
un frame di elaborazione lungo 512 campioni con il solito overlap al 50% (Figura 54).
Figura 53. Prova real time a 32KHz del VAD con alpha=0.98 e soglia=0.2 dopo 2 minuti e 30 secondi
circa di conversazione.
Figura 54. Prova real time a 32KHz del VAD con alpha=0.98 e soglia=0.5 dopo 8 minuti e 30 secondi
circa di conversazione. Ora il blocco NUT utilizzato è VADonHOS_512 che implementa
l’algoritmo con un frame di lavoro di 512 campioni.
59
Per eseguire la prova a 32KHz alla voce Driver della finestra Settings del Nu-Tech si
è dovuto cambiare oltre alla frequenza di campionamento anche il Frame Size, il cui
valore minimo adatto alla prova e permesso dalla scheda audio diventa 4096. La scheda
audio, a seconda della frequenza di campionamento, supporta dei valori minimi di
Frame Size. Infatti questa può permettere un valore di Frame Size anche minore di
quelli impostati ma non sarebbero stati adatti al caso in esame poiché, per come è stato
scritto il codice in C, il Frame Size deve essere un multiplo esatto del frame di lavoro
altrimenti ci sarebbe un numero di campioni persi, cioè non elaborati, per ogni Frame
Size, pari al resto della divisione tra Frame Size e il frame di lavoro.
3.2.1 Risorse di calcolo impiegate dall’algoritmo
Le prestazioni in termini di impiego della CPU con cui si è realizzata la prova sono
evidenziate in rosso nelle Figura 55, Figura 56, Figura 57 e Figura 58. Il Nu-Tech
permette di visualizzare questo valore in termini di percentuale nella finestra Transport
Panel. Per il caso off-line e real time a 8KHz la CPU viene impiegata al 2,2% circa, per
il caso a 32KHz la percentuale sale al 9,5% mentre per quello con la stessa frequenza di
campionamento ma frame di lavoro a 512 campioni sale al 15,3% circa.
Figura 55. Percentuale d’impiego della CPU richiesta dalla totalità dei blocchi usati per la prova off-line.
60
Figura 56. Percentuale d’impiego della CPU richiesta dalla totalità dei blocchi usati per la prova real
time.
Figura 57. Percentuale d’impiego della CPU richiesta dalla totalità dei blocchi usati per la prova real time
con frequenza di campionamento a 32KHz e con il frame di lavoro originale (256 campioni).
61
Figura 58. Percentuale d’impiego della CPU richiesta dalla totalità dei blocchi usati per la prova real time
con frequenza di campionamento a 32KHz e con il frame di lavoro lungo 512 campioni.
3.3 Confronto tra MATLAB e Nu-Tech
In questo paragrafo viene mostrato un confronto tra i valori dei parametri media e
varianza, i più significativi, che si ottengono nei due ambienti di lavoro utilizzati, cioè
MATLAB e Nu-Tech, entrambi eseguiti in debugging (per il Nu-Tech il debugging è
effettuato con il Visual Studio 2005). La comparazione viene fatta per evidenziare la
loro congruenza anche dopo molte iterazioni.
Come segnale vocale di prova viene preso il file wave audio standard di parlato
maschile a 8KHz opportunamente modificato già descritto nel paragrafo 3.1, ma questa
volta l’aggiunta di rumore bianco gaussiano porta a 20dB il suo rapporto segnalerumore. I numeri di iterazioni che vengono considerati sono 1, 1000, 2000 e 3000 che
temporalmente corrispondono a 16ms, 16s, 32s e 48s.
Nel primo caso (Figura 59) l’uguaglianza si ha fino alla ottava cifra dopo la virgola
per entrambe le medie e per la varianza del secondo andamento e salgono a nove per la
varianza del primo andamento.
62
Figura 59. Confronto tra i valori dei parametri in MATLAB e in Nu-Tech dopo una iterazione.
Figura 60. Confronto tra i valori dei parametri in MATLAB e in Nu-Tech dopo 1000 iterazioni.
63
Nel secondo caso (Figura 60) l’uguaglianza per la media e per la varianza
dell’andamento 1 arriva fino all’ottava cifra dopo la virgola mentre scende alla settima
per la media e per la varianza dell’andamento 2.
Nel terzo caso (Figura 61) le cifre uguali dopo la virgola sono sette per la media del
primo andamento e per la varianza del secondo andamento, sono sei nella media
dell’andamento 2 ma sono dieci nella varianza dell’andamento 1.
Figura 61. Confronto tra i valori dei parametri in MATLAB e in Nu-Tech dopo 2000 iterazioni.
Nell’ultimo caso analizzato (Figura 62) le cifre uguali dopo la virgola salgono a otto
per la media del primo andamento e per la varianza del secondo andamento, rimangono
sempre sei nella media dell’andamento 2 e passano a nove nella varianza
dell’andamento 1.
64
Figura 62. Confronto tra i valori dei parametri in MATLAB e in Nu-Tech dopo 3000 iterazioni.
3.4 Tempi di convergenza dei parametri del VAD
L’algoritmo, essendo adattativo e di apprendimento, può raggiungere velocemente la
convergenza dei suoi parametri aumentando la rapidità con cui essi tendono ad
assumere un range di valori stabili e tali da essere considerati separati per ogni classe,
inoltre deve essere in grado di discernere velocemente tra le due situazioni, parlato e
non parlato, in un certo periodo iniziale in cui l’algoritmo le apprende dai parametri e
dai dati che elabora nella fase iniziale.
Per quanto riguarda la rapidità con cui i parametri convergono verso un range di
valori di regime, essa dipende, come già osservato nel paragrafo 3.1, da alpha che per
valori bassi, vicino a 0.5, provoca una convergenza lenta, mentre per valori alti, sopra
0.9, genera una convergenza rapida.
65
Per il secondo aspetto, la capacità di decidere velocemente, si deve tener presente
che, per poter apprendere, l’algoritmo VAD necessita di processare per opportuni istanti
iniziali sia frames di parlato sia frames di non parlato, in modo da permettere una
iniziale separazione tra i parametri relativi a ogni classe. Infatti se ci fosse per il periodo
iniziale solo parlato o non-parlato, l’algoritmo otterrebbe dei valori di media e di
varianza simili per ogni classe, non riuscendo così a discriminarle in maniera corretta.
Così la decisione sarebbe nuovamente frastagliata, dato che la piccola differenza tra i
parametri delle due classi genererebbe una scelta dipendente dal modo in cui la feature
migliorata influisce sulle gaussiane. Queste sarebbero infatti simili, alte e schiacciate o
basse e spanciate, e poco distanti tra loro avendo medie quasi uguali.
Infatti solamente dopo aver confrontato le due medie è possibile effettuare la
decisione. Perciò è importante che esse siano sufficientemente distaccate per poter
affermare che l’algoritmo è giunto a convergenza.
feature fx(magenta), mu1(red) e mu2(green)
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
200
400
600
800
1000
1200
1400
1600
Numero iterazioni
Figura 63. Andamento delle medie associate alle due classi per il file audio che inizia con il parlato
(SNR=60dB, alpha=0.9).
Tutto questo è verificabile attraverso i grafici sottostanti che, in Figura 63, Figura 64,
Figura 65 e Figura 66 mostrano un esempio in cui l’algoritmo è applicato ad una
sequenza che inizia per circa 18 secondi di parlato, mentre in Figura 67, Figura 68,
Figura 69 e Figura 70 mostrano un esempio in cui l’algoritmo è applicato ad una
66
sequenza che inizia per circa 5 secondi di non parlato. Il file wave in questione è lo
stesso file di partenza (voce maschile a 8KHz) utilizzato nelle prove precedenti, con la
differenza che in questo caso è stato solo aggiunto silenzio dopo (per 10 secondi) e
prima (per 4 secondi). Inoltre al file wave è stato aggiunto rumore bianco gaussiano tale
da condurre ad un SNR pari a 60dB.
feature fx(magenta), chi1(red) e chi2(green)
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
200
400
600
800
1000
1200
1400
1600
Numero iterazioni
Figura 64. Andamento delle probabilità stimate associate alle due classi per il file audio che inizia con il
parlato (SNR=60dB, alpha=0.9).
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
200
400
600
80
1000
1200
1400
1600
Numero iterazioni
Figura 65. Andamento delle probabilità filtrate associate alle due classi per il file audio che inizia con il
parlato (SNR=60dB, alpha=0.9).
67
segnale x(blue), feature migliorata fxp(cyan), vad(black)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
0
5
10
15
20
25
Tempo [s]
Figura 66. VAD applicato al file audio che inizia con il parlato (SNR=60dB). Le frecce rosse indicano
l’errore dovuto alla non convergenza. Alpha=0.9, soglia=0.5.
feature fx(magenta), mu1(red) e mu2(green)
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
200
400
600
800
1000
1200
1400
Numero
Figura 67. Andamento delle medie associate alle due classi per il file audio che inizia con il non-parlato
(SNR=60dB, alpha=0.9).
68
feature fx(magenta), chi1(red) e chi2(green)
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
200
400
600
800
1000
1200
1400
Numero iterazioni
Figura 68. Andamento delle probabilità stimate associate alle due classi per il file audio che inizia con il
non-parlato (SNR=60dB, alpha=0.9).
feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green)
1.2
1
0.8
0.6
0.4
0.2
0
0
200
400
600
800
1000
1200
1400
Numero iterazioni
Figura 69. Andamento delle probabilità filtrate associate alle due classi per il file audio che inizia con il
non-parlato (SNR=60dB, alpha=0.9).
69
segnale x(blue), feature migliorata fxp(cyan), vad(black)
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
0
2
4
6
8
10
12
14
16
18
20
22
Tempo [s]
Figura 70. VAD applicato al file audio che inizia con il non-parlato (SNR=60dB). La freccia rossa indica
l’errore dovuto alla non convergenza. Alpha=0.9, soglia=0.5.
In pratica viene mostrato come l’algoritmo impieghi pochissimo tempo per separare i
suoi parametri dal momento in cui si passa da una situazione iniziale prolungata, cioè di
almeno 3-4 secondi, di non-parlato o parlato all’altra.
3.5 Prestazioni dell’algoritmo VAD per diversi SNR
Per dare una valutazione delle prestazioni dell’algoritmo si sono confrontati i risultati
relativi ad un segnale vocale in cui è stato aggiunto di volta in volta, in misura sempre
crescente, rumore bianco gaussiano, con il risultato ottenuto processando lo stesso
segnale vocale ma con un SNR pari a 60dB. Perciò si considera quest’ultimo file audio
quello che genera il risultato ideale, cioè un VAD in grado di distinguere tra parlato e
non parlato senza sbagliare.
Visto che viene considerato VAD un segnale binario in cui lo zero indica il non
parlato e l’uno indica il parlato per ogni frame elaborato, è possibile effettuare una
differenza tra il risultato di riferimento e i risultati in prova. Questa operazione conduce
a tre valori corrispondenti a tre casi:
70
•
il frame di parlato o di non parlato è individuato correttamente quindi la
differenza tra il VAD di riferimento e il VAD a più basso SNR è 0;
•
il frame di parlato del VAD di riferimento non viene riconosciuto nel VAD in
prova dunque la differenza è pari a 1;
•
il frame di non parlato del VAD di riferimento non viene riconosciuto nel
VAD in prova dunque la differenza è pari a -1.
Contare il numero di volte in cui capitano questi casi conduce a tre diversi indicatori:
percentuale di frames correttamente rilevati, percentuale di frames parlato sbagliati e
percentuale di frames non parlato sbagliati. Bisogna inizialmente sapere il numero dei
frames totali del segnale vocale analizzato. Poi bisogna calcolare il numero di 0, quindi
di frames non parlato, e di 1, quindi di frames parlato, presenti nel VAD di riferimento.
Infine si possono fare i seguenti rapporti per trovare i tre indicatori:
•
•
•
%
°
0
100
;
°
°
%
°
%
1
100
;
1
°
°
‐1
100
‐1
.
Questi calcoli sono stati effettuati in MATLAB nella funzione StatVAD.m di cui si
riporta solo la parte che permette di calcolare gli indicatori in quanto la parte del calcolo
del VAD è stata già riportata in VADonHOS.m in appendice.
stats=vad2-vad1; %il 2 è il file di riferimento
for i=1:length(vad1)
if stats(i)== 0
framecorretti = framecorretti+1;
end
if stats(i)== -1
framenonparlatosbag = framenonparlatosbag+1;
end
if stats(i)== 1
frameparlatosbag = frameparlatosbag+1;
end
end
frametotali=length(vad2); %conta frames totali
for i=1:length(vad2)
if vad2(i)== 0
framenonparlatot = framenonparlatot+1; %conta frames non parlato
else if vad2(i)==1
frameparlatot = frameparlatot+1; %conta frames parlato
end
end
end
71
Framerightperc = 100*(framecorretti/frametotali); %frames corretti
Frameparlatosbagperc = 100*(frameparlatosbag/frameparlatot); %frames parlato sbagliati
Framenonparlatosbagperc = 100*(framenonparlatosbag/framenonparlatot); %frames non
parlato sbagliati
end
Il segnale vocale con un SNR di 60dB che genera il VAD di riferimento è stato
elaborato con una soglia pari a 0.5 e un alpha pari a 0.9. Questo è sembrato un ottimo
compromesso per le due variabili. Infatti, dato che la scelta di considerare un frame
parlato dipende dalla probabilità, è ragionevole pensare che una probabilità più vicina
ad 1 possa imporre che il frame sia di parlato, mentre una probabilità più vicino allo 0
impone che non sia vero che il frame sia di parlato. Per cui spostare la soglia verso 1 o
verso 0 implica considerare rispettivamente che ci sia una minore o maggiore possibilità
che il frame sia di parlato. Nel caso di SNR alto come 60dB è plausibile pensare che ci
sia la stessa possibilità di stabilire che sia vero che il frame sia di parlato oppure no e
quindi impostare la soglia a 0.5. Alpha a 0.9 invece permette di trovare il giusto
compromesso di convergenza in caso di basso rumore. Il risultato di questa elaborazione
è stato anche ascoltato per confermare l’ottima decisione dell’algoritmo e la sua perfetta
intelligibilità.
Nelle seguenti tabelle sono riportati i dati relativi agli indicatori definiti in
precedenza calcolati sullo stesso segnale vocale con diversi SNR, diversi alpha e diverse
soglie, riferiti al VAD considerato ideale.
SNR (dB) FrameCorretti%
60
95,227
55
95,253
50
94,347
45
95,360
40
91,867
35
94,080
30
90,560
25
90,907
20
84,400
15
79,973
10
66,613
5
45,333
alpha = 0.6, soglia = 0.5
Frame non-parlato sbagliati%
5,971
6,261
7,304
5,623
11,130
5,217
12,000
7,710
14,957
7,188
8,812
32,232
Frame parlato sbagliati%
3,753
3,457
4,247
3,802
5,580
6,519
7,259
10,272
16,148
30,963
54,321
73,778
Tabella 5. Prestazioni del VAD con alpha=0.6 e soglia=0.5 applicato al file audio di test al variare del
SNR. Percentuali calcolate come indicate nel paragrafo 3.5.
72
SNR (dB) FrameCorretti%
60
100,000
55
98,987
50
97,600
45
97,573
40
96,987
35
97,760
30
97,200
25
95,200
20
92,640
15
85,387
10
72,533
5
59,040
alpha = 0.9, soglia = 0.5
Frame non-parlato sbagliati%
0,000
1,391
3,826
2,841
3,130
0,522
0,058
1,565
0,000
0,058
0,000
3,652
Frame parlato sbagliati%
0,000
0,691
1,185
2,074
2,914
3,704
5,136
7,556
13,630
27,012
50,864
72,741
Tabella 6. Prestazioni del VAD con alpha=0.9 e soglia=0.5 applicato al file audio di test al variare del
SNR. Percentuali calcolate come indicate nel paragrafo 3.5. In questa tabella è possibile notare
il VAD di riferimento per SNR = 60dB.
SNR (dB) FrameCorretti%
60
100,000
55
98,987
50
97,600
45
97,573
40
96,987
35
97,760
30
97,627
25
96,533
20
94,667
15
90,347
10
81,840
5
60,320
alpha = 0.9, soglia = 0.25
Frame non-parlato sbagliati%
0,000
1,391
3,826
2,841
3,130
0,522
1,739
1,971
2,319
2,899
7,826
62,203
Frame parlato sbagliati%
0,000
0,691
1,185
2,074
2,914
3,704
2,914
4,741
7,901
15,407
26,963
20,494
Tabella 7. Prestazioni del VAD con alpha=0.9 e soglia=0.25 applicato al file audio di test al variare del
SNR. Percentuali calcolate come indicate nel paragrafo 3.5.
SNR (dB) FrameCorretti%
30
97,867
25
97,147
20
95,360
15
90,800
10
82,080
5
65,413
alpha = 0.98, soglia = 0.25
Frame non-parlato sbagliati%
0,812
0,406
0,406
0,986
4,290
45,681
Frame parlato sbagliati%
3,259
4,938
8,247
16,198
29,531
25,136
Tabella 8. Prestazioni del VAD con alpha=0.98 e soglia=0.25 applicato al file audio di test al variare del
SNR. Percentuali calcolate come indicate nel paragrafo 3.5.
73
SNR (dB) FrameCorretti%
30
97,947
25
97,200
20
95,947
15
91,440
10
82,560
5
56,907
alpha = 0.98, soglia = 0.2
Frame non-parlato sbagliati%
1,275
0,812
0,928
3,014
14,841
92,638
Frame parlato sbagliati%
2,716
4,494
6,716
13,284
19,654
0,889
Tabella 9. Prestazioni del VAD con alpha=0.98 e soglia=0.2 applicato al file audio di test al variare del
SNR. Percentuali calcolate come indicate nel paragrafo 3.5.
Frame corretti %
100
80
70
60
soglia=0.5 alpha=0.6
soglia=0.25 alpha=0.9
soglia=0.2 alpha=0.98
soglia=0.5 alpha=0.9
soglia=0.25 alpha=0.98
Frame corretti %
90
50
40
60
50
40
30
20
10
0
SNR [dB]
Figura 71. Andamento della percentuale dei frames correttamente rilevati al diminuire del SNR.
Nella Figura 71 si può notare come all’aumentare del rumore ci sia un progressivo
degrado delle prestazioni dell’algoritmo intese come riduzione dei frames correttamente
rilevati con conseguente diminuzione dell’intelligibilità del parlato. In particolare se si
osserva la curva per alpha=0.6 si vede come questa sia sempre più bassa rispetto al
riferimento di circa 7-8% con andamenti variabili. Questa curva conferma l’instabilità
che questo valore per questo parametro genera sulla convergenza dell’algoritmo e ciò
suggerisce di mantenere alpha piuttosto vicino all’unità. Per alpha
0.9 le curve con
74
SNR superiore a 30dB hanno, anche variando la soglia, uguali prestazioni che sono
superiori al 97%, questo significa che il VAD riconosce i frames quasi allo stesso modo
del VAD di riferimento con SNR pari a 60dB. Scendendo sotto i 30dB di SNR si può
notare come l’effetto dell’aumento di alpha e della diminuzione della soglia faccia
aumentare sensibilmente la percentuale dei frames correttamente rilevati, in particolare
proprio la diminuzione della soglia fa aumentare le prestazioni maggiormente rispetto
all’aumento di alpha. Fino a 10dB, anche grazie all’ascolto dei files a cui si applica
l’algoritmo del VAD con le situazioni descritte, si riesce a mantenere una intelligibilità
sufficiente a capire il discorso, in generale si può affermare che fino a 15dB di SNR il
VAD funziona correttamente.
Frames di non parlato sbagliati %
100
soglia=0.5 alpha=0.9
soglia=0.25 alpha=0.98
90
80
70
60
50
40
30
20
Frames di non parlato sbagliati %
soglia=0.5 alpha=0.6
soglia=0.25 alpha=0.9
soglia=0.2 alpha=0.98
10
0
60
50
40
30
SNR [dB]
20
10
0
Figura 72. Andamento della percentuale dei frames di non-parlato sbagliati al diminuire del SNR.
Analizzando la Figura 72 è possibile studiare l’andamento della percentuale dei
frames di non-parlato sbagliati al diminuire del SNR. Si nota che per valori di alpha
prossimi all’unità il VAD riconosce meglio il non-parlato in quanto tende a dare una
probabilità che il frame non-parlato sia parlato quasi 0. Infatti se si passa per un valore
di soglia pari a 0.25 da alpha=0.9 a alpha=0.98 è evidente una diminuzione percentuale
75
dei frames di non-parlato sbagliati. Grazie a questo fenomeno, in condizioni più
rumorose, è possibile abbassare la soglia e permettere il riconoscimento di più frames di
parlato a discapito di un modesto peggioramento nel riconoscimento del non-parlato.
Frames di parlato sbagliati %
100
soglia=0.5 alpha=0.9
soglia=0.25 alpha=0.98
90
80
70
60
50
40
30
Frames di parlato sbagliati %
soglia=0.5 alpha=0.6
soglia=0.25 alpha=0.9
soglia=0.2 alpha=0.98
20
10
0
60
50
40
30
SNR [dB]
20
10
0
Figura 73. Andamento della percentuale dei frames di parlato sbagliati al diminuire del SNR.
Per quanto riguarda le Figura 73 e Figura 74 qui si ha l’andamento della percentuale
dei frames di parlato sbagliati al diminuire del SNR. I grafici confermano che per basse
soglie, con alpha prossimo all’unità, si ha un miglioramento nel riconoscimento del
parlato. Sempre considerando le curve per soglia pari a 0.25 ma con alpha=0.9 e
alpha=0.98 si osserva che in questo caso si ha un modesto aumento percentuale di
frames di parlato sbagliati. Se si porta la soglia a un valore di 0.2 invece la curva
migliora anche rispetto all’andamento con soglia=0.25 e alpha=0.9. Quindi è possibile
affermare che alpha è un parametro che agisce meglio nel riconoscimento del nonparlato affetto da rumore mentre la soglia è un parametro che agisce meglio sul
riconoscimento del parlato affetto da rumore. Per tale ragione si è deciso di lasciar
libero il loro cambiamento nell’utilizzo nella piattaforma Nu-Tech. Una ulteriore
osservazione può essere fatta se si osserva come a 5dB di SNR sembrerebbero
76
migliorare decisamente le prestazioni nel riconoscimento del parlato. In realtà si deve
considerare che l’eccessivo rumore tende a portare le probabilità attorno a 0.5 creando
una grossa indecisione. Avendo valori di soglia inferiori a 0.5 ciò comporta che si faccia
passare come parlato la maggior parte dei frames quindi, se è vero che i frames di
parlato vengono riconosciuti è anche vero che i frames di non-parlato non vengono
eliminati provocando un funzionamento non corretto del VAD. Comunque questo è
visibile dalla Figura 71 dove per SNR=5dB la percentuale dei frames correttamente
identificati scende al 60% a causa dell’elevata percentuale di frames di non-parlato
sbagliati (fino a oltre il 90% per alpha=0.98 e soglia=0.2) come mostrato in Figura 72.
Frames di parlato sbagliati %
40
soglia=0.5 alpha=0.6
30
soglia=0.25 alpha=0.9
soglia=0.25 alpha=0.98
25
soglia=0.2 alpha=0.98
20
15
10
Frames di parlato sbagliati %
35
soglia=0.5 alpha=0.9
5
0
35
30
25
20
15
SNR [dB]
10
5
0
Figura 74. Zoom sull’andamento della percentuale dei frames di parlato sbagliati al diminuire del SNR.
A conferma di quanto affermato sulle prestazioni dell’algoritmo applicato a files
audio con diversi SNR per diversi valori delle variabili che caratterizzano il VAD,
vengono riportate di seguito alcune figure (dalla Figura 75 alla Figura 86) che
permettono un confronto visivo sulle medie, sulle probabilità e naturalmente sul VAD.
Le figure che possono essere considerate di riferimento poiché riguardano il file wave
con SNR=60dB si trovano nel paragrafo 3.1 e vanno dalla Figura 30 alla Figura 46.
77
SNR 25dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.6
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 25dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.9
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 25dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.98
1.5
1
0.5
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 75. Andamento delle medie associato alle due classi per lo stesso file audio
con SNR=25dB per tre diversi valori di alpha. In magenta la feature.
78
SNR 25dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.6
1
0.8
0.6
0.4
0.2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 25dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.9
1
0,75
0,5
soglia 0,25
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 25dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.98
1
0,75
0,5
soglia 0,25
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 76. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio con
SNR=25dB per tre diversi valori di alpha. In cyan la feature migliorata.
79
segnale x(blue) SNR 25dB, feature migliorata fxp(cyan), vad(black) con alpha=0.6
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 25dB, feature migliorata fxp(cyan), vad(black) con alpha=0.9
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 25dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.25
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo [s]
Figura 77. VAD con tre diversi valori di alpha e due diverse soglie applicato allo stesso file
audio con SNR=25dB. Dove non esplicitamente indicato la soglia è 0.5.
80
SNR 20dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.6
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 20dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.9
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 20dB: feature
fx(magenta), mu1(red) e mu2(green) con alpha=0.98
1.8
1.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 78. Andamento delle medie associato alle due classi per lo stesso file audio
con SNR=20dB per tre diversi valori di alpha. In magenta la feature.
81
SNR 20dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.6
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 20dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.9
1
0,75
0,5
soglia 0,25
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 20dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.98
1
0,75
0,5
soglia 0,25
soglia 0,2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 79. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio
con SNR=20dB per tre diversi valori di alpha. In cyan la feature migliorata.
82
segnale x(blue) SNR 20dB, feature migliorata fxp(cyan), vad(black) con alpha=0.6
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 20dB, feature migliorata fxp(cyan), vad(black) con alpha=0.9
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 20dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.25
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
Figura 80. VAD con tre diversi valori di alpha e una diversa soglia applicato allo stesso file
audio con SNR=20dB. Dove non esplicitamente indicato la soglia è 0.5.
83
SNR 15dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.6
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 15dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.9
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 15dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.98
1.4
1.2
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 81. Andamento delle medie associato alle due classi per lo stesso file audio con
SNR=15dB per tre diversi valori di alpha. In magenta la feature.
84
SNR 15dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.6
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 15dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.9
1
0,75
0,5
soglia 0,25
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 15dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.98
1
0,75
0,5
soglia 0,25
soglia 0,2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 82. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio con
SNR=15dB per tre diversi valori di alpha. In cyan la feature migliorata.
85
segnale x(blue) SNR 15dB, feature migliorata fxp(cyan), vad(black) con alpha=0.9
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 15dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.25
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 15dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.2
1
0.
0.
0.
0.
0
-
0
1
2
3
4
5
6
Tempo
Figura 83. VAD con tre diversi valori di alpha e due diverse soglie applicato allo stesso file
audio con SNR=15dB. Dove non esplicitamente indicato la soglia è 0.5.
86
SNR 10dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.6
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 10dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.9
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 10dB: feature fx(magenta), mu1(red) e mu2(green) con alpha=0.98
1
0.8
0.6
0.4
0.2
0
-0.2
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 84. Andamento delle medie associato alle due classi per lo stesso file audio con
SNR=10dB per tre diversi valori di alpha. In magenta la feature.
87
SNR 10dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.6
1
0.8
0.6
0.4
0.2
0
-
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 10dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.9
1
0,75
0,
soglia 0,25
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
SNR 10dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con alpha=0.98
1
0,75
0,5
soglia 0,25
soglia 0,2
0
0
500
1000
1500
2000
2500
3000
3500
Numero iterazioni
Figura 85. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio con
SNR=10dB per tre diversi valori di alpha. In cyan la feature migliorata.
88
segnale x(blue) SNR 10dB, feature migliorata fxp(cyan), vad(black) con alpha=0.9 e soglia=0.25
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 10dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.25
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
segnale x(blue) SNR 10dB, feature migliorata fxp(cyan), vad(black) con alpha=0.98 e soglia=0.2
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
0
10
20
30
40
50
60
Tempo [s]
Figura 86. VAD con due diversi valori di alpha e due diverse soglie applicato allo stesso file audio con
SNR=10dB.
89
Infine (Figura 87, Figura 88, Figura 89) è mostrata anche l’applicazione del VAD ad
alcuni files audio con diverso SNR nella piattaforma Nu-tech.
Figura 87. Risultato in Nu-Tech del VAD applicato al file audio di test. SNR=20dB, alpha=0.98,
soglia=0.25.
Figura 88. Risultato in Nu-Tech del VAD applicato al file audio di test. SNR=15dB, alpha=0.98,
soglia=0.2.
90
Figura 89. Risultato in Nu-Tech del VAD applicato al file audio di test. SNR=10dB, alpha=0.98,
soglia=0.2.
3.5.1 Ulteriore miglioramento dell’algoritmo per bassi SNR
Si è voluto testare l’algoritmo per bassi SNR con la modifica effettuata nel paragrafo
3.2 per l’elaborazione in tempo reale ma lasciando inalterata a 8KHz la frequenza di
campionamento. Viene cioè solamente raddoppiata la lunghezza della trama di lavoro
che passa quindi da 256 campioni a 512.
SNR (dB) FrameCorretti%
60
93,947
55
94,587
50
94,213
45
94,533
40
95,280
35
95,280
30
96,027
25
97,253
20
97,413
15
95,973
10
92,293
5
80,453
trama 512, alpha = 0.99, soglia 0.18
Frame non-parlato sbagliati%
Frame parlato sbagliati%
13,043
0,099
11,652
0,099
12,464
0,099
11,768
0,099
9,971
0,247
9,739
0,444
7,942
0,593
4,754
1,037
4,232
1,185
2,145
5,630
0,638
13,728
11,304
26,568
Tabella 10. Prestazioni del VAD con una trama lunga 512 campioni, alpha=0.99 e soglia=0.18 applicato
al file audio di test al variare del SNR. Percentuali calcolate come indicate nel paragrafo 3.5.
91
Come si nota dalla Tabella 10 e dal conseguente grafico delle prestazioni in Figura
90, per SNR inferiori ai 20dB c’è un notevole aumento percentuale delle prestazioni in
termini di frames correttamente rilevati.
Frame corretti %
100
80
soglia=0.5 alpha=0.6
70
soglia=0.5 alpha=0.9
60
soglia=0.25 alpha=0.9
Frame corretti %
90
soglia=0.25 alpha=0.98
50
soglia=0.2 alpha=0.98
trama 512 soglia=0.18 alpha=0.99
40
60
50
40
30
SNR [dB]
20
10
0
Figura 90. Andamento della percentuale dei frames correttamente rilevati al diminuire del SNR.
Frames di non parlato sbagliati %
90
soglia=0.5 alpha=0.9
80
soglia=0.25 alpha=0.9
soglia=0.25 alpha=0.98
70
soglia=0.2 alpha=0.98
60
trama 512 soglia=0.18 alpha=0.99
50
40
30
20
Frames di non parlato sbagliati %
100
soglia=0.5 alpha=0.6
10
0
60
50
40
30
SNR [dB]
20
10
0
Figura 91. Andamento della percentuale dei frames di non-parlato sbagliati al diminuire del SNR.
92
Dai grafici di Figura 91 e Figura 92 si vede come il netto miglioramento sia dato da
un maggior riconoscimento di frames di parlato il che permette un apprezzabile
aumento dell’intelligibilità delle parole diminuendo il frastagliamento.
Frames di parlato sbagliati %
100
soglia=0.5 alpha=0.6
soglia=0.25 alpha=0.9
80
soglia=0.25 alpha=0.98
70
soglia=0.2 alpha=0.98
60
trama 512 soglia=0.18 alpha=0.99
50
40
30
20
Frames di parlato sbagliati %
90
soglia=0.5 alpha=0.9
10
0
60
50
40
30
SNR [dB]
20
10
0
Figura 92. Andamento della percentuale dei frames di parlato sbagliati al diminuire del SNR.
SNR 15dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con trama 512 e alpha=0.99
1
0,8
0,6
0,4
0,25
soglia 0,18
0
0
200
400
600
800
1000
1200
1400
1600
1800
Numero Iterazioni
Figura 93. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio con
SNR=15dB usato nel paragrafo 3.5 per un frame di elaborazione pari a 512 campioni ed un
alpha=0.99. In cyan la feature migliorata.
93
segnale x(blue) SNR 15dB, feature migliorata fxp(cyan), vad(black) con trama 512,
alpha=0.99 e soglia=0.18
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo [s]
Figura 94. VAD con trama di lavoro di 512 campioni, alpha=0.99 e soglia=0.18 applicato allo stesso file
audio con SNR=15dB usato nel paragrafo 3.5.
Il tutto è ben visibile se si confrontano rispettivamente per un SNR=15dB la Figura
82 e la Figura 83 con la Figura 93 e la Figura 94, mentre per un SNR=10dB si devono
confrontare la Figura 85 e la Figura 86 con la Figura 95 e la Figura 96.
SNR 10dB: feature migliorata fxp(cyan), probFIR1(red) e probFIR2(green) con trama 512 e alpha=0.99
1
0,8
0,6
0,4
0,25
soglia 0,18
0
0
200
400
600
800
1000
1200
1400
1600
1800
Numero Iterazioni
Figura 95. Andamento delle probabilità filtrate FIR delle due classi per lo stesso file audio con
SNR=10dB usato nel paragrafo 3.5 per un frame di elaborazione pari a 512 campioni ed un
alpha=0.99. In cyan la feature migliorata.
94
segnale x(blue) SNR 10dB, feature migliorata fxp(cyan), vad(black) con trama 512,
alpha=0.99 e soglia=0.18
1
0.5
0
-0.5
0
10
20
30
40
50
60
Tempo
Figura 96. VAD con trama di lavoro di 512 campioni, alpha=0.99 e soglia=0.18 applicato allo stesso file
audio con SNR=10dB usato nel paragrafo 3.5.
95
Capitolo 4
Conclusioni
È stato proposto un nuovo metodo real time per il VAD. Il metodo usa le statistiche
di ordine superiore migliorate attraverso una caratteristica pesata dall’autocorrelazione
per migliorare l’immunità ai rumori non-gaussiani. È stato inoltre studiato l’uso delle
HOS per discriminare il parlato in campo vicino e in campo lontano, che è un problema
importante nelle interazioni tra più persone. Sono stati proposti e analizzati diversi
metodi decisionali per effettuare la scelta di classificazione tra parlato e non parlato. La
classificazione è fatta real time da un metodo di cluster online basato sull’algoritmo
EM. Il passo E è rimpiazzato da un’approssimazione stocastica ricorsiva per permettere
all’algoritmo di cambiare il suo stato ad ogni nuovo frame, perciò fornisce una stima del
rumore senza richiedere uno schema separato per la stima del SNR.
Il metodo è stato implementato e valutato sia in Matlab che in linguaggio C
attraverso la piattaforma Nu-Tech confrontando i risultati ottenuti elaborando un file a
cui viene aggiunto rumore AWGN a diversi SNR con un VAD di riferimento. Sono
state fatte anche prove real time ed è stata confermata la robustezza dell’algoritmo alla
poca densità del parlato.
E’ stato effettuato un confronto sui parametri dell’algoritmo in Matlab e in C
riscontrando una congruenza numerica fino alla sesta cifra dopo la virgola.
Si sono evidenziate le caratteristiche dell’algoritmo, i miglioramenti apportati
attraverso i filtraggi delle probabilità e i filtraggi della feature, i problemi dovuti alle
polarizzazioni intrinseche della schede audio, e le soluzioni per risolverli.
E’ stato mostrato l’uso della soglia sulla probabilità e l’uso del parametro alpha di
convergenza evidenziando che in condizioni di elevata rumorosità la soglia può essere
abbassata, rendendo intelligibile il parlato, ma introducendo anche frames di rumore che
vengono percepiti. Questi parametri sono stati lasciati liberi e impostabili dall’utente
finale per lasciare la massima libertà di ottimizzazione in tutte le condizioni di
rumorosità.
Sono stati provati diversi setup di prova per analizzare le risorse di calcolo in termini
di impiego di CPU richieste dall’algoritmo.
Sono stati effettuate prove per verificare la prontezza e la convergenza dei parametri
che caratterizzano il VAD stabilendo che l’alpha deve essere maggiore di 0.9 al fine di
ottenere un’immediata convergenza dell’algoritmo.
E’ stata raddoppiata la lunghezza del frame di lavoro che spinge l’algoritmo a
lavorare in maniera soddisfacente, a livello di intelligibilità, fino a bassissimi SNR
(10dB).
Figura 97. Risultato in Nu-Tech del VAD con frame di lavoro lungo 512 campioni applicato al file audio
di test. SNR=10dB, alpha=0.99, soglia=0,18.
Questo schema potrebbe essere ulteriormente migliorato. Ad esempio provando ad
inizializzare i parametri dell’EM Online attraverso l’algoritmo k-mean anziché
inizializzarli a caso a discapito di un ritardo nell’elaborazione di qualche istante.
97
La stima dell’EM online non è affidabile fino a che qualche dato che rappresenta il
parlato non è disponibile, perché essendo adattativo l’algoritmo deve apprendere le due
situazioni. Considerando esplicitamente una conoscenza a priori e confrontando i
modelli, il trattamento Bayesiano dell’EM online potrebbe risolvere questo problema e
fornire una migliore precisione.
Infine si potrebbe migliorare l’algoritmo aumentando la lunghezza del frame di
lavoro e massimizzandola fino ad ottenere decisioni ottime per alti livelli di rumore.
98
Appendice
Listati dell’algoritmo
Vengono riportate le implementazioni scritte in codice MATLAB e in C
dell’algoritmo VAD.
A. Listato in MATLAB
Sono state scritte diverse funzioni per rendere chiaro, modulare e portabile
l’algoritmo coerentemente con lo schema a blocchi di Figura 2.
La funzione principale con cui far partire l’algoritmo è VADonHOS.m riportata di
seguito, i valori iniziali caricati per i parametri sono riferiti alla Figura 11. Il file wave
va caricato come argomento nella funzione.
VADonHOS.m
function VADonHOS(file)
clc; %pulisce la Command Window
[campioni,Fs] = leggiwave(file); %file è il file wave da elaborare
x=[zeros(128,1);campioni]; %aggiunti 128 zeri all'inizio per congruenza con il Nu-Tech
%stampa delle informazioni sul file wave
fprintf('La frequenza di campionamento del segnale è %gHz\n',Fs);
fprintf('Il file è lungo %g campioni e dura %g secondi\n',length(x),length(x)/Fs);
%Si devono analizzare trame di 256 campioni con un overlap del 50%, quindi bisogna
iterare per un numero di volte pari alla lunghezza di x diviso 128 campioni meno uno
(meno uno perché ogni finestra, la trama, è compresa tra due valori dei puntatori che
indicano l'iterazione).
Num_iterazioni = fix(length(x)/128) - 1; %la funzione fix restituisce il numero intero
approssimato per difetto
fprintf('Il numero di iterazioni eseguite sono %d\n',Num_iterazioni);
punt=1; %inizializzazione del puntatore che permette di prendere le trame da analizzare
%%%%%%%%%%%%%%% Inizializzazione dei parametri per l'algoritmo EM online %%%%%%%%%%%%%%%
%I parametri sono vettori di due elementi perché corrispondono ai due valori che
identificano le classi parlato e non parlato.
%I parametri che si riferiscono all'iterzione precedende vengono indicati con il
suffisso "_p".
%N.B.: le due medie e le due varianze iniziali non possono essere uguali tra loro
altrimenti l'algoritmo non separerebbe i due andamenti.
alpha=0.9; %compreso tra 0.5 e 1, agisce sulla funzione gamma_t=(n+1)^(-alpha)
mu_p=[0.05,0.8]; %"mu" identifica la media della gaussiana
variance_p=[0.155,1.9]; %"variance" identifica la varianza della gaussiana
X_t_p=[0.02,0.48]; %"X_t" corrisponde a X circonflesso di t (stima di fx)
chi_p=[0.4,0.6]; %"chi" corrisponde al simbolo greco chi
X_t_quadro_p=[0.0645,1.78]; %"X_t" corrisponde alla stima di fx al quadrato
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Inizializzazione dei vettori necessari a salvare i valori dei parametri tra le
iterazioni per stampare e/o graficare i risultati
f_xstamp=zeros(1,Num_iterazioni);
X_t_1stamp=zeros(1,Num_iterazioni);
X_t_2stamp=zeros(1,Num_iterazioni);
chi_1stamp=zeros(1,Num_iterazioni);
chi_2stamp=zeros(1,Num_iterazioni);
mu_1stamp=zeros(1,Num_iterazioni);
mu_2stamp=zeros(1,Num_iterazioni);
X_t_quadro_1stamp=zeros(1,Num_iterazioni);
X_t_quadro_2stamp=zeros(1,Num_iterazioni);
variance_1stamp=zeros(1,Num_iterazioni);
variance_2stamp=zeros(1,Num_iterazioni);
vad=zeros(1,Num_iterazioni);
prob_1stamp=zeros(1,Num_iterazioni);
prob_2stamp=zeros(1,Num_iterazioni);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Inizializzazione vettori e parametri per la decisione (versione modificata
dell'algoritmo originale)
f_x_p2=0;
f_x_p1=0;
f_x_p=0;
f_x_pstamp=zeros(1,Num_iterazioni);
p1=[0,0];
p2=[0,0];
p3=[0,0];
sommap_1stamp=zeros(1,Num_iterazioni);
sommap_2stamp=zeros(1,Num_iterazioni);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Inizio iterazioni %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for n=1:Num_iterazioni
[x256,punt] = trama(x,punt); %prepara la trama da 256 campioni saltando alla
successiva dopo 128 campioni (overlap 50%)
e = res_lpc(x256); %calcola il residuo lpc della trama n-esima
[ac_causale,peak] = peak_picking(e); %estrae il picco massimo dell'autocorrelazione
normalizzata del residuo escluso il picco per ritardo zero
m_x = peak; %copia il valore del picco nella notazione usata nell'articolo
expt = my_expt(e); %calcola la media del residuo
v = my_variance(e,expt); %calcola la varianza del residuo
k_x = my_kurtosis(e,expt,v); %calcola la kurtosi del residuo prendendo anche in
ingresso la sua media e la sua varianza
f_x = m_x*log(1 + k_x); %calcola la caratteristica(feature): una kurtosi migliorata
f_xstamp(n) = f_x; %salva il valore attuale della feature fx
gamma_t = (n+1)^(-alpha); %calcola gamma_t
%%%%%%%%%%%%%%%%%%%%%%%%%%% Calcolo parametri %%%%%%%%%%%%%%%%%%%%%%%%%%%
%si ottengono i parametri stimati per ogni classe(parlato/non parlato)
100
[X_t,chi,mu,X_t_quadro,variance]=em_online(f_x,mu_p,variance_p,X_t_p,gamma_t,chi_p,X_t_q
uadro_p);
%viene salvato ogni parametro su due vettori(classi parlato/non parlato) per
stampare e/o graficare i valori di ogni iterazione
X_t_1stamp(n)=X_t(1);
X_t_2stamp(n)=X_t(2);
chi_1stamp(n)=chi(1);
chi_2stamp(n)=chi(2);
mu_1stamp(n)=mu(1);
mu_2stamp(n)=mu(2);
X_t_quadro_1stamp(n)=X_t_quadro(1);
X_t_quadro_2stamp(n)=X_t_quadro(2);
variance_1stamp(n)=variance(1);
variance_2stamp(n)=variance(2);
%%%%%%%%%Filtraggio IIR del 3° ordine della caratteristica fx%%%%%%%%%
f_x_p1=(f_x_p2+f_x_p1)/2;
f_x_p2=f_x_p1;
f_x_p=(f_x_p1+f_x_p)/2;
f_x_p1=f_x_p;
f_x_p=(f_x_p+f_x)/2; %caratteristica migliorata fxp per la decisione
f_x_pstamp(n)=f_x_p; %stampa della fxp necessaria per la visualizzazione
%%%%%%%%%%%%%%%%%%%%%Decisione della classe:il VAD%%%%%%%%%%%%%%%%%%%%%
[prob,p1,p2,p3,sommap,vad(n)]=decisione(f_x_p,p1,p2,p3,mu,variance);
%%%%%%%%%%%%%%%%%%%%%Stampe delle probailità%%%%%%%%%%%%%%%%%%%%%
prob_1stamp(n)=prob(1); %probabilità non filtrata FIR
prob_2stamp(n)=prob(2); %probabilità non filtrata FIR
sommap_1stamp(n)=sommap(1); %probabilità filtrata FIR
sommap_2stamp(n)=sommap(2); %probabilità filtrata FIR
%%%%%%%%%Aggiornamento dei parametri per la prossima iterazione%%%%%%%%
for c=1:2
X_t_p(c) = X_t(c);
chi_p(c) = chi(c);
mu_p(c) = mu(c);
X_t_quadro_p(c) = X_t_quadro(c);
variance_p(c) = variance(c);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% GRAFICI %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%grafica la caratteristica fx e quella migliorata fxp per la decisione
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,f_x_pstamp, 'cyan');
xlabel('Numero iterazioni');
title('feature fx(magenta) e feature migliorata fxp(cyan)');
%grafica la caratteristica fx e le sue stime X_t
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,X_t_1stamp, 'red');
plot(1:Num_iterazioni,X_t_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature fx(magenta), X_t_1(red) e X_t_2(green)')
%grafica la caratteristica fx e le chi
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,chi_1stamp, 'red');
plot(1:Num_iterazioni,chi_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature fx(magenta), chi_1(red) e chi_2(green)')
101
%grafica la caratteristica fx e le medie
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,mu_1stamp, 'red');
plot(1:Num_iterazioni,mu_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature fx(magenta), mu_1(red) e mu_2(green)')
%grafica la caratteristica fx e le X_t_quadro
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,X_t_quadro_1stamp, 'red');
plot(1:Num_iterazioni,X_t_quadro_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature fx(magenta), X_tquadro_1(red) e X_tquadro_2(green)')
%grafica la caratteristica fx e le varianze
figure
plot(1:Num_iterazioni,f_xstamp, 'magenta');
hold all
plot(1:Num_iterazioni,variance_1stamp, 'red');
plot(1:Num_iterazioni,variance_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature fx(magenta), variance_1(red) e variance_2(green)')
%grafica la caratteristica migliorata fxp e le probabilità non filtrate
figure
plot(1:Num_iterazioni,f_x_pstamp, 'cyan');
hold all
plot(1:Num_iterazioni,prob_1stamp, 'red');
plot(1:Num_iterazioni,prob_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature migliorata fxp(cyan), prob_1(red) e prob_2(green)')
%grafica la caratteristica migliorata fxp e le probabilità filtrate FIR
figure
plot(1:Num_iterazioni,f_x_pstamp, 'cyan');
hold all
plot(1:Num_iterazioni,sommap_1stamp, 'red');
plot(1:Num_iterazioni,sommap_2stamp, 'green');
xlabel('Numero iterazioni');
title('feature migliorata fxp(cyan), probFIR_1(red) e probFIR_2(green)')
%grafica il segnale nel tempo con la caratteristica migliorata fxp sovrapposta e il VAD
figure
plot([1:length(x)]/Fs,x); %segnale d'ingresso nel tempo(secondi)
hold all
f_x_pmantenuto=zeros(1,(Num_iterazioni+1)*128); %feature migliorata fxp paragonabile
temporalmente con il segnale
%fprintf('f_x_mantenuto è lungo %g\n',length(f_x_mantenuto));
for k=0:(Num_iterazioni-1)
for l=1:128
f_x_pmantenuto(128*k+l)=f_x_pstamp(k+1);
end
end
plot([1:(Num_iterazioni+1)*128]/Fs,f_x_pmantenuto,'cyan');
vad_stamp=zeros(1,(Num_iterazioni+1)*128); %vad
%fprintf('vad_stamp è lungo %g\n',length(vad_stamp));
for k=0:(Num_iterazioni-1)
for l=1:128
vad_stamp(k*128+l)=vad(k+1);
end
end
plot([1:(Num_iterazioni+1)*128]/Fs,vad_stamp, 'black');
xlabel('Tempo [s]');
title('segnale x(blue), feature migliorata fxp(cyan), vad(black)')
102
%togliere il commento se si vuole ascoltare il risultato
%{
%%%%%%%%Ascolto dell'elaborazione dell'algoritmo VAD sul file wave%%%%%%%%
xplay=zeros((Num_iterazioni+1)*128,1);
for i=1:(Num_iterazioni+1)*128
xplay(i)=x(i)*vad_stamp(i);
end
wavplay(xplay,Fs);
%}
%togliere i commenti nel caso si volgiano graficare i vari parametri
%confrontabili con il segnale vocale nel tempo
%{
f_xmantenuto=zeros(1,(Num_iterazioni+1)*128); %feature fx paragonabile temporalmente con
il segnale
for k=0:(Num_iterazioni-1)
for l=1:128
f_xmantenuto(128*k+l)=f_x_pstamp(k+1);
end
end
%feature stimata X_t
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_xmantenuto,'magenta'); %feature fx paragonabile
temporalmente con il segnale
X_t_1=zeros(1,Num_iterazioni*128);
X_t_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
X_t_1(128*k+l)=X_t_1stamp(k+1);
X_t_2(128*k+l)=X_t_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,X_t_1, 'red');
plot([1:Num_iterazioni*128]/Fs,X_t_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature fx(magenta), X_t_1(red) e X_t_2(green)')
%probabilità stimate chi
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_xmantenuto,'magenta'); %feature fx paragonabile
temporalmente con il segnale
chi_1=zeros(1,Num_iterazioni*128);
chi_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
chi_1(128*k+l)=chi_1stamp(k+1);
chi_2(128*k+l)=chi_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,chi_1, 'red');
plot([1:Num_iterazioni*128]/Fs,chi_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature fx(magenta), chi_1(red) e chi_2(green)')
%medie mu
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_xmantenuto,'magenta'); %feature fx paragonabile
temporalmente con il segnale
mu_1=zeros(1,Num_iterazioni*128);
mu_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
mu_1(128*k+l)=mu_1stamp(k+1);
mu_2(128*k+l)=mu_2stamp(k+1);
end
103
end
plot([1:Num_iterazioni*128]/Fs,mu_1, 'red');
plot([1:Num_iterazioni*128]/Fs,mu_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature fx(magenta), mu_1(red) e
mu_2(green)')
%feature quadro stimate X_t_quadro
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_xmantenuto,'magenta'); %feature fx paragonabile
temporalmente con il segnale
X_t_quadro_1=zeros(1,Num_iterazioni*128);
X_t_quadro_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
X_t_quadro_1(128*k+l)=X_t_quadro_1stamp(k+1);
X_t_quadro_2(128*k+l)=X_t_quadro_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,X_t_quadro_1, 'red');
plot([1:Num_iterazioni*128]/Fs,X_t_quadro_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature fx(magenta), X_tquadro_1(red) e X_tquadro_2(green)')
%varianze variance
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_xmantenuto,'magenta'); %feature fx paragonabile
temporalmente con il segnale
variance_1=zeros(1,Num_iterazioni*128);
variance_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
variance_1(128*k+l)=variance_1stamp(k+1);
variance_2(128*k+l)=variance_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,variance_1, 'red');
plot([1:Num_iterazioni*128]/Fs,variance_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature fx(magenta), variance_1(red) e variance_2(green)')
%probabilità non filtrate FIR prob
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_x_pmantenuto,'cyan'); %feature fx paragonabile
temporalmente con il segnale
prob_1=zeros(1,Num_iterazioni*128);
prob_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
for l=1:128
prob_1(128*k+l)=prob_1stamp(k+1);
prob_2(128*k+l)=prob_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,prob_1, 'red');
plot([1:Num_iterazioni*128]/Fs,prob_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature migliorata fxp(cyan), prob_1(red) e prob_2(green)')
%probabilità filtrate FIR sommap
figure
plot([1:length(x)]/Fs,x);
hold all
plot([1:(Num_iterazioni+1)*128]/Fs,f_x_pmantenuto,'cyan'); %feature fx paragonabile
temporalmente con il segnale
sommap_1=zeros(1,Num_iterazioni*128);
sommap_2=zeros(1,Num_iterazioni*128);
for k=0:(Num_iterazioni-1)
104
for l=1:128
sommap_1(128*k+l)=sommap_1stamp(k+1);
sommap_2(128*k+l)=sommap_2stamp(k+1);
end
end
plot([1:Num_iterazioni*128]/Fs,sommap_1, 'red');
plot([1:Num_iterazioni*128]/Fs,sommap_2, 'green');
xlabel('Tempo [s]');
title('segnale x(blue), feature migliorata fxp(cyan), probFIR_1(red) e
probFIR_2(green)')
%}
end
leggiwave.m
function [x,Fs]= leggiwave(file)
[x,Fs]=wavread(file);
%wavplay(x,Fs); %da togliere il commento per sentire il file originale
end
trama.m
%Trama prelevata dal vettore x, il quale contiene i campioni di ingresso del segnale
function [x256,punt]= trama(x,punt) %restituisce i 256 valori della trama e il puntatore
alla successiva
x256=x(punt:punt+255); %punt va inizializzato fuori della funzione e funge da puntatore
punt=punt+128; %riporta l'indice alla trama successiva con un overlap del 50%
end
res_lpc.m
function [e]= res_lpc(x256) %calcola il residuo lpc della trama e lo restituisce in e
lpc_coeff=lpc(x256,10); %calcolo dei coefficienti lpc usati per la ricostruzione del
segnale:
%essendo l'ordine p=10, il numero dei coefficienti lpc è p+1=11, con il primo
coefficiente sempre uguale a 1.
%Per ricostruire il frame occorre filtrare con un FIR di ordine p così costruito:
FIR_coeff=[0 -lpc_coeff(2:end)]
est_x256 = filter([0 -lpc_coeff(2:end)],1,x256); %stima del frame di 256 campioni (32ms
a 8kHz)
e = x256 - est_x256; %calcolo del residuo
end
peak_picking.m
%Calcola l'autocorrelazione normalizzata del residuo ed estrae il valore del picco
massimo escluso il picco per ritardo zero
function [ac_causale,peak] = peak_picking(e)
[acs,lags] = xcorr(e,'coeff'); %calcola l'autocorrelazione normalizzata
ac_causale = acs(length(e)+1 : end); %sono presi solo i valori positivi di tau(lags)
escluso lo zero
peak=0;
for i=1:length(ac_causale)
if ac_causale(i) >= peak %prende solo il picco positivo
peak = ac_causale(i);
end
end
end
my_expt.m
%%%%%%%%%%%%%%%%% Calcola la media statistica (Expectation) %%%%%%%%%%%%%%%%%
function [expt] = my_expt(e)
105
tmp=0;
for i=1:length(e)
tmp=e(i)+tmp ; %somma tutti i valori del vettore "e"
end
expt=tmp/length(e); %media
end
my_variance.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%Calcola la varianza%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%in questo caso del residuo "e"
function [v] = my_variance(e,media) %"media" è la media del vettore "e"
tmp=0;
for i=1:length(e)
tmp=(e(i)-media)^2 + tmp; %somma il quadrato di tutti i valori del vettore "e" meno
media
end
v = tmp/length(e); %varianza
end
my_kurtosis.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Calcola la kurtosi%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%in questo caso del residuo "e"
function [k] = my_kurtosis(e,media,v) %"media" e "v" sono la media e la varianza del
vettore "e"
for i=1:length(e)
val_int(i)=(e(i)-media)^4 ; %calcolo del vettore su cui fare la media
end
k=(my_expt(val_int))/(v^2) -3; %kurtosi
end
em_online.m
%Esegue un passo dell'algoritmo EM ONLINE per ogni classe(parlato/non parlato)
function
[X_t,chi,mu,X_t_quadro,variance]=em_online(f_x,mu_p,variance_p,X_t_p,gamma_t,chi_p,X_t_q
uadro_p)
p_gauss=zeros(1,2);
P_i=zeros(1,2);
X_t=zeros(1,2);
chi=zeros(1,2);
mu=zeros(1,2);
X_t_quadro=zeros(1,2);
variance=zeros(1,2);
for c=1:2
p_gauss(c) = 1/sqrt(2*pi*variance_p(c)) * exp((-1/2)*((f_xmu_p(c))^2)/variance_p(c));
end
psum=p_gauss(1)+p_gauss(2);
for c=1:2
P_i(c) = p_gauss(c)/psum;
X_t(c) = X_t_p(c) + gamma_t*(P_i(c)*f_x - X_t_p(c));
chi(c) = chi_p(c) + gamma_t*(P_i(c) - chi_p(c));
mu(c) = X_t(c)/chi(c);
X_t_quadro(c) = X_t_quadro_p(c)+ gamma_t*(P_i(c)*(f_x^2) - X_t_quadro_p(c));
%CONVERGE SOLO per gamma_t=(n+1)^(-alpha);
variance(c)= abs(X_t_quadro(c)/chi(c) - mu(c)^2); %infatti con gamma_t=(n)^(-alpha)
e per n=1, porta una varianza nulla (f_x^2 - f_x^2)
%if variance(c) <= 0.000001 %per evitare che si blocchi con una divisione per 0
%
variance(c) = 0.00001;
%end
end
%if abs(mu(1)-mu(2)) <= 0.000000001 %soluzione al caso in cui le medie non si separino
%
mu(1)=0.1+mu(2);
end
106
decisione.m
%Il VAD:viene decisa la classe(parlato/non parlato) della trama
function [prob,p1,p2,p3,sommap,vad]=decisione(f_x_p,p1,p2,p3,mu,variance)
sommap=zeros(1,2);
p_gauss_attuale=zeros(1,2);
prob=zeros(1,2);
for c=1:2
p_gauss_attuale(c) = 1/sqrt(2*pi*variance(c)) * exp((-1/2)*((f_x_pmu(c))^2)/variance(c));
end
psum=p_gauss_attuale(1)+p_gauss_attuale(2);
for c=1:2
prob(c)=p_gauss_attuale(c)/psum;
sommap(c)=(prob(c)+p1(c)+p2(c)+p3(c))/4;
p3(c)=p2(c);
p2(c)=p1(c);
p1(c)=prob(c);
end
soglia=0.5;
if mu(1) >= mu(2) %l'indice 1 classifica il parlato
if sommap(1) >= soglia
vad=1; %allora è parlato
else %sommap(1) < soglia
vad=0; %allora è rumore
end
else %mu(2) > mu(1) quindi l'indice 2 classifica il parlato
if sommap(2) >= soglia
vad=1; %allora è parlato
else %sommap(2) < soglia
vad=0; %allora è rumore
end
end
end
B.
Listato in C
Plugin.h
#pragma once
#include "LEEffect.h"
#include <math.h>
#include "ipp.h"
#include "ipps.h"
#define PLAYBUFFER_TXT "PlayBuffer"
#define SCALAR_TXT "Scalar"
#define VECTOR_TXT "Vector"
#define VARLEN_TXT "VarLen"
#define
#define
#define
#define
INT16_TXT
INT32_TXT
FLT32_TXT
DBL64_TXT
"Integer 16bit"
"Integer 32bit"
"Float 32bit"
"double 64bit"
#define DATATYPEBITMASK VECTOR|SCALAR|BUFFSTREAMING|VARLEN
#define DATALENBITMASK DATAINT32|DATAINT16|DATAINT8|DATAFLOAT32|DATADOUBLE64|CUSTOM
#define WIDTHDEF 75
#define WORK_BUFFERSIZE 128
#define ORDERLPC 10
107
#define IDXALPHA 1
#define IDXTHRESHOLD 2
#define PI 3.141592653589793
class PlugIn : public LEEffect
{
public:
PlugIn(InterfaceType _CBFunction,void * _PlugRef,HWND ParentDlg);
~PlugIn(void)
{
}
void __stdcall LESetName(char *Name);
void __stdcall LEPlugin_Init();
int __stdcall LEPlugin_Process(PinType **Input,PinType **Output,LPVOID
ExtraInfo);
void __stdcall LEPlugin_Delete(void);
bool __stdcall LEInfoIO(int index,int type, char *StrInfo);
int __stdcall
int __stdcall
int __stdcall
LEGetNumInput();};
int __stdcall
LEGetNumOutput();};
LEGetNumInput(){return LEEffect::LEGetNumInput();};
LEGetNumOutput(){return LEEffect::LEGetNumOutput();};
LESetNumInput(int Val,PinType *TypeNewIn=0){return
LESetNumOutput(int Val,PinType *TypeNewOut=0){return
void __stdcall LESetParameter(int Index,void *Data,LPVOID bBroadCastInfo);
int __stdcall LEGetParameter(int Index,void *Data);
int __stdcall LESetDefPin(int index,int type, PinType *Info)
{
if (type==OUTPUT)
{
int
FrameSz=CBFunction(this,NUTS_GETFRAME_RATE,0,(LPVOID)AUDIOPROC);
Info->DataType=PLAYBUFFER;
Info->Exclusive=true;
Info->DataLen=FrameSz;
Info->MaxDataLen=FrameSz;
return OUTPUT;
}
if (type==INPUT)
{
int
FrameSz=CBFunction(this,NUTS_GETFRAME_RATE,0,(LPVOID)AUDIOPROC);
Info->DataType=PLAYBUFFER;
Info->Exclusive=true;
Info->DataLen=FrameSz;
Info->MaxDataLen=FrameSz;
return INPUT;
}
return -1;
};
HWND __stdcall LEGetWndSet(){return 0;};
int __stdcall LEWinSetStatusChange(int NewStatus){return 0;};
void __stdcall LESaveSetUp();
void __stdcall LELoadSetUp();
void __stdcall LESampleRateChange(int NewVal,int TrigType){};
void __stdcall LEFrameSizeChange (int NewVal,int TrigType){};
108
void __stdcall LEConnectionChange(int IOType,int Index,bool Connected){};
int __stdcall LEExtraInfoPinChange(int IOType,int Index,PinExtraInfoType
ExInfo){return 0;};
void __stdcall LERTWatchInit();
private: // dichiarazione delle variabili e delle funzioni per VAD
// dichiarazione delle variabili per VAD
typedef struct {
double mu[2];
double variance[2];
double X_t[2];
double chi[2];
double X_t_quadro[2];
} Parametri;
Parametri par_p,par;
double m_x, expt, var, k_x, f_x, f_x_p, f_x_p1, f_x_p2;
double Alpha;
double Threshold;
double gamma_t, psum;
int i,n_prec;
double
double
double
double
*InputBuffer;
*InputBufferOld;
*OutputBuffer;
*WorkBuffer;
double *AutocorrWB;
float *AutocorrWB_32f;
float *LPCcoeff_32f;
double *LPCcoeff;
float *RC_lpc;
float *pRREnergy;
double *FIRcoeff;
double *speechLPC;
double *ResidualLPC;
double *AutC;
double *val_int; //valore di argomento per la kurtosis
double *p_gauss, *P_i;
double *p1, *p2, *p3;
// dichiarazione delle funzioni per VAD
void my_FIR(const Ipp64f* WorkBuffer, Ipp64f* FIRcoeff, Ipp64f* speechLPC) {
//speechLPC è il segnale stimato
int i;
for (i=0; i<=2*WORK_BUFFERSIZE-1; i++)
{
if (i==0)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0];
else if (i==1)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1];
else if (i==2)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2];
else if (i==3)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3];
else if (i==4)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4];
else if (i==5)
109
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5];
else if (i==6)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5]+WorkBuffer[i-6]*FIRcoeff[6];
else if (i==7)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5]+WorkBuffer[i-6]*FIRcoeff[6]+WorkBuffer[i7]*FIRcoeff[7];
else if (i==8)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5]+WorkBuffer[i-6]*FIRcoeff[6]+WorkBuffer[i7]*FIRcoeff[7]+WorkBuffer[i-8]*FIRcoeff[8];
else if (i==9)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5]+WorkBuffer[i-6]*FIRcoeff[6]+WorkBuffer[i7]*FIRcoeff[7]+WorkBuffer[i-8]*FIRcoeff[8]+WorkBuffer[i-9]*FIRcoeff[9];
else //if (i>=10)
speechLPC[i]=WorkBuffer[i]*FIRcoeff[0]+WorkBuffer[i1]*FIRcoeff[1]+WorkBuffer[i-2]*FIRcoeff[2]+WorkBuffer[i-3]*FIRcoeff[3]+WorkBuffer[i4]*FIRcoeff[4]+WorkBuffer[i-5]*FIRcoeff[5]+WorkBuffer[i-6]*FIRcoeff[6]+WorkBuffer[i7]*FIRcoeff[7]+WorkBuffer[i-8]*FIRcoeff[8]+WorkBuffer[i-9]*FIRcoeff[9]+WorkBuffer[i10]*FIRcoeff[10];
};
return ;
};
double Peak_Picking(const double* ResidualLPC) {
double Peak=0, AutCorMax=0;
int n,k,i;
//calcolo della autocorrelazione normalizzata
ippsZero_64f(AutC, 2*WORK_BUFFERSIZE); //for (n=0; n<=2*WORK_BUFFERSIZE1; n++) AutC[n]=0;
for (n=0; n<=2*WORK_BUFFERSIZE-1; n++){
AutCorMax+=ResidualLPC[n]*ResidualLPC[n];
};
for (k=0; k<=2*WORK_BUFFERSIZE-1; k++){
for (n=k; n<=2*WORK_BUFFERSIZE-1; n++){
AutC[k]+= ResidualLPC[n]*ResidualLPC[n-k];
};
AutC[k]=AutC[k]/AutCorMax;
};
//estrazione del picco di autocorrelazione escluso il picco per ritardo
zero
for (i=1; i<= 2*WORK_BUFFERSIZE-1; i++){
if (AutC[i]>=Peak)
Peak=AutC[i];
};
return Peak;
};
//funzione che calcola l'expectation di un vettore
double my_expt(const double* ResidualLPC){
double expt=0;
int i;
for (i=0; i<=2*WORK_BUFFERSIZE-1; i++){
expt+=ResidualLPC[i];
};
expt/=2*WORK_BUFFERSIZE;//expt=expt/(2*WORK_BUFFERSIZE)
return expt;
};
//funzione che calcola la varianza a partire da un vettore e dal suo valor medio
double my_variance(const double* ResidualLPC, const double expt){
110
double variance=0;
int i;
for (i=0; i<=2*WORK_BUFFERSIZE-1; i++){
variance+=(ResidualLPC[i]-expt)*(ResidualLPC[i]-expt);
};
variance/=2*WORK_BUFFERSIZE;
return variance;
};
//funzione che calcola la kurtosi a partire da un vettore dal suo valor medio e
dalla sua varianza
double my_kurtosis(const double* ResidualLPC, const double expt, const double
variance){
double kurtosis=0;
int i;
for (i=0; i<=2*WORK_BUFFERSIZE-1; i++){
val_int[i]=(ResidualLPC[i]-expt)*(ResidualLPC[i]expt)*(ResidualLPC[i]-expt)*(ResidualLPC[i]-expt);
};
kurtosis=my_expt(val_int)/(variance*variance)-3;
return kurtosis;
};
//funzione che numera le iterazioni
int number_iteration(int n_prec){
n_prec++;
return n_prec;
};
//funzione che implementa l'algoritmo EM online
void em_online(double f_x, double gamma_t, Parametri *par_p, Parametri *par){
int c;
double p_gauss[2],psum, P_i[2];
for (c=0; c<=1; c++)
p_gauss[c]=(1/sqrt(2*PI*par_p->variance[c]))*exp((-pow(f_x-par_p>mu[c],2))/(2*par_p->variance[c]));
psum=p_gauss[0]+p_gauss[1];
for (c=0; c<=1; c++)
P_i[c]=p_gauss[c]/psum; //calcola la probabilità di ogni
classe(parlato o non parlato)
for (c=0; c<=1 ; c++){
par->X_t[c]= par_p->X_t[c] + gamma_t*(P_i[c]*f_x - par_p->X_t[c]);
//X_t aggiornati in par
par->chi[c]= par_p->chi[c] + gamma_t*(P_i[c] - par_p->chi[c]);
//chi aggiornati in par
par->mu[c]= par->X_t[c]/par->chi[c]; //mu aggiornati in par
par->X_t_quadro[c]= par_p->X_t_quadro[c] +
gamma_t*(P_i[c]*(pow(f_x,2)) - par_p->X_t_quadro[c]); //X_t_quadro aggiornati in par
par->variance[c]= fabs(par->X_t_quadro[c]/par->chi[c] - (pow(par>mu[c],2))); //variance aggiornati in par
//if (par->variance[c]<=0.000001) // nel caso si blocchi
l'algoritmo
//
par->variance[c]=0.00001;
};
//if (abs(par->mu[1]-par->mu[2])<=0.000000001) //nel caso in cui le
medie non si separino
//
par->mu[1]=0.1+par->mu[2];
return ;
};
//funzione che implementa la decisione per stabilire se un frame è di parlato o
no
void decisione(Parametri par, double *OutputBuffer, double *InputBuffer, double
f_x_p, double *p1, double *p2, double *p3){
int c;
double psum, p_gauss[2]={0,0}, sommap[2]={0,0};
for (c=0; c<=1 ; c++)
p_gauss[c]=(1/sqrt(2*PI*par.variance[c]))*exp((-pow(f_x_ppar.mu[c],2))/(2*par.variance[c]));
psum=p_gauss[0]+p_gauss[1];
for (c=0;c<=1;c++) {
P_i[c]=p_gauss[c]/psum;
111
sommap[c]=(P_i[c]+p1[c]+p2[c]+p3[c])/4;
p3[c]=p2[c];
p2[c]=p1[c];
p1[c]=P_i[c];
};
if (par.mu[0]>=par.mu[1]) //il parlato è identificato dall'indice 0
if (sommap[0]>=Threshold)
memcpy(OutputBuffer, InputBuffer,
(WORK_BUFFERSIZE)*sizeof(double));
else
ippsZero_64f(OutputBuffer, WORK_BUFFERSIZE);
else
//il parlato è identificato dall'indice 1
if (sommap[1]>=Threshold)
memcpy(OutputBuffer, InputBuffer,
(WORK_BUFFERSIZE)*sizeof(double));
else
ippsZero_64f(OutputBuffer, WORK_BUFFERSIZE);
return ;
};
//funzione che aggiorna i paramentri dell'algoritmo EM online
void ParUpdate(Parametri *par, Parametri *par_p){
int i;
for (i=0; i<=1 ; i++){
par_p->mu[i]=par->mu[i];
par_p->variance[i]=par->variance[i];
par_p->X_t[i]=par->X_t[i];
par_p->chi[i]=par->chi[i];
par_p->X_t_quadro[i]=par->X_t_quadro[i];
};
return ;
};
double SetAlphaValue(double NewValue);
double GetAlphaValue();
double SetThresholdValue(double NewValue1);
double GetThresholdValue();
};
////////////////////////////////////////////////////////////////////////////////////////
////
////////////////////////////////////
LOADER
///////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////
LEEffect * __stdcall LoadEffect(InterfaceType _CBFunction,void *PlugRef,HWND ParentDlg)
{
return new PlugIn(_CBFunction,PlugRef,ParentDlg);
}
////////////////////////////////////////////////////////////////////////////////////////
////
/////////////////////////////////
GetStartUpInfo
//////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////
void __stdcall LENUTSDefProps(char *NameEffect,int *Width, void *data)
{
strncpy(NameEffect,"VADonHOS",MAXNAME);
112
*Width=WIDTHDEF;
if (data!=0)
{
StartUpNUTSProps *Info=(StartUpNUTSProps *)data;
Info->NumInStartUp=1;
Info->NumOutStartUp=1;
}
}
Plugin.cpp
#include
#include
#include
#include
#include
#include
#include
#include
"StdAfx.h"
".\plugin.h"
<stdio.h>
<stdlib.h>
<math.h>
"ipp.h"
"ipps.h"
"ippsc.h"
PlugIn::PlugIn(InterfaceType _CBFunction,void * _PlugRef,HWND ParentDlg):
LEEffect(_CBFunction,_PlugRef,ParentDlg)
{
//inizializzazione dei parametri iniziali quando verrà caricato il plug in
//(costruttore dove allocare una volta per tutte le variabili, altrimenti lo
mettiamo nella init)
Alpha=0.9;
Threshold=0.5;
}
int __stdcall PlugIn::LEPlugin_Process(PinType **Input,PinType **Output,LPVOID
ExtraInfo)
{
int nSample;
int n, index_i=0, index_j=0;
//gestione della process suddivide il frame dato in pasto dalla scheda audio in
altri sottoframe
while(index_i < Input[0]->DataLen)
{
nSample = min(WORK_BUFFERSIZE - index_j, Input[0]->DataLen-index_i );
memcpy( &InputBuffer[index_j], &((double*)Input[0]->DataBuffer)[index_i],
nSample*sizeof(double) );
memcpy( &((double*)Output[0]->DataBuffer)[index_i],
&OutputBuffer[index_j], nSample*sizeof(double) );
index_i += nSample;
index_j += nSample;
if(index_j == WORK_BUFFERSIZE)
{
index_j = 0;
// EXAMPLE with 50% OVERLAP-and-SAVE STRUCTURE
memcpy( WorkBuffer, InputBufferOld,
WORK_BUFFERSIZE*sizeof(double)); //memcopy copia n elementi dal secondo argomento al
primo(in questo caso 128 elementi)
memcpy( &WorkBuffer[WORK_BUFFERSIZE], InputBuffer,
WORK_BUFFERSIZE*sizeof(double));// copia n elementi nella seconda parte di workbuffer
memcpy( InputBufferOld, InputBuffer,
WORK_BUFFERSIZE*sizeof(double));// copia inputbuffer in inputbufferold per la successiva
iterazione
for (i=0; i<=2*WORK_BUFFERSIZE-1; i++) WorkBuffer[i]/=32768;
113
ippsAutoCorr_64f(WorkBuffer, 2*WORK_BUFFERSIZE, AutocorrWB,
ORDERLPC+1); //calcola l'autocorrelazione del frame(prende la parte positiva
dell'autocorrelazione, da 0 a 255)
ippsConvert_64f32f(AutocorrWB, AutocorrWB_32f , ORDERLPC+1);
//casting di AutocorrWB da double a float
ippsLevinsonDurbin_G729_32f(AutocorrWB_32f, ORDERLPC
,LPCcoeff_32f, RC_lpc, pRREnergy); //genera i coefficenti LPC
ippsConvert_32f64f(LPCcoeff_32f, LPCcoeff, ORDERLPC+1);
//casting di LPCcoeff da float a double
FIRcoeff[0]=0;
for (i=1 ; i<=ORDERLPC; i++) FIRcoeff[i]=(-1)*LPCcoeff[i];
//generazione dei tappi del filtro con i coefficenti LPC per sintetizzare il segnale
d'ingresso
my_FIR( WorkBuffer, FIRcoeff, speechLPC); //calcola attraverso
il filtro LPC il segnale sintetizzato eccitandolo con il segnale d'ingresso
for (i=0; i<=2*WORK_BUFFERSIZE-1 ; i++)
ResidualLPC[i]=WorkBuffer[i]-speechLPC[i]; //calcolo del
residuo LPC
m_x=Peak_Picking( ResidualLPC); //preleva il picco
dell'autocorrelazione del residuo LPC
expt=my_expt(ResidualLPC); //calcola la media
var=my_variance( ResidualLPC, expt); //calcola la varianza
k_x=my_kurtosis( ResidualLPC, expt, var); //calcola la kurtosi
f_x=m_x*log(1+k_x); //calcola la caratteristica(feature) f_x: la
kurtosi migliorata
n=number_iteration(n_prec); //parametro che tiene conto del numero
di iterazioni e utilizzato per gamma_t
gamma_t=pow(n,-Alpha); //calcola gamma di t: parametro che agisce
sulla velocità di convergenza dell'algoritmo EM online
//filtro iir del terzo ordine per la kurtosi migliorata necessario
per effettuare una decisione efficiente
f_x_p=(((f_x_p2+f_x_p1)/2+f_x_p)/2+f_x)/2;
f_x_p2=f_x_p1;
f_x_p1=f_x_p;
em_online(f_x, gamma_t, &par_p, &par); //esegue un passo
dell'algoritmo em online
decisione( par, OutputBuffer, InputBuffer, f_x_p, p1, p2, p3);
//esegue la decisione sul tipo di classe (parlato o non parlato)
ParUpdate( &par, &par_p); //aggiorna i parametri per l'iterazione
successiva
n_prec=n; //memorizza il valore di iterazione per il ciclo
successivo
}; //fine if
}; //fine while
index_i=0;
return COMPLETED;
}
void __stdcall PlugIn::LEPlugin_Init()
{
//va caricata qui l'allocazione e l'inizializzazione dei vettori;
//non serve allocare variabili perchè sono già iniziallizzate nello stack (come
le variabili di tipo struttura)
WorkBuffer = (double*) malloc((2*WORK_BUFFERSIZE)*sizeof(double));
InputBufferOld = (double*) malloc(WORK_BUFFERSIZE*sizeof(double));
InputBuffer = (double*) malloc(WORK_BUFFERSIZE*sizeof(double));
OutputBuffer = (double*) malloc(WORK_BUFFERSIZE*sizeof(double));
AutocorrWB =
(double*) malloc((ORDERLPC+1)*sizeof(double));
AutocorrWB_32f =
(float*) malloc((ORDERLPC+1)*sizeof(float));
LPCcoeff_32f = (float*) malloc((ORDERLPC+1)*sizeof(float));
LPCcoeff =
(double*) malloc((ORDERLPC+1)*sizeof(double));
RC_lpc = (float*) malloc((ORDERLPC)*sizeof(float));
pRREnergy = (float*) malloc((ORDERLPC+1)*sizeof(float));
114
FIRcoeff =
(double*) malloc((ORDERLPC+1)*sizeof(double));
speechLPC = (double*) malloc((2*WORK_BUFFERSIZE)*sizeof(double));
ResidualLPC = (double*) malloc((2*WORK_BUFFERSIZE)*sizeof(double));
AutC = (double*) malloc((2*WORK_BUFFERSIZE)*sizeof(double));
val_int = (double*) malloc((2*WORK_BUFFERSIZE)*sizeof(double));
p_gauss = (double*) malloc(2*sizeof(double));
P_i = (double*) malloc(2*sizeof(double));
p1 = (double*) malloc(2*sizeof(double));
p2 = (double*) malloc(2*sizeof(double));
p3 = (double*) malloc(2*sizeof(double));
ippsZero_64f(WorkBuffer, 2*WORK_BUFFERSIZE);
ippsZero_64f(InputBufferOld, WORK_BUFFERSIZE);
ippsZero_64f(InputBuffer, WORK_BUFFERSIZE);
ippsZero_64f(AutocorrWB, ORDERLPC+1);
ippsZero_32f(AutocorrWB_32f, ORDERLPC+1);
ippsZero_32f(LPCcoeff_32f, ORDERLPC+1);
ippsZero_64f(LPCcoeff, ORDERLPC+1);
ippsZero_32f(RC_lpc, ORDERLPC); //La funzione LPC la dà comunque in uscita ma non
serve nel nostro caso
ippsZero_32f(pRREnergy, ORDERLPC+1); //La funzione LPC la dà comunque in uscita
ma non serve nel nostro caso
n_prec=1;
gamma_t=0;
psum=0;
p_gauss[0]=0;
p_gauss[1]=0;
p1[0]=0;
p1[1]=0;
p2[0]=0;
p2[1]=0;
p3[0]=0;
p3[1]=0;
P_i[0]=0;
P_i[1]=0;
m_x=0;
expt=0;
var=0;
k_x=0;
f_x=0;
f_x_p=0;
f_x_p1=0;
f_x_p2=0;
par_p.mu[0]=0.050000000000;
par_p.variance[0]=0.155000000000;
par_p.X_t[0]=0.020;
par_p.chi[0]=0.40;
par_p.X_t_quadro[0]=0.06450;
par_p.mu[1]=0.800000000000;
par_p.variance[1]=1.900000000000;
par_p.X_t[1]=0.480;
par_p.chi[1]=0.60;
par_p.X_t_quadro[1]=1.780;
}
void __stdcall PlugIn::LEPlugin_Delete()
{
free(WorkBuffer);
free(InputBufferOld);
free(InputBuffer);
free(OutputBuffer);
115
free(AutocorrWB);
free(AutocorrWB_32f);
free(LPCcoeff_32f);
free(LPCcoeff);
free(RC_lpc);
free(pRREnergy);
free(FIRcoeff);
free(speechLPC);
free(ResidualLPC);
free(AutC);
free(val_int);
free(p_gauss);
free(P_i);
free(p1);
free(p2);
free(p3);
}
bool __stdcall PlugIn::LEInfoIO(int index,int type, char *StrInfo)
{
if ((type==INPUT) && (index==0)) sprintf(StrInfo,"Speech[%d]",index);
if ((type==OUTPUT) && (index==0)) sprintf(StrInfo,"VAD[%d]",index);
return true;
}
void __stdcall PlugIn::LESetName(char *Name)
{
strncpy(Name,"VADonHOS",MAXNAME);
}
double PlugIn::SetAlphaValue(double NewValue)
{
if (NewValue!=Alpha)
{
CBFunction(this,NUTS_GETSECURETIME,NUTSSECURE,0);
Alpha=NewValue;
CBFunction(this,NUTS_RELEASESECURETIME,NUTSSECURE,0);
CBFunction(this,NUTS_UPDATERTWATCH,IDXALPHA,0);
}
return Alpha;
}
double PlugIn::SetThresholdValue(double NewValue1)
{
if (NewValue1!=Threshold)
{
CBFunction(this,NUTS_GETSECURETIME,NUTSSECURE,0);
Threshold=NewValue1;
CBFunction(this,NUTS_RELEASESECURETIME,NUTSSECURE,0);
CBFunction(this,NUTS_UPDATERTWATCH,IDXTHRESHOLD,0);
}
return Threshold;
}
double PlugIn::GetAlphaValue()
{
return Alpha;
}
116
double PlugIn::GetThresholdValue()
{
return Threshold;
}
void __stdcall PlugIn::LESetParameter(int Index,void *Data,LPVOID bBroadCastInfo)
{
if (Index==IDXALPHA)
{
double NewValue=*((double*)Data);
SetAlphaValue(NewValue);
}
if (Index==IDXTHRESHOLD)
{
double NewValue1=*((double*)Data);
SetThresholdValue(NewValue1);
}
}
int
{
__stdcall PlugIn::LEGetParameter(int Index,void *Data)
if (Index==IDXALPHA)
{
*((double*)Data)=GetAlphaValue();
}
if (Index==IDXTHRESHOLD)
{
*((double*)Data)=GetThresholdValue();
}
return 0;
}
void __stdcall PlugIn::LESaveSetUp()
{
double AlphaTmp=GetAlphaValue();
CBFunction(this,NUTS_WRITEFILE,sizeof(double),&AlphaTmp);
double ThresholdTmp=GetThresholdValue();
CBFunction(this,NUTS_WRITEFILE,sizeof(double),&ThresholdTmp);
}
void __stdcall PlugIn::LELoadSetUp()
{
double AlphaTmp;
CBFunction(this,NUTS_READFILE,sizeof(double),&AlphaTmp);
SetAlphaValue(AlphaTmp);
double ThresholdTmp;
CBFunction(this,NUTS_READFILE,sizeof(double),&ThresholdTmp);
SetThresholdValue(ThresholdTmp);
}
void __stdcall PlugIn::LERTWatchInit()
{
WatchType NewWatch;
memset(&NewWatch,0,sizeof(WatchType));
NewWatch.EnableWrite=true;
NewWatch.LenByte=sizeof(double);
NewWatch.TypeVar=WTC_DOUBLE;
NewWatch.IDVar=IDXALPHA;
sprintf(NewWatch.VarName,"Alpha");
CBFunction(this,NUTS_ADDRTWATCH,0,(LPVOID)&NewWatch);
WatchType NewWatch1;
memset(&NewWatch1,0,sizeof(WatchType));
NewWatch1.EnableWrite=true;
NewWatch1.LenByte=sizeof(double);
NewWatch1.TypeVar=WTC_DOUBLE;
NewWatch1.IDVar=IDXTHRESHOLD;
sprintf(NewWatch1.VarName,"Threshold");
117
CBFunction(this,NUTS_ADDRTWATCH,0,(LPVOID)&NewWatch1);
}
118
Bibliografia
[1] D. Cournapeau and T. Kawahara “Voice Activity Detection Based on High Order
Statistics and Online EM Algorithm” IEICE Trans. Inf. & Syst., Vol. E91–D, NO.12
December 2008.
[2] L.R. Rabiner and B.H. Juang, “Fundamentals of speech recognition” Prentice Hall,
1993.
[3] B. Kingsbury, G. Saon, L. Mangu, M. Padmanabhan, and R. Sarikaya, “Robust
speech recognition in noisy environments: The 2001 IBM Spine evaluation system”
ICASSP, 2002.
[4] G. Lathoud and I. McCowan, “Location based speaker segmentation" Proc. 2003
IEEE International Conference on Acoustics, Speech, and Signal Processing
(ICASSP-03), 2003.
[5] T. Pfau, D. Ellis, and A. Stolcke, “Multispeaker speech activity detection for the
ICSI meeting recorder” Proc. IEEE Automatic Speech Recognition and
Understanding Workshop, 2001.
[6] E. Nemer, R. Goubran, and S. Mahmoud, “Robust voice activity detection using
higher-order statistics in the LPC residual domain” IEEE Trans. Speech Audio
Process., vol.9, no.3, pp.217–231, 2001.
[7] K. Li, M.S.S. Swamy, and M.O. Ahmad, “An improved voice activity detection
using high order statistics” IEEE Trans. Speech Audio Process., vol.13, no.5,
pp.965–974, 2005.
[8] R.J. McAulay and T.F. Quatieri, “Speech analysis/synthesis based on a sinusoidal
representation” IEEE Trans. Acoust. Speech Signal Process., vol.34, no.4, pp.744–
754, 1986.
[9] “ITU-T: A silence compression scheme for G.729 optimized for terminals
conforming to recommendation v.70, annex B.” Nov. 1996.
[10] N. Kitaoka, T. Yamada, S. Tsuge, C. Miyajima, T. Nishiura, M. Nakayama, Y.
Denda,M. Fujimoto, K. Yamamoto, T. Takiguchi, and S. Nakamura, “CENSREC-1-
C: Development of evaluation framework for voice activity detection under noisy
environment” IPSJ SIG Technical Report, 2006.
[11] S. Ahmadi and A.S. Spanias, “Cepstrum-based pitch detection using a new
statistical V/UV classification algorithm” IEEE Trans. Speech Audio Process., vol.7,
no.3, pp.333–338, May 1999.
[12] J.K. Shah, A.N. Iyer, B.Y. Smolenski, and R.E. Yantorno, “Robust voiced unvoiced classification using novel features and Gaussian mixture model” IEEE
ICASSP’04, 2004.
[13] Q. Li, J. Zheng, Q. Zhou, and C.H. Lee, “A robust, real-time endpoint detector with
energy normalization for ASR in adverse environments” ICASSP01, IEEE, 2001.
[14] L.T. DeCarlo, “On the meaning and use of kurtosis” Psychological Method, vol.2,
pp.292–303, 1997.
[15] H.M. Finucan, “A note on kurtosis” J. Royal Statistical Society. Series B
(Methodological), vol.26, pp.111–112, 1964.
[16] S. Basu, “A linked-HMM model for robust voicing and speech detection” IEEE
Int. Conf. Acoustics, Speech, and Signal Processing (ICASSP ’03), 2003.
[17] I. Shafran and R. Rose, “Robust speech detection and segmentation for real-time
ASR applications” IEEE Int. Conf. Acoustics, Speech, and Signal Processing
(ICASSP ’03), pp.432–435, 2003.
[18] A.P. Dempster, N.M. Laird, and D.B. Rubin, “Maximum likelihood from
incomplete data via the EM algorithm” J. Royal Statistical Society. Series B
(Methodological), vol.39, pp.1–38, 1977.
[19] O. Cappe, M. Charbit, and E. Moulines, “Recursive EM algorithm with
applications to DOA estimation” Proc. 2006 IEEE International Conference on
Acoustics, Speech, and Signal Processing, ICASSP 2006, 2006.
[20] M. Sato and S. Ishii, “On-line EM algorithm for the normalized Gaussian network”
Neural Comput., vol.12, pp.407–432, 2000.
[21] H.J. Kushner and G.G. Yin, Stochastic approximation algorithms and applications,
Springer-Verlag, 1997.
[22] Levinson N., The Wiener Root Mean Square (RMS) Error Criterion in Filter
Design and Prediction, Journal of Mathematics and Physics, vol. 25, pp. 214-218,
1947.
120
[23] Russell Stuart J., Norvig Peter, “Intelligenza artificiale – Un approccio moderno”
vol. 2, Pearson Education Italia.
[24] Deitel H., Deitel P., “C corso completo di programmazione” Apogeo.
121