BluetoothDevice and MidiDevice

110 views
Skip to first unread message

mario...@gmail.com

unread,
Jan 8, 2019, 11:53:15 AM1/8/19
to android-midi
I have a question on the lifetime of BluetoothDevice and MidiDevice

In order to create a Midi Device from a BluetoothDevice I have to call MidiManager.openBluetoothDevice.

From that point onward the BluetoothDevice is no more discoverable by a scan.

When will the MidiDevice disappear?

1) when MidiDevice.close() is called
2) when MidiDevice is recollected during gc
3) at the end of the app

It looks like a combination of 1 and 2, maybe with a grace period.

Does anybody know the answer?

Andrea

mario...@gmail.com

unread,
Jan 8, 2019, 4:07:00 PM1/8/19
to android-midi
What I find confusing as well is that after the BluetoothDevice is opened (creating the MidiDevice in the callbak), a MidiDeviceInfo is created in the MidiManager and passed to the callback listeners.
They open it and get another MidiDevice which is then used to open ports.

So the openBluetoothDevice seems an odd design to me, its return value is discarded most of the times (e.g. in the example apps), where all ports are opened via the MidiPortSelector which knows nothing about Bluetooth, but only listens on MidiManager callbacks.

Is there some reference counting here? It seems that as long as I hold of the MidiDevice returned by openBluetoothDevice I can open the other one, but if I call openBluetoothDevice and discard the result (in the callback) then the MidiManager does not always gets notified of a new device being added.

Does it make sense at all?

So, now I have 2 MidiDevices opened for the same BluetoothDevice.

Phil Burk

unread,
Jan 9, 2019, 11:15:08 AM1/9/19
to android-midi
Bluetooth MIDI devices are only available after MidiManager.openBluetoothDevice() is called.
Once that happens anywhere in the system, then the BLE-MIDI device will appear as just another MidiDevice to other apps.

> When will the MidiDevice disappear?
> 1) when MidiDevice.close() is called
> 2) when MidiDevice is recollected during gc

If the device opened using openBluetoothDevice()  is closed, then it will no longer be available. To other apps, it will appear as if the BLE MidiDevice had been unplugged.
If a MidiDevice is garbage collected then it will be closed automatically.
So if you want the BLE-MIDI device to remain available you should keep the original object from MidiManager.openBluetoothDevice().

> Does it make sense at all?

I think you have an accurate understanding of the situation. Is it ideal? No.
So we are looking at ways to simplify the use of BLE-MIDI devices.

Here are links to an app that can be used to create and hold open a BLE-MIDI device.

Here is a BLE-MIDI test procedure:


Phil Burk
 

mario...@gmail.com

unread,
Jan 9, 2019, 3:23:54 PM1/9/19
to android-midi
Ok you are confirming my understanding.
I have taken the MidiBtlePairing app as an example.

And I have found that if the Bluetooth connection goes away in the middle of some operations, I get a full OS crash with reboot. (android 7 galaxy tab S2).

But I guess it is difficult to handle all sort of hardware hotplugging.

Thank you

mario...@gmail.com

unread,
Jan 9, 2019, 3:35:14 PM1/9/19
to android-midi
One last thing on Bluetooth.

If the App is just echoing the MIDI back to the piano and the Local Control is set to ON, so that the note will sound twice

It is possible then to measure the round trip delay.
And it is huge: I recorded and it looks about 10-15 ms.
On a USB MIDI cable I cannot hear the difference.

If I switch the Local Control OFF and only get the note played via the echo app, the piano is unplayable, the delay is off putting.

It really depends on the type of app, wheter Bluetooth is an option.

I guess there is not really anything that can be done. Am I right?

Cheers

Phil Burk

unread,
Jan 9, 2019, 7:10:15 PM1/9/19
to android-midi
> And it is huge: I recorded and it looks about 10-15 ms.

For round trip BLE-MIDI, that is pretty good.
The latency can range from a few msec up to whatever the BLE connection interval is. That can range from 7.5 to 50 msec depending on the peripheral, phone, app, OS version, etc.

This quantizing of events can cause jitter. So BLE-MIDI uses timestamps to record performances more accurately.

The audio output latency on Android can vary from 6 msec to over 1000 msec depending on the device. But typically it will be under 100 msec. We are working closely with manufacturers to reduce this latency.

> I guess there is not really anything that can be done. Am I right?

BLE-MIDI will have higher latency than USB-MIDI. There is not much an app can do.

Phil Burk

mario...@gmail.com

unread,
Jan 13, 2019, 11:04:58 AM1/13/19
to android-midi
The question I was asking might be a bit more concrete that purely theoretical.

As we said the bluetooth device is opened and the corresponding midi device held somewhere (e.g. in the MidiBtlePairing app).

Now, my apps can open the BTLE Midi Device like any other USB midi device.
Imagine I rotate the screen: in most cases onDestroy() and onCreate() are called.

OnDestroy() will clean up the resources including all the MidiDevices held (e.g. MidiInputPortSelector.onClose(), called by MidiScope.MainActivity.onDestroy()).
So by the time onCreate() is called, the BTLE device should have gone.

This is not what I see as the Bluetooth device seems to survive a rotation, while other times it disappears from the drop down a few seconds later.

Does MidiDevice.close() really closes the Bluetooth Device?

If so, then a robust app needs a much more sophisticated handling of device opening that the simple examples provided, probably handing the device management to a ViewModel.

If not, why? What is the exact rule around the lifetime of these devices?

I know I have been asking this for a while, but I can seem to land on a predictable behaviour.

Thank you

Core Form

unread,
Jan 13, 2019, 6:25:41 PM1/13/19
to androi...@googlegroups.com
You don't have to hold objects with the Activity context, although that is the norm for 99% of apps and Devs, the 1% is where apps are interesting.

E.g. I overhauled a banking app to reuse a WebView by holding it with Application context. Unfortunately Google didn't appreciate that possibility and didn't think to allow for such a scenario when rolling out their Chrome WebView, so be careful of Google seriously messing things up but don't let that stop you innovating.


--
You received this message because you are subscribed to the Google Groups "android-midi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-midi...@googlegroups.com.
To post to this group, send email to androi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-midi/fb4a2df6-c827-4959-b36e-04012f7d51da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

mario...@gmail.com

unread,
Jan 14, 2019, 4:36:48 PM1/14/19
to android-midi

In order to remove my errors from the equation I have used just the plain Midi+BTLE from Google Play.

The first scan returns a device to the main screen.
The I press the X and the device goes.

Then I scan again and the device returned to the main screen has a 50-50 chance (probably more) to disappear within a second.

I have the exact same behaviour on my app (which mirrors closely Midi+BTLE) and I can guarantee that nothing is calling .close() on the MidiDevice.

I have tried to debug but a lot of the code in no reachable with a debugger (I think it is native code).
This behaviour happens every time I run the app.

I guess one could blame the Piano (a CA78), but why would the first time an app connects works and then stop till the app runs again?

Regards
Reply all
Reply to author
Forward
0 new messages