rilevare il numero di picchi nella registrazione audio


12

Sto cercando di capire come rilevare il numero di sillabe in un corpus di registrazioni audio. Penso che un buon proxy potrebbe essere un picco nel file wave.

Ecco cosa ho provato con un file di me che parlavo in inglese (il mio caso d'uso reale è in Kiswahili). La trascrizione di questo esempio di registrazione è: "Sono io che sto cercando di usare la funzione timer. Sto guardando pause, vocalizzazioni". Ci sono un totale di 22 sillabe in questo passaggio.

file wav: https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0

Il seewavepacchetto in R è eccezionale e ci sono diverse potenziali funzioni. Per prima cosa, importa il file wave.

library(seewave)
library(tuneR)
w <- readWave("YOURPATHHERE/test.wav")  
w
# Wave Object
# Number of Samples:      278528
# Duration (seconds):     6.32
# Samplingrate (Hertz):   44100
# Channels (Mono/Stereo): Stereo
# PCM (integer format):   TRUE
# Bit (8/16/24/32/64):    16

La prima cosa che ho provato è stata la timer()funzione. Una delle cose che restituisce è la durata di ogni vocalizzazione. Questa funzione identifica 7 vocalizzazioni, che è di gran lunga inferiore a 22 sillabe. Un rapido sguardo alla trama suggerisce che le vocalizzazioni non eguagliano le sillabe.

t <- timer(w, threshold=2, msmooth=c(400,90), dmin=0.1)
length(t$s)
# [1] 7

inserisci qui la descrizione dell'immagine

Ho anche provato la funzione fpeaks senza impostare una soglia. Ha restituito 54 picchi.

ms <- meanspec(w)
peaks <- fpeaks(ms)

inserisci qui la descrizione dell'immagine

Questo traccia l'ampiezza in base alla frequenza anziché al tempo. L'aggiunta di un parametro di soglia pari a 0,005 filtra il rumore e riduce il conteggio a 23 picchi, che è abbastanza vicino al numero effettivo di sillabe (22).

inserisci qui la descrizione dell'immagine

Non sono sicuro che questo sia l'approccio migliore. Il risultato sarà sensibile al valore del parametro di soglia e devo elaborare un grosso batch di file. Qualche idea migliore su come codificare questo per rilevare picchi che rappresentano sillabe?


2
Questa è una domanda molto interessante, ma potresti ottenere un migliore aiuto sui metodi nel sito di domande e risposte sull'elaborazione del segnale di scambio di stack .
eipi10,

ok grazie. lo verificherà se nessuno risponde. molto apprezzato.
Eric Green,

Solo un'idea, ma varrebbe la pena prendere in considerazione l' analisi del punto di cambiamento ? L'analisi può essere effettuata facilmente in R con l'uso del changepointpacchetto. In poche parole, l'analisi del punto di cambiamento si concentra sul rilevamento del cambiamento, l'esempio collegato riguarda i dati commerciali, ma potrebbe essere interessante applicare questa tecnica a dati validi.
Konrad,

Accetterò la risposta che ha il maggior numero di voti, che sembra essere il mio tentativo di implementare un'altra idea CV. Penso che la domanda principale rimanga comunque: come utilizzare le caratteristiche delle registrazioni per rilevare con precisione un numero di picchi che corrisponde al numero di sillabe pronunciate. Grazie per tutte le idee. Riporterò post qui quando avrò una soluzione.
Eric Green,

Risposte:


5

Non credo che ciò che segue sia la soluzione migliore, ma @ eipi10 ha avuto un buon suggerimento per dare un'occhiata a questa risposta su CrossValidated . Così ho fatto.

Un approccio generale consiste nel livellare i dati e quindi trovare i picchi confrontando un filtro massimo locale con il liscio.

Il primo passo è creare la argmaxfunzione:

argmax <- function(x, y, w=1, ...) {
  require(zoo)
  n <- length(y)
  y.smooth <- loess(y ~ x, ...)$fitted
  y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
  delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
  i.max <- which(delta <= 0) + w
  list(x=x[i.max], i=i.max, y.hat=y.smooth)
}

Il suo valore di ritorno include gli argomenti dei massimi locali (x) - che risponde alla domanda - e gli indici negli array x e y in cui si verificano quei massimi locali (i).

Ho apportato lievi modifiche alla testfunzione di stampa: (a) per definire esplicitamente xey e (b) per mostrare il numero di picchi:

test <- function(x, y, w, span) {
  peaks <- argmax(x, y, w=w, span=span)

  plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", 
                                              span, ", peaks = ", 
                                              length(peaks$x), sep=""))
  lines(x, peaks$y.hat,  lwd=2) #$
  y.min <- min(y)
  sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
                                    col="Red", lty=2))
  points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}

