All notable changes to MIKMIDI are documented in this file. This project adheres to Semantic Versioning. GitHub issue numbers for changes are in parentheses where available.
This section is for recent changes not yet included in an official release.
- A brand new version of the MIDI Testbed example app written using SwiftUI. Thanks to @jranson. (#302)
(NS)NotificationCenter
notifications are posted for MIDI Device and Entity changes (#319)MIKMIDIEntityWasChangedNotification
's user info now has the changed object as the value for theMIKMIDIEntityKey
(#319, #321)
- 14-bit messages are correctly split into separate MSB and LSB messages when sending via a virtual endpoint (#329)
- MIDI to Audio example no longer fails due to changed MIKMIDI APIs. Thanks to @jupdike. (#316)
- Support for recording control change (CC) events in MIKMIDISequencer (#262)
- MIKMIDI can now be built as a xcframework with support for iOS (device and simulator), macOS, and Mac Catalyst. Run the
build_xcframework.sh
script inFramework/
or build the MIKMIDI.xcframework target in Xcode.
- Bug where
-[MIKMIDIInputPort sourceEndpointForConnectionToken:]
always returned nil, causing duplicate event handler calls upon re-establishing a previous connection (#263) - Failure to copy
lastSyncedMusicTimeStamp
to historical clock inMIKMIDIClock
(#268) - Race condition in
MIKMIDISynthesizer
- Greatly improved performance of
-[MIKMIDITrack eventsOfClass:fromTimeStamp:toTimeStamp:]
(and dependent methods) (#275) - Incorrect behavior of
-[MIKMIDITrack eventsOfClass:fromTimeStamp:toTimeStamp:]
when passed aNil
eventClass
- Build warning in Xcode 12 beta
Thanks to all who contributed bug reports and pull requests to this release!
- An
outputPort
property onMIKMIDIDeviceManager
(#251) - Support for saving/loading MIDI mappings on iOS (#131)
- Support for sending 14-bit control change messages (#230/#235)
- Sysex message coalescing (#122, #198, #200)
- Custom initializers for various
MIKMIDIMetaEvent
subclasses (#150)
- MIKMIDISynthesizer (and subclass) creation methods now take an
NSError
parameter. Non-error-returning versions are deprecated. (#217)
- Several sharp edges when bridging into Swift (#207, #216, #238)
- Exception thrown when converting channel pressure and polyphonic key pressure events to commands (#249)
- Failure to parse sysex messages in certain circumstances (#233)
- Bug that caused setting
MIKMIDISystemExclusiveCommand.sysexChannel
to sometimes delete or corruptsysexData
(#239) - Crash caused by race condition in
MIKMIDIInputPort
(#223) - Failure to notice new virtual endpoints created in other processes (#120)
- Duplicate virtual devices in connection manager
- Crash when MIDI events are received after an
MIKMIDIConnectionManager
has been deallocated (#215)
- System Exclusive multi-packet coalescing (#200)
MIKMIDISystemKeepAliveCommand
for keep alive messagesMIKMIDIPacketCreateFromCommands()
- Convenience method for creating control change commands
-[MIKMIDIDeviceManager connectedDevices]
is no longer always nil (#162)- Incorrect MIKMIDIClock timing on iOS devices (#180 and #199)
- Incorrect metaDataType on instances of
MIKMIDIMetaEvent
subclasses (#151) - Minor GCD queue creation bug (#204)
- Parsing multiple MIDI messages of different types in a single incoming packet (#201)
- Buffer overflow in
-[MIKMIDISystemExclusiveCommand manufacturerID]
(#197) - Memory leak in
MIKStringPropertyFromMIDIObject()
(#206) - Retain cycle between
MIKMIDISequence
andMIKMIDISequencer
(#205) - Bug that caused note offs to be scheduled early by
MIKMIDISequencer
- Frequent hash collisions between instances of
MIKMIDIObject
(#181) - Minor Swift incompatibilities
- MIDI To Audio example project showing how to use MIKMIDI to do offline rendering of MIDI to an audio file. (#164)
- Incorrect nullability annotations for MIKMIDINoteEvent convenience methods.
- Minor documentation mistakes.
- Updated example projects for Xcode 8.
- Moved macOS example projects into a "macOS" subfolder of Examples.
- Email address for maintainer (Andrew Madsen).
MIKMIDISequencer
now respects the offset, muted, and solo properties ofMIKMIDITrack
. (#99)- Error-returning variant of
-[MIKMIDISequence addTrack:]
,-addTrackWithError:
.-addTrack:
is now deprecated. (#134) - Added
maximumLookAheadInterval
property toMIKMIDISequencer
(ac8142b) - Fixed issue where click track events would be added to the beginning of a loop when the status was EnabledOnlyInPreRoll. (2535c5b)
- Convenience initializers for
MIKMIDINoteOn/OffCommand
that takeMIDITimeStamp
s instead ofNSDate
s. (0bf4a00) - Custom initializers for several
MIKMIDIMetaEvent
subclasses, greatly simplifing their creation. (#150) MIKMIDIPacketCreate()
function to ease creatingMIDIPacket
structs in Swift. (a12f121)
- Improved support for subclassing
MIKMIDISynthesizer
and customizing MIDI event scheduling (87b38ea)
- Issue where
MIKMIDISequencer
would almost immediately stop recording if its sequence was empty. (#45) MIKMIDIMetronome
allows loading soundfonts. (a50ccdf)- Issue with stuck notes in
MIKMIDISequencer
's pre-roll. (07a9304) MIKMIDISequencer
now ignores incoming MIDI in recording mode during the pre-roll. (2312e4d)- Potentional crash in
MIKMIDISequencer
. (4c0ce02) MIKMIDIGetCurrentTimeStamp()
is now available in Swift (658cb63)- Scheduling issues in
MIKMIDISynthesizer
(6698fad) - Updated MIDI Files Testbed to fix deprecation warnings.
- Improved MIDI Soundboard example for iOS (#119, d0ada0a, a35ee94)
- Incorrect length for some
MIKMIDICommand
subclass instances when created with alloc/init. (#125) - Incorrect MSB calculation for pitch bend commands. (#147, thanks to akmidd)
- Bug in logic for detecting and exposing available virtual sources and destinations (#144, #145, thanks to jrmaxdev)
This release deprecates a number of existing MIKMIDI APIs. These APIs remain available, and functional, but developers should switch to the use of their replacements as soon as possible.
-[MIKMIDISequence addTrack:]
. Use-addTrackWithError:
instead. (#134)
MIKMIDISynthesizer
for general-purpose MIDI synthesis.MIKMIDIEndpointSynthesizer
is now a subclass ofMIKMIDISynthesizer
.MIKMIDISequencer
now has API for routing tracks to MIDI endpoints, synthesizers, or other command scheduling objects (-(setC|c)ommandScheduler:forTrack:
)- Nullability and Objective-C generics annotations for much nicer usage from Swift. (#39 & #108)
- API for loading soundfont files using
-[MIKMIDISynthesizer loadSoundfontFromFileAtURL:error:]
. (#47) - Added
MIKMIDIEvent
subclassMIKMIDIChannelEvent
and related children (MIKMIDIPitchBendChangeEvent
,MIKMIDIControlChangeEvent
, etc.). (#63) - Added
MIKMIDIChannelVoiceCommand
subclasses for remaining MIDI channel voice message types (pitch bend, polyphonic key pressure, channel pressure). (#65) - API on
MIKMIDISequence
to control whether channels are split into individual tracks or not. (#66) - Preliminary unit tests (still need a lot more coverage with tests).
- API on
MIKMIDISequencer
to set playback tempo (overrides sequence tempo). (#81) - Ability to explicitly stop
MIKMIDIMappingGenerator
's mapping via-[MIKMIDIMappingGenerator endMapping]
. (#84) - Looping API on
MIKMIDISequencer
(#85) - API for syncing
MIKMIDIClock
s (see-[MIKMIDIClock syncedClock]
). (#86) - Ability to suspend MIDI mapping generation, then later resume right where it left off (
-[MIKMIDIMappingGenerator suspendMapping/resumeMapping]
). (#102) - API for customizing mapping file naming. See
MIKMIDIMappingManagerDelegate
. (#114) MIKMIDIConnectionManager
which implements a generic MIDI device connection manager including support for saving/restoring connection configuration to NSUserDefaults, etc. (#106)- Other minor API additions and improvements. (#87, #89, #90, #93, #94)
MIKMIDIEndpointSynthesizerInstrument
was renamed toMIKMIDISynthesizerInstrument
. This does not break existing code, due to the use of@compatibility_alias
MIKMIDISequencer
creates and uses default synthesizers for each track, allowing a minimum of configuration for simple MIDI playback. (#34)MIKMIDISequence
andMIKMIDITrack
are now KVO compliant for most of their properties. Check documentation for specifics. (#35 & #67)MIKMIDISequencer
can now send MIDI to any object that conforms to the newMIKMIDICommandScheduler
protocol. Removes the need to use virtual endpoints for internal scheduling. (#36)- Significantly improved performance of MIDI responder hierarchy search code, including adding (optional) caching. (#82)
- Improved
MIKMIDIDeviceManager
API to simplify device disconnection, in particular. (#109)
MIKMIDIEndpointSynthesizer
had too much reverb by default. (#38)MIKMIDISequencer
's playback would stall or drop notes when the main thread was busy/blocked. Processing is now done in the background. (#48 & #92)MIKMIDIEvent
(or subclass) instances created withalloc/init
no longer have a NULLeventType
. (#59)- Warnings when using MIKMIDI.framework in a Swift project. (#64)
- Bug that could cause
MIKMIDISequencer
to sometimes skip the first events in its sequence upon starting playback. (#95) - Occasional crash (in
MIKMIDIEventIterator
) duringMIKMIDISequencer
playback. (#100) - KVO notifications for
MIKMIDIDeviceManager
'savailableDevices
property now includ validNSKeyValueChangeOld/NewKey
entries and associated values. (#112) - Exception is no longer thrown when setting "empty"
MIKMutableMIDIMetaTimeSignatureEvent
's numerator. (#57) - Other minor bug fixes (#71, #83)
This release deprecates a number of existing MIKMIDI APIs. These APIs remain available, and functional, but developers should switch to the use of their replacements as soon as possible.
-[MIKMIDITrack getTrackNumber:]
. UsetrackNumber
@property onMIKMIDITrack
instead.-[MIKMIDISequence getTempo:atTimeStamp:]
. Use-tempoAtTimeStamp:
instead.-[MIKMIDISequence getTimeSignature:atTimeStamp:]
. Use-timeSignatureAtTimeStamp:
instead.doesLoop
,numberOfLoops
,loopDuration
, andloopInfo
onMIKMIDITrack
. These methods affect looping when usingMIKMIDIPlayer
, but notMIKMIDISequencer
. Use-[MIKMIDISequencer setLoopStartTimeStamp:endTimeStamp:]
instead.-insertMIDIEvent:
,-insertMIDIEvents:
,-removeMIDIEvents:
, and-clearAllEvents
on MIKMIDITrack. Use-addEvent:
,-removeEvent:
,-removeAllEvents
instead.-[MIKMIDIDeviceManager disconnectInput:forConnectionToken:]
. Use-disconnectConnectionForToken:
instead.-setMusicTimeStamp:withTempo:atMIDITimeStamp:
,+secondsPerMIDITimeStamp
,+midiTimeStampsPerTimeInterval:
onMIKMIDIClock
. See documentation for replacement API.+[MIKMIDICommand supportsMIDICommandType:]
. Use+[MIKMIDICommand supportedMIDICommandTypes]
instead. This is only relevant when creating custom subclasses ofMIKMIDICommand
, which most MIKMIDI users do not need to do. (#57)
- Support for Carthage
- Better error handling for
MIKMIDIClientSource/DestinationEndpoint
, particularly on iOS. MIKMIDISequence
initializer methods that include an error parameter.
- Improved documentation.
MIKMIDIMetronome
on iOS (8).MIKMIDICommand
's channel now defaults to 0 as it should.
-[MIKMIDISequence initWithData:]
. Use-[MIKMIDISequence initWithData:error:]
, instead.+[MIKMIDISequence sequenceWithData:]
. Use+[MIKMIDISequence sequenceWithData:error:]
, instead.-[MIKMIDISequence/MIKMIDITrack setDestinationEndpoint:]
. Use API on MIKMIDISequencer instead.
- MIDI Files Testbed OS X example app
- Added
MIKMIDISequence
,MIKMIDITrack
,MIKMIDIEvent
, etc. to support loading, creating, saving MIDI files - API on
MIKMIDIManager
to allow obtaining only bundled or user mappings MIKMIDIPlayer
for playing MIDI files- Preliminary (experimental/incomplete) implementation of
MIKMIDISequencer
for both playback and recording MIKMIDIEndpointSynthesizerInstrument
and associated instrument selection API for MIDI synthesis- API (
MIKMIDIClientSource/DestinationEndpoint
) for creating virtual MIDI endpoints - iOS framework target.
- Improved README.
- Fixed bug where sending a large number of MIDI messages at a time could fail.
MIKMIDIMapping
save/load is now supported on iOS.- Warnings when building for iOS.
- Added
MIKMIDIEndpointSynthesizer
for synthesizing incoming MIDI (OS X only for now). - Added Cocoapods podspec file to repository.
MIKMIDIInputPort
can parse multiple MIDI messages out of a single packet.
Minor documentation typo fixes.
Initial release