3

このビート検出アルゴリズムを使用して、Pythonでオーディオ処理を試しています。前述の記事の最初の(最適化されていないバージョン)を実装しました。いくつかの結果を出力しますが、サウンドの再生方法がわからないため、正確に動作するかどうかを検出する方法がありません。

現在、Popen計算ループに入る前に、曲を使用してメディアプレーヤーを非同期で起動するために使用していますが、この戦略が機能し、同期結果が得られるかどうかはわかりません。

#!/usr/bin/python

import scipy.io.wavfile, numpy, sys, subprocess

# Some abstractions for computation
def sumsquared(arr):
    sum = 0
    for i in arr:
            sum = sum + (i[0] * i[0]) + (i[1] * i[1])

    return sum

if sys.argv.__len__() < 2:
    print 'USAGE: wavdsp <wavfile>'
    sys.exit(1)

numpy.set_printoptions(threshold='nan')
rate, data = scipy.io.wavfile.read(sys.argv[1])


# Beat detection algorithm begin 
# the algorithm has been implemented as per GameDev Article
# Initialisation
data_len = data.__len__()
idx = 0
hist_last = 44032
instant_energy = 0
local_energy = 0
le_multi = 0.023219955 # Local energy multiplier ~ 1024/44100


# Play the song
p = subprocess.Popen(['audacious', sys.argv[1]])

while idx < data_len - 48000:
    dat = data[idx:idx+1024]
    history = data[idx:hist_last]
    instant_energy = sumsquared(dat)
    local_energy = le_multi * sumsquared(history)
    print instant_energy, local_energy
    if instant_energy > (local_energy * 1.3):
            print 'Beat'

    idx = idx + 1024
    hist_last = hist_last + 1024 # Right shift history buffer

 p.terminate()

時間同期された方法でオーディオ出力とアルゴリズム(コンソール)出力を取得するために、スクリプトにどのような変更/追加を行うことができますか?つまり、コンソール出力が特定のフレームの結果である場合、そのフレームはスピーカーで再生されている必要があります。

4

3 に答える 3

4

ワーキングビート検出コード (NumPy / PyAudio)

NumPy を使用している場合、このコードが役立つ場合があります。信号 (PyAudio で読み取られる) は 16 ビット幅の Int であると想定しています。そうでない場合は、signal.astype() を変更または削除し、正規化除算器を調整します (ここでは最大 int16)。

class SimpleBeatDetection:
    """
    Simple beat detection algorithm from
    http://archive.gamedev.net/archive/reference/programming/features/beatdetection/index.html
    """
    def __init__(self, history = 43):
        self.local_energy = numpy.zeros(history) # a simple ring buffer
        self.local_energy_index = 0 # the index of the oldest element

    def detect_beat(self, signal):

        samples = signal.astype(numpy.int) # make room for squares
        # optimized sum of squares, i.e faster version of (samples**2).sum()
        instant_energy = numpy.dot(samples, samples) / float(0xffffffff) # normalize

        local_energy_average = self.local_energy.mean()
        local_energy_variance = self.local_energy.var()

        beat_sensibility = (-0.0025714 * local_energy_variance) + 1.15142857
        beat = instant_energy > beat_sensibility * local_energy_average

        self.local_energy[self.local_energy_index] = instant_energy
        self.local_energy_index -= 1
        if self.local_energy_index < 0:
            self.local_energy_index = len(self.local_energy) - 1

        return beat

wav read または mic record の PyAudio の例は、必要な信号データを提供します。NumPy 配列を効率的に作成するfrombuffer()

data = stream.read(CHUNK)
signal = numpy.frombuffer(data, numpy.int16)
于 2013-03-12T19:56:12.073 に答える
1

よりシンプルな非リアルタイム アプローチ

コンソール出力とリアルタイム オーディオの同期については楽観視できません。私のアプローチはもう少し単純です。ファイルを読み込んで処理しながら、サンプルを新しいオーディオ ファイルに書き出します。ビートが検出されたときはいつでも、作成中のオーディオに大きくて短いサイン トーンなど、聞き逃しにくいサウンドを追加します。そうすれば、結果の品質を聴覚的に評価できます。

ビート インジケータ サウンドを合成します。

def testsignal(hz,seconds=5.,sr=44100.):
    '''
    Create a sine wave at hz for n seconds
    '''
    # cycles per sample
    cps = hz / sr
    # total samples
    ts = seconds * sr
    return np.sin(np.arange(0,ts*cps,cps) * (2*np.pi))

signal = testsignal(880,seconds = .02)

ループ内で、whileビートが検出された場合はテスト信号を入力フレームに追加し、ビートが検出されなかった場合はフレームを変更せずに残します。それらのフレームをファイルに書き出し、それを聞いてビート検出の品質を評価します。

これは、aubioライブラリがビート検出結果を評価するために使用するアプローチです。こちらのドキュメントを参照してください。特に興味深いのは、--outputコマンド ライン オプションのドキュメントです。

このファイルに結果を保存します。ファイルは、入力ファイルのモデルで作成されます。結果は、非常に短い木版サンプルによってマークされます。

最適化

numpy は既に依存関係にあるため、その機能を使用してアルゴリズムを高速化します。sumsquared関数を次のように書き換えることができます。

def sumsquared(arr):
    return (arr**2).sum()

Python の for ループを取り除き、それらの計算を C コードにプッシュすると、速度が向上するはずです。

また、この質問またはこの質問whileを見て、メソッドを使用して、ループ内のローカル エネルギーと瞬間エネルギーの比較をベクトル化する方法を理解してくださいnumpy.lib.stride_tricks

于 2012-11-07T19:42:48.020 に答える
0

portaudio (pyaudio) を試してデータをライブにすることをお勧めします。そうすれば、一致するかどうかを確認できるはずです。

pyaudio でマイクからの fft を使用した良い例を次に示します。

http://www.swharden.com/blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/

于 2012-11-07T18:54:07.397 に答える