Il modo più semplice per rilevare dove iniziano e si fermano le buste audio


43

Di seguito è riportato un segnale che rappresenta una registrazione di qualcuno che parla. Vorrei creare una serie di segnali audio più piccoli basati su questo. L'idea è di rilevare quando il suono "importante" inizia e finisce e usare quelli per i marcatori per creare un nuovo frammento di audio. In altre parole, vorrei usare il silenzio come indicatore di quando un "blocco" audio è stato avviato o interrotto e creare nuovi buffer audio basati su questo.

Quindi, ad esempio, se una persona si registra dicendo

Hi [some silence] My name is Bob [some silence] How are you?

quindi vorrei fare tre clip audio da questo. Uno che dice Hi, uno che dice My name is Bobe uno che dice How are you?.

La mia idea iniziale è quella di passare attraverso il buffer audio controllando costantemente dove ci sono aree di bassa ampiezza. Forse potrei farlo prendendo i primi dieci campioni, calcolando la media dei valori e se il risultato è basso, etichettarlo come silenzioso. Procederei nel buffer controllando i successivi dieci campioni. Incrementando in questo modo ho potuto rilevare dove iniziano e si fermano le buste.

Se qualcuno ha qualche consiglio su un modo buono, ma semplice per farlo, sarebbe fantastico. Per i miei scopi la soluzione può essere abbastanza rudimentale.

Non sono un professionista in DSP, ma capisco alcuni concetti di base. Inoltre, lo farei a livello di codice, quindi sarebbe meglio parlare di algoritmi e campioni digitali.

Grazie per tutto l'aiuto!

inserisci qui la descrizione dell'immagine


MODIFICA 1

Grandi risposte finora! Volevo solo chiarire che questo non è sull'audio dal vivo e scriverò io stesso gli algoritmi in C o Objective-C, quindi tutte le soluzioni che usano le librerie non sono davvero un'opzione.


1
Sembra che tu stia provando a romperlo usando periodi di silenzio come punti di interruzione. Perché non usare semplicemente la soglia di potenza per determinare il "silenzio" e avere un tempo di soglia per determinare se è abbastanza lungo da costituire una rottura?
Jim Clay,

@JimClay Sì, è esattamente quello che sto cercando di fare. Non ho mai sentito parlare della soglia di potenza, ma sembra qualcosa che potrei usare. È complicato? Potresti ampliarlo un po '?
Eric Brotto,

@EricBrotto Forse dovresti dirci qualcosa sulle capacità che hai nelle tue librerie. Ciò ci consentirà di massaggiare meglio la metodologia attuale.
Spacey,

questo approccio per il rilevamento del silenzio è migliore di ciò che dovrebbe essere il livello di guardia diverso da 0,05 x = wavread ('s1.wav'); i = 1; mentre abs (x (i)) <0,05% Rilevazione del silenzio i = i + 1; fine x (1: i) = []; x (6000: 10000) = 0;
Zeee,

Risposte:


26

Questo è il classico problema del rilevamento vocale . La prima cosa da fare sarebbe il concetto di Google. È ampiamente usato nella comunicazione digitale e ci sono state molte ricerche condotte sull'argomento e ci sono buoni documenti là fuori.

In generale, maggiore è il rumore di fondo che devi affrontare, più elaborato deve essere il tuo metodo di rilevazione vocale. Se stai usando registrazioni registrate in una stanza tranquilla, puoi farlo molto facilmente (più tardi). Se hai rumori di ogni genere mentre qualcuno parla (camion che passano, cani che abbaiano, piatti che si rompono, alieni che attaccano), dovrai usare qualcosa di molto più intelligente.

Guardando la forma d'onda che hai attaccato, il tuo rumore è minimo, quindi suggerisco quanto segue:

  1. Estrai inviluppo del segnale
  2. Scegli una buona soglia
  3. Rileva i luoghi in cui la grandezza dell'inviluppo supera la soglia

Cosa significa tutto questo? Un inviluppo di un segnale è una curva che descrive la sua grandezza nel tempo, indipendentemente da come il suo contenuto di frequenza lo fa oscillare (vedi immagine sotto).

inserisci qui la descrizione dell'immagine

L'estrazione della busta può essere eseguita creando un nuovo segnale che contiene valori assoluti del segnale originale, ad esempio diventa e quindi passa-basso filtrando il risultato. Il filtro passa-basso più semplice può essere implementato sostituendo ciascun valore del campione con una media dei suoi N vicini su entrambi i lati. Il miglior valore di N può essere trovato sperimentalmente e può dipendere da diversi fattori come la frequenza di campionamento.{1,45,6,2,43,2}{1,45,6,2,43,2}

