philburk / android-midisuite Goto Github PK
View Code? Open in Web Editor NEWAndroid MIDI test programs and examples.
License: Apache License 2.0
Android MIDI test programs and examples.
License: Apache License 2.0
A reviewer requested having two keyboards stacked so she can reach more keys on screen.
It is supposed to have an X in a red circle.
I'm still getting this SecurityException when closing the Synth Activity
Needed to compile with current Android Studio.
Trying to understand the way MidiFramer handles SysEx messages.
If a long SysEx arrives, is the MidiFramer goal to present it to the next MidiReceiver as a single package?
My piano sends back a 30 byte SysEx message, but the MidiFramer sends it back in 3 tranches.
Before investigating more, whose role would it be to make it a single long SysEx message?
The Google Play Store require SDK 33 for new apps.
We should use 33 in case developers copy these apps.
When upgrading to 33 I started getting exceptions for missing Permissions for the MIDI+BTLE app.
I needed to add BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions.
Hi, is it possible to use this in order to say attach a USB midi keyboard to my Android phone and via Bluetooth connect to my iPad.
Ideally I'd then be able to play the keyboard and send midi data to my iPad.
If the MidiKeyboard app is started and then connected to the SynthExample then the latency is high.
But if the SynthExample app is started first and then connected to a USB MIDI Keyboard then the latency is low.
See internal Android bug b/70851203 | SynthExample audio latency unexpectedly high, 240 msec, app bug
Hi,
just bought a AkaiPRO LPK25 wireless to use with my tabled and smartphone.
On my Redmi Note 7, running on LineageOS 18.1 official, the "Midi Ble connect"-app works perfect. But on my Galaxy S5e tables (runnin gon stock ROM, Android 11) the Midi Ble connect-app can't find the LPK25 wireless midi keyboard.
The tablet can find the LPK 25 wireless using the Android default bluetooth app, but without the Midi Ble connect app it can't pair properly for midi purpose.
Contacting the developer he told me to open a case right here containind the information above.
I came here after strugling with this in my own use of this android api. I see the same behaviour with you code here. For me it seems gthat android bluetooth midi scanner input device output port is broken or not compatible some android versions.
I tested it on Samsun Galaxy tab 6 lite android 13 TP1A
I also tested with same behaviour on Androiud 11 Xiaomi M9T
Setp to reproduce:
Start bluetooth advertise on MacOS. Open MIDI+BTLE start scan connect, open sytnh set port , toas ok displays..
On macos nothing changes and device is not accesible.
I open Gadget on ipad, bluetooth midi devices , connect to same macbook , device opens up midi studio and is accesible in ableton live.
Android just dont work at all with macbook/macos for me.
Is there any solution ? I have see one difference that pairing dialog popped up for ipad but not android devices.
When the spinner associated to the MidiPortSelector is recreated after a screen rotation, it might not select the same Midi device as before the selection.
This happens if a device is added, as it will go to the end of the list, not its natural position when the Port selector queries devices after the rotation.
gradle-6.7.1 is too old , when I check out poject I have to update to build it..
08-08 10:45:31.439 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{1acc375 net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false 08-08 10:45:31.440 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{b9b0f0a net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false 08-08 10:45:31.441 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{b56a37b net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false 08-08 10:45:31.442 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{5d54598 net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false 08-08 10:45:31.443 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{29321f1 net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false 08-08 10:45:31.443 12717-12717/? I/MidiTools: MidiPortSelector.onDeviceStatusChanged status = mInputPortOpen=[true] mOutputPortOpenCount=[], mType = 1, activity = com.mobileer.midikeyboard, info = MidiDeviceInfo[mType=2,mInputPortCount=1,mOutputPortCount=0,mProperties=Bundle[{manufacturer=Volcano Mobile, product=Wavetable Synth, service_info=ServiceInfo{e6311d6 net.volcanomobile.sonivoxeasmidi.MidiSynthDeviceService}}],mIsPrivate=false
A reviewer requested being able to move the keys down to get lower pitches.
We should add a sliding bar above the keys for transposing.
Some devices could generate input events with a negative X or Y.
This caused the X to Pitch calculation to generate a negative array index.
java.lang.ArrayIndexOutOfBoundsException:
at com.mobileer.miditools.MusicKeyboardView.xToWhitePitch (MusicKeyboardView.java:344)
at com.mobileer.miditools.MusicKeyboardView.onFingerMove (MusicKeyboardView.java:272)
at com.mobileer.miditools.MusicKeyboardView.onTouchEvent (MusicKeyboardView.java:236)
Hi - I have used your code for creating a simple app based on MidiScope that bridges input ports to output ports. This combined to MIDI-BTLE gives access to MIDI BTLE to systems that are only USB-MIDI compliant.
The code is ready and I'm looking for guidance on making this contribution as I'd like to see this in the Play Store.
Connect a WidiJack BLE-MIDI device to a Pixel 8 Pro running UDC.
Select the WidiJack in the MIDI Keyboard app.
Go back to the MIDI+BTLE app.
Press the X button.
EXPECT - close the WidiJack device
ACTUAL - button press ignored
When I deselect WidiJack in the MIDI Keyboard then the item closes in the MIDI+BTLE app.
Mario wrote:
If I have 2 selectors, and they both select (different) ports on the same device, when one of the spinners changes selection, the close() method is called on the device. But this device is being used by the other selector, is it reference counted internally? What does it mean to close it, while a port might be still in use elsewhere?
Good question. This needs to be investigated.
Hi
I built an app https://play.google.com/store/apps/details?id=com.humtools.midikontrol
This is based on your MIDI synthesizer example. For USB interfacing, I have used your code verbatim.
However a lot of users have been complaining that the app disconnects after around 10 minutes. And this is on various devices as reported by users.
Here are two of the reviews (and many others have reported a similar thing):
After 10 minutes of testing this app on Bitwig, it throws a message saying "Please connect a valid Midi receiver through the MIDI port on your device". Meaning the phone stopped working as a Midi device, tested with different cables with the same result on a Samsung Galaxy Note 8.
Another review:
I wanted to report one little bug. Sometimes when using the app it stops sending MIDI to computer. Mostly it happens after leaving the app for a moment and going back into it.
When it stops sending MIDI I discovered the whole USB functions in Android doesn't work anymore. Then I have to restart my phone to make it work again.
I am at a loss as to why this should happen.
Any suggestions would be helpful.
I can share the entire source code if you so wish.
regards
To reproduce:
Run MidiKeyboard on a device that does not have the MIDI feature.
(Not sure how that can happen. Maybe it was side loaded by an OEM.)
Then Click one of the Program buttons.
EXPECT: no response
ACTUAL:
Caused by: java.lang.NullPointerException:
at com.mobileer.midikeyboard.MainActivity.midiSend (MainActivity.java:176)
at com.mobileer.midikeyboard.MainActivity.midiCommand (MainActivity.java:157)
at com.mobileer.midikeyboard.MainActivity.onProgramSend (MainActivity.java:111)
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
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.
Steps to repro
Expected result
Actual result
I tried this on 2 Pixel XLs running Android 10. Interestingly if I go to bluetooth settings -> Pair new device the BLE-MIDI device is listed in the list of available devices so my guess is something has changed in Android 10 (more stringent permissions maybe?) which is stopping the app from scanning correctly.
Good evening,
Do you plan on converting these to kotlin form at any point? I've spent hours pouring over the android docs which are java centric as well as your examples, and while it seems I can get 80% of the way there with the android studio auto convert, ultimately, nothing works.
I know it's software and not hardware as both the midi pairing and midi scope apps on the playstore work just fine with my keyboard.
Thank you.
I've encountered everything from small unresolveable issues with work arounds
e.g. this filter removes the keyboard from the list, yet in your app source code the filter exists and the app shows up.
my solution: no filters but then I see every possible bluetooth device in the vicinity.
val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
.addServiceUuid(ParcelUuid.fromString("03B80E5A-EDE8-4B33-A751-6CE34EC4C700"), null)
.build()
to more serious problems:
I can pair to and see the bt device and even open it e.g. getting as far as this callback and null check pass- but pressing keys on the keyboard doesn't trigger any printouts.
private fun onBluetoothDeviceOpen(
bluetoothDevice: BluetoothDevice,
midiDevice: MidiDevice?
) {
Log.d("tok", "on bt open, open callback")
val outputPort2: MidiOutputPort? = (midiDevice?.openOutputPort(0))
if (outputPort2 != null) {
Log.d("tok", "null check pass")
outputPort2.connect(MyReceiver())
}
}
internal class MyReceiver : MidiReceiver() {
@Throws(IOException::class)
override fun onSend(
data: ByteArray, offset: Int,
count: Int, timestamp: Long
) {
// parse MIDI or whatever
Log.d("tok", timestamp.toString())
Log.d("tok", data.toString())
}
}
Please could you add the Bluetooth LE connection parameters for the lowest possible latency with a BLE-MIDI keyboard.
Hi, I have the latest Android Studio on my Win11 computer. I tried opening your MIDISCOPE project in it, and it shows this error:
BUG! exception in phase 'semantic analysis' in source unit 'BuildScript' Unsupported class file major version 61
I didnt change anything, I just tried opening it on Android Studio. Any suggestion how can I fix it?
We pass an Activity to the constructor but it would be more helpful to just pass the Spinner.
We can add a new constructor without breaking old apps.
Should probably be (23)
@TargetApi(3)
public void update() {
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.