pygame midi read PC (program change) messages

◇◆丶佛笑我妖孽 提交于 2021-02-11 17:11:48

问题


My goal is to listen to a MIDI to USB adapter that is connected to my guitar pedalboard switcher. When a program change, (PC) message is received, play the appropriate mp2 file.

I've tried a number of different Python MIDI modules and pygame has got me the closest.

Below is the code I have been tinkering with and it is printing messages when I send program messages for the pedal switcher. I just do not know how to extract and interpret what I need.

For instance, the pedal switcher sends a PC message MIDI Chnl 3, Program Change 1

My code,

print (convert)

Returns,

<Event(34-Unknown {'status': 240, 'data1': 65, 'data2': 0, 'data3': 0, 'timestamp': 4674, 'vice_id': 3})>, <Event(34-Unknown {'status': 0, 'data1': 0, 'data2': 20, 'data3': 18, 'timestamp': 4674, 'vice_id': 3})>, <Event(34-Unknown {'status': 127, 'data1': 1, 'data2': 0, 'data3': 67, 'timestamp': 4674, 'vice_id': 3})>, <Event(34-Unknown {'status': 61, 'data1': 247, 'data2': 0, 'data3': 0, 'timestamp': 4674, 'vice_id': 3})>]

Or, MIDI Chnl 3, Program Change 2

Code returns,

[[<Event(34-Unknown {'status': 240, 'data1': 65, 'data2': 0, 'data3': 0, 'timestamp': 2248, 'vice_id': 3})>, <Event(34-Unknown {'status': 0, 'data1': 0, 'data2': 20, 'data3': 18, 'timestamp': 2248, 'vice_id': 3})>, <Event(34-Unknown {'status': 127, 'data1': 1, 'data2': 0, 'data3': 68, 'timestamp': 2248, 'vice_id': 3})>, <Event(34-Unknown {'status': 60, 'data1': 247, 'data2': 0, 'data3': 0, 'timestamp': 2248, 'vice_id': 3})>]

Scratching my head on how to translate that to Channel 3, PC 1 and/or Channel 3, PC 2

Any guidance out there?

Entire test script,

import pygame, pygame.midi
pygame.midi.init()
pygame.init()
count = pygame.midi.get_count()
print ("There are ", count, "MIDI devices")

dev1 = pygame.midi.get_device_info(1)
print ("1= ",dev1)

dev2 = pygame.midi.get_device_info(2)
print ("2= ",dev2)

dev3 = pygame.midi.get_device_info(3)
print ("3= ",dev3)

inp = pygame.midi.Input(3,100)
print(inp)

while True:
     if inp.poll():
         # no way to find number of messages in queue
         # so we just specify a high max value
         #print (inp.read(1000))
         read = inp.read(100)
         #print(read)
         convert = pygame.midi.midis2events(read,3)
         print (convert)
         

 
     # wait 10ms - this is arbitrary, but wait(0) still resulted
     # in 100% cpu utilization
     pygame.time.wait(10)

Ok, so continuing to dig...

I found my pedalboard was spitting out a whole lot of MIDI messages that did not pertain to what I was doing. Now, I have the pedalboard settled down I'm getting messages that make sense.

When I send a Chnl 3 PC 1 program change message I get,

[<Event(34-Unknown {'status': 196, 'data1': 0, 'data2': 0, 'data3': 0, 'timestamp': 3942, 'vice_id': 3})>, <Event(34-Unknown {'status': 180, 'data1': 80, 'data2': 0, 'data3': 0, 'timestamp': 3943, 'vice_id': 3})>, <Event(34-Unknown {'status': 180, 'data1': 81, 'data2': 0, 'data3': 0, 'timestamp': 3943, 'vice_id': 3})>]

When I send a Chnl 3 PC 1 2 get,

[<Event(34-Unknown {'status': 196, 'data1': 1, 'data2': 0, 'data3': 0, 'timestamp': 3942, 'vice_id': 3})>, <Event(34-Unknown {'status': 180, 'data1': 80, 'data2': 0, 'data3': 0, 'timestamp': 3943, 'vice_id': 3})>, <Event(34-Unknown {'status': 180, 'data1': 81, 'data2': 0, 'data3': 0, 'timestamp': 3943, 'vice_id': 3})>]

So, three "Events" I'm only interested in events with staus: 196 as that is chnl 3.

I found this, which shed some light on these MIDI messages,

[url]https://www.midimountain.com/midi/midi_status.htm[/url]

So, now I need to scan this long string for "'status': 196" and if found grab the value of data1

If anyone has an elegant way of doing that, I would be much appreciative...


回答1:


The midis2events() function is pointless if you are not using the event loop.

Just extract the values from the data you have read:

...
read = inp.read(100)
for event in read:
    ((status,data1,data2,data3),timestamp) = event
    if status == 196:
        print(f"change to program {data1}")


来源:https://stackoverflow.com/questions/62983509/pygame-midi-read-pc-program-change-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!