sim_lib_midi_live/
ring.rs1use std::{collections::VecDeque, convert::Infallible};
2
3use sim_lib_midi_core::{MidiEvent, MidiSink, MidiSource, TrackedMidiEvent, TrackedMidiSource};
4
5use crate::LiveMidiError;
6
7#[derive(Clone, Debug)]
13pub struct RingMidiBuffer {
14 tpq: u32,
15 capacity: usize,
16 dropped_events: usize,
17 events: VecDeque<MidiEvent>,
18}
19
20impl RingMidiBuffer {
21 pub fn new(tpq: u32, capacity: usize) -> Result<Self, LiveMidiError> {
25 if capacity == 0 {
26 return Err(LiveMidiError::ZeroCapacity);
27 }
28 Ok(Self {
29 tpq,
30 capacity,
31 dropped_events: 0,
32 events: VecDeque::with_capacity(capacity),
33 })
34 }
35
36 pub fn capacity(&self) -> usize {
38 self.capacity
39 }
40
41 pub fn len(&self) -> usize {
43 self.events.len()
44 }
45
46 pub fn is_empty(&self) -> bool {
48 self.events.is_empty()
49 }
50
51 pub fn dropped_events(&self) -> usize {
53 self.dropped_events
54 }
55
56 pub fn clear(&mut self) {
58 self.events.clear();
59 }
60
61 pub fn snapshot(&self) -> Vec<MidiEvent> {
63 self.events.iter().cloned().collect()
64 }
65
66 fn push_back(&mut self, event: MidiEvent) {
67 if self.events.len() == self.capacity {
68 let _ = self.events.pop_front();
69 self.dropped_events += 1;
70 }
71 self.events.push_back(event);
72 }
73}
74
75impl MidiSource for RingMidiBuffer {
76 type Err = Infallible;
77
78 fn tpq(&self) -> u32 {
79 self.tpq
80 }
81
82 fn next(&mut self) -> Result<Option<MidiEvent>, Self::Err> {
83 Ok(self.events.pop_front())
84 }
85}
86
87impl MidiSink for RingMidiBuffer {
88 type Err = Infallible;
89
90 fn tpq(&self) -> u32 {
91 self.tpq
92 }
93
94 fn write(&mut self, event: &MidiEvent) -> Result<(), Self::Err> {
95 self.push_back(event.clone());
96 Ok(())
97 }
98
99 fn flush(&mut self) -> Result<(), Self::Err> {
100 Ok(())
101 }
102}
103
104#[derive(Clone, Debug)]
107pub struct RingTrackedMidiBuffer {
108 tpq: u32,
109 capacity: usize,
110 dropped_events: usize,
111 last_track: usize,
112 n_tracks: usize,
113 events: VecDeque<TrackedMidiEvent>,
114}
115
116impl RingTrackedMidiBuffer {
117 pub fn new(tpq: u32, capacity: usize) -> Result<Self, LiveMidiError> {
122 if capacity == 0 {
123 return Err(LiveMidiError::ZeroCapacity);
124 }
125 Ok(Self {
126 tpq,
127 capacity,
128 dropped_events: 0,
129 last_track: 0,
130 n_tracks: 0,
131 events: VecDeque::with_capacity(capacity),
132 })
133 }
134
135 pub fn capacity(&self) -> usize {
137 self.capacity
138 }
139
140 pub fn len(&self) -> usize {
142 self.events.len()
143 }
144
145 pub fn is_empty(&self) -> bool {
147 self.events.is_empty()
148 }
149
150 pub fn last_track(&self) -> usize {
152 self.last_track
153 }
154
155 pub fn dropped_events(&self) -> usize {
157 self.dropped_events
158 }
159
160 pub fn clear(&mut self) {
162 self.events.clear();
163 self.last_track = 0;
164 self.n_tracks = 0;
165 }
166
167 pub fn snapshot(&self) -> Vec<TrackedMidiEvent> {
169 self.events.iter().cloned().collect()
170 }
171
172 pub fn push_tracked_event(&mut self, event: TrackedMidiEvent) {
175 self.n_tracks = self.n_tracks.max(event.last_track + 1);
176 if self.events.len() == self.capacity {
177 let _ = self.events.pop_front();
178 self.dropped_events += 1;
179 }
180 self.events.push_back(event);
181 }
182}
183
184impl MidiSource for RingTrackedMidiBuffer {
185 type Err = Infallible;
186
187 fn tpq(&self) -> u32 {
188 self.tpq
189 }
190
191 fn next(&mut self) -> Result<Option<MidiEvent>, Self::Err> {
192 let event = self.events.pop_front();
193 if let Some(event) = &event {
194 self.last_track = event.last_track;
195 }
196 Ok(event.map(|item| item.event))
197 }
198}
199
200impl TrackedMidiSource for RingTrackedMidiBuffer {
201 fn last_track(&self) -> usize {
202 self.last_track
203 }
204
205 fn n_tracks(&self) -> usize {
206 self.n_tracks
207 }
208
209 fn next_tracked(&mut self) -> Result<Option<TrackedMidiEvent>, Self::Err> {
210 let event = self.events.pop_front();
211 if let Some(event) = &event {
212 self.last_track = event.last_track;
213 }
214 Ok(event)
215 }
216}