Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
508 views
in Technique[技术] by (71.8m points)

python - Pygame.midi: How to detect simultaneous inputs from a synthesizer?

I'm using a synthesizer, to detect input of notes with 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)

notes are working, but how i can detect the simultaneous inputs 36 + 40 + 43+ 46, knowing the input 36=c, 40=e and 43=g anyway to do this ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...