查找声音文件中是否有回声

时间:2016-12-08 17:37:50

标签: python wav aec

我有成千上万的录音,我用于我正在制作的应用程序。 最近我注意到一些录音有一个奇怪的回声。

录音是.wav格式,我使用python来处理它们。

我看到许多问题,其中pepole试图取消回声,但我只需要找到这些文件。

是否有可用于查找这些文件的工具或代码(无需取消回声)。

我尝试编写一些代码来取消回声,看看这是否有助于我理解文件何时有回声,但它没有起作用。 结果文件只是噪音,所以我猜我的算法错了。

    def nlms(u, d, M, step, eps=0.001, leak=0, initCoeffs=None, N=None, returnCoeffs=False):
  # Initialization
  if N is None:
    N = len(u)-M+1
  if initCoeffs is None:
    initCoeffs = np.zeros(M)
  y = np.zeros(N)  # Filter output
  e = np.zeros(N)  # Error signal
  w = initCoeffs  # Initial filter coeffs
  leakstep = (1 - step*leak)
  if returnCoeffs:
      W = np.zeros((N, M))  # Matrix to hold coeffs for each iteration

  # Perform filtering
  for n in xrange(N):
      x = np.flipud(u[n:n+M])  # Slice to get view of M latest datapoints
      y[n] = np.dot(x, w)
      e[n] = d[n+M-1] - y[n]

      normFactor = 1./(np.dot(x, x) + eps)
      w = leakstep * w + step * normFactor * x * e[n]
      y[n] = np.dot(x, w)
      if returnCoeffs:
          W[n] = w

  if returnCoeffs:
      w = W

  return y, e, w



def CancelEcho(file_path):
  np.seterr(all='raise')

  audio_file = wave.open(file_path, 'r')
  audio_params = audio_file.getparams()
  new_frames = []
  u = 'a'
  while u != " ":
      data = audio_file.readframes(1024)
      u = np.fromstring(data, np.int16)
      u = np.float64(u)
      if len(u) ==0:
        break
      # Generate received signal d(n) using randomly chosen coefficients
      coeffs = np.concatenate(([0.8], np.zeros(8), [-0.7], np.zeros(9),
                               [0.5], np.zeros(11), [-0.3], np.zeros(3),
                               [0.1], np.zeros(20), [-0.05]))

      coeffs.dtype = np.int16
      d = np.convolve(u, coeffs)

      # Add background noise
      v = np.random.randn(len(d)) * np.sqrt(5000)
      d += v

      # Apply adaptive filter
      M = 100  # Number of filter taps in adaptive filter
      step = 0.1  # Step size
      y, e, w = nlms(u, d, M, step, returnCoeffs=True)

      new_frames.extend(y)

  audio_file.close()
  audio_file = wave.open(out_file, 'w')
  audio_file.setparams(audio_params)
  audio_file.writeframes(y.astype(np.int16).tostring())
  audio_file.close()

1 个答案:

答案 0 :(得分:0)

一个想法是获取文件的一部分,然后将其移动到文件的其余部分,并找到一个信号转换为另一个信号所需的倍增因子。

代码归属: https://docs.python.org/2/library/audioop.html

这可能有效:

def echocancel(outputdata, inputdata):
  pos = audioop.findmax(outputdata, 800)    # one tenth second
  out_test = outputdata[pos*2:]
  in_test = inputdata[pos*2:]
  ipos, factor = audioop.findfit(in_test, out_test)
  # Optional (for better cancellation):
  # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
  #              out_test)
  return factor

因子越接近1.0,就越有可能出现回声