同时生成Python线程?

同时生成Python线程?,python,multithreading,audio,Python,Multithreading,Audio,现在,我和一些朋友正在制作一个程序,使用Python中的方波生成音乐(我们还处于开发的早期阶段)。其中一个障碍是,我们认为PyAudio一次只能播放一个声音,如果您试图播放彼此之间的声音,例如制作和弦,这些声音就会相互覆盖。我们当前的策略是使用线程来绕过它,它几乎可以正常工作,但线程开始的时间却非常缓慢。下面是生成C大调和弦的代码片段: import numpy as np import pyaudio import math from scipy import signal import mu

现在,我和一些朋友正在制作一个程序,使用Python中的方波生成音乐(我们还处于开发的早期阶段)。其中一个障碍是,我们认为PyAudio一次只能播放一个声音,如果您试图播放彼此之间的声音,例如制作和弦,这些声音就会相互覆盖。我们当前的策略是使用线程来绕过它,它几乎可以正常工作,但线程开始的时间却非常缓慢。下面是生成C大调和弦的代码片段:

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、信号量、互斥等。这是一个相当广泛的领域,但是有很多可用的资源(不幸的是,超出了问题的范围),并且应该以相当精确的程度确定是可行的。如果时间非常关键,您可能还需要查看流程优先级等。