sim_lib_midi_live/
session.rs1use std::convert::Infallible;
2
3use sim_lib_midi_core::{MidiEvent, MidiSink, MidiSource};
4
5use crate::{LiveMidiError, RingMidiBuffer};
6
7const DEFAULT_TPQ: u32 = 480;
8const DEFAULT_CAPACITY: usize = 1024;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum LiveMidiDirection {
13 Source,
15 Sink,
17 Duplex,
19}
20
21impl LiveMidiDirection {
22 fn sink_enabled(self) -> bool {
23 matches!(self, Self::Sink | Self::Duplex)
24 }
25}
26
27#[derive(Debug)]
33pub struct LiveMidiSession {
34 ring: RingMidiBuffer,
35 direction: LiveMidiDirection,
36}
37
38impl LiveMidiSession {
39 pub fn modeled(direction: LiveMidiDirection) -> Result<Self, LiveMidiError> {
42 Self::with_ring(DEFAULT_TPQ, DEFAULT_CAPACITY, direction)
43 }
44
45 pub fn with_ring(
47 tpq: u32,
48 capacity: usize,
49 direction: LiveMidiDirection,
50 ) -> Result<Self, LiveMidiError> {
51 Ok(Self {
52 ring: RingMidiBuffer::new(tpq, capacity)?,
53 direction,
54 })
55 }
56
57 pub fn direction(&self) -> LiveMidiDirection {
59 self.direction
60 }
61
62 pub fn source_mut(&mut self) -> &mut dyn MidiSource<Err = Infallible> {
64 &mut self.ring
65 }
66
67 pub fn sink_mut(&mut self) -> Option<&mut dyn MidiSink<Err = Infallible>> {
69 if self.direction.sink_enabled() {
70 Some(&mut self.ring)
71 } else {
72 None
73 }
74 }
75
76 pub fn enqueue_from_callback(&mut self, event: &MidiEvent) -> Result<(), Infallible> {
78 self.ring.write(event)
79 }
80
81 pub fn close(self) -> Result<(), LiveMidiError> {
83 Ok(())
84 }
85}