Pygame.midi:如何检测来自合成器的同时输入? [英] Pygame.midi: How to detect simultaneous inputs from a synthesizer?

查看:29
本文介绍了Pygame.midi:如何检测来自合成器的同时输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用合成器,通过 pygame.midi 检测音符输入

import pygame.midi

def readInput(input_device):

    while True:
        if input_device.poll():
            event = input_device.read(1)[0]
            data = event[0]
            timestamp = event[1]
            note_number = data[1]
            velocity = data[2]
            print(data[2])

            if data[1] == 36 and 40 and 43 and 46: #not working
                 print("chord = Cmaj7")
            else:
                 print(data[2])

if __name__ == '__main__':
    pygame.midi.init()
    my_input = pygame.midi.Input(1)
    readInput(my_input)

笔记正在起作用,但是我如何检测同时输入 36 + 40 + 43+ 46,知道输入 36=c、40=e 和 43=g 无论如何要这样做?

推荐答案

好的,您需要了解 midi 的工作原理.当任何合成键的状态发生变化时,会触发 MIDI 事件(input_device.poll() 为 True),例如键被按下或释放.发生这种情况时,您的数据变量包含带有 [状态、注释、速度、某些东西(我无法识别它)] 的列表.此外,还有15个频道.我发现按键调用状态 128+channel_number 和键释放调用状态为 144+channel_number 的事件.您必须自己跟踪实际按下的音符.以下是您要执行的操作的示例代码:

Okay, you need to understand how midi works. MIDI event is triggered(input_device.poll() is True) when there is a change of state of any synth keys, e.g. key was pressed or released. When this happens, your data variable contains list with [state, note, velocity, something(I couldn't identify it)]. Also, there are 15 channels. I found out that key press calls state 128+channel_number and key release calls event with state 144+channel_number. You have to keep track of actually pressed notes by yourself. Here's sample code for what you're trying to do:

pressed = []
def readInput(input_device, channel):
    while True:
        if input_device.poll():
            event = input_device.read(1)[0]
            data = event[0]
            # [state, note, velocity, something(always 0 for me)]
            timestamp = event[1]
            if data[0] == 128 + channel:  # note off on channel data[0]-128
                if data[1] in pressed:
                    pressed.remove(data[1])
            if data[0] == 144 + channel:  # note on on channel data[0]-144
                if not data[1] in pressed:
                    pressed.append(data[1])

            if all(el in pressed for el in [36, 40, 43, 46]):
                print("chord = Cmaj7")

这篇关于Pygame.midi:如何检测来自合成器的同时输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