mixedinkey-opensource / MIKMIDI

MIDI Library for Swift and Objective-C Mac and iOS apps.
Other
492 stars 95 forks source link

Replace deprecated Core MIDI method calls with designated ones for iOS 14.2 #296

Open hgwhittle opened 3 years ago

hgwhittle commented 3 years ago

Core MIDI APIs such as MIDISourceCreate and MIDISend are deprecated and causing crashes on iOS 14.2. The contemporary methods must be implemented into MIKMIDI to conform to Apple's current MIDI standards and avoid these crashes.

MIDISourceCreate -> MIDISourceCreateWithProtocol https://developer.apple.com/documentation/coremidi/3566495-midisourcecreatewithprotocol?language=occ

MIDISend -> MIDISendEventList https://developer.apple.com/documentation/coremidi/3566494-midisendeventlist

armadsen commented 3 years ago

Thanks for filing this issue. These two functions aren't actually deprecated, they're marked as "to be deprecated", meaning they'll be formally deprecated in a future release. With that in mind, I'm surprised they'd cause a crash, and I wonder if you can provide more information about the crashes you're seeing.

Moving to their replacements seems straightforward, but needs to be conditionalized on availability to continue supporting OS versions older than iOS 14.0 and macOS 11.0 which is when the new variants were added.

ardentra commented 3 years ago

@armadsen have you seen other issues with iOS 14.2? We are sunk right now with customers upgrading to 14.2 and there is no way for them to go back to 14.1 😞.

hgwhittle commented 3 years ago

Hi @armadsen thanks for your response. Hmm.. Apple developer documentation says "Deprecated use X instead" so that's just what I was going off of https://developer.apple.com/documentation/coremidi/1495212-midisourcecreate?language=objc

But I'm also surprised they're causing a crash. This seemed to have come out of nowhere with iOS 14.2. All our investigation points to these methods crashing consistently on iOS 14.2. Here's another example of developers seeing the same thing https://jamosapien.com/t/ios-14-2-beta-external-midi-output-crash/2284

It seems that iOS 14.2 wants MIDI to be setup with either MIDIProtocol_1_0 or MIDIProtocol_2_0. The new APIs support this, while the old ones don't. Here's an example crash that we received. This was on iOS simulator connected to a MIDI network session and sending MIDI notes. I estimate this will be fairly easy to reproduce with a similar environment, but if you need more info please let me know.

Screen Shot 2020-11-14 at 1 26 31 PM
armadsen commented 3 years ago

Thanks for the follow up, @hgwhittle. As of yet, I've been unable to reproduce this. I'm running a simple app in the iOS 14.2 simulator from Xcode 12.2 on macOS 11.0.1 with a Network Session. Sending notes to the network session's endpoint from the iOS app, they show up fine in MIDI Monitor running on the Mac, and the code path you show crashing is not crashing here.

I'm updating my iPad to 14.2 to try there as well.

If you have a project you can share, that would be very helpful.

The project I'm using is here: MIDITest.zip. You'll have to run carthage update before it will build (don't worry about the Carthage build failure, it doesn't matter).

armadsen commented 3 years ago

I've worked on this again today, and have still been unable to reproduce the bug, including on an iPad running 14.2 and outputting to an external hardware MIDI synthesizer. I'm going to implement the new MIDI methods discussed here, but won't be able to test that they actually fix the crashes you've seen. I'll hopefully have that done tonight or tomorrow.

hgwhittle commented 3 years ago

@armadsen thank you for following up. I've since been trying to see if the issue is on my end in any way. I did find that a threading change lessened the chances of the crash, but it's still not done away with completely. I've struggled to find a further pattern, but have come up empty-handed so far. After googling around a bit, I've found more threads complaining about this issue in Core MIDI (will link below).

Definitely a bummer that you aren't able to repro, and I wish I could give more definitive steps. I tried for a bit to tweak the test app that you linked to highlight the crash but no luck so far.

I appreciate your willingness to support the new APIs. I'll definitely give that a try on my end once available and report back to you. Thanks again.

https://forum.juce.com/t/ios-14-2-midi-connections-broken/42440/9

https://www.matrixsynth.com/2020/11/ios-142-breaks-patch-base.html

armadsen commented 3 years ago

Thanks, those links are helpful. I'm a little stuck on implementing MIDISendEventList(), or probably rather doing something wrong in building up a MIDIEventList (which is also new). In particular, while I've written code that I think makes sense, I'm not getting anything out of my synth, so I'll need to do some deeper digging to figure out what's actually getting sent across the wire (if anything), but that'll have to wait until I have some more time. I'm concerned that there's some endianness swap that's happening to break things. Unfortunately, there doesn't seem to be anyone else out there that has implemented any of this new stuff in open source code, nor anyone talking about it, and as usual the documentation is very close to non-existent.

More to come...

armadsen commented 3 years ago

OK, the good news is, I've figured out how to successfully use MIDISendEventList() to send MIDI 1.0 messages. The bad news is that to fully support that and the other new MIDI APIs throughout MIKMIDI is going to take a bit of work. The raw message format for MIDI 1.0 messages under the MIDI 2.0 spec (and thus these new APIs) is called UMP (Universal MIDI Packet) and includes some new, extra information that MIKMIDI doesn't currently know about. In the next few days, I'll push a super limited, experimental implementation for you to test out. It likely won't support sending SysEx messages to start with, since those have changed the most. But it should at least allow you to test that sending messages is no longer crashing on iOS 14.2 (worth noting that I still haven't experienced any crashes on iOS 14.2 in my experimentation).

hgwhittle commented 3 years ago

Thank you @armadsen. I'll update here if I find out anything further as well.