问题
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