Есть ли способ создать простой пользовательский интерактивный музыкальный синтезатор в python? - PullRequest
0 голосов
/ 12 февраля 2019

В настоящее время я пытаюсь написать синтезатор python, используя либо pygame.mixer, либо sounddevice, чтобы вывести сэмплы синусоидальной волны, которые я создал в numpy array.Продолжительность волны должна быть указана до создания синусоидальной волны, например: sin(frequency * 2 * Pi * duration), поэтому, как вы воспроизводите этот звук во время нажатия клавиши пользователя.

Не так много статей оэто для python, когда я читаю, что, кажется, легко понять, поэтому любая помощь будет признательна.

Также, если кто-то может объяснить или привести пример того, как sounddevice.Stream или sounddevice.RawStream с использованием буферных объектов Python работает иесли бы это помогло в моей ситуации, это было бы очень полезно.

Я уже пробовал использовать 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()

Есть ли способ создать его как событие пигмея, которое воспроизводит синусоидальную волну только тогда, когда ключнажимается и останавливается при отпускании клавиши.

...