Come determinare la frequenza (in Hertz, tempo reale) con Java Sound

7

Mi sono guardato intorno e ho trovato alcune domande simili alle mie ma non sono mai stato abbastanza soddisfatto delle risposte. Sono più o meno un Java n00b, anche se sono moderatamente esperto di C ++ e mi considero intermedio o avanzato, come programmatore in generale. Sto cercando di scrivere un programma in Java che funzioni in modo simile a un sintonizzatore: quello che voglio fare è registrare il pitch di uno strumento su un intervallo di tempo di 3 secondi e misurare la deviazione media. (Questo è per una classe di banda.)

Quello che sto pensando è che avrò una grande serie di numeri, e ogni voce nell'array sarà un numero in termini di frequenza. Voglio essere in grado di scorrere l'array e calcolare l'Hertz medio per visualizzarlo sullo schermo o qualcosa del genere. Quindi quello che voglio fare è avere un modo di "interrogare" (per mancanza di una parola migliore) il microfono per vedere quale frequenza viene immessa proprio in quell'istante.

C'è un modo semplice per accettare l'input audio da un microfono in termini di Hertz? Questo sarà in Java, sotto una piattaforma Windows.

    
posta Lincoln Bergeson 22.02.2012 - 00:08
fonte

3 risposte

3

Dovrai fare qualche analisi dello spettro. Prendi un breve pezzo di dati audio, forse circa 256 campioni, quindi calcola una veloce trasformata di Fourier (FFT) per ogni pezzo di dati. Tuttavia, una trasformata di Fourier non è sufficiente poiché il processo di riduzione del suono in campioni brevi introduce una certa distorsione. Questa distorsione sarà principalmente nelle frequenze più alte. Per il rilevamento del pitch, è possibile farla franca semplicemente filtrando questa distorsione usando un filtro passa-basso. In alternativa, puoi eseguire il windowing del tuo campione sonoro, solitamente usando le funzioni hanning o blackman window (diverse sinusoidali, in pratica). Per migliorare la risoluzione temporale, dovresti anche sovrapporre i singoli campioni che prendi. Alla fine, dovresti calcolare la media dei tuoi spettri individuali per tutto il tempo che vuoi analizzare.

Fare tutto ciò che ti darà qualcosa chiamato funzione Power Spectral Density. Questo metodo per derivarlo è chiamato il metodo Welch. Quindi, se sei fortunato, Java Sound includerà un metodo per calcolare uno di questi. In molti ambienti di elaborazione del segnale, questo sarebbe chiamato "pwelch" o "psd".

Naturalmente, lo spettro userà le frequenze logaritmiche (modo più punti di frequenza verso le alte frequenze) e le ampiezze molto probabilmente saranno denormalizzate e lineari invece dei semplici valori di dB. Inoltre, dovrai comunque trovare un buon metodo per trovare la frequenza effettiva del tuo pitch tra tutto il rumore armonico ecc.

Quello che voglio dire è questo: o la tua biblioteca ha una funzione semplice che fa esattamente ciò che vuoi o questa roba è probabilmente troppo complessa per avere una risposta facile. Siamo spiacenti.

    
risposta data 22.02.2012 - 15:36
fonte
1

Ti suggerisco di esaminare alcuni tutorial o libri di testo sull'elaborazione del segnale digitale. Quello che stai cercando di fare è in realtà piuttosto complicato. Alcune delle cose che lo rendono complicato sono:

  • I campioni audio verranno inviati dalla scheda audio in campioni PCM (Pulse Code Modulated). Questo è solo un termine di fantasia per i campioni del dominio del tempo. Cioè, l'onda sonora analogica che entra nel microfono viene campionata ad intervalli regolari e ti vengono dati quei numeri come numeri. Questo non ti dà direttamente alcuna informazione sulla frequenza, dovrai eseguire un FFT per trasformare i dati del dominio del tempo nel dominio della frequenza.

  • Anche dopo la FFT, non hai ancora la gamma di frequenze che stai cercando. Quello che hai è una matrice di magnitudini a ciascuna frequenza campionata. Quindi dovrai fare un qualche tipo di rilevamento per determinare quali frequenze sono effettivamente presenti nel tuo segnale. Questa potrebbe essere una semplice soglia e picco di scelta, o qualcosa di più coinvolto.

  • Oltre a questa difficoltà, c'è un compromesso quando si eseguono analisi spettrali con la FFT tra la risoluzione temporale e la frequenza. Se si desidera ottenere una maggiore risoluzione di frequenza, è necessario sacrificare la risoluzione temporale. Ad esempio, se si desidera essere in grado di rilevare una variazione di 1 Hz in un segnale campionato a 44100 Hz, sarà necessario eseguire un FFT di 44100 campioni. Bene, 44100 campioni è un intero secondo di dati, il che significa che anche se è possibile rilevare un segnale a una risoluzione di 1 Hz, non si sa dove sia successo in quel momento. Questo è il motivo per cui molti algoritmi di rilevamento del passo utilizzano metodi del dominio del tempo come l'auto-correlazione per trovare il tono.

  • Un'altra difficoltà è che uno strumento non produce un tono puro (frequenza singola), ma produce anche un certo numero di armoniche. Quindi non avrai solo la vera frequenza di pitch, ma nel segnale ci saranno altre frequenze che dovrai rendere conto.

Tutto questo non è per scoraggiarti dal fare questo progetto, sto solo cercando di delineare alcuni dei problemi che potresti incontrare quando fai il progetto. Ho lavorato a un progetto simile e ho riscontrato questi problemi.

    
risposta data 22.02.2012 - 16:48
fonte
0

Dipende dal formato in cui ottieni i tuoi dati, il modo più efficace è diretto PCM che è veramente solo esempi del flusso sonoro (e ciò che probabilmente otterrai dalla maggior parte delle API dei mouse).

Per ottenere le frequenze da questo devi fourier transform i campioni. Ciò comporterà un insieme di valori (uno per ciascuna frequenza).

    
risposta data 22.02.2012 - 01:40
fonte

Leggi altre domande sui tag