Riconoscimento veloce del tono


8

Ho bisogno di rilevare il tono (misura la frequenza del segnale) mentre i musicisti suonano, dando un avvertimento se sono stonati, ma la musica sembra essere un po 'troppo veloce per FFT (Fast Fourier Transform).

Di seguito provo a fornire una descrizione tecnica del problema.

I musicisti suonano musica a 90-140 bpm. Ciò significa che ci sono 90-140 gruppi di note al minuto, fino a 8 (più frequentemente, fino a 4) note in ciascun gruppo (60/140/8 = 0,0536 sec, 60/90/4 = 0,167 sec), che cioè, le note possono cambiare al ritmo di 6-19 note al secondo.

La musica usa una scala logaritmica (vedi l'immagine allegata): l'intervallo tra, diciamo, 440Hz e 880Hz è diviso in 12 note, di cui solo 7 sono usate per la melodia. (Fondamentalmente, usano solo i tasti bianchi sul piano; quando vogliono spostare la frequenza iniziale, usano alcuni dei tasti neri e non usano alcuni tasti bianchi.) Cioè, la frequenza di ogni nota successiva viene moltiplicata di 2 ^ (1/12) = 1.05946.

Per rendere le cose più complicate, la frequenza A (La) può variare da 438 a 446 Hz. Gli strumenti a corda in teoria possono essere accordati, mentre gli strumenti a fiato dipendono dalla temperatura e dall'umidità dell'aria, quindi la frequenza viene rinegoziata dai musicisti durante il controllo del suono.

A volte musicisti e cantanti commettono errori in frequenza, lo chiamano "stonato". Vogliono un dispositivo che li informi di tali "errori di sintonia". Hanno sintonizzatori, ma i sintonizzatori richiedono di riprodurre lo stesso suono per circa 1 secondo prima di iniziare a mostrare qualcosa. Funziona per l'accordatura, ma non funziona durante la riproduzione della musica.

Molto probabilmente, il sintonizzatore sta facendo FFT, e grazie alla formula df=1/T attende 1 secondo per ottenere la risoluzione 1Hz.

Per A = 440Hz, la differenza di frequenza tra due note è 440 * 0,05946 = 26,16 Hz, per ottenere quella risoluzione di frequenza, si deve usare un tempo di acquisizione di 0,038 sec, cioè a tempo = 196bpm FFT è in grado di distinguere solo due osserva che a 98 bpm è in grado di dire un errore stonato del 50% a condizione che inizi l'acquisizione nel momento stesso in cui il tono cambia. Se permettiamo il cambio di intonazione nel corso di un periodo di acquisizione, otteniamo 49 bpm, che è troppo lento. Inoltre, è molto desiderabile essere più precisi sulla frequenza, per esempio, rilevare un errore stonato del 25% o del 12%.

C'è un modo per misurare la frequenza (rilevare il pitch) meglio di FFT, ovvero con una migliore risoluzione in meno tempo di acquisizione? (Almeno 2 volte meglio, idealmente, 8-16 volte meglio.) In cambio, non ho bisogno di distinguere tra note di ottave diverse, ad esempio sia 440 che 880 possono essere riconosciuti come A. Non ho bisogno della linearità di FFT output, una scala logaritmica sarebbe migliore. (Probabilmente, sono possibili più compromessi, proprio ora non mi viene in mente altro.)

Ecco un disegno davvero buono:

Nota le frequenze collegate da Wikipedia


bel disegno. dovrebbero capovolgerli in modo che i simboli della chiave (e il rigo musicale) siano rivolti a destra. ma poi tutti i numeri di frequenza e periodo e MIDI sarebbero sottosopra.
robert bristow-johnson,

Sembra che tu abbia bisogno di un rilevamento polifonico del tono invece di un rilevamento monofonico (cioè una nota alla volta). È corretto?
Jazzmaniac,

@Jazzmaniac Polyphonic sarebbe sicuramente un vantaggio, cioè monofonico sarebbe una restrizione. Se potessi usare FFT, visualizzerei diversi picchi su un diagramma frequenza-tempo 2D. D'altra parte, se ho capito bene, gli strumenti a fiato sono monofonici e il violino è abbastanza vicino a quello.
18446744073709551615

Gli strumenti a fiato funzionano sicuramente con algoritmi di rilevamento monofonico. Gli strumenti a corda (con più di una corda) sono tuttavia difficili, e la maggior parte se non tutti i rivelatori monofonici producono risultati inaffidabili o addirittura inutilizzabili in presenza di toni in decomposizione da stringhe non perfettamente disattivate, stringhe aperte che risuonano o semplicemente dialogano dal microfono. Detto questo, il rilevamento polifonico è difficile. Tuttavia, poiché non è necessario un rilevamento preciso delle note ma solo un rilevamento accurato, è possibile trovare un algoritmo adatto. Tuttavia, non sarà un rilevatore di tonalità monofonica.
Jazzmaniac,

Questo potrebbe spiegare il downvote della risposta di RBJ, o qualcuno potrebbe essersi offeso dal suo campo di vendite in qualche modo non obiettivo. In ogni caso, non saltare sulla sua nave troppo presto. Ci sono altre opzioni per quello che vuoi, e molto probabilmente anche quelle migliori.
Jazzmaniac,

Risposte:


9

" Esiste un modo per misurare la frequenza (rilevare il pitch) meglio di FFT, ovvero con una risoluzione migliore in meno tempo di acquisizione? "

si C'è. o sono. ci sono molti modi migliori per eseguire il rilevamento del pitch musicale in tempo reale che sono molto, molto meglio che eseguire una FFT.

considerare :

Funzione differenza magnitudo media (AMDF)

Qx[k]=n|x[n]x[nk]|

Funzione differenza quadrata media (ASDF)

Qx[k]=n(x[n]x[nk])2

Funzione di autocorrelazione (AF)

Rx[k]=nx[n]x[nk]

nota che sto giocando a tutto tondo con i limiti della somma.

si noti inoltre che non vi sono ipotesi sulla forma della forma d'onda o sul passaggio per lo zero o altri passaggi per la soglia. l'unica ipotesi è che quando il ritardok è approssimativamente un periodo (o due periodi o qualche altro multiplo intero della durata del periodo), x[n] assomiglia molto x[nk]. quindi l'unica ipotesi è che l'intonazione sia correlata alla frequenza fondamentale di una funzione periodica o quasi periodica (che mi piace chiamare "quasi periodica").

il mio preferito è l'ASDF (e questo è un segreto commerciale sottilmente velato che ho appena annunciato a tutti, ma la gente su comp.dsp lo sapeva già). questi sono tutti domini, AMDF e ASDF sembrano molto simili e ASDF sembra una versione capovolta di AF. stai cercando valori null in AMDF o ASDF o picchi in AF che corrispondano a potenziali lunghezze di periodo dell'input quasi periodico.

ecco un altro paio di trucchi:

  1. puoi sempre correlare il più attuale N campioni contro alcuni N campioni ritardati di k. in questo modo hai a che fare con i dati più recenti possibili nell'applicazione in tempo reale.

  2. non è necessario calcolare la correlazione per ogni ritardo intero k. infatti, poiché ti piace la frequenza di log, la spaziatura è maggiorek potrebbe essere maggiore della spaziatura per minore k.

  3. quando viene trovato un potenziale null (AM_F) o un picco (AF), è possibile calcolare la correlazione per valori interi adiacenti di k.

  4. tra valori interi adiacenti di k, è possibile eseguire l'interpolazione per determinare la posizione del picco con una precisione del campione frazionario. non ti dirò come. Usa la tua immaginazione.

  5. l'intero trucco (e questa è la salsa segreta in cui si applicano segreti commerciali e brevetti IVL) è scegliere il picco o il null corretti quando ci sono più candidati. la scelta del picco o null errato comporterà un "errore di ottava". non ti dirò come farlo. Usa la tua immaginazione.

mandami una e-mail e possiamo discutere dei termini contrattuali se vuoi che io ti progetti un rilevatore di intonazione. molto meglio di YIN, che, secondo me, funziona come una merda.


1
Un commento sul voto negativo sarebbe apprezzato. Se c'è qualcosa che non va, lo voglio sapere. Questa risposta non fornisce alcuna ricetta, ma almeno c'è un elenco di cosa leggere (beh, non sembra una lettura facile, ma è qualcosa di meglio di niente). Per favore non cancellare questa risposta.
18446744073709551615

1
chi cancellerebbe la risposta? me?
robert bristow-johnson,

3

Ho già risposto alla tua domanda qui: /programming/33667275/fast-frequency-measurement/33678202#33678202

Ma, in sintesi, in determinate circostanze, è possibile interpolare un risultato FFT a una risoluzione più fine della spaziatura del cestino FFT, consentendo in tal modo di utilizzare una finestra di dati più corta per una migliore risoluzione temporale.

Ma la frequenza FFT non è la frequenza del tono. E per alcuni strumenti musicali (quelli che producono toni leggermente inarmonici), nemmeno la frequenza della funzione di auto-correlazione (o dei suoi parenti come AMDF). Questo perché il tono è un fenomeno psicoacustico.


due note: se vuoi che il rilevamento del tono sia " veloce ", non consiglierei di farlo nel dominio della frequenza (a meno che forse non stai facendo qualcosa di multi-rate con più FFT. Il motivo per cui sei tu non si può nemmeno iniziare a FFT fino a quando non si ottengono tutti i campioni. per una FFT di lunghezza decente (per ottenere una risoluzione sufficiente a tonalità basse), si è già aspettato, diciamo, 0,1 secondi. (e intensità) sono misure psicoacustiche che a volte correlare bene con le proprietà fisiche come il periodo (e il potere)
.per

ma ho appena eseguito il mio piccolo script matlab su un hit tom registrato e mi è sembrato che il tono restituito sarebbe un valore di nota plausibile.
robert bristow-johnson,
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.