2011-12-29 12 views
6

Sono stato incuriosito da un po 'di tempo quindi ho pensato di postare qui potrei ottenere delle buone risposte.Scrittura software per dire da dove viene il suono (ascolto direzionale)

Quello che so finora:

Gli esseri umani possono utilizzare i loro due orecchie per ottenere non solo quello che suona "suona come" , ma anche dove si sono provenienti da. Pitch è la nota che sentiamo, e qualcosa di simile alla voce umana ha varie piazzole sovrapposti

Quello che mi piacerebbe sapere (non un tono puro .):

Come posso fare sulla scrittura di un programma che può sapere da dove viene il suono? Da un punto di vista teorico avrei bisogno di due microfoni, quindi registrerei i dati del suono che arrivano ai microfoni e memorizzerò i dati audio in modo tale che un secondo di dati audio possa essere messo in una tupla come [streamA, streamB].

Mi sembra che ci possa essere un modo matematico/matematico per calcolare in base all'audio da cui proviene un suono. Mi sembra anche possibile prendere i dati del flusso e addestrare un discente (dargli un campione audio e dirgli da dove proviene l'audio) e farlo classificare l'audio in ingresso in quel modo.

Qual è il modo migliore per fare questo/ci sono buone risorse da cui posso imparare di più sull'argomento?

EDIT:

Esempio:

  front 

sinistra (MIC) x ======== x (MIC) a destra

  back 

          x (sound source should return "back" or "right" or "back right") 

voglio per scrivere un programma che può tornare in avanti/indietro a sinistra/a destra per la maggior parte del suono che sente. Da quanto ho capito dovrebbe essere semplice impostare due microfoni puntati "avanti". Basandomi su questo, sto cercando di capire un modo in cui possiamo triangolare il suono e sapere dove si trova in relazione ai microfoni della sorgente.

+0

