【问题标题】:Writing software to tell where sound comes from (directional listening) [closed]编写软件来判断声音的来源(定向聆听)[关闭]
【发布时间】:2012-01-29 14:01:43
【问题描述】:

我一直对此感到好奇,所以我想也许在这里发帖我可以得到一些好的答案。

到目前为止我所知道的:

人类不仅可以用两只耳朵听到“听起来像”的声音 而且他们来自哪里。音高是我们听到的音符,并且 像人声这样的东西有不同的音高叠加(不是 纯音。)

我想知道的:

如何编写一个可以知道声音来自何处的程序?从理论上讲,我需要两个麦克风,然后我会记录来自麦克风的声音数据并存储音频数据,以便可以将一瞬间的音频数据放入像 [streamA,streamB] 这样的元组中。

我觉得可能有一种公式/数学方法可以根据声音的来源进行计算。我也觉得可以获取流数据并训练学习者(给它样本音频并告诉它音频来自哪里)并让它以这种方式对传入的音频进行分类。

做这件事的最佳方法是什么/有什么好的资源可以让我了解更多关于这个主题的信息?

编辑:

例子:

          front

左(麦克风)x ======== x(麦克风)右

          back

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

我想编写一个程序,它可以返回它听到的大部分声音的前/后左/右。据我了解,设置两个指向“向前”的麦克风应该很简单。基于此,我正在尝试找出一种方法,我们可以对声音进行三角测量,并了解音源相对于麦克风的位置。

【问题讨论】:

  • 我猜你想在两个通道之间做一个离散的cross-correlation
  • @HotLicks:这并不能告诉你太多。知道左右麦克风之间的相对延迟只会将位置缩小到椭圆体的表面。
  • BBN 通过销售这样的系统赚取了数百万美元。他们没有说明是如何获得专利的,或者他们是否已经申请了专利。
  • 嗯,不过,这似乎并不难。如果有的话,我觉得我们可以训练机器学习器/分类器来做到这一点,而不是编写算法。我只是不确定我应该研究哪种 ML 算法,或者我应该在哪里寻找更多关于这个主题的信息。当然,由物理距离 x 隔开的两个单独的声音流之间肯定存在数学关系,这为我们提供了从给定“向前”位置的方向。
  • @OliCharlesworth -- 这是你将从声音中获得的尽可能多的信息,除非你能以某种方式提取回声(这在auto-correlstion 中是隐约可能的)。

标签: speech-recognition wav audio waveform


【解决方案1】:

如果您查看有关多相麦克风阵列的研究论文,特别是那些用于水下测向的论文(即冷战期间的大量潜艇研究 - 电机声音来自哪里,以便我们可以瞄准鱼雷? ) 然后您将找到在给定两个或更多麦克风输入的情况下找到声音位置所需的技术和数学。

这很重要,也不能在这里广泛讨论,所以你不会找到一个简单的代码 sn-p 和/或库来做你需要的。

主要问题是消除回声和阴影。一种简单的方法是从单音开始,滤除除该音之外的所有内容,然后测量该音的两个麦克风之间的相位差。相位差会给你很多关于音调位置的信息。

然后,您可以选择是要处理回声和多路径问题(其中许多问题可以通过移除除最强音之外的所有声音来消除),还是转向包含非单音的相关声音 - 一个人说话,或玻璃破碎,例如。从小而轻松开始,然后从那里扩展。

