From dc87afbd4361ae5ec192e1fab0a6409dd13d4011 Mon Sep 17 00:00:00 2001 From: Gabriele Svelto Date: Thu, 2 Sep 2021 17:28:43 +0200 Subject: [PATCH 01/13] Changes required for vendoring the midir crate into mozilla-central * The coremidi dependencies was updated to pick up a more recent non-released branch. This was done so that we don't need to vendor old versions of the core-foundation and core-foundation-sys crates * The wasm32 target was removed in order not to have to vendor all its dependencies (which would be unused) --- Cargo.toml | 23 +---------------------- README.md | 4 +++- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8f140de..29ff4ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,28 +33,7 @@ nix = "0.15" libc = "0.2.21" [target.'cfg(target_os = "macos")'.dependencies] -coremidi = "0.4.0" +coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev = "753163a8e5aeb8d69d2e0558301fd34a3d04327a" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["mmsystem", "mmeapi"] } - -[target.'cfg(target_arch = "wasm32")'.dependencies] -js-sys = "0.3" -wasm-bindgen = "0.2" -web-sys = { version = "0.3", features = [ - "Event", - "Navigator", - "Window", - "MidiAccess", - "MidiInput", - "MidiInputMap", - "MidiMessageEvent", - "MidiOptions", - "MidiOutput", - "MidiOutputMap", - "MidiPort", - "MidiPortType" -]} - -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wasm-bindgen-test = "0.2" diff --git a/README.md b/README.md index 642848c..42e1012 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # midir [![crates.io](https://img.shields.io/crates/v/midir.svg)](https://crates.io/crates/midir) [![Build Status](https://dev.azure.com/Boddlnagg/midir/_apis/build/status/Boddlnagg.midir?branchName=master)](https://dev.azure.com/Boddlnagg/midir/_build/latest?definitionId=1) -Cross-platform, realtime MIDI processing in Rust. +Cross-platform, realtime MIDI processing in Rust. This is a friendly fork with +small changes required for vendoring the crate in Firefox. It will go away as +soon as we will be able to vendor the upstream crate. ## Features **midir** is inspired by [RtMidi](https://github.com/thestk/rtmidi) and supports the same features*, including virtual ports (except on Windows) and full SysEx support – but with a rust-y API! From bc0a5d22282854d0a6371c160490ace22926b305 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 6 Jan 2022 14:33:43 +0900 Subject: [PATCH 02/13] Use a versioned dependency on coremidi We'll handle picking the right version on the gecko side. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 29ff4ef..2de9295 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ nix = "0.15" libc = "0.2.21" [target.'cfg(target_os = "macos")'.dependencies] -coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev = "753163a8e5aeb8d69d2e0558301fd34a3d04327a" } +coremidi = "0.6.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["mmsystem", "mmeapi"] } From 6369feb003a415e507970d0a14cf5026398c33ed Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 6 Jan 2022 14:34:04 +0900 Subject: [PATCH 03/13] Restore the wasm32 dependencies This reduces the differences with upstream. --- Cargo.toml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 2de9295..49089e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,24 @@ coremidi = "0.6.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["mmsystem", "mmeapi"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +js-sys = "0.3" +wasm-bindgen = "0.2" +web-sys = { version = "0.3", features = [ + "Event", + "Navigator", + "Window", + "MidiAccess", + "MidiInput", + "MidiInputMap", + "MidiMessageEvent", + "MidiOptions", + "MidiOutput", + "MidiOutputMap", + "MidiPort", + "MidiPortType" +]} + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +wasm-bindgen-test = "0.2" From e1b4dcb767f9e69afe95a860374aaa9635d81e3d Mon Sep 17 00:00:00 2001 From: Gabriele Svelto Date: Fri, 22 Jul 2022 11:29:13 +0200 Subject: [PATCH 04/13] Fix deprecated unaligned reads --- src/backend/winmm/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/winmm/mod.rs b/src/backend/winmm/mod.rs index 8435878..2d20004 100644 --- a/src/backend/winmm/mod.rs +++ b/src/backend/winmm/mod.rs @@ -103,7 +103,7 @@ impl MidiInputPort { return Err(PortInfoError::CannotRetrievePortName) } let device_caps = unsafe { device_caps.assume_init() }; - let pname: &[u16] = unsafe { &device_caps.szPname }; // requires unsafe because of packed alignment ... + let pname = device_caps.szPname; let output = from_wide_ptr(pname.as_ptr(), pname.len()).to_string_lossy().into_owned(); Ok(output) } @@ -365,7 +365,7 @@ impl MidiOutputPort { return Err(PortInfoError::CannotRetrievePortName) } let device_caps = unsafe { device_caps.assume_init() }; - let pname: &[u16] = unsafe { &device_caps.szPname }; // requires unsafe because of packed alignment ... + let pname = device_caps.szPname; let output = from_wide_ptr(pname.as_ptr(), pname.len()).to_string_lossy().into_owned(); Ok(output) } From f7f57701d1be91d653f34a21c78c044936f6a575 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 7 Dec 2022 07:51:36 +0900 Subject: [PATCH 05/13] Upgrade to alsa 0.7 --- Cargo.toml | 3 +-- src/backend/alsa/mod.rs | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 49089e0..177b095 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,7 @@ libc = { version = "0.2.21", optional = true } winrt = { version = "0.7.0", optional = true} [target.'cfg(target_os = "linux")'.dependencies] -alsa = "0.4.3" -nix = "0.15" +alsa = "0.7" libc = "0.2.21" [target.'cfg(target_os = "macos")'.dependencies] diff --git a/src/backend/alsa/mod.rs b/src/backend/alsa/mod.rs index 4971413..f57ffb7 100755 --- a/src/backend/alsa/mod.rs +++ b/src/backend/alsa/mod.rs @@ -1,6 +1,5 @@ extern crate libc; extern crate alsa; -extern crate nix; use std::mem; use std::thread::{Builder, JoinHandle}; @@ -651,11 +650,11 @@ fn handle_input(mut data: HandlerData, user_data: &mut T) -> HandlerData ev, - Err(ref e) if e.errno() == Some(self::nix::errno::Errno::ENOSPC) => { + Err(ref e) if e.errno() == alsa::nix::errno::Errno::ENOSPC => { let _ = writeln!(stderr(), "\nError in handle_input: ALSA MIDI input buffer overrun!\n"); continue; }, - Err(ref e) if e.errno() == Some(self::nix::errno::Errno::EAGAIN) => { + Err(ref e) if e.errno() == alsa::nix::errno::Errno::EAGAIN => { let _ = writeln!(stderr(), "\nError in handle_input: no input event from ALSA MIDI input buffer!\n"); continue; }, From 6e7a930f0e0e20cc268dfeb2ef7a3420298c195e Mon Sep 17 00:00:00 2001 From: Be Date: Thu, 27 Jan 2022 18:07:40 -0600 Subject: [PATCH 06/13] fix build with pipewire-jack https://github.com/RustAudio/rust-jack/pull/154 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 177b095..372cc9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ jack = ["jack-sys", "libc"] [dependencies] bitflags = "1.2" memalloc = "0.1.0" -jack-sys = { version = "0.1.0", optional = true } +jack-sys = { version = "0.2", optional = true } libc = { version = "0.2.21", optional = true } winrt = { version = "0.7.0", optional = true} From 935828ccaf82604e639d95eecb913d0a7f9713ea Mon Sep 17 00:00:00 2001 From: Patrick Reisert Date: Mon, 25 Apr 2022 19:15:25 +0200 Subject: [PATCH 07/13] Fix unaligned reference violation (error on recent nightly) --- src/backend/winmm/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/winmm/mod.rs b/src/backend/winmm/mod.rs index 2d20004..e10201a 100644 --- a/src/backend/winmm/mod.rs +++ b/src/backend/winmm/mod.rs @@ -103,8 +103,8 @@ impl MidiInputPort { return Err(PortInfoError::CannotRetrievePortName) } let device_caps = unsafe { device_caps.assume_init() }; - let pname = device_caps.szPname; - let output = from_wide_ptr(pname.as_ptr(), pname.len()).to_string_lossy().into_owned(); + let pname_ptr: *const [u16; 32] = std::ptr::addr_of!(device_caps.szPname); + let output = from_wide_ptr(pname_ptr as *const _, 32).to_string_lossy().into_owned(); Ok(output) } @@ -365,8 +365,8 @@ impl MidiOutputPort { return Err(PortInfoError::CannotRetrievePortName) } let device_caps = unsafe { device_caps.assume_init() }; - let pname = device_caps.szPname; - let output = from_wide_ptr(pname.as_ptr(), pname.len()).to_string_lossy().into_owned(); + let pname_ptr: *const [u16; 32] = std::ptr::addr_of!(device_caps.szPname); + let output = from_wide_ptr(pname_ptr as *const _, 32).to_string_lossy().into_owned(); Ok(output) } From 1a49aab7a38eb4535ebcfd79d69d40262c9d891d Mon Sep 17 00:00:00 2001 From: Patrick Reisert Date: Mon, 25 Apr 2022 19:27:22 +0200 Subject: [PATCH 08/13] coremidi: Add option to send messages with current host time Fixes #94 --- Cargo.toml | 1 + src/backend/coremidi/mod.rs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 372cc9e..b407a8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ license = "MIT" [features] default = [] avoid_timestamping = [] +coremidi_send_timestamped = [] jack = ["jack-sys", "libc"] [dependencies] diff --git a/src/backend/coremidi/mod.rs b/src/backend/coremidi/mod.rs index 31fd905..f129e04 100644 --- a/src/backend/coremidi/mod.rs +++ b/src/backend/coremidi/mod.rs @@ -337,7 +337,12 @@ impl MidiOutputConnection { } pub fn send(&mut self, message: &[u8]) -> Result<(), SendError> { - let packets = PacketBuffer::new(0, message); + let send_time = if cfg!(feature = "coremidi_send_timestamped") { + unsafe { external::AudioGetCurrentHostTime() } + } else { + 0 + }; + let packets = PacketBuffer::new(send_time, message); match self.details { OutputConnectionDetails::Explicit(ref port, ref dest) => { port.send(&dest, &packets).map_err(|_| SendError::Other("error sending MIDI message to port")) From 82d469a8d34ba86343bce65a61b66730c25ca5f4 Mon Sep 17 00:00:00 2001 From: Pedro Tacla Yamada Date: Thu, 5 May 2022 03:57:39 +1000 Subject: [PATCH 09/13] Fix ios compilation --- Cargo.toml | 3 +++ src/backend/mod.rs | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b407a8e..b6a5b66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,9 @@ winrt = { version = "0.7.0", optional = true} alsa = "0.7" libc = "0.2.21" +[target.'cfg(target_os = "ios")'.dependencies] +coremidi = "0.6.0" + [target.'cfg(target_os = "macos")'.dependencies] coremidi = "0.6.0" diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 2940dae..a948a9d 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -3,20 +3,37 @@ // TODO: improve feature selection (make sure that there is always exactly one implementation, or enable dynamic backend selection) // TODO: allow to disable build dependency on ALSA -#[cfg(all(target_os="windows", not(feature = "winrt")))] mod winmm; -#[cfg(all(target_os="windows", not(feature = "winrt")))] pub use self::winmm::*; +#[cfg(all(target_os = "windows", not(feature = "winrt")))] +mod winmm; +#[cfg(all(target_os = "windows", not(feature = "winrt")))] +pub use self::winmm::*; -#[cfg(all(target_os="windows", feature = "winrt"))] mod winrt; -#[cfg(all(target_os="windows", feature = "winrt"))] pub use self::winrt::*; +#[cfg(all(target_os = "windows", feature = "winrt"))] +mod winrt; +#[cfg(all(target_os = "windows", feature = "winrt"))] +pub use self::winrt::*; -#[cfg(all(target_os="macos", not(feature = "jack")))] mod coremidi; -#[cfg(all(target_os="macos", not(feature = "jack")))] pub use self::coremidi::*; +#[cfg(all(target_os = "macos", not(feature = "jack")))] +mod coremidi; +#[cfg(all(target_os = "macos", not(feature = "jack")))] +pub use self::coremidi::*; -#[cfg(all(target_os="linux", not(feature = "jack")))] mod alsa; -#[cfg(all(target_os="linux", not(feature = "jack")))] pub use self::alsa::*; +#[cfg(all(target_os = "ios", not(feature = "jack")))] +mod coremidi; +#[cfg(all(target_os = "ios", not(feature = "jack")))] +pub use self::coremidi::*; -#[cfg(all(feature = "jack", not(target_os="windows")))] mod jack; -#[cfg(all(feature = "jack", not(target_os="windows")))] pub use self::jack::*; +#[cfg(all(target_os = "linux", not(feature = "jack")))] +mod alsa; +#[cfg(all(target_os = "linux", not(feature = "jack")))] +pub use self::alsa::*; -#[cfg(target_arch="wasm32")] mod webmidi; -#[cfg(target_arch="wasm32")] pub use self::webmidi::*; +#[cfg(all(feature = "jack", not(target_os = "windows")))] +mod jack; +#[cfg(all(feature = "jack", not(target_os = "windows")))] +pub use self::jack::*; + +#[cfg(target_arch = "wasm32")] +mod webmidi; +#[cfg(target_arch = "wasm32")] +pub use self::webmidi::*; From 580f8d664e2b4399ca4590fd070d51e12d4e0b1b Mon Sep 17 00:00:00 2001 From: Ruby Lazuli Date: Fri, 13 May 2022 11:06:00 -0500 Subject: [PATCH 10/13] alsa: Fix undefined behaviour Previously, the ALSA backend created a new `Vec` and immediately called `Vec::set_len`. This exposes uninitialized `pollfd`s, which causes undefined behaviour. This commit fixes this by initializing the `Vec` with invalid, but still initialized, `pollfd`s before filling it. In addition, this commit simplifies the code slightly by removing the usage of `Vec::into_boxed_slice`. Fixes #110. --- src/backend/alsa/mod.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/backend/alsa/mod.rs b/src/backend/alsa/mod.rs index f57ffb7..a8cd58c 100755 --- a/src/backend/alsa/mod.rs +++ b/src/backend/alsa/mod.rs @@ -588,6 +588,13 @@ impl Drop for MidiOutputConnection { fn handle_input(mut data: HandlerData, user_data: &mut T) -> HandlerData { use self::alsa::PollDescriptors; use self::alsa::seq::Connect; + use self::libc::pollfd; + + const INVALID_POLLFD: pollfd = pollfd { + fd: -1, + events: 0, + revents: 0, + }; let mut continue_sysex: bool = false; @@ -596,22 +603,17 @@ fn handle_input(mut data: HandlerData, user_data: &mut T) -> HandlerData; - { - let poll_desc_info = (&data.seq, Some(Direction::Capture)); - let poll_fd_count = poll_desc_info.count() + 1; - let mut vec = Vec::with_capacity(poll_fd_count); - unsafe { - vec.set_len(poll_fd_count); - poll_fds = vec.into_boxed_slice(); - } - poll_desc_info.fill(&mut poll_fds[1..]).unwrap(); - } - poll_fds[0].fd = data.trigger_rcv_fd; - poll_fds[0].events = self::libc::POLLIN; - + let poll_desc_info = (&data.seq, Some(Direction::Capture)); + let mut poll_fds = vec![INVALID_POLLFD; poll_desc_info.count() + 1]; + poll_fds[0] = pollfd { + fd: data.trigger_rcv_fd, + events: self::libc::POLLIN, + revents: 0, + }; + + poll_desc_info.fill(&mut poll_fds[1..]).unwrap(); + let mut message = MidiMessage::new(); { // open scope where we can borrow data.seq From 93691ad1fe421d6c4b7dbff5c576b3d2402f7928 Mon Sep 17 00:00:00 2001 From: Patrick Reisert Date: Fri, 13 May 2022 18:10:51 +0200 Subject: [PATCH 11/13] Prepare 0.8.0 release --- CHANGELOG.md | 7 ++++--- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83a0987..f6f0e94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ All major changes to this project will be documented in this file. -## [Unreleased] +## [0.8.0] - 2022-05-13 -- ... +- Upgrade `coremidi` and `alsa` dependencies +- Implement `PartialEq` for ports ## [0.7.0] - 2020-09-05 @@ -47,4 +48,4 @@ All major changes to this project will be documented in this file. ## [0.3.0] - 2017-03-21 -- Fix compilation on ARM platforms \ No newline at end of file +- Fix compilation on ARM platforms diff --git a/Cargo.toml b/Cargo.toml index b6a5b66..ee0afcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ [package] name = "midir" -version = "0.7.0" +version = "0.8.0" authors = ["Patrick Reisert"] description = "A cross-platform, realtime MIDI processing library, inspired by RtMidi." repository = "https://github.com/Boddlnagg/midir" From ffe61d2776b21638fb76161951f4e0ad29af7db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jun 2022 21:05:15 +0200 Subject: [PATCH 12/13] remove memalloc dependency - Replace memalloc crate dependency with rust std alloc/dealloc --- Cargo.toml | 3 +-- src/backend/dummy/mod.rs | 0 src/backend/winmm/mod.rs | 6 +++--- src/lib.rs | 2 -- 4 files changed, 4 insertions(+), 7 deletions(-) create mode 100644 src/backend/dummy/mod.rs diff --git a/Cargo.toml b/Cargo.toml index ee0afcc..61d6902 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ jack = ["jack-sys", "libc"] [dependencies] bitflags = "1.2" -memalloc = "0.1.0" jack-sys = { version = "0.2", optional = true } libc = { version = "0.2.21", optional = true } winrt = { version = "0.7.0", optional = true} @@ -38,7 +37,7 @@ coremidi = "0.6.0" [target.'cfg(target_os = "macos")'.dependencies] coremidi = "0.6.0" -[target.'cfg(windows)'.dependencies] +[target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3", features = ["mmsystem", "mmeapi"] } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/src/backend/dummy/mod.rs b/src/backend/dummy/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/backend/winmm/mod.rs b/src/backend/winmm/mod.rs index e10201a..9e75996 100644 --- a/src/backend/winmm/mod.rs +++ b/src/backend/winmm/mod.rs @@ -7,9 +7,9 @@ use std::sync::Mutex; use std::io::{Write, stderr}; use std::thread::sleep; use std::time::Duration; -use memalloc::{allocate, deallocate}; use std::mem::MaybeUninit; use std::ptr::null_mut; +use std::alloc::{alloc, dealloc, Layout}; use self::winapi::shared::basetsd::{DWORD_PTR, UINT_PTR}; use self::winapi::shared::minwindef::{DWORD, UINT}; @@ -218,7 +218,7 @@ impl MidiInput { // Allocate and init the sysex buffers. for i in 0..RT_SYSEX_BUFFER_COUNT { handler_data.sysex_buffer.0[i] = Box::into_raw(Box::new(MIDIHDR { - lpData: unsafe { allocate(RT_SYSEX_BUFFER_SIZE/*, mem::align_of::()*/) } as *mut i8, + lpData: unsafe { alloc(Layout::from_size_align_unchecked(RT_SYSEX_BUFFER_SIZE, 1)) } as *mut i8, dwBufferLength: RT_SYSEX_BUFFER_SIZE as u32, dwBytesRecorded: 0, dwUser: i as DWORD_PTR, // We use the dwUser parameter as buffer indicator @@ -285,7 +285,7 @@ impl MidiInputConnection { let result; unsafe { result = midiInUnprepareHeader(*in_handle_lock, self.handler_data.sysex_buffer.0[i], mem::size_of::() as u32); - deallocate((*self.handler_data.sysex_buffer.0[i]).lpData as *mut u8, RT_SYSEX_BUFFER_SIZE/*, mem::align_of::()*/); + dealloc((*self.handler_data.sysex_buffer.0[i]).lpData as *mut u8, Layout::from_size_align_unchecked(RT_SYSEX_BUFFER_SIZE, 1)); // recreate the Box so that it will be dropped/deallocated at the end of this scope let _ = Box::from_raw(self.handler_data.sysex_buffer.0[i]); } diff --git a/src/lib.rs b/src/lib.rs index 99d6840..39911c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -extern crate memalloc; - #[cfg(feature = "jack")] #[macro_use] extern crate bitflags; From b5fd51961a1f51de06858e301c3cc611cf1d19f6 Mon Sep 17 00:00:00 2001 From: kbone Date: Thu, 30 Jun 2022 23:23:05 +0900 Subject: [PATCH 13/13] Fix received data buffer size when using WinRT --- src/backend/winrt/mod.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/backend/winrt/mod.rs b/src/backend/winrt/mod.rs index a8204ec..2cb52d5 100644 --- a/src/backend/winrt/mod.rs +++ b/src/backend/winrt/mod.rs @@ -14,13 +14,13 @@ winrt::import!( windows::foundation::* windows::devices::midi::* windows::devices::enumeration::DeviceInformation - windows::storage::streams::{Buffer, DataWriter} + windows::storage::streams::{DataReader, DataWriter} ); use self::windows::foundation::*; use self::windows::devices::midi::*; use self::windows::devices::enumeration::DeviceInformation; -use self::windows::storage::streams::{Buffer, DataWriter}; +use self::windows::storage::streams::{DataReader, DataWriter}; #[derive(Clone, PartialEq)] pub struct MidiInputPort { @@ -127,15 +127,13 @@ impl MidiInput { fn handle_input(args: &MidiMessageReceivedEventArgs, handler_data: &mut HandlerData) { let ignore = handler_data.ignore_flags; let data = &mut handler_data.user_data.as_mut().unwrap(); - let timestamp; - let byte_access: IMemoryBufferByteAccess; - let message_bytes; - let message = args.message().expect("get_message failed"); - timestamp = message.timestamp().expect("get_timestamp failed").duration as u64 / 10; - let buffer = message.raw_data().expect("get_raw_data failed"); - let membuffer = Buffer::create_memory_buffer_over_ibuffer(&buffer).expect("create_memory_buffer_over_ibuffer failed"); - byte_access = membuffer.create_reference().expect("create_reference failed").try_into().unwrap(); - message_bytes = unsafe { byte_access.get_buffer().expect("get_buffer failed") }; // TODO: somehow make sure that the buffer is not invalidated while we're reading from it ... + let message = args.message().expect("Message failed"); + let timestamp = message.timestamp().expect("Timestamp failed").duration as u64 / 10; + let buffer = message.raw_data().expect("raw_data failed"); + let length = buffer.length().expect("length failed") as usize; + let data_reader = DataReader::from_buffer(&buffer).expect("from_buffer failed"); + let mut message_bytes = vec![0; length]; + data_reader.read_bytes(&mut message_bytes).expect("read_bytes failed"); // The first byte in the message is the status let status = message_bytes[0]; @@ -145,7 +143,7 @@ impl MidiInput { status == 0xF8 && ignore.contains(Ignore::Time) || status == 0xFE && ignore.contains(Ignore::ActiveSense)) { - (handler_data.callback)(timestamp, message_bytes, data); + (handler_data.callback)(timestamp, &message_bytes, data); } }