iOS 14.2 MIDI connections broken

Does this fix work at runtime, or is it compile time thing? I haven’t done swift, so I don’t know about the @available thingy :slight_smile:

1 Like

@available works at runtime, which means if you build with the iOS 14 SDK but an old deployment target, the resulting app should work smoothly on all devices, selecting the newer API if it is a available and falling back to the old one otherwise.

We’ve also added compiletime SDK-version checks. This means that if you only build with an old SDK, the codepath using the new API won’t be built at all; and if you build with a deployment target of iOS 14+, the codepath using the old API won’t be built at all.

Using the new fix, I’m still getting at least one of the 2 errors I was getting before… I still get CoreMIDI errors thrown in getMidiObjectInfo(), but this time they have different numbers:

CoreMIDI error: 366 - ffffffce
CoreMIDI error: 372 - ffffffce
CoreMIDI error: 380 - ffffffce

I tested various deployment targets to make sure that the compile-time and runtime logic you describe above and I think it does (I also don’t know anything about swift!).

If I build with a deployment target of iOS 11 (as usual), I get into these if clauses:

And if I build with iOS 14 or 14.2 as deployment targets I’m avoiding all this stuff due to JUCE_HAS_OLD_COREMIDI_API being set to 0 at the beginning of the file.

This is all with xcode 12.2. I believe I could potentially test older iOS SDKs if I downloaded older versions of xcode, but I wasn’t sure if that would be helpful? I couldn’t find how to use an older SDK inside xcode 12.2…

OTOH, iOS 14.3 beta 2 and 3 have been really stable for me… Hopefully we get a release soon :crossed_fingers:

Seems like this is still broken in iOS 14.3.

When I was initially looking at this issue, I put together a test app which was sending midi messages on a fast timer, which was crashing fairly consistently. I just tested the same demo program on a device running iOS 14.3, and it doesn’t crash at all. It works whether I use the “old” or “new” CoreMIDI APIs. If there are still MIDI issues in 14.3, I think they may be different issues, or at least trigger under different circumstances.

Please can you provide more details about the issue you’re seeing? What kind of failure are you getting? (A crash, an assertion, messages in the console, build errors…). Can you share any code which triggers the issue?

I’m sending sysEx messages. I’m not seeing crashes anymore, but my sysEx messages aren’t being sent either. I’m do some more testing.

If you find an issue, it’d also be useful to know which JUCE version you’re using for testing, which Xcode version you’re using for building, and which deployment target you’re building for.

I’m not using juce, so I don’t really expect any support. I’ll share what I’m seeing though. Using the deprecated methods, i’m seeing issues when connecting / disconnecting to MIDIEndpoints. The first time connecting is not an issue, but connecting, sending a sysEx and then disconnecting causes ios 14.2+ to hang. Crash report is below.

Using the new methods, there are no crashes with connecting and / disconnecting to endpoints, but there are still issues handling sysEx messages. To be honest, I’m not even sure how to pack my 7bit sysEx messages inside the 32 bit packets. Is it one sysEx byte per packet packet, or do we need to pack four bytes into one packet? I suspect it’s the later.

Regards,
Rob

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Termination Description: SPRINGBOARD, <RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: application<com.audiofront.eDrumIn-iOS>:1039 exhausted real (wall clock) time allowance of 10.00 seconds | ProcessVisibility: Foreground | ProcessState: Running | WatchdogEvent: scene-update | WatchdogVisibility: Background | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 12.560 (user 12.560, system 0.000), 63% CPU", | "Elapsed application CPU time (seconds): 9.915, 50% CPU" | ) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001ac7aebf0 __semwait_signal + 8
1   libsystem_c.dylib             	0x0000000189d6a6d4 nanosleep + 212
2   libsystem_c.dylib             	0x0000000189d6a5ac usleep + 64
3   CoreMIDI                      	0x00000001b08991b8 LocalMIDIReceiverList::ReceiverConnectEndpoint+ 283064 (unsigned int, unsigned int, void*, bool) + 164
4   CoreMIDI                      	0x00000001b0899800 MIDIPortDisconnectSource + 468

That’s an interesting bug, if I get a chance I’ll see if I can repro it here.

Each SysEx7 packet is actually made up of two 32-bit words. The first word contains two bytes of book-keeping info (message type, group, sysex type, num bytes), followed by up to 6 7-bit values. The exact structure is a bit involved to explain here - I’d recommend signing up to the MIDI association website, and downloading the Universal MIDI Packet spec. You could also check this site for an overview of the packet structure - look for 8-byte Data messages.

Looks like I have resolved the issue by changing the location of where I create my MIDI Client.