9

我想做一个平台来像吉他一样演奏和弦。例如 - 要演奏 E 和弦,它会演奏 [0, 2, 2, 1, 0, 0](从 Low-E 弦到 High-E 弦)。

我试图通过同时播放所有不同的字符串(通过使用线程)在 python 上播放和弦。

问题是每次我开始演奏下一根弦时,似乎最后一根琴弦停止演奏,而新的一根弦取代了它。所以我在弹奏一个和弦后听到的都是最高的弦(最后一个)。

我没有正确使用线程吗?还是当前功能有问题?或者也许是无法处理这类事情的 winsound.Beep() 函数?

这是我的代码:

from winsound import Beep
import threading
import time


def play(freq, dur):
    Beep(round(freq), round(dur))


def get_freq(string, fret):
    a3_freq = 220
    half_tone = 2 ** (1 / 12)

    higher_from_a3_by = 5 * (string - 2) + fret
    if string > 4:
        higher_from_a3_by += 1
    return a3_freq * half_tone ** higher_from_a3_by


def strum(string, fret, time):
    freq = get_freq(string, fret)
    t = threading.Thread(target=play, args=(freq, time))
    t.start()
    return t


def chord(frets, dur):
    threads = []
    for i in range(6):
        if frets[i] != -1:
            threads.append(strum(i + 1, frets[i], dur))
    for t in threads:
        t.join()


chord((-1, 0, 2, 2, 2, 0), 1000) # plays the A chord for one second, for example.

根据我的检查, play() 和 get_freq() 函数没有任何问题。

那么问题是什么,我该如何解决?

编辑:

我已经在 C# 中尝试过,但它也没有工作。这是在 C# 中启动线程的正确方法吗?

foreach (Thread t in threads)
    t.Start();
foreach (Thread t in threads)
    t.Join();
4

3 回答 3

1

Gevent 会让这一切变得容易得多。虽然在技术上仍然是单线程的,但上下文切换是如此之快,以至于它看起来像是同时发生的。您甚至可以使用 GIPC 进行多线程双向多进程通信。

但是我认为你的问题要简单得多。您的问题是风声模块。哔声不是异步的。所以这是你的限制。你需要使用

winsound.SND_ASYNC

这将允许您发送多个事件以同时播放。

于 2018-04-11T19:07:07.343 回答
0

Python does not support true parallel execution of threads. Multithreading with python will spawn a new process. However you would be unable to access the process to manage it once its running so the timing might be off if you spawned up a new process to execute.

However you could make a series of libraries for each underlying note and use a coroutine library like gevent to manage the timing and execution of these notes to combine into a chord.

于 2018-04-05T19:17:52.960 回答
0

我真的建议不要为此使用线程,解决您的复音问题没有必要而且非常复杂。另一种解决方案可能是访问当前正在播放的弦乐的样本,并简单地将任何新播放的弦乐相加。但是,当您使用 winsound 时,这可能是不可能的。所以我建议使用python查看其他播放和/或生成声音的方式,快速搜索显示了这一点

于 2018-04-05T20:45:47.713 回答