【讨论】:

    【解决方案2】:

    我正在查找类似的内容,并在此处写了一个愚蠢的答案,但已被删除。我有一些想法,但并没有真正正确地写出来。删除给了我互联网挫伤的自我自豪感,所以我决定尝试这个问题,我认为它有效!

    实际上尝试按照亚当戴维斯的答案进行真正的定位非常困难,但我认为进行人性化的定位(查看第一个来源,忽略回声或将它们视为来源)并不算太糟糕无论如何,我都不是信号处理专家。

    我读过thisthis。这让我意识到问题实际上是找到两个信号之间的时间偏移(互相关)。从那里您将使用声速计算角度。请注意,您将获得两种解决方案(正面和背面)。

    我读到的关键信息是在this answer 和同一页面上的其他人,其中讨论了如何在 scipy 中进行快速傅立叶变换,以找到互相关曲线。

    基本上,您需要将wave文件导入python。见this

    如果您的波形文件(输入)是一个具有两个 numpy 数组(左、右)的元组,零填充至少与自身一样长(以阻止它明显循环对齐),则代码遵循古斯塔沃的回答。我认为您需要认识到,ffts 做出了时间不变性假设,这意味着如果您想要获得任何类型的基于时间的信号跟踪,您需要“咬掉”小数据样本。

    我从上述来源收集了以下代码。它将生成一个图表,显示估计的时间延迟,以帧为单位,从左到右(负/正)。要转换为实际时间,请除以采样率。如果你想知道你需要什么角度:

    • 假设一切都在一个平面上(没有高度因素)
    • 忘记前后声音的区别(你无法区分)

    您还需要使用两个麦克风之间的距离来确保您没有收到回声(时间延迟大于 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 找到的一些立体声音频进行了尝试。我使用了汽车示例(立体声文件)。它产生了this

    要即时执行此操作,我想您需要有一个传入的立体声源,您可以在短时间内“收听”(我使用 1000 帧 = 0.0208 秒),然后计算并重复。

    [编辑:发现您可以轻松使用 fft convolve 函数,使用两者之一的倒置时间序列进行相关]

    【讨论】:

      【解决方案3】:

      这是一个有趣的问题。我不知道这方面的任何参考资料,但我在音频软件和信号处理方面确实有一些经验,这可能会帮助您指明正确的方向。

      确定声源方向(声音来自您周围的位置)相当简单。获取 6 个指向性麦克风并将它们指向上、下、前、后、左和右。通过查看麦克风信号响应声音的相对幅度,您可以很容易地确定特定声音来自哪个方向。增加麦克风数量以提高分辨率。

      2 个麦克风只能告诉您声音是来自右侧还是左侧。两只耳朵之所以能分辨出声音是来自前方还是后方,是因为耳朵的外部结构会根据方向改变声音,大脑会对其进行解释并进行校正。

      【讨论】:

      • 当你失去一只耳朵的听力时,你就失去了辨别方向的能力 - 耳朵的外部结构有帮助,但两只耳朵都是必需的 - hearinglosshelp.com/weblog/… 。为了确定方向,您的大脑会在两只耳朵之间执行相当复杂的关联和计时。
      • 这个答案有点误导。通过使用适当的双耳技术,2 个麦克风可以为您提供 2D 平面(方位角)的位置估计,而不仅仅是在一条线上(左右)。请参阅sdac.kaist.ac.kr/upload/paper/ICCAS_2007_Hwang.pdf 和其他论文。最近已经表明,也可以实现海拔估计 jp.honda-ri.com/upload/document/entry/20110911/...。如果可以对来源做出一些假设,则可以提高准确性,例如ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5443663.
      • 它的范围可能有点有限,但我不会称之为误导。虽然您的第二个链接不起作用,并且您的第三个链接需要会员资格,但第一个链接讨论了涉及模仿外耳结构的实验,我在答案的最后部分进行了讨论。但是,OP 主要询问的是“公式/数学计算方式”位置的方法。模拟外耳的行为需要专门的硬件。
      【解决方案4】:

      互相关是一种主要方法,但它有一些细节。有多种方法可以帮助有效地检测带有麦克风阵列的源。有些无需校准也可以工作,有些则需要校准以适应房间的几何形状。

      您可以尝试现有的开源软件来完成源本地化任务

      万年机器人声源分离与定位 https://sourceforge.net/projects/manyears/

      用于机器人应用的 HARK 工具包 http://www.ros.org/wiki/hark

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多