Dall'immagine puoi vedere che non hai molto rumore presente, l'inviluppo del segnale sarà sempre al di sopra di una certa soglia (livello di intensità) e puoi considerare quelle regioni come regioni rilevate dal parlato .


3
In realtà l'avevo implementato come uno dei plug-in di Good'ol Winamp. Quello che stai descrivendo è buono ma non sufficiente. Di solito ci sono suoni sonori (vocali) e suoni non sonori (consonenti). Se ci fosse solo un suono espresso, ciò che stai descrivendo funzionerà, ma i suoni non emessi sono a bassissima energia e non sono del tutto distinguibili dal rumore generale. E anche le condizioni di non rumore sono molto rare anche negli studi.
Dipan Mehta,

come raggiungere questo obiettivo in Python?
kRazzy R,

26

Quello che vuoi veramente fare è essenzialmente chiamato Voice Activity Detection o rilevamento vocale.

Fondamentalmente qualsiasi segnale vocale puro (che non contiene musica) ha tre parti.

  1. Il suono espresso - che è fondamentalmente causato da Vowels
  2. Il suono non emesso - che contiene consonanti.

La caratteristica del suono umano è tale che mentre molta energia viene utilizzata nel suono espresso, le informazioni reali sono contenute nelle consonanti. Inoltre, il suono espresso è di solito una frequenza più bassa, mentre i suoni non emessi sono frequenze più alte. [Per essere precisi, tutti i suoni sonori sono risuonati più o meno una frequenza costante per una determinata persona che è il suo tono].

Ora, come qualsiasi sistema, c'è del rumore. Il suono espresso è di solito abbastanza potente da poter essere distinto visibile. Quando si applica un filtro a frequenza inferiore, è possibile raccogliere una buona ampiezza di suoni sonori, tuttavia il suono non sonoro (con tutte le informazioni utili) andrà perso.

Venendo alla domanda come risolverlo:

Il trucco sta nel fatto che il suono non emesso proviene ancora da una sorgente risonante; e intrinsecamente limitato su una certa frequenza. Dove, il rumore è piuttosto uniforme. Quindi una semplice misura che distingue tutti e tre è il "potere locale" o in alternativa, ma l'equivalente è prendere l'auto-correlazione finestrata.

Se prendi alla volta 100 campioni - e ti auto correli, se contiene solo rumore i risultati saranno praticamente zero (questa è la proprietà del rumore bianco) dove per quanto riguarda il segnale vocale, questa grandezza sarà osservabile perché il segnale ha ancora una struttura migliore. Questo ha funzionato per me in passato.

VAD è stata un'area di ricerca attiva, perché quasi tutte le comunicazioni di telefonia mobile vogliono rilevare parti non vocali e rimuoverle dalla codifica. Ma se eliminassero i discorsi non espressi ciò renderebbe inutile la telefonia.

Lo standard G.729 calcola VAD in base a caratteristiche quali: frequenze spettrali di linea, energia a banda intera, energia a banda bassa (<1 kHz) e velocità di attraversamento zero.

Lo standard GSM funziona come segue: L'opzione 1 calcola il SNR in nove bande e applica una soglia a questi valori. L'opzione 2 calcola diversi parametri: potenza del canale, metriche vocali e potenza del rumore. Quindi soglie le metriche vocali utilizzando una soglia che varia in base al SNR stimato. (da Wikipedia)

Per tecniche più avanzate sto elencando alcuni riferimenti su questo argomento.

  1. Riferimento più situato: Jongseo Sohn; Nam Soo Kim; Wonyong Sung; "Rilevazione dell'attività vocale basata su modelli statistici" Signal Processing Letters, IEEE, gen 1999, Volume: 6 Edizione: 1 pp: 1-3

  2. I più rilevanti per te: Mark Marzinzik e Birger Kollmeier "Rilevazione della pausa del parlato per la stima dello spettro di rumore mediante il monitoraggio della dinamica dell'involucro di potenza" OPERAZIONI IEEE SU DISCORSO AUDIO E SPEECH, VOL. 10, NO. 2, FEBBRAIO 2002 pagg. 109

  3. Ramírez, J .; JM Górriz, JC Segura (2007). "Rilevamento delle attività vocali. Robustezza del sistema di riconoscimento vocale e dei concetti fondamentali". In M. Grimm e K. Kroschel. Riconoscimento e comprensione del parlato. pagg. 1–22. ISBN 978-3-902613-08-0.

  4. Presentazione: Jonathan Kola, Carol Espy-Wilson e Tarun Pruthi "Voice Activity Detection"


