2

作成中のアプリに使用する何千もの記録があります。最近、一部の録音に奇妙なエコーがあることに気付きました。

録音は .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()
4

1 に答える 1

0

ファイルの一部を取り、それをファイルの残りの部分に移動し、1 つの信号が別の信号に変わるのに必要な倍率を見つけます。

コードの帰属: 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 に近いほど、エコーが発生する可能性が高くなります。

于 2016-12-08T19:19:50.000 に答える