pub(crate) fn ports_internal(&self) -> Vec<::common::MidiInputPort> { let device_collection = DeviceInformation::find_all_async_aqs_filter(&self.selector).unwrap().get().expect("find_all_async failed"); let count = device_collection.size().expect("get_size failed") as usize; letmut result = Vec::with_capacity(count as usize); for device_info in device_collection.into_iter() { let device_id = device_info.id().expect("get_id failed");
result.push(::common::MidiInputPort {
imp: MidiInputPort { id: device_id }
});
}
result
}
pubfn port_count(&self) -> usize { let device_collection = DeviceInformation::find_all_async_aqs_filter(&self.selector).unwrap().get().expect("find_all_async failed");
device_collection.size().expect("get_size failed") as usize
}
pubfn port_name(&self, port: &MidiInputPort) -> Result<String, PortInfoError> { let device_info_async = DeviceInformation::create_from_id_async(&port.id).map_err(|_| PortInfoError::InvalidPort)?; let device_info = device_info_async.get().map_err(|_| PortInfoError::InvalidPort)?; let device_name = device_info.name().map_err(|_| PortInfoError::CannotRetrievePortName)?;
Ok(device_name.to_string())
}
fn handle_input<T>(args: &MidiMessageReceivedEventArgs, handler_data: &mut HandlerData<T>) { 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 ...
// The first byte in the message is the status let status = message_bytes[0];
if !(status == 0xF0 && ignore.contains(Ignore::Sysex) ||
status == 0xF1 && ignore.contains(Ignore::Time) ||
status == 0xF8 && ignore.contains(Ignore::Time) ||
status == 0xFE && ignore.contains(Ignore::ActiveSense))
{
(handler_data.callback)(timestamp, message_bytes, data);
}
}
struct RtMidiInPort(MidiInPort); unsafeimpl Send for RtMidiInPort {}
pubstruct MidiInputConnection<T> {
port: RtMidiInPort,
event_token: EventRegistrationToken, // TODO: get rid of Arc & Mutex? // synchronization is required because the borrow checker does not // know that the callback we're in here is never called concurrently // (always in sequence)
handler_data: Arc<Mutex<HandlerData<T>>>
}
impl<T> MidiInputConnection<T> { pubfn close(self) -> (MidiInput, T) { let _ = self.port.0.remove_message_received(self.event_token); let closable: IClosable = self.port.0.try_into().unwrap(); let _ = closable.close(); let device_selector = MidiInPort::get_device_selector().expect("get_device_selector failed"); // probably won't ever fail here, because it worked previously letmut handler_data_locked = self.handler_data.lock().unwrap();
(MidiInput {
selector: device_selector,
ignore_flags: handler_data_locked.ignore_flags
}, handler_data_locked.user_data.take().unwrap())
}
}
/// This is all the data that is stored on the heap as long as a connection /// is opened and passed to the callback handler. /// /// It is important that `user_data` is the last field to not influence /// offsets after monomorphization. struct HandlerData<T> {
ignore_flags: Ignore,
callback: Box<dyn FnMut(u64, &[u8], &mut T) + Send>,
user_data: Option<T>
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.