Sto indovinando si vuole fare una discreta [correlazione incrociata] (http://en.wikipedia.org/wiki/Cross-correlation) tra i due canali. –

+0

@HotLicks: Questo non ti dice molto. Conoscere il ritardo relativo tra microfono sinistro e destro limita solo la posizione fino alla superficie di un ellissoide. –

+0

BBN fa milioni di dollari vendendo un sistema che fa questo. Non stanno dicendo come, o se lo hanno brevettato. – bmargulies

risposta

5

Se si guarda in documenti di ricerca sugli array di microfoni a più fasi, in particolare quelli utilizzati per il rilevamento della direzione subacquea (ovvero, una grande area di ricerca sui sottomarini durante la guerra fredda), dov'è il suono del motore proveniente da s o possiamo mirare ai siluri?) poi troverai la tecnologia e la matematica necessarie per trovare la posizione di un suono dato due o più ingressi microfonici.

Non è banale, e non qualcosa che potrebbe essere discusso così ampiamente qui, però, quindi non troverete un semplice frammento di codice e/o libreria per fare ciò che vi serve.

Il problema principale è l'eliminazione di echi e ombre. Un metodo semplicistico sarebbe iniziare con un tono singolo, filtrando tutto tranne quel tono, quindi misurando la differenza di fase tra i due microfoni di quel tono. La differenza di fase ti darà molte informazioni sulla posizione del tono.

È quindi possibile scegliere se si vuole affrontare con echi e problemi di multipath (molti dei quali possono essere eliminati rimuovendo tutti, ma il tono più forte) o passare correlando suoni che consistono in qualcosa di diverso da un singolo tono - una persona parlare, o una pausa di vetro, per esempio. Inizia in modo semplice e semplice ed espandi da lì.

+0

grazie adam, questo è quello che stavo cercando. questo argomento è davvero interessante. hm. – Sam

2

Questo è un problema interessante. Non conosco alcun materiale di riferimento per questo, ma ho una certa esperienza nel software audio e nell'elaborazione del segnale che può aiutarti a orientarti nella giusta direzione.

Determinare la direzione della sorgente audio (dove il suono proviene da intorno a) è abbastanza semplice. Ottieni 6 microfoni direzionali e puntali in alto, in basso, davanti, dietro, a sinistra e a destra. Osservando le ampiezze relative dei segnali microfonici in risposta ad un suono, si potrebbe facilmente determinare da quale direzione proviene un particolare suono. Aumentare il numero di microfoni per aumentare la risoluzione.

2 microfoni ti direbbero solo se un suono proviene da destra o da sinistra. Il motivo per cui le tue 2 orecchie possono capire se un suono proviene di fronte o dietro di te, è perché la struttura esterna dell'orecchio modifica il suono a seconda della direzione, che il tuo cervello interpreta e quindi corregge.

+1

Quando perdi l'udito in un orecchio, perdi la capacità di dire la direzione - la struttura esterna dell'orecchio aiuta, ma entrambe le orecchie sono necessarie - http://hearinglosshelp.com/weblog/single-sided-deafness-and-directional -hearing-tricks.php. Il tuo cervello esegue correlazioni e tempi piuttosto complessi tra le due orecchie per determinare la direzione. –

+0

Questa risposta è un po 'fuorviante. Con l'uso di appropriate tecniche binaurali, 2 microfoni possono fornire una stima della posizione in piano 2D (azimuth), non solo su una linea (sinistra-destra). Vedi http://sdac.kaist.ac.kr/upload/paper/ICCAS_2007_Hwang.pdf e altri documenti.Più recentemente è stato dimostrato che una stima dell'elevazione può anche essere ottenuta jp.honda-ri.com/upload/document/entry/20110911/.... La precisione può essere migliorata se alcune ipotesi possono essere fatte sulla fonte, ad es. ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5443663. –

+2

Potrebbe essere un po 'limitato nella portata, ma non lo definirei fuorviante. Mentre il tuo secondo link non funziona, e il tuo terzo link richiede un abbonamento, il primo link discute esperimenti che implicano l'imitazione della struttura dell'orecchio esterno, che ho discusso nella parte finale della risposta. Tuttavia, l'OP chiedeva in primo luogo un metodo per la posizione "formulaico/matematico per calcolare". Emulare il comportamento dell'orecchio esterno richiederebbe hardware specializzato. – Blake

2

La correlazione incrociata è un metodo principale ma presenta alcune specifiche.Esistono diversi approcci che aiutano a rilevare la sorgente con l'array di microfoni in modo efficiente. Alcuni funzionano anche senza calibrazione, alcuni richiedono la calibrazione per adattarsi alla geometria della stanza.

È possibile provare il software open source esistenti per l'attività di localizzazione delle sorgenti

Manyears separazione robot sorgente sonora e la localizzazione https://sourceforge.net/projects/manyears/

toolkit HARK per applicazioni di robotica http://www.ros.org/wiki/hark

+0

grazie:] Dò un'occhiata – Sam

3

Stavo cercando qualcosa di simile e ho scritto una risposta stupida qui che è stata cancellata. Ho avuto alcune idee ma non le ho scritte veramente bene. La cancellazione mi ha dato quell'orgoglio orgoglioso di Internet ferito, quindi ho deciso di provare il problema e penso che abbia funzionato!

In realtà, provare a fare una vera localizzazione a la risposta di Adam Davis è molto difficile, ma fare una location in stile umano (guardare la prima fonte, ignorare gli echi o trattarli come fonti) non è male, penso, anche se non sono un esperto di elaborazione del segnale con qualsiasi mezzo.

Ho letto this e this. Il che mi ha fatto capire che il problema è in realtà quello di trovare il time shift (cross-correlazione) tra due segnali. Da lì si calcola l'angolo usando la velocità del suono. Nota che avrai due soluzioni (anteriore e posteriore).

Le informazioni chiave che ho letto erano in this answer e altre sulla stessa pagina che parla di come eseguire trasformazioni di Fourier veloci in scipy, per trovare la curva di correlazione incrociata.

Fondamentalmente, è necessario importare il file wave in python. Vedi this.

