summaryrefslogtreecommitdiffstats
path: root/third_party/rust/coremidi-sys
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/coremidi-sys')
-rw-r--r--third_party/rust/coremidi-sys/.cargo-checksum.json1
-rw-r--r--third_party/rust/coremidi-sys/Cargo.lock16
-rw-r--r--third_party/rust/coremidi-sys/Cargo.toml24
-rw-r--r--third_party/rust/coremidi-sys/LICENSE21
-rw-r--r--third_party/rust/coremidi-sys/README.md20
-rw-r--r--third_party/rust/coremidi-sys/build.rs5
-rw-r--r--third_party/rust/coremidi-sys/examples/print_midi_device_count.rs10
-rw-r--r--third_party/rust/coremidi-sys/src/generated.rs1102
-rw-r--r--third_party/rust/coremidi-sys/src/lib.rs149
9 files changed, 1348 insertions, 0 deletions
diff --git a/third_party/rust/coremidi-sys/.cargo-checksum.json b/third_party/rust/coremidi-sys/.cargo-checksum.json
new file mode 100644
index 0000000000..da15f635ba
--- /dev/null
+++ b/third_party/rust/coremidi-sys/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"5f0a97e828227e612f93d11707b32067b20cac33e35645418dc88dd48e431db0","Cargo.toml":"6ec83d2168da5c4190a607fdb75a14b594fdc2d92bfaff4b8025385c414cda2a","LICENSE":"9e3de4600052da55698dfbcaa43a90324434d82efde92c7bf7d48010f9a579c7","README.md":"1fc9252739d1755842422b776d76f6bee502ac81c3f546d619a017246e5aeeba","build.rs":"73ba81bf5151f18b6c53acc94097cf2abb4c8c3832d1d0eaf661dab22342c1b7","examples/print_midi_device_count.rs":"24d69d14b80ad0d376e98914a3e1c5ffe27ae8bb8243704fe5bf72ea9297e21e","src/generated.rs":"93726f070406362aa1947848756d598307f6e80531cd961c679da2712ffc9628","src/lib.rs":"12e05f6db827a29821be82581b4fa5b9f64d2eca4ae7f95c0bcc433252be5165"},"package":"79a6deed0c97b2d40abbab77e4c97f81d71e162600423382c277dd640019116c"} \ No newline at end of file
diff --git a/third_party/rust/coremidi-sys/Cargo.lock b/third_party/rust/coremidi-sys/Cargo.lock
new file mode 100644
index 0000000000..58f59780b8
--- /dev/null
+++ b/third_party/rust/coremidi-sys/Cargo.lock
@@ -0,0 +1,16 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "coremidi-sys"
+version = "3.1.0"
+dependencies = [
+ "core-foundation-sys",
+]
diff --git a/third_party/rust/coremidi-sys/Cargo.toml b/third_party/rust/coremidi-sys/Cargo.toml
new file mode 100644
index 0000000000..92dae60449
--- /dev/null
+++ b/third_party/rust/coremidi-sys/Cargo.toml
@@ -0,0 +1,24 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+name = "coremidi-sys"
+version = "3.1.0"
+authors = ["Jonas Klesy", "Patrick Reisert"]
+description = "Low-level FFI bindings for the CoreMIDI framework"
+documentation = "https://docs.rs/coremidi-sys"
+categories = ["external-ffi-bindings", "multimedia::audio"]
+license = "MIT"
+repository = "https://github.com/jonas-k/coremidi-sys"
+[package.metadata.docs.rs]
+default-target = "x86_64-apple-darwin"
+[target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.core-foundation-sys]
+version = "0.8.3"
diff --git a/third_party/rust/coremidi-sys/LICENSE b/third_party/rust/coremidi-sys/LICENSE
new file mode 100644
index 0000000000..9ace21803f
--- /dev/null
+++ b/third_party/rust/coremidi-sys/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Jonas Klesy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/third_party/rust/coremidi-sys/README.md b/third_party/rust/coremidi-sys/README.md
new file mode 100644
index 0000000000..640c9cd841
--- /dev/null
+++ b/third_party/rust/coremidi-sys/README.md
@@ -0,0 +1,20 @@
+# coremidi-sys
+
+Low level Rust bindings for CoreMIDI
+
+`generated.rs` is generated with [bindgen](https://github.com/rust-lang/rust-bindgen) 0.59.2 using the following commands:
+
+```
+export FRAMEWORKS_DIR=$(xcrun --sdk macosx --show-sdk-path)/System/Library/Frameworks
+
+bindgen ${FRAMEWORKS_DIR}/CoreMIDI.framework/Headers/MIDIServices.h \
+ --whitelist-type "MIDI.*" --whitelist-function "MIDI.*" --whitelist-var "kMIDI.*" \
+ --blacklist-type "(__)?CF.*" \
+ --constified-enum ".*" --no-prepend-enum-name \
+ --no-debug "MIDI(Event)?Packet.*" \
+ --no-copy "MIDI(Event)?Packet.*" \
+ --no-doc-comments \
+ -- -F ${FRAMEWORKS_DIR} > src/generated.rs
+```
+
+As of version 3 the minimum required Rust version is 1.51 due to the use of `std::ptr::addr_of`.
diff --git a/third_party/rust/coremidi-sys/build.rs b/third_party/rust/coremidi-sys/build.rs
new file mode 100644
index 0000000000..682c19b2a0
--- /dev/null
+++ b/third_party/rust/coremidi-sys/build.rs
@@ -0,0 +1,5 @@
+fn main() {
+ if std::env::var("TARGET").expect("cannot read TARGET environment variable").contains("apple") {
+ println!("cargo:rustc-link-lib=framework=CoreMIDI");
+ }
+} \ No newline at end of file
diff --git a/third_party/rust/coremidi-sys/examples/print_midi_device_count.rs b/third_party/rust/coremidi-sys/examples/print_midi_device_count.rs
new file mode 100644
index 0000000000..fe88d8994f
--- /dev/null
+++ b/third_party/rust/coremidi-sys/examples/print_midi_device_count.rs
@@ -0,0 +1,10 @@
+extern crate coremidi_sys as cm;
+
+fn main()
+{
+ let src: u64 = unsafe { cm::MIDIGetNumberOfSources() };
+ let dest: u64 = unsafe { cm::MIDIGetNumberOfDestinations() };
+
+ println!("Number of MIDI sources: {}", src);
+ println!("Number of MIDI destinations: {}", dest);
+}
diff --git a/third_party/rust/coremidi-sys/src/generated.rs b/third_party/rust/coremidi-sys/src/generated.rs
new file mode 100644
index 0000000000..918912fcca
--- /dev/null
+++ b/third_party/rust/coremidi-sys/src/generated.rs
@@ -0,0 +1,1102 @@
+/* automatically generated by rust-bindgen 0.59.2 */
+
+pub type UInt8 = ::std::os::raw::c_uchar;
+pub type UInt16 = ::std::os::raw::c_ushort;
+pub type UInt32 = ::std::os::raw::c_uint;
+pub type SInt32 = ::std::os::raw::c_int;
+pub type UInt64 = ::std::os::raw::c_ulonglong;
+pub type OSStatus = SInt32;
+pub type ByteCount = ::std::os::raw::c_ulong;
+pub type ItemCount = ::std::os::raw::c_ulong;
+pub type Boolean = ::std::os::raw::c_uchar;
+pub type Byte = UInt8;
+pub const kMIDIInvalidClient: ::std::os::raw::c_int = -10830;
+pub const kMIDIInvalidPort: ::std::os::raw::c_int = -10831;
+pub const kMIDIWrongEndpointType: ::std::os::raw::c_int = -10832;
+pub const kMIDINoConnection: ::std::os::raw::c_int = -10833;
+pub const kMIDIUnknownEndpoint: ::std::os::raw::c_int = -10834;
+pub const kMIDIUnknownProperty: ::std::os::raw::c_int = -10835;
+pub const kMIDIWrongPropertyType: ::std::os::raw::c_int = -10836;
+pub const kMIDINoCurrentSetup: ::std::os::raw::c_int = -10837;
+pub const kMIDIMessageSendErr: ::std::os::raw::c_int = -10838;
+pub const kMIDIServerStartErr: ::std::os::raw::c_int = -10839;
+pub const kMIDISetupFormatErr: ::std::os::raw::c_int = -10840;
+pub const kMIDIWrongThread: ::std::os::raw::c_int = -10841;
+pub const kMIDIObjectNotFound: ::std::os::raw::c_int = -10842;
+pub const kMIDIIDNotUnique: ::std::os::raw::c_int = -10843;
+pub const kMIDINotPermitted: ::std::os::raw::c_int = -10844;
+pub const kMIDIUnknownError: ::std::os::raw::c_int = -10845;
+pub type _bindgen_ty_63 = ::std::os::raw::c_int;
+pub type MIDIObjectRef = UInt32;
+pub type MIDIClientRef = MIDIObjectRef;
+pub type MIDIPortRef = MIDIObjectRef;
+pub type MIDIDeviceRef = MIDIObjectRef;
+pub type MIDIEntityRef = MIDIObjectRef;
+pub type MIDIEndpointRef = MIDIObjectRef;
+pub type MIDITimeStamp = UInt64;
+pub type MIDIObjectType = SInt32;
+pub const kMIDIObjectType_Other: ::std::os::raw::c_int = -1;
+pub const kMIDIObjectType_Device: ::std::os::raw::c_int = 0;
+pub const kMIDIObjectType_Entity: ::std::os::raw::c_int = 1;
+pub const kMIDIObjectType_Source: ::std::os::raw::c_int = 2;
+pub const kMIDIObjectType_Destination: ::std::os::raw::c_int = 3;
+pub const kMIDIObjectType_ExternalDevice: ::std::os::raw::c_int = 16;
+pub const kMIDIObjectType_ExternalEntity: ::std::os::raw::c_int = 17;
+pub const kMIDIObjectType_ExternalSource: ::std::os::raw::c_int = 18;
+pub const kMIDIObjectType_ExternalDestination: ::std::os::raw::c_int = 19;
+pub type _bindgen_ty_64 = ::std::os::raw::c_int;
+pub const kMIDIObjectType_ExternalMask: MIDIObjectType = 16;
+pub type MIDIUniqueID = SInt32;
+pub const kMIDIInvalidUniqueID: ::std::os::raw::c_uint = 0;
+pub type _bindgen_ty_65 = ::std::os::raw::c_uint;
+pub type MIDIProtocolID = SInt32;
+pub const kMIDIProtocol_1_0: ::std::os::raw::c_uint = 1;
+pub const kMIDIProtocol_2_0: ::std::os::raw::c_uint = 2;
+pub type _bindgen_ty_66 = ::std::os::raw::c_uint;
+pub type MIDINotifyProc = ::std::option::Option<
+ unsafe extern "C" fn(message: *const MIDINotification, refCon: *mut ::std::os::raw::c_void),
+>;
+pub type MIDINotifyBlock = *mut ::std::os::raw::c_void;
+pub type MIDIReceiveBlock = *mut ::std::os::raw::c_void;
+pub type MIDIReadProc = ::std::option::Option<
+ unsafe extern "C" fn(
+ pktlist: *const MIDIPacketList,
+ readProcRefCon: *mut ::std::os::raw::c_void,
+ srcConnRefCon: *mut ::std::os::raw::c_void,
+ ),
+>;
+pub type MIDIReadBlock = *mut ::std::os::raw::c_void;
+pub type MIDICompletionProc =
+ ::std::option::Option<unsafe extern "C" fn(request: *mut MIDISysexSendRequest)>;
+#[repr(C, packed(4))]
+pub struct MIDIEventPacket {
+ pub timeStamp: MIDITimeStamp,
+ pub wordCount: UInt32,
+ pub words: [UInt32; 64usize],
+}
+#[test]
+fn bindgen_test_layout_MIDIEventPacket() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIEventPacket>(),
+ 268usize,
+ concat!("Size of: ", stringify!(MIDIEventPacket))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIEventPacket>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIEventPacket))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventPacket>())).timeStamp as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventPacket),
+ "::",
+ stringify!(timeStamp)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventPacket>())).wordCount as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventPacket),
+ "::",
+ stringify!(wordCount)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventPacket>())).words as *const _ as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventPacket),
+ "::",
+ stringify!(words)
+ )
+ );
+}
+#[repr(C)]
+pub struct MIDIEventList {
+ pub protocol: MIDIProtocolID,
+ pub numPackets: UInt32,
+ pub packet: [MIDIEventPacket; 1usize],
+}
+#[test]
+fn bindgen_test_layout_MIDIEventList() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIEventList>(),
+ 276usize,
+ concat!("Size of: ", stringify!(MIDIEventList))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIEventList>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIEventList))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventList>())).protocol as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventList),
+ "::",
+ stringify!(protocol)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventList>())).numPackets as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventList),
+ "::",
+ stringify!(numPackets)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIEventList>())).packet as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIEventList),
+ "::",
+ stringify!(packet)
+ )
+ );
+}
+#[repr(C, packed(4))]
+pub struct MIDIPacket {
+ pub timeStamp: MIDITimeStamp,
+ pub length: UInt16,
+ pub data: [Byte; 256usize],
+}
+#[test]
+fn bindgen_test_layout_MIDIPacket() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIPacket>(),
+ 268usize,
+ concat!("Size of: ", stringify!(MIDIPacket))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIPacket>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIPacket))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIPacket>())).timeStamp as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIPacket),
+ "::",
+ stringify!(timeStamp)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIPacket>())).length as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIPacket),
+ "::",
+ stringify!(length)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIPacket>())).data as *const _ as usize },
+ 10usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIPacket),
+ "::",
+ stringify!(data)
+ )
+ );
+}
+#[repr(C)]
+pub struct MIDIPacketList {
+ pub numPackets: UInt32,
+ pub packet: [MIDIPacket; 1usize],
+}
+#[test]
+fn bindgen_test_layout_MIDIPacketList() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIPacketList>(),
+ 272usize,
+ concat!("Size of: ", stringify!(MIDIPacketList))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIPacketList>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIPacketList))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIPacketList>())).numPackets as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIPacketList),
+ "::",
+ stringify!(numPackets)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDIPacketList>())).packet as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIPacketList),
+ "::",
+ stringify!(packet)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct MIDISysexSendRequest {
+ pub destination: MIDIEndpointRef,
+ pub data: *const Byte,
+ pub bytesToSend: UInt32,
+ pub complete: Boolean,
+ pub reserved: [Byte; 3usize],
+ pub completionProc: MIDICompletionProc,
+ pub completionRefCon: *mut ::std::os::raw::c_void,
+}
+#[test]
+fn bindgen_test_layout_MIDISysexSendRequest() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDISysexSendRequest>(),
+ 40usize,
+ concat!("Size of: ", stringify!(MIDISysexSendRequest))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDISysexSendRequest>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(MIDISysexSendRequest))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDISysexSendRequest>())).destination as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(destination)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDISysexSendRequest>())).data as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(data)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDISysexSendRequest>())).bytesToSend as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(bytesToSend)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDISysexSendRequest>())).complete as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(complete)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDISysexSendRequest>())).reserved as *const _ as usize },
+ 21usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(reserved)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDISysexSendRequest>())).completionProc as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(completionProc)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDISysexSendRequest>())).completionRefCon as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDISysexSendRequest),
+ "::",
+ stringify!(completionRefCon)
+ )
+ );
+}
+pub type MIDINotificationMessageID = SInt32;
+pub const kMIDIMsgSetupChanged: ::std::os::raw::c_uint = 1;
+pub const kMIDIMsgObjectAdded: ::std::os::raw::c_uint = 2;
+pub const kMIDIMsgObjectRemoved: ::std::os::raw::c_uint = 3;
+pub const kMIDIMsgPropertyChanged: ::std::os::raw::c_uint = 4;
+pub const kMIDIMsgThruConnectionsChanged: ::std::os::raw::c_uint = 5;
+pub const kMIDIMsgSerialPortOwnerChanged: ::std::os::raw::c_uint = 6;
+pub const kMIDIMsgIOError: ::std::os::raw::c_uint = 7;
+pub type _bindgen_ty_67 = ::std::os::raw::c_uint;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct MIDINotification {
+ pub messageID: MIDINotificationMessageID,
+ pub messageSize: UInt32,
+}
+#[test]
+fn bindgen_test_layout_MIDINotification() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDINotification>(),
+ 8usize,
+ concat!("Size of: ", stringify!(MIDINotification))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDINotification>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDINotification))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDINotification>())).messageID as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDINotification),
+ "::",
+ stringify!(messageID)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<MIDINotification>())).messageSize as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDINotification),
+ "::",
+ stringify!(messageSize)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct MIDIObjectAddRemoveNotification {
+ pub messageID: MIDINotificationMessageID,
+ pub messageSize: UInt32,
+ pub parent: MIDIObjectRef,
+ pub parentType: MIDIObjectType,
+ pub child: MIDIObjectRef,
+ pub childType: MIDIObjectType,
+}
+#[test]
+fn bindgen_test_layout_MIDIObjectAddRemoveNotification() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIObjectAddRemoveNotification>(),
+ 24usize,
+ concat!("Size of: ", stringify!(MIDIObjectAddRemoveNotification))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIObjectAddRemoveNotification>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIObjectAddRemoveNotification))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).messageID as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(messageID)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).messageSize as *const _
+ as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(messageSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).parent as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(parent)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).parentType as *const _
+ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(parentType)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).child as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(child)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectAddRemoveNotification>())).childType as *const _
+ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectAddRemoveNotification),
+ "::",
+ stringify!(childType)
+ )
+ );
+}
+#[repr(C)]
+pub struct MIDIObjectPropertyChangeNotification {
+ pub messageID: MIDINotificationMessageID,
+ pub messageSize: UInt32,
+ pub object: MIDIObjectRef,
+ pub objectType: MIDIObjectType,
+ pub propertyName: CFStringRef,
+}
+#[test]
+fn bindgen_test_layout_MIDIObjectPropertyChangeNotification() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIObjectPropertyChangeNotification>(),
+ 24usize,
+ concat!(
+ "Size of: ",
+ stringify!(MIDIObjectPropertyChangeNotification)
+ )
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIObjectPropertyChangeNotification>(),
+ 8usize,
+ concat!(
+ "Alignment of ",
+ stringify!(MIDIObjectPropertyChangeNotification)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectPropertyChangeNotification>())).messageID as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectPropertyChangeNotification),
+ "::",
+ stringify!(messageID)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectPropertyChangeNotification>())).messageSize as *const _
+ as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectPropertyChangeNotification),
+ "::",
+ stringify!(messageSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectPropertyChangeNotification>())).object as *const _
+ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectPropertyChangeNotification),
+ "::",
+ stringify!(object)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectPropertyChangeNotification>())).objectType as *const _
+ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectPropertyChangeNotification),
+ "::",
+ stringify!(objectType)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIObjectPropertyChangeNotification>())).propertyName
+ as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIObjectPropertyChangeNotification),
+ "::",
+ stringify!(propertyName)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct MIDIIOErrorNotification {
+ pub messageID: MIDINotificationMessageID,
+ pub messageSize: UInt32,
+ pub driverDevice: MIDIDeviceRef,
+ pub errorCode: OSStatus,
+}
+#[test]
+fn bindgen_test_layout_MIDIIOErrorNotification() {
+ assert_eq!(
+ ::std::mem::size_of::<MIDIIOErrorNotification>(),
+ 16usize,
+ concat!("Size of: ", stringify!(MIDIIOErrorNotification))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<MIDIIOErrorNotification>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(MIDIIOErrorNotification))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIIOErrorNotification>())).messageID as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIIOErrorNotification),
+ "::",
+ stringify!(messageID)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIIOErrorNotification>())).messageSize as *const _ as usize
+ },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIIOErrorNotification),
+ "::",
+ stringify!(messageSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIIOErrorNotification>())).driverDevice as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIIOErrorNotification),
+ "::",
+ stringify!(driverDevice)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<MIDIIOErrorNotification>())).errorCode as *const _ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(MIDIIOErrorNotification),
+ "::",
+ stringify!(errorCode)
+ )
+ );
+}
+extern "C" {
+ pub static kMIDIPropertyName: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyManufacturer: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyModel: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyUniqueID: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyDeviceID: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceiveChannels: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitChannels: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyMaxSysExSpeed: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyAdvanceScheduleTimeMuSec: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsEmbeddedEntity: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsBroadcast: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertySingleRealtimeEntity: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyConnectionUniqueID: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyOffline: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyPrivate: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyDriverOwner: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyFactoryPatchNameFile: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyUserPatchNameFile: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyNameConfiguration: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyNameConfigurationDictionary: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyImage: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyDriverVersion: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertySupportsGeneralMIDI: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertySupportsMMC: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyCanRoute: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesClock: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesMTC: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesNotes: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesProgramChanges: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesBankSelectMSB: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyReceivesBankSelectLSB: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsClock: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsMTC: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsNotes: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsProgramChanges: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsBankSelectMSB: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyTransmitsBankSelectLSB: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyPanDisruptsStereo: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsSampler: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsDrumMachine: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsMixer: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyIsEffectUnit: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyMaxReceiveChannels: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyMaxTransmitChannels: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyDriverDeviceEditorApp: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertySupportsShowControl: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyDisplayName: CFStringRef;
+}
+extern "C" {
+ pub static kMIDIPropertyProtocolID: CFStringRef;
+}
+extern "C" {
+ pub fn MIDIClientCreate(
+ name: CFStringRef,
+ notifyProc: MIDINotifyProc,
+ notifyRefCon: *mut ::std::os::raw::c_void,
+ outClient: *mut MIDIClientRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIClientCreateWithBlock(
+ name: CFStringRef,
+ outClient: *mut MIDIClientRef,
+ notifyBlock: MIDINotifyBlock,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIClientDispose(client: MIDIClientRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIInputPortCreateWithProtocol(
+ client: MIDIClientRef,
+ portName: CFStringRef,
+ protocol: MIDIProtocolID,
+ outPort: *mut MIDIPortRef,
+ receiveBlock: MIDIReceiveBlock,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIInputPortCreate(
+ client: MIDIClientRef,
+ portName: CFStringRef,
+ readProc: MIDIReadProc,
+ refCon: *mut ::std::os::raw::c_void,
+ outPort: *mut MIDIPortRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIInputPortCreateWithBlock(
+ client: MIDIClientRef,
+ portName: CFStringRef,
+ outPort: *mut MIDIPortRef,
+ readBlock: MIDIReadBlock,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIOutputPortCreate(
+ client: MIDIClientRef,
+ portName: CFStringRef,
+ outPort: *mut MIDIPortRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIPortDispose(port: MIDIPortRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIPortConnectSource(
+ port: MIDIPortRef,
+ source: MIDIEndpointRef,
+ connRefCon: *mut ::std::os::raw::c_void,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIPortDisconnectSource(port: MIDIPortRef, source: MIDIEndpointRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIGetNumberOfDevices() -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIGetDevice(deviceIndex0: ItemCount) -> MIDIDeviceRef;
+}
+extern "C" {
+ pub fn MIDIDeviceGetNumberOfEntities(device: MIDIDeviceRef) -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIDeviceGetEntity(device: MIDIDeviceRef, entityIndex0: ItemCount) -> MIDIEntityRef;
+}
+extern "C" {
+ pub fn MIDIEntityGetNumberOfSources(entity: MIDIEntityRef) -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIEntityGetSource(entity: MIDIEntityRef, sourceIndex0: ItemCount) -> MIDIEndpointRef;
+}
+extern "C" {
+ pub fn MIDIEntityGetNumberOfDestinations(entity: MIDIEntityRef) -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIEntityGetDestination(
+ entity: MIDIEntityRef,
+ destIndex0: ItemCount,
+ ) -> MIDIEndpointRef;
+}
+extern "C" {
+ pub fn MIDIEntityGetDevice(inEntity: MIDIEntityRef, outDevice: *mut MIDIDeviceRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIGetNumberOfSources() -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIGetSource(sourceIndex0: ItemCount) -> MIDIEndpointRef;
+}
+extern "C" {
+ pub fn MIDIGetNumberOfDestinations() -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIGetDestination(destIndex0: ItemCount) -> MIDIEndpointRef;
+}
+extern "C" {
+ pub fn MIDIEndpointGetEntity(
+ inEndpoint: MIDIEndpointRef,
+ outEntity: *mut MIDIEntityRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIDestinationCreateWithProtocol(
+ client: MIDIClientRef,
+ name: CFStringRef,
+ protocol: MIDIProtocolID,
+ outDest: *mut MIDIEndpointRef,
+ readBlock: MIDIReceiveBlock,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIDestinationCreate(
+ client: MIDIClientRef,
+ name: CFStringRef,
+ readProc: MIDIReadProc,
+ refCon: *mut ::std::os::raw::c_void,
+ outDest: *mut MIDIEndpointRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIDestinationCreateWithBlock(
+ client: MIDIClientRef,
+ name: CFStringRef,
+ outDest: *mut MIDIEndpointRef,
+ readBlock: MIDIReadBlock,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDISourceCreateWithProtocol(
+ client: MIDIClientRef,
+ name: CFStringRef,
+ protocol: MIDIProtocolID,
+ outSrc: *mut MIDIEndpointRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDISourceCreate(
+ client: MIDIClientRef,
+ name: CFStringRef,
+ outSrc: *mut MIDIEndpointRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIEndpointDispose(endpt: MIDIEndpointRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIGetNumberOfExternalDevices() -> ItemCount;
+}
+extern "C" {
+ pub fn MIDIGetExternalDevice(deviceIndex0: ItemCount) -> MIDIDeviceRef;
+}
+extern "C" {
+ pub fn MIDIObjectGetIntegerProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ outValue: *mut SInt32,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectSetIntegerProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ value: SInt32,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectGetStringProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ str_: *mut CFStringRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectSetStringProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ str_: CFStringRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectGetDataProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ outData: *mut CFDataRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectSetDataProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ data: CFDataRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectGetDictionaryProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ outDict: *mut CFDictionaryRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectSetDictionaryProperty(
+ obj: MIDIObjectRef,
+ propertyID: CFStringRef,
+ dict: CFDictionaryRef,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectGetProperties(
+ obj: MIDIObjectRef,
+ outProperties: *mut CFPropertyListRef,
+ deep: Boolean,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectRemoveProperty(obj: MIDIObjectRef, propertyID: CFStringRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIObjectFindByUniqueID(
+ inUniqueID: MIDIUniqueID,
+ outObject: *mut MIDIObjectRef,
+ outObjectType: *mut MIDIObjectType,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDISendEventList(
+ port: MIDIPortRef,
+ dest: MIDIEndpointRef,
+ evtlist: *const MIDIEventList,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDISend(
+ port: MIDIPortRef,
+ dest: MIDIEndpointRef,
+ pktlist: *const MIDIPacketList,
+ ) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDISendSysex(request: *mut MIDISysexSendRequest) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIReceivedEventList(src: MIDIEndpointRef, evtlist: *const MIDIEventList) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIReceived(src: MIDIEndpointRef, pktlist: *const MIDIPacketList) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIFlushOutput(dest: MIDIEndpointRef) -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIRestart() -> OSStatus;
+}
+extern "C" {
+ pub fn MIDIEventListInit(
+ evtlist: *mut MIDIEventList,
+ protocol: MIDIProtocolID,
+ ) -> *mut MIDIEventPacket;
+}
+extern "C" {
+ pub fn MIDIEventListAdd(
+ evtlist: *mut MIDIEventList,
+ listSize: ByteCount,
+ curPacket: *mut MIDIEventPacket,
+ time: MIDITimeStamp,
+ wordCount: ByteCount,
+ words: *const UInt32,
+ ) -> *mut MIDIEventPacket;
+}
+extern "C" {
+ pub fn MIDIPacketListInit(pktlist: *mut MIDIPacketList) -> *mut MIDIPacket;
+}
+extern "C" {
+ pub fn MIDIPacketListAdd(
+ pktlist: *mut MIDIPacketList,
+ listSize: ByteCount,
+ curPacket: *mut MIDIPacket,
+ time: MIDITimeStamp,
+ nData: ByteCount,
+ data: *const Byte,
+ ) -> *mut MIDIPacket;
+}
diff --git a/third_party/rust/coremidi-sys/src/lib.rs b/third_party/rust/coremidi-sys/src/lib.rs
new file mode 100644
index 0000000000..60b8945a8e
--- /dev/null
+++ b/third_party/rust/coremidi-sys/src/lib.rs
@@ -0,0 +1,149 @@
+#![cfg(any(target_os = "macos", target_os = "ios"))]
+
+#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
+
+extern crate core_foundation_sys;
+
+use core_foundation_sys::string::*;
+use core_foundation_sys::data::*;
+use core_foundation_sys::dictionary::*;
+use core_foundation_sys::propertylist::*;
+
+use std::{ptr, mem};
+
+include!("generated.rs");
+
+#[inline]
+pub unsafe fn MIDIPacketNext(pkt: *const MIDIPacket) -> *const MIDIPacket {
+ // Get pointer to potentially unaligned data without triggering undefined behavior
+ // addr_of does not require creating an intermediate reference to unaligned data.
+ let ptr = ptr::addr_of!((*pkt).data) as *const u8;
+ let offset = (*pkt).length as isize;
+ if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
+ // MIDIPacket must be 4-byte aligned on ARM
+ ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIPacket
+ } else {
+ ptr.offset(offset) as *const MIDIPacket
+ }
+}
+
+#[inline]
+pub unsafe fn MIDIEventPacketNext(pkt: *const MIDIEventPacket) -> *const MIDIEventPacket {
+ // Get pointer to potentially unaligned data without triggering undefined behavior
+ // addr_of does not require creating an intermediate reference to unaligned data.
+ let ptr = ptr::addr_of!((*pkt).words) as *const u8;
+ let offset = (((*pkt).wordCount as usize) * mem::size_of::<u32>()) as isize;
+ if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
+ // MIDIEventPacket must be 4-byte aligned on ARM
+ ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIEventPacket
+ } else {
+ ptr.offset(offset) as *const MIDIEventPacket
+ }
+}
+
+#[allow(dead_code)]
+mod static_test {
+ /// Statically assert the correct size of `MIDIPacket` and `MIDIPacketList`,
+ /// which require non-default alignment.
+ unsafe fn assert_sizes() {
+ use super::{MIDIPacket, MIDIPacketList};
+ use std::mem::{transmute, zeroed};
+
+ let p: MIDIPacket = zeroed();
+ transmute::<_, [u8; 268]>(p);
+
+ let p: MIDIPacketList = zeroed();
+ transmute::<_, [u8; 272]>(p);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn midi_packet_next() {
+ const BUFFER_SIZE: usize = 65536;
+ let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
+ let pkt_list_ptr = buffer.as_mut_ptr() as *mut MIDIPacketList;
+
+ let packets = vec![
+ (1, vec![0x90, 0x40, 0x7f]), // tuple of (time, [midi bytes])
+ (2, vec![0x90, 0x41, 0x7f]),
+ ];
+
+ unsafe {
+ let mut pkt_ptr = MIDIPacketListInit(pkt_list_ptr);
+ for pkt in &packets {
+ pkt_ptr = MIDIPacketListAdd(
+ pkt_list_ptr,
+ BUFFER_SIZE as ByteCount,
+ pkt_ptr,
+ pkt.0,
+ pkt.1.len() as ByteCount,
+ pkt.1.as_ptr(),
+ );
+ assert!(!pkt_ptr.is_null());
+ }
+ }
+
+ unsafe {
+ let first_packet = &(*pkt_list_ptr).packet as *const MIDIPacket; // get pointer to first midi packet in the list
+ let len = (*first_packet).length as usize;
+ assert_eq!(
+ &(*first_packet).data[0..len],
+ &[0x90, 0x40, 0x7f]
+ );
+
+ let second_packet = MIDIPacketNext(first_packet);
+ let len = (*second_packet).length as usize;
+ assert_eq!(
+ &(*second_packet).data[0..len],
+ &[0x90, 0x41, 0x7f]
+ );
+ }
+ }
+
+ #[test]
+ fn midi_event_packet_next() {
+ const BUFFER_SIZE: usize = 65536;
+ let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
+ let pkt_list_ptr = buffer.as_mut_ptr() as *mut MIDIEventList;
+
+ let packets = vec![
+ (1, vec![10u32, 20]), // tuple of (time, [midi words])
+ (2, vec![30u32, 40, 50]),
+ ];
+
+ unsafe {
+ let mut pkt_ptr = MIDIEventListInit(pkt_list_ptr, kMIDIProtocol_2_0 as MIDIProtocolID);
+ for pkt in &packets {
+ pkt_ptr = MIDIEventListAdd(
+ pkt_list_ptr,
+ BUFFER_SIZE as ByteCount,
+ pkt_ptr,
+ pkt.0,
+ pkt.1.len() as ByteCount,
+ pkt.1.as_ptr(),
+ );
+ assert!(!pkt_ptr.is_null());
+ }
+ }
+
+ unsafe {
+ let first_packet = &(*pkt_list_ptr).packet as *const MIDIEventPacket; // get pointer to first midi packet in the list
+ let len = (*first_packet).wordCount as usize;
+ assert_eq!(
+ &(*first_packet).words[0..len],
+ &[10, 20]
+ );
+
+ let second_packet = MIDIEventPacketNext(first_packet);
+ let len = (*second_packet).wordCount as usize;
+ assert_eq!(
+ &(*second_packet).words[0..len],
+ &[30, 40, 50]
+ );
+ }
+ }
+}