philburk / android-midisuite

Android MIDI test programs and examples.
Apache License 2.0
153 stars 53 forks source link

Unreliable opening 2 ports from same device. #45

Open audetto opened 6 years ago

audetto commented 6 years ago

I've created a test app

https://github.com/audetto/MIDIDeviceTest

Where there is just a fragment with 2 port selectors. And there is a dummy MIDI service. I've made 2 small changes to the MidiTools files

1) Pass a View to MidiPortSelector rather than Activity 2) call myOutputPort.close() in MidiOutputPortSelector.onClose() (but it makes no difference)

Run the app, select 2 ports from the same device and start changing screen orientation.

The ports & the selector are closed in the onDestroy() method, called after a screen turn.

Errors will be logged as

01-23 21:43:57.380 4866-4879/inc.andsoft.asisynth E/MidiTools: could not open MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=1,mProperties=Bundle[{manufacturer=AndSoft Inc., product=ASIMidiSynth, service_info=ServiceInfo{c56d327 inc.andsoft.asisynth.service.SynthMIDIServer}}],mIsPrivate=false 01-23 21:43:57.426 4866-4889/inc.andsoft.asisynth E/MidiTools: could not open MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=1,mProperties=Bundle[{manufacturer=AndSoft Inc., product=ASIMidiSynth, service_info=ServiceInfo{c56d327 inc.andsoft.asisynth.service.SynthMIDIServer}}],mIsPrivate=false

What is strange is that if I select ports from a Service from a different app, the error is less likely to happen.

audetto commented 6 years ago

This time I made 0 changes to the MidiTools files from this repository.

https://github.com/audetto/MyApplicationTestMidi2

There is no MidiService bundled in the app so you will have to try a bit longer to change orientation to get the problem.

1 in 5 it happens to me.

audetto commented 5 years ago

Hi has there been any progress on understanding what happens when 2 ports (an input and an output) are opened from the same device?

philburk commented 2 years ago

@robertwu1 - This sounds similar to the multi-port bug that you just fixed. Although that may have been specific to USB. Can you please investigate this?

robertwu1 commented 2 years ago

The main issue here is that we are calling openDevice for both ports. This is not a good solution to the problem. We should really only open the device once and use it for both ports.

I wrote an MidiInputOutputPortSelector in Kotlin. I'm not sure if we should bring this into our current set of tools given that all of them open either an input port or an output port.

audetto commented 2 years ago

I was writing some filters that would receive midi, modify and send back, and with the current design it was difficult and frustrating.

At minimum, it should error if someone uses it in the wrong way. Otherwise, random behaviour is the worse a programmer can face.

I ended up writing my own layer ensuring I would only ever open the device once.

audetto commented 2 years ago

I found that the device can be opened twice, but success is not guaranteed, and even when it works, should it be closed once? multiple times? If it could just fail the 2nd time it is opened, it would be a lot simpler.