0

次のようなライブラリadaptfilt 2.0のpython 3.4で「エコーキャンセル」の例を使用しようとしています:

import numpy as np
import adaptfilt as adf

# Get u(n) - this is available on github or pypi in the examples folder
u = np.load('speech.npy')

# 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]))

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 = adf.nlms(u, d, M, step, returnCoeffs=True)

# Calculate mean square weight error
mswe = adf.mswe(w, coeffs)

期待どおりに動作します。しかし、音楽ファイルの実際のデータで同じことをしたかったのですが、エラーが発生しました:

Traceback (most recent call last):
  File "C:/Python34/Lib/site-packages/adaptfilt/echocancel.py", line 86, in <module>
    y, e, w = adf.nlms(u, d, M, step, returnCoeffs=True)
  File "C:\Python34\Lib\site-packages\adaptfilt\nlms.py", line 149, in nlms
    w = leakstep * w + step * normFactor * x * e[n]
FloatingPointError: invalid value encountered in multiply

私が使用したコードは次のとおりです。

import numpy as np
import adaptfilt as adf
import pyaudio
import wave

np.seterr(all='raise')
p = pyaudio.PyAudio()
stream = p.open(format = p.get_format_from_width(2),
                        channels = 1,
                        rate = 44100,
                        input = True,
                        output = True,
                        #stream_callback = self.callback
                        )
wf = wave.open("XXX.wav", 'rb')
while u != " ":
    data = wf.readframes(1024)
    u = np.fromstring(data, np.int16)

    # 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 = adf.nlms(u, d, M, step, returnCoeffs=True)

    # Calculate mean square weight error
    mswe = adf.mswe(w, coeffs)

    stream.write(y.astype(np.int16).tostring())

私が見る唯一の違いは、「speech.npy」からの配列が float64 のタイプであり、wav ファイルからの私の配列が int16 のタイプであることです。

4

2 に答える 2

1

また、「data」を float64 にキャストすることで、「adaptfilt 2.0」を音楽データ (44.1kHz サンプリング レートのモノラル .wav ファイル) で動作させることができました。

適応フィルターは収束に時間がかかりましたが、問題なく動作しました。以下は、フィルタの収束を示す平均二乗重み誤差プロットです。

http://i.imgur.com/xcpFUn2.png

また、これを音楽に適用するには、より長いフィルタータップ (M) が必要になる可能性が高いことも付け加えておきます。元のスクリプトで使用されている 'speech.npy' 配列は、サンプル レート情報を持たない単なる配列ですが、音声ファイルのサンプル レートは 44.1kHz より低いと想定できます。

'speech.npy' をさまざまなサンプル レートで再生しました。何が自然に聞こえるかを聞いただけで、10 ~ 12kHz の範囲にあると推測されます。これは、'coeffs' に格納された「インパルス応答」が ~5.7 ms (10kHz のサンプリング レートを想定) であることを意味します。44.1kHz では、インパルス応答はわずか ~1.3ms です。これは非常に短く、実際の信号のインパルス応答をモデル化する可​​能性は低いです。

于 2015-09-28T23:11:20.403 に答える
0

このエラーは、モジュール内のどこかで計算に int16 型を使用する場合の数値の問題が原因で発生します。あなたの例を使用して、入力データを次のような浮動小数点型にキャストします

u = np.fromstring(data, np.int16)
u = np.float64(u)

私の問題を解決します。

于 2015-04-23T09:22:08.237 に答える