#[cfg(feature = "midir")]
use midir::{self, MidiOutputConnection};
use midly::{
live::{SystemCommon, SystemRealtime},
MidiMessage,
};
use crate::{
event::{Event, MidiEvent, Moment},
Timer,
};
#[doc = include_str!("doc_player.md")]
pub struct Player<T: Timer, C: Connection> {
pub con: C,
timer: T,
}
impl<T: Timer, C: Connection> Player<T, C> {
pub fn new(timer: T, con: C) -> Self {
Self { con, timer }
}
pub fn set_timer(&mut self, timer: T) -> T {
std::mem::replace(&mut self.timer, timer)
}
pub fn play(&mut self, sheet: &[Moment]) -> bool {
let mut counter = 0_u32;
for moment in sheet {
if !moment.is_empty() {
self.timer.sleep(counter);
counter = 0;
for event in &moment.events {
match event {
Event::Tempo(val) => self.timer.change_tempo(*val),
Event::Midi(msg) => {
if !self.con.play(*msg) {
return false;
}
}
_ => (),
};
}
}
counter += 1;
}
true
}
}
pub trait Connection {
fn play(&mut self, event: MidiEvent) -> bool;
fn send_sys_rt(&mut self, _msg: SystemRealtime) {}
fn send_sys_common(&mut self, _msg: SystemCommon<'_>) {}
fn all_notes_off(&mut self) {
for ch in 0..16 {
for note in 0..=127 {
self.play(MidiEvent {
channel: ch.into(),
message: MidiMessage::NoteOff {
key: note.into(),
vel: 127.into(),
},
});
}
}
}
}
#[cfg(feature = "midir")]
impl Connection for MidiOutputConnection {
fn play(&mut self, msg: MidiEvent) -> bool {
let mut buf = Vec::with_capacity(8);
let _ = msg.write(&mut buf);
let _ = self.send(&buf);
true
}
fn send_sys_rt(&mut self, msg: SystemRealtime) {
let mut buf = Vec::with_capacity(8);
let _ = midly::live::LiveEvent::Realtime(msg).write(&mut buf);
let _ = self.send(&buf);
}
fn send_sys_common(&mut self, msg: SystemCommon<'_>) {
let mut buf = Vec::with_capacity(8);
let _ = midly::live::LiveEvent::Common(msg).write(&mut buf);
let _ = self.send(&buf);
}
}