Come l' fpeaksapproccio che ho citato nella mia domanda iniziale, anche questo approccio richiede una buona messa a punto. Non saprò la risposta "giusta" (cioè il numero di sillabe / picchi) in questo, quindi non sono sicuro di come definire una regola di decisione.

par(mfrow=c(3,1))
test(ms[,1], ms[,2], 2, 0.01)
test(ms[,1], ms[,2], 2, 0.045)
test(ms[,1], ms[,2], 2, 0.05)

inserisci qui la descrizione dell'immagine

A questo punto mi fpeakssembra un po 'meno complicato, ma ancora non soddisfacente.


Potrebbe non essere soddisfacente perché i parametri di loess non eseguono un livellamento sufficiente. La scelta di un prodotto più fluido deve essere guidata dalla natura dei dati e degli obiettivi; non è qualcosa da lasciare a tutto ciò che viene offerto dalla piattaforma informatica e ai valori predefiniti che fornisce.
whuber

Queste non sono impostazioni predefinite. Solo esempi. Sono perplesso dalla più grande sfida dell'apprendimento senza supervisione in questo caso. Non conosco il numero di sillabe nelle registrazioni, quindi non sono sicuro di come ottimizzare un batch di file. I parametri costanti probabilmente non hanno senso, ma non sono sicuro di come impostare alcune altre regole di decisione (ad esempio, altre metriche dell'onda che potrebbero essere utilizzate per determinare i valori ottimali per questi parametri). Sto pensando di dover creare un set di training che aiuti alcuni algoritmi a impostare questi parametri. Non sono sicuro però.
Eric Green,

Nel tuo comando loess, non vedo argomenti esplicitamente dati per il grado di smoothing. In realtà, è inutile far correre loess su una finestra mobile: lo fa già internamente.
whuber

Vedo il tuo punto. Ho pensato che wfosse un argomento nel livellare. Ecco come l'autore della soluzione originale ha descritto la funzione: "Esistono due parametri da sintonizzare sulle circostanze: w è la mezza larghezza della finestra utilizzata per calcolare il massimo locale ... Un altro - non esplicito in questo codice - è l'argomento span del loess più fluido. "
Eric Green,

Quell'autore ha incluso wuno dei parametri perché aveva in mente un approccio molto generale in cui il più fluido potrebbe non essere loess ma potrebbe essere una mediana a finestre, o Hanning, o qualsiasi altra cosa ritenuta appropriata per il comportamento statistico dei dati e obiettivi dell'analista. Le proprietà di molti di questi levigatori dipendono dalla larghezza della finestra.
whuber

1