come raggiungere questo obiettivo in Python?
kRazzy R,

9

Vorrei assolutamente assecondare Jim Clay nel suo approccio, ma variare leggermente il sapore usando la busta:

Sappiamo che i discorsi si verificano principalmente intorno a 1-2kHz. È probabile che il campionamento dei dati sia di 44 kHz (dipende dal dispositivo di registrazione). Quindi quello che farei per primo è una media mobile del segnale quadrato in tempo reale su 10 punti, per avere un inviluppo della potenza del segnale. Ciò indurrà un ritardo nel rilevamento, quindi tieni basso.

Quindi aggiungerei una fase di calibrazione sul tuo sistema: chiedi all'utente di rimanere in silenzio, premere un pulsante e registrare il rumore di fondo per 10 secondi. Prendi l'ampiezza media o mediana della busta, moltiplica per 2 per avere una sicurezza e questo ti darebbe la soglia di cui Jim ha parlato, automaticamente.

Se non si tratta di una registrazione in tempo reale, potrebbe essere utile utilizzare la media mobile in fase 0 per ridurre il disturbo causato dal ritardo. Dicci se funziona per te così com'è.


9

Eric,

Se stai veramente cercando qualcosa di veloce e sporco, la prima cosa che devi ottenere è la busta, e lo farei semplicemente (in MATLAB):

 envelope = abs(hilbert(yourSignal));

A quel punto, vorrei semplicemente soglia e "la voce esiste" se si supera una determinata soglia.

Questa è una soluzione molto semplice tra l'altro, ma potrebbe funzionare per te.


1
+1. Forse potresti approfondire il metodo alla base di questa riga di codice? Sono sicuro che l'OP non ha familiarità con l'estrazione della busta tramite la trasformazione di Hilbert.
Phonon,

@Mohammad Grazie! Ma per favore, vedi il mio EDIT 1. Vorrei sicuramente essere veloce e sporco, ma ho anche bisogno di fare da solo gli algoritmi :)
Eric Brotto,

@EricBrotto Ah ok, bene, posso dirti come implementare un trasformatore Hilbert, ma suppongo che tu abbia la capacità di fare un FFT nelle tue librerie C / Obj-C? Altrimenti questo sarà un problema ... :-)
Spacey,

come raggiungere questo obiettivo in Python?
kRazzy R,

Gentile Signore / Signora, potresti indicarmi le risorse su come implementare questo Hilbert in Python?
kRazzy R

6

Presumo che tu abbia a che fare con segnali reali, non complessi, se non è così, fammi sapere e posso modificare la risposta.

La potenza è definita come il quadrato del segnale (ovvero i campioni di segnale moltiplicati per se stessi). È possibile confrontare la potenza con una certa soglia per determinare se è presente il parlato o meno. Probabilmente avresti bisogno di fare alcune misurazioni sulle tue registrazioni per trovare empiricamente una buona soglia.

Se le tue registrazioni sono "pulite" (cioè non molto rumore), probabilmente andrei il più semplice possibile confrontando la potenza istantanea (cioè un singolo campione) con la soglia. Ciò significa che non è nemmeno necessario quadrarlo se non lo si desidera, è sufficiente il valore assoluto e confrontarlo con la radice quadrata della soglia di potenza, che può essere pre-calcolata. Quando rilevi un discorso, prendilo e un po 'di registrazione prima di esso, per assicurarti di ottenere tutto il discorso (forse 1/10 di secondo?). Continuare fino a trovare un periodo prolungato di nessun campione che superi la soglia. Ancora una volta, la durata del periodo dovrebbe essere determinata empiricamente.

Risciacqua e ripeti.


4

Ho scritto una classe di rilevatore di attività in Java. Fa parte della mia collezione di DSP Java open source . È possibile utilizzare il programma di test WavSplitter.java per verificarlo con un file WAV come input.


Tieni presente che l'OP afferma specificamente che deve scrivere lui stesso gli algoritmi in C.
Sam Maloney il

È molto facile convertire tali algoritmi da Java a C.
Christian d'Heureuse,

Signore, come raggiungerlo in Python?
kRazzy R,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.