如何使用pyPortMidi或pygame发送MIDI控制变更消息(CC)?

2 投票
2 回答
4653 浏览
提问于 2025-04-16 06:02

我正在使用Python和Pygame,Pygame的MIDI模块是用pyPortMidi实现的。我现在通过Midi Yoke把NoteOn和NoteOff消息发送到Ableton Live,这一切都很顺利。但是我就是搞不清楚怎么发送CC消息……

有没有人能帮忙?

这个(能正常工作的)类大概是这样的。

class MidiIO:         
    def __init__(self, device_id = None, inst=0):
        pygame.midi.init()
        pygame.fastevent.init()

        if device_id is None:
            self.output_id = pygame.midi.get_default_output_id()
        else:
            self.output_id = device_id

        self._print_device_info()

        port = self.output_id

        print ("using output_id :%s:" % port)

        self.midi_out = pygame.midi.Output(port, 0)
        self.midi_out.set_instrument(inst)

        self.pressed = False

def midiOut(self, btns, note=60, vel=100):
        if btns == 1:
            if not self.pressed:
                self.midi_out.note_on(note, vel)
                self.pressed = 1

        elif btns == 0:
            self.midi_out.note_off(note)
            self.pressed = 0

2 个回答

0

如果你也需要一种方法来发送NRPN(非注册参数号),除了CC(控制变化)之外,可以给我发个消息,我会把我的代码发给你。我正在用pygame制作一个MIDI应用,它可以同时与MIDI CC和NRPN进行通信。

顺便说一下,处理音符开启和关闭的消息时要小心。有些合成器或MIDI控制器在音符关闭时发送的状态消息和音符开启时是一样的,而有些则发送不同的状态消息。你需要确保你的应用不会被这些状态消息搞混。你还需要检查状态消息,以确保它是一个消息,而不是CC消息,反之亦然,否则你可能会触发音符,而不是发送CC消息。

我做的事情是制作一个简单的MIDI接收pygame应用,这帮助我研究MIDI消息的内容以及它们在我用Alesis Andromeda A6合成器触发音符和旋转旋钮时是如何形成的,我使用了简单的打印语句。

顺便问一下,你正在制作什么类型的应用?我很感兴趣。

祝你好运!!!

3

看起来你可以用 write_short 方法来写入原始的MIDI数据包,或者如果你想一次发送多个数据包,可以用 write 方法。举个例子,如果你想在控制器17上发送值123,代码会是这样的:

self.midi_out.write_short(0xb0, 17, 123)

你可能没有在文档中注意到这一点,是因为在MIDI协议中,“状态”这个词通常用来指代消息类型(比如,音符开始、音符结束、控制变化等等)。

撰写回答