Ho avuto problemi simili per analizzare i profili di elettroforesi delle proteine. Li ho risolti applicando alcune delle funzioni del pacchetto msprocess R sui secondi derivati ​​dei profili (vedi https://fr.wikipedia.org/wiki/D%C3%A9pouillement_d 'une_courbe # Position_et_hauteur_du_pic). Questo è stato pubblicato qui: http://onlinelibrary.wiley.com/doi/10.1111/1755-0998.12389/abstract;jsessionid=8EE0B64238728C0979FF71C576884771.f02t03

Non ho idea se una soluzione simile possa funzionare per te. In bocca al lupo


grazie, @ user17493.bis. complimenti a te per la pubblicazione con materiale supplementare. mi renderà molto più semplice provare questa idea!
Eric Green,

0

Ecco una libreria in Python che ho usato prima mentre cercavo di stimare la periodicità trovando picchi nella funzione di autocorrelazione.

Utilizza differenze del primo ordine / derivate discrete per il rilevamento dei picchi e supporta la sintonizzazione mediante parametri di soglia e distanza minima (tra picchi consecutivi). Si può anche migliorare la risoluzione di picco usando la stima e l'interpolazione della densità gaussiana (vedi link).

Per me ha funzionato abbastanza bene senza molte modifiche, anche per i dati rumorosi. Provaci.


Grazie, @ tool.ish. Sembra una buona alternativa ai metodi R che ho citato. Penso che avrei comunque la sfida di messa a punto, comunque.
Eric Green,

0

Vorrei suggerire una soluzione utilizzando il changepointpacchetto. L'esempio semplicistico di seguito tenta di identificare i picchi, qui definiti come punti di cambiamento osservando un canale dai dati disponibili.

Esempio

Approvvigionamento di dati

# Libs
library(seewave)
library(tuneR)

# Download
tmpWav <- tempfile(fileext = ".wav")
download.file(url = "https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0",
              destfile = tmpWav)

# Read
w <- readWave(filename = tmpWav)

Preparazione dei dati

# Libs
require(changepoint)

# Create time series data for one channel as an example
leftTS <- ts(data = w@left)

## Preview
plot.ts(leftTS)

Grafico generato tramite la plot.tschiamata: Canale come serie storica

Analisi del punto di cambiamento

Il changepointpacchetto offre una serie di opzioni per identificare cambiamenti / picchi nei dati. Il codice seguente fornisce solo un semplice esempio di ricerca di 3 picchi usando il metodo BinSeg :

# BinSeg method (example)
leftTSpelt <- cpt.var(data = leftTS, method = "BinSeg", penalty = "BIC", Q = 3)
## Preview
plot(leftTSpelt, cpt.width = 3)

Grafico ottenuto: Alcuni punti di cambiamento è anche possibile ottenere valori:

cpts(leftTSpelt)
[1]  89582 165572 181053

Note a margine

L'esempio fornito riguarda principalmente l'illustrazione di come l'analisi del punto di cambiamento può essere applicata ai dati forniti; occorre prestare attenzione rispetto ai parametri passati alla cp.varfunzione. Una spiegazione dettagliata del pacchetto e delle funzionalità disponibili è riportata nel seguente documento:

Killick, Rebecca ed Eckley, Idris (2014) changepoint: un pacchetto R per l'analisi del changepoint. Journal of Statistical Software, 58 (3). pagine 1-19.

ecp

ecp, vale la pena menzionare un altro pacchetto R. L' ecpanalisi punto di cambio facilita impegno di non-parametrica multivariata, che può essere utile se l'vorrebbe identificare i punti di cambiamento che avviene attraverso canali multipli.


Grazie @konrad. Non sapevo di nessuno dei due pacchetti, quindi grazie per aver dedicato del tempo alla demo. Penso che la sfida fondamentale che ho con tutti questi pacchetti sia quella di non sapere quanti picchi cercare, quindi non sono sicuro di come ottimizzare i parametri. Questa sembra ancora una situazione in cui devo usare alcuni algoritmi per determinare come impostare i parametri per identificare con precisione il numero corretto di picchi (es. Sillabe).
Eric Green,

@EricGreen In linea di principio l'analisi del punto di cambio ti consentirebbe di identificare i tuoi picchi semplicemente guardando la distribuzione. Si tratterebbe di applicare un metodo adeguato, sanzioni e così via. Suggerirei di dare un'occhiata al sito Web collegato nel mio commento precedente in quanto delinea il processo in dettaglio.
Konrad,

Non sono sicuro se intendi letteralmente bulbo oculare della distribuzione. Ho 2000 file e ho bisogno di un modo per automatizzare questo. Anche se potessi esaminare ogni file, trovo difficile vedere il numero di sillabe come picchi. Forse sono denso e verrò a vedere i meriti di questo approccio. Sono ancora bloccato sulla necessità di un modo per sintonizzare automaticamente i parametri di ciascun file, quindi il numero risultante di picchi rilevati è un proxy accurato per il numero di sillabe.
Eric Green,

@EricGreen No, non letterario ovviamente. Se capisci i parametri appropriati che dovrebbero essere passati a una delle funzioni cpt sarai in grado di eseguirlo su un numero qualsiasi di oggetti. Dato che non ho esperienza in linguistica, non so se le sillabe corrisponderebbero ai soliti picchi osservati sui dati delle serie storiche.
Konrad,

Gotcha. Penso di essermi imbattuto nel passaggio "capire i parametri appropriati" per questo caso d'uso specifico. Ma ho apprezzato tutte le idee e ho appreso alcuni nuovi pacchetti che potrebbero essere buone alternative a quelli che ho provato.
Eric Green,
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.