2016-07-11 24 views
0

与えられた周波数と持続時間で正弦波ノイズを生成したいと思います。 GUIを使っているときに同時に再生したいと思います。Pythonマルチスレッド - 複数の正弦波を同時に再生

スレッドを使用するクラスを作成しましたが、動作しないようです。 .run()行を呼び出すと同時にコードを実行することはできません。たとえば、以下のコードを実行すると、サウンドが完了した後にprintステートメントが実行されます。

import pyaudio 
import numpy as np 
import threading 

class WavePlayerLoop(threading.Thread) : 
    """ 
    A simple class based on PyAudio to play sine wave at certain frequency. 
    It's a threading class. You can play audio while your application 
    continues to do stuff. 
    """ 

    def __init__(self, freq=440., length=1., volume=0.5): 
    threading.Thread.__init__(self) 
    self.p = pyaudio.PyAudio() 

    self.volume = volume  # range [0.0, 1.0] 
    self.fs = 44100   # sampling rate, Hz, must be integer 
    self.duration = length # in seconds, may be float 
    self.f = freq   # sine frequency, Hz, may be float 

    def run(self) : 
    """ 
    Just another name for self.start() 
    """ 
    # generate samples, note conversion to float32 array 
    self.samples = (np.sin(2*np.pi*np.arange(self.fs*self.duration)*self.f/self.fs)).astype(np.float32) 

    # for paFloat32 sample values must be in range [-1.0, 1.0] 
    self.stream = self.p.open(format=pyaudio.paFloat32, 
        channels=1, 
        rate=self.fs, 
        output=True) 

    # play. May repeat with different volume values (if done interactively) 
    self.stream.write(self.volume*self.samples) 

    self.stream.stop_stream() 
    self.stream.close() 

    self.p.terminate() 

s = WavePlayerLoop(freq=440., length=10., volume=0.5) 
s.run() 
print 'this should print while there is a beep sound' 

他のコードの実行中にこのサウンドを同時に再生するには、どうすればよいですか?

+0

*どのように動作していないのですか?詳細を記入するために質問を編集してください。 – SiHa

+0

コメントありがとうございます。私は主な説明を更新しました! – Sam

答えて

1

完全に正しいと思われるようです。次のテストコードは、あなたのコードで完璧に動作しています。

objs = [] 
number_of_threads = 10 

print 'Creating thread objects' 
for i in range(number_of_threads): 
    objs.append(WavePlayerLoop(freq=440 * i, length=10., volume=0.1 * i)) 

print 'Starting thread objects' 
for i in range(number_of_threads): 
    objs[i].start() 

print 'Waiting for threads to finish' 
for i in range(number_of_threads): 
    objs[i].join() 

print ('Finishing program') 
+0

だから、.run()の代わりに.start()をやらなければならなかったのですか?私は十分に十分にスレッドのドキュメントに読んでいないように見える...フェア十分! – Sam