首页 文章

完全同时生成Python线程?

提问于
浏览
-1

现在有些朋友和我正在制作一个程序,用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

如你所见,线程相隔千分之一秒 . 这令人惊讶地显而易见,即使只有一个和弦,但我们担心如果我们试图制作一首真正的歌曲,这将成为一个更大的问题,因为曲目将分开并彼此消失 . 请注意,我们使用DO测试的所有计算机都有多个物理核心 . 有没有办法让线程更好地同步,或者我们最好找到替代解决方案?

1 回答

  • 1

    一个选项是在播放声音之前在每个线程中有一个延迟 . 如果您对启动线程所涉及的偏移有一个合理的了解,则可以将该值作为延迟传递 .

    例如,假设启动线程之间有1ms的延迟:

    • 0ms:启动线程1,延迟1ms

    • 0ms:线程1在新核心上启动,等待

    • 1ms:启动线程2,没有延迟

    • 1ms:线程1在延迟后开始播放

    • 1ms:线程2在新核心上启动,没有延迟,并开始播放

    另一种选择是让每个线程启动,但在开始播放之前等待主进程循环到所有线程的信号 .

相关问题