同时生成Python线程?
现在,我和一些朋友正在制作一个程序,使用Python中的方波生成音乐(我们还处于开发的早期阶段)。其中一个障碍是,我们认为PyAudio一次只能播放一个声音,如果您试图播放彼此之间的声音,例如制作和弦,这些声音就会相互覆盖。我们当前的策略是使用线程来绕过它,它几乎可以正常工作,但线程开始的时间却非常缓慢。下面是生成C大调和弦的代码片段:同时生成Python线程?,python,multithreading,audio,Python,Multithreading,Audio,现在,我和一些朋友正在制作一个程序,使用Python中的方波生成音乐(我们还处于开发的早期阶段)。其中一个障碍是,我们认为PyAudio一次只能播放一个声音,如果您试图播放彼此之间的声音,例如制作和弦,这些声音就会相互覆盖。我们当前的策略是使用线程来绕过它,它几乎可以正常工作,但线程开始的时间却非常缓慢。下面是生成C大调和弦的代码片段: import numpy as np import pyaudio import math from scipy import signal import mu
import numpy as np
import pyaudio
import math
from scipy import signal
import multiprocessing
from time import time
def noteTest(frequency):
l = np.linspace(0, 2, 384000, endpoint=False)
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=192000, output=True)
wave_data = signal.square(2 * math.pi * frequency * l)
stream.write(wave_data)
def playNotes():
if __name__ == "__main__":
multiprocessing.Process(target = noteTest, args = [523.25113060119]).start()
print(time())
multiprocessing.Process(target = noteTest, args = [659.25511382575]).start()
print(time())
multiprocessing.Process(target = noteTest, args = [783.99087196355]).start()
print(time())
playNotes()
当我查看程序的输出时,下面是它给出的时间:
1510810518.870557
1510810518.8715587
1510810518.8730626
正如你所看到的,这些线之间的间隔超过了千分之一秒。即使只有一个和弦,这一点也非常明显,但我们担心,如果我们尝试制作一首真正的歌曲,这将成为一个更大的问题,因为这些曲目会彼此分离,失去时间。请注意,我们测试的所有计算机都有多个物理内核。有没有办法让线程更好地同步,或者我们最好找到一个替代解决方案?一个选项是在播放声音之前,每个线程都有一个延迟。如果您对启动线程所涉及的偏移量有一个合理的想法,那么可以将该值作为延迟传入 例如,假设启动线程之间有1ms的延迟:
- 0ms:启动线程1,延迟1ms
- 0ms:线程1在新核心上启动,等待
- 1ms:启动线程2,无延迟
- 1ms:线程1在延迟后开始播放
- 1ms:线程2在新内核上启动,没有延迟,并开始播放
另一种选择是让每个线程启动,但等待主进程循环向所有线程发出信号,然后再开始播放。线程仍将从运行程序的单个进程启动(即使它位于不同的内核上),因此很可能会有延迟。假设线程将有一个延迟的开始,但是给线程一个开始播放特定乐器的时间偏移量,怎么样?也就是说,线程2将比线程1晚启动,所以让线程1等待一个特定的时间(启动后)开始播放。我喜欢第二个建议,但多处理是否提供了一些解决方案,或者我们需要找出我们自己的解决方案来解决这个问题?查看IPC、信号量、互斥等。这是一个相当广泛的领域,但是有很多可用的资源(不幸的是,超出了问题的范围),并且应该以相当精确的程度确定是可行的。如果时间非常关键,您可能还需要查看流程优先级等。