有没有办法在python中创建简单的用户交互音乐合成器

时间:2019-02-12 01:47:40

标签: python-3.x numpy pygame synthesizer python-sounddevice

我目前正在尝试使用pygame.mixersounddevice编写python合成器,以输出在numpy array中创建的正弦波的样本。在创建正弦波之前,必须先声明波形的持续时间,例如:sin(frequency * 2 * Pi * duration),因此,在用户按键期间,如何播放此声音。

当我阅读本书时,关于python的文章并不多,这些文章似乎很容易理解,因此可以提供任何帮助。

如果有人可以解释或给出使用Python缓冲区对象的sounddevice.Streamsounddevice.RawStream的工作方式以及是否对我的情况有所帮助,将不胜感激。

我已经尝试使用sounddevice.play(),但这对于我要实现的目标来说似乎非常基础。我还尝试过创建一小段正弦波并将其循环以供用户输入,但是当我调制该声音时,这将无法正常工作。

我不喜欢使用sounddevice.play()的另一个原因是因为您需要像我使用sounddevice.wait()一样延迟程序,就好像程序没有播放任何内容都运行到最后一样。

观看此视频时,https://www.youtube.com/watch?v=tgamhuQnOkM ...使用c++来编程合成器,他使用了一个单独的模块,我认为该模块运行一个后台线程,但是他的模块将每个样本分开而不是单独采样作为数组。

我也尝试使用pygame.sndarray.make_sound()。 这是当合成器工作时//我想做的事情的一个示例:

            import numpy as np # download
            import sounddevice as sd # download
            import time

            stream = []

            # Main Controls
            sps = 44100 # DON'T CHANGE

            carrier_hz = 440.0

            duration_s = 1.0

            atten = 0.3

            def amplitudeMod(t_samples, carrier):
                # Modulate the amplitude of the carrier
                ac = 0.2 # amplitude 0 = min, 1 = max
                ka = 1.0 # range of change 0.1 = less, 1.0 = most
                modulator_hz = 0.0 # frequency of modulation 20hz max
                modulator = np.sin(2 * np.pi * modulator_hz * t_samples / sps)
                envelope = ac * (1.0 + ka * modulator)
                return carrier * envelope

            def frequencyMod(t_samples, sps):
                # Modulate the frequency of the carrier
                k = 50.0 # range of change 0.1 = less, ?? = most
                modulator_hz = 10.0 # frequency of modulation
                carrier2 = 2 * np.pi * t_samples * carrier_hz / sps
                modulator = k * np.sin(2 * np.pi * t_samples * modulator_hz / sps)
                return np.cos(carrier2 + modulator)

            # Create carrier wave
            t_samples = np.arange(duration_s * sps)
            carrier = np.sin(2 * np.pi * carrier_hz * t_samples / sps)

            choice = input("1) Play sine\n2) Play amplitude modulation\n3) Play frequency modulation\n;")
            if choice == "1":
                output = carrier
            if choice == "2":
                output = amplitudeMod(t_samples, carrier)
            if choice == "3":
                output = frequencyMod(t_samples, sps)

            # Output

            output *= atten

            sd.play(output, sps)
            sd.wait()
            sd.stop()

是否有任何方法可以将其创建为pygame键事件,该事件仅在按下键时播放正弦波,而在释放键时停止。

0 个答案:

没有答案