2016-05-02 47 views
1

私はPython sounddevicePySoundFileを使用して、音声を "邪魔しない"、つまりノンブロッキングコールバックを使用しています。 (https://stackoverflow.com/users/500098/matthiasの帽子の先端とクルー - これらのパッケージは使いやすく、必要なものすべてをやります。)注意:sd.play()を使用する方がはるかに簡単ですが、私はこのパックを選択しました。コールバックメソッド内で追加処理を行うことができます。コールバック内からPythonサウンドデバイスを正常に停止する方法

私はサウンドファイルの終わりに達したときを検出できますが、最後にキューに入れられたバッファを再生した後にサウンドデバイスが停止するように指示する方法は明確ではありません。

ここでは、機能しないコールバックの例を示します。サウンドファイル全体を再生しますが、最後のバッファを処理した後は停止しません。コールバックでは、私はsd.CallbackStop()を上げますが、ストリームの状態はstoppedなりません:

def callback(outdata, frame_count, time, status): 
     view = sf.read(frame_count, dtype='float32', out=outdata) 
     if (view.size != outdata.size): # this was the last buffer. 
      print('stopping') 
      sd.CallbackStop() 

    with sd.OutpuStream(samplerate=sf.samplerate, 
         channels=sf.channels, 
         dtype=np.float32, 
         callback=callback) as ss: 
     while (ss.active): 
      time.sleep(0.1) 
+0

[sd.play()](http://python-sounddevice.readthedocs.io/en/latest/#sounddevice.play)を使用して*もっと簡単な方法が追加されているはずです。 – Matthias

+1

完了。私は彼らが行くようにビットを触れることができるようにしたいことを明確にした。 –

答えて

1

いやはや!もしあなたがraiseでない場合、例外はうまく動作しません!最後にすべての方法を再生し、最後のバッファが再生された後に停止し、

def callback(outdata, frame_count, time, status): 
    view = sf.read(frame_count, dtype='float32', out=outdata) 
    if (view.size != outdata.size): # this was the last buffer. 
     # zero the part of outdata not written into by sf.read() 
     outdata[view.shape[0]:,:].fill(0.0) 
     print('stopping') 
     raise sd.CallbackStop() 

...とそれだけで完璧に動作します:コールバックのための適切なコードです。

+0

それはうまくいくと聞いてうれしく思いますが、あなたのサンプルコードは見た目には見えません。私は 'sf.read()'の代わりに 'mysoundfile.read()'を意味していたと思います。また、必ず 'outdata'に意味のある値を書き込むべきですが、最後のブロックでは部分的に書きます。 – Matthias

+0

私のコードには表示されていません: 'SoundFile as SoundFile'と' SoundFile(filename)をsf: 'とするので、' sf.read() 'は実際には正しいです。そして、良いキャッチ:outdataの書かれていない部分は、最後の呼び出しでゼロになる必要があります。それに応じてサンプルをテストして編集します。 –

+0

@Matthias:修正に同意しますか? –

関連する問題