use mseq_core::MidiOut;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::time::Instant;
pub struct DebugMidiOutInner {
pub notes_on: HashMap<(u8, u8), u8>,
pub start_timestamp: Instant,
}
pub struct DebugMidiOut(pub Rc<RefCell<DebugMidiOutInner>>);
impl DebugMidiOut {
fn print_elapsed(&self, message: &str) {
println!(
"[{}]\t{message}",
self.0.borrow().start_timestamp.elapsed().as_secs_f32()
)
}
}
impl MidiOut for DebugMidiOut {
type Error = String;
fn send_start(&mut self) -> Result<(), String> {
self.print_elapsed("Start");
Ok(())
}
fn send_continue(&mut self) -> Result<(), String> {
self.print_elapsed("Continue");
Ok(())
}
fn send_stop(&mut self) -> Result<(), String> {
self.print_elapsed("Stop");
Ok(())
}
fn send_clock(&mut self) -> Result<(), String> {
self.print_elapsed("Clock");
Ok(())
}
fn send_note_on(&mut self, channel_id: u8, note: u8, velocity: u8) -> Result<(), String> {
let message = format!("On\tchn:{}\tnte:{}\tvel:{}", channel_id, note, velocity);
self.print_elapsed(&message);
self.0
.borrow_mut()
.notes_on
.insert((channel_id, note), velocity);
Ok(())
}
fn send_note_off(&mut self, channel_id: u8, note: u8) -> Result<(), String> {
let message = format!("Off\tchn:{}\tnte:{}", channel_id, note);
self.print_elapsed(&message);
let mut inner = self.0.borrow_mut();
assert!(inner.notes_on.contains_key(&(channel_id, note)));
inner.notes_on.remove(&(channel_id, note));
Ok(())
}
fn send_cc(&mut self, channel_id: u8, parameter: u8, value: u8) -> Result<(), String> {
let message = format!("Cc\tchn:{}\tprm:{}\tval:{}", channel_id, parameter, value);
self.print_elapsed(&message);
Ok(())
}
fn send_pc(&mut self, channel: u8, value: u8) -> Result<(), String> {
let message = format!("Pc\tchn:{}\tval:{}", channel, value);
self.print_elapsed(&message);
Ok(())
}
fn send_pitch_bend(&mut self, channel: u8, value: u16) -> Result<(), String> {
let message = format!("PitchBend\tchn:{}\tval:{}", channel, value);
self.print_elapsed(&message);
Ok(())
}
}