Написание программного обеспечения, чтобы сказать, откуда исходит звук (направленное прослушивание) - PullRequest
6 голосов
/ 29 декабря 2011

Мне было любопытно об этом в течение некоторого времени, поэтому я подумал, что, возможно, опубликовав здесь, я мог бы получить несколько хороших ответов.

Что я знаю до сих пор:

Люди могут использоватьих два уха, чтобы получить не только то, что звучит как «звучит», но и откуда они берутся.Тональность - это нота, которую мы слышим, и что-то похожее на человеческий голос имеет различные наложения (не чистый тон).

Что я хотел бы знать:

Как мне написать программу, которая может знать, откуда исходит звук?С теоретической точки зрения мне понадобятся два микрофона, а затем я записываю звуковые данные, поступающие на микрофоны, и сохраняю аудиоданные так, чтобы доли секунды аудиоданных можно было поместить в кортеж, например [streamA, streamB].

Мне кажется, что может существовать формальный / математический способ расчета на основе аудио, откуда исходит звук.Я также чувствую, что можно взять потоковые данные и обучить ученика (дать ему образец аудио и сообщить, откуда он пришел) и заставить его классифицировать входящее аудио таким образом.

Какой лучший способпродолжать делать это / есть хорошие ресурсы, из которых я могу узнать больше о предмете?

РЕДАКТИРОВАТЬ:

Пример:

          front

слева (микрофон) x ======== x (mic) right

          back

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

Я хочу написать программу, которая может возвращать вперед / назад влево / вправо для большей части слышимого звука,Из того, что я понимаю, должно быть просто настроить два микрофона с указанием «вперед».Исходя из этого, я пытаюсь выяснить, как мы можем триангулировать звук и узнать, где по отношению к микрофонам источник.

Ответы [ 4 ]

5 голосов
/ 29 декабря 2011

Если вы посмотрите на исследовательские работы, посвященные многофазным микрофонным решеткам, особенно тем, которые используются для подводного радиопеленгации (т. Е. Большой области исследований подводных лодок во время холодной войны - откуда исходит звук двигателя, чтобы мы могли наводить торпеды? ) тогда вы найдете технологию и математику, необходимые для определения местоположения звука по двум или более микрофонным входам.

Это нетривиально, и это не то, что можно так широко обсудить здесь, поэтому вы не найдете простой фрагмент кода и / или библиотеку, которая сделает то, что вам нужно.

Основная проблема - устранение эха и теней. Упрощенным методом было бы начать с одного тона, отфильтровывая все, кроме этого тона, а затем измеряя разность фаз между двумя микрофонами этого тона. Разность фаз даст вам много информации о местоположении тона.

Затем вы можете выбрать, хотите ли вы иметь дело с эхом и проблемами многолучевого распространения (многие из которых можно устранить, удалив все, кроме самого сильного тона), или перейдите на коррелирующие звуки, которые состоят из чего-то другого, кроме одного тона - говорящий человек или разбитие стекла, например. Начните с малого и просто и продолжайте расширяться.

3 голосов
/ 20 ноября 2013

Я искал что-то похожее и написал здесь тупой ответ, который был удален. У меня были некоторые идеи, но я не написал их должным образом. Удаление дало мне эту интернет-гордость, поэтому я решил попробовать проблему, и я думаю, что это сработало!

На самом деле, попытка найти настоящую локализацию а-ля Адама Дэвиса очень сложна, но сделать локализацию в человеческом стиле (глядя на первый источник, игнорируя эхо или трактуя их как источники), я думаю, не так уж и плохо Я ни в коем случае не эксперт по обработке сигналов.

Я прочитал это и это . Это заставило меня понять, что проблема на самом деле заключается в нахождении временного сдвига (взаимной корреляции) между двумя сигналами. Оттуда вы будете рассчитывать угол, используя скорость звука. Обратите внимание, что вы получите два решения (спереди и сзади).

Ключевая информация, которую я прочитал, была в этом ответе и других на той же странице, которые рассказывают о том, как делать быстрые преобразования Фурье в scipy, чтобы найти кривую взаимной корреляции.

По сути, вам нужно импортировать волновой файл в python. Смотрите это .

Если ваш волновой файл (входной) является кортежем с двумя массивами (слева, справа), заполненными нулями, по крайней мере, до тех пор, пока он сам (очевидно, для остановки кругового выравнивания), код следует из ответа Густаво. Я думаю, вам нужно признать, что эти FFT предполагают неизменность времени, что означает, что если вы хотите получить какой-либо вид отслеживания сигналов на основе времени, вам нужно «откусить» небольшие выборки данных.

Я собрал следующий код из упомянутых источников. Будет выведен график, показывающий предполагаемую задержку в кадрах слева направо (отрицательный / положительный). Чтобы преобразовать в фактическое время, разделите на частоту дискретизации. Если вы хотите знать, что такое угол, вам нужно:

  • предположим, что все на плоскости (без коэффициента высоты)
  • забудьте разницу между звуком спереди и сзади (вы не можете различить)

Вы также хотели бы использовать расстояние между двумя микрофонами, чтобы убедиться, что вы не получаете эхо (задержка больше, чем для задержки 90 градусов).

Я понимаю, что взял много заимствований здесь, так что спасибо всем, кто непреднамеренно внес свой вклад!

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()

Я попробовал это, используя стереозвук, который нашел в equilogy . Я использовал автомобильный пример (стереофайл). Это произвело это .

Чтобы сделать это на лету, я думаю, вам понадобится входящий стереофонический источник, который вы могли бы «слушать» в течение короткого времени (я использовал 1000 кадров = 0,0208 с), а затем вычислить и повторить.

[править: найдено, что вы можете легко использовать функцию FFT Convolve, используя инвертированные временные ряды одного из двух для создания корреляции]

2 голосов
/ 29 декабря 2011

Кросс-корреляция - это основной метод, но он имеет некоторые особенности. Существуют различные подходы, которые помогают эффективно определять источник с массивом микрофонов. Некоторые также работают без калибровки, некоторые требуют калибровки для адаптации к геометрии помещения.

Вы можете попробовать существующее программное обеспечение с открытым исходным кодом для задачи локализации источника

Разделение и локализация источника звука робота Manyears https://sourceforge.net/projects/manyears/

HARK инструментарий для робототехники http://www.ros.org/wiki/hark

2 голосов
/ 29 декабря 2011

Это интересная проблема. Я не знаю ни одного справочного материала для этого, но у меня есть некоторый опыт в аудио-программном обеспечении и обработке сигналов, которые могут помочь направить вас в правильном направлении.

Определить направление источника звука (откуда звук вокруг вас) довольно просто. Получить 6 направленных микрофонов и направить их вверх, вниз, спереди, сзади, влево и вправо. Глядя на относительные амплитуды микрофонных сигналов в ответ на звук, вы можете довольно легко определить, из какого направления исходит конкретный звук. Увеличьте количество микрофонов для увеличения разрешения.

2 микрофона только сообщат вам, идет ли звук справа или слева. Причина, по которой ваши 2 уха могут понять, идет ли звук перед вами или позади вас, заключается в том, что внешняя структура вашего уха изменяет звук в зависимости от направления, которое ваш мозг интерпретирует, а затем корректирует.

...