Se il proprio file wave (input) è una tupla con due array numpy (a sinistra, a destra), riempito a zero almeno quanto se stesso (per fermarlo allineato in modo apparente) il codice segue la risposta di Gustavo. Penso che sia necessario riconoscere che i ffts fanno l'ipotesi dell'invarianza del tempo, il che significa che se si desidera ottenere un qualsiasi tipo di tracciamento dei segnali basato sul tempo, è necessario "mordere" piccoli campioni di dati.

Ho portato insieme il seguente codice dalle fonti menzionate.Produrrà un grafico che mostra il ritardo temporale stimato, in frame, da sinistra a destra (negativo/positivo). Per convertire in tempo reale, dividere per la frequenza di campionamento. Se volete sapere che cosa l'angolo è che dovete:

  • assumere tutto ciò che si trova su un piano (senza fattore di altezza)
  • dimenticare la differenza tra suono davanti e quelli dietro (non si può differenziare)

Si consiglia inoltre di utilizzare la distanza tra i due microfoni per assicurarsi che non si ottengano echi (ritardi superiori a quello per il ritardo di 90 gradi).

Mi rendo conto che ho preso molto in prestito qui, quindi grazie a tutti quelli che hanno contribuito inavvertitamente!

import wave 
import struct 
from numpy import array, concatenate, argmax 
from numpy import abs as nabs 
from scipy.signal import fftconvolve 
from matplotlib.pyplot import plot, show 
from math import log 

def crossco(wav): 
    """Returns cross correlation function of the left and right audio. It 
    uses a convolution of left with the right reversed which is the 
    equivalent of a cross-correlation. 
    """ 
    cor = nabs(fftconvolve(wav[0],wav[1][::-1])) 
    return cor 

def trackTD(fname, width, chunksize=5000): 
    track = [] 
    #opens the wave file using pythons built-in wave library 
    wav = wave.open(fname, 'r') 
    #get the info from the file, this is kind of ugly and non-PEPish 
    (nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams() 

    #only loop while you have enough whole chunks left in the wave 
    while wav.tell() < int(nframes/nchannels)-chunksize: 

     #read the audio frames as asequence of bytes 
     frames = wav.readframes(int(chunksize)*nchannels) 

     #construct a list out of that sequence 
     out = struct.unpack_from("%dh" % (chunksize * nchannels), frames) 

     # Convert 2 channels to numpy arrays 
     if nchannels == 2: 
      #the left channel is the 0th and even numbered elements 
      left = array (list (out[0::2])) 
      #the right is all the odd elements 
      right = array (list (out[1::2])) 
     else: 
      left = array (out) 
      right = left 

     #zero pad each channel with zeroes as long as the source 
     left = concatenate((left,[0]*chunksize)) 
     right = concatenate((right,[0]*chunksize)) 

     chunk = (left, right) 

     #if the volume is very low (800 or less), assume 0 degrees 
     if abs(max(left)) < 800 : 
      a = 0.0 
     else: 
      #otherwise computing how many frames delay there are in this chunk 
      cor = argmax(crossco(chunk)) - chunksize*2 
      #calculate the time 
      t = cor/framerate 
      #get the distance assuming v = 340m/s sina=(t*v)/width 
      sina = t*340/width 
      a = asin(sina) * 180/(3.14159) 



     #add the last angle delay value to a list 
     track.append(a) 


    #plot the list 
    plot(track) 
    show() 

ho provato questo utilizzando alcuni audio stereo ho trovato su equilogy. Ho usato l'esempio di auto (file stereo). Ha prodotto this.

Per fare questo on-the-fly, credo che avresti bisogno di avere una fonte stereo in ingresso che si potrebbe 'ascoltare' per un breve periodo (io ho usato 1000 fotogrammi = 0.0208s) e quindi calcolare e ripetere .

[edit: trovato si può facilmente utilizzare la funzione FFT convolve, utilizzando le serie storiche invertita di uno dei due per fare una correlazione]