Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIDI port connection changes not detected (3301) #1637

Open
GalacticEmperor1 opened this issue Feb 12, 2023 · 0 comments
Open

MIDI port connection changes not detected (3301) #1637

GalacticEmperor1 opened this issue Feb 12, 2023 · 0 comments
Labels
bug Not working as intended midi pygame.midi

Comments

@GalacticEmperor1
Copy link
Collaborator

Issue №3301 opened by Erriez at 2022-07-13 19:56:02

Environment:

  • Operating system: Windows 10
  • Python version : 3.91.0
  • SDL version: N.A.
  • PyGame version : 2.1.2
  • Relevant hardware: N.A.

Current behavior:

The function pygame.midi.get_count() always returns the same number of MIDI ports after startup, even after a MIDI device connect/disconnect.

Application background: When clicking on a drop-down box, it should update new connected/disconnected MIDI ports.

Expected behavior:

Update number of MIDI ports after connect/disconnect.

Screenshots

N.A.

Test code

  1. Run test code:
import pygame

pygame.init()
pygame.midi.init()

while True:
    print(pygame.midi.get_count())
    time.sleep(1)

Output for example: 2 MIDI ports.

  1. Connect MIDI device.
  2. Output is still 2 MIDI ports.
  3. Restart Python script
  4. Output is for example: 4 MIDI ports.

Stack trace/error output/other error logs

N.A.


Comments

# # Starbuck5 commented at 2022-07-14 07:13:49

Would it work if you quit and re init the midi module?

pygame.midi.quit()
pygame.midi.init()

I don't think the portmidi backend has hotplugging support, see: mixxxdj/portmidi#8 issuecomment-933869739


# # Erriez commented at 2022-07-14 11:20:38

I created a test case which calls the quit() and init() functions before get_count() and then the number of ports is updated correctly. However, open MIDI connections are closed which is a problem for my application design.

Testcase:

import pygame
import pygame.midi
import time


def get_mini_ports():
    #  Hack to re-initialize MIDI to return updated `get_count()`
    #  Open MIDI connections are closed!
    pygame.midi.quit()
    pygame.midi.init()

    midi_ports = []
    for i in range(pygame.midi.get_count()):
        (midi_interface, midi_name, midi_input, midi_output, opened) = pygame.midi.get_device_info(i)

        midi_interface = midi_interface.decode('utf-8')
        midi_name = midi_name.decode('utf-8')

        midi_ports.append({
            'ID': i,
            #  'midi_interface': midi_interface,
            'midi_name': midi_name,
            'midi_input': midi_input,
            'midi_output': midi_output,
            'opened': opened
        })
    return midi_ports


def print_mini_ports(portout):
    #  Send some Sysex data
    portout.write_sys_ex(pygame.midi.time(), [0xf0, 0x00, 0x00, 0x00, 0x00, 0xf7])
    print('Write before MIDI quit()/init(): OK')

    print('MIDI ports: ')
    for port in get_mini_ports():
        print('  {}'.format(port))

    #  Send some Sysex data
    portout.write_sys_ex(pygame.midi.time(), [0xf0, 0x00, 0x00, 0x00, 0x00, 0xf7])
    print('Write after MIDI quit()/init(): OK')


if __name__ == '__main__':
    #  Initialize Pygame
    pygame.init()
    pygame.fastevent.init()
    pygame.midi.init()

    #  Open MIDI port
    portout = pygame.midi.Output(1)

    while True:
        print_mini_ports(portout)
        time.sleep(1)

I don't think the portmidi backend has hotplugging support, see: mixxxdj/portmidi#8 issuecomment-933869739

Thanks for your confirmation.

It looks like correctly handled by Python https://github.com/mido/mido package, but need to investigate further:

import mido
import time

#  Connect/disconnect MIDI devices while printing MIDI ports:
while True:
    print('MIDI inputs:')
    print(mido.get_input_names())
    print('MIDI outputs:')
    print(mido.get_output_names())
    time.sleep(1)

# # Starbuck5 commented at 2022-07-15 01:02:54

It looks like correctly handled by Python https://github.com/mido/mido package, but need to investigate further:

See, it's funny you say that, since mido says it has three backends:

  • pygame
  • portmidi (pygame's backend)
  • rtmidi (unrelated)

# # Erriez commented at 2022-07-15 17:31:19

You're right, I used the mido API with backend python-rtmidi. After some additional investigation, I found a bug in python-rtmidi: Incorrect MIDI port names. I reported the bug in mido/mido#381, SpotlightKid/python-rtmidi#111.

So I'll continue with Pygame and implement a workaround where the MIDI ports are not updated after init and connect/disconnect. In this case the user should always disconnect an open MIDI port, then the MIDI ports are updated correctly as you suggested.

@GalacticEmperor1 GalacticEmperor1 added bug Not working as intended midi pygame.midi labels Feb 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not working as intended midi pygame.midi
Projects
None yet
Development

No branches or pull requests

1 participant