mod common;
use std::{cell::RefCell, rc::Rc, time::Instant};
use common::*;
use mseq_core::*;
use std::collections::HashMap;
struct DebugInputConductor {
midi_out: Rc<RefCell<DebugMidiOutInner>>,
}
impl Conductor for DebugInputConductor {
fn init(&mut self, context: &mut Context) -> Vec<Instruction> {
context.start();
vec![]
}
fn update(&mut self, context: &mut Context) -> Vec<Instruction> {
if context.get_step() == 30 {
context.quit();
return vec![];
}
if (21..=24).contains(&context.get_step()) {
assert!(
self.midi_out.borrow().notes_on.contains_key(&(
1,
MidiNote {
note: Note::CS,
octave: 4,
vel: 160,
}
.midi_value()
))
);
} else {
assert!(self.midi_out.borrow().notes_on.is_empty());
}
vec![]
}
fn handle_input(
&mut self,
input: mseq_core::MidiMessage,
_context: &Context,
) -> Vec<Instruction> {
match input {
mseq_core::MidiMessage::NoteOff { channel, note } => {
vec![Instruction::MidiMessage {
midi_message: MidiMessage::NoteOff {
channel,
note: note.transpose(3),
},
}]
}
mseq_core::MidiMessage::NoteOn { channel, note } => {
vec![Instruction::MidiMessage {
midi_message: MidiMessage::NoteOn {
channel,
note: note.transpose(3),
},
}]
}
_ => vec![],
}
}
}
fn input_test_simulation(ctx: &Context, input_queue: &mut InputQueue) {
if ctx.get_step() == 20 {
input_queue.push_back(MidiMessage::NoteOn {
channel: 1,
note: MidiNote {
note: Note::AS,
octave: 3,
vel: 160,
},
});
} else if ctx.get_step() == 24 {
input_queue.push_back(MidiMessage::NoteOff {
channel: 1,
note: MidiNote {
note: Note::AS,
octave: 3,
vel: 160,
},
});
}
}
fn test_conductor_with_input<T: MidiOut>(
mut conductor: impl Conductor,
mut midi_controller: MidiController<T>,
input_simulation: impl Fn(&Context, &mut InputQueue),
) {
let mut ctx = Context::default();
let mut input_queue = InputQueue::new();
conductor.init(&mut ctx);
while ctx.is_running() {
input_simulation(&ctx, &mut input_queue);
ctx.process_pre_tick(&mut conductor, &mut midi_controller);
ctx.process_post_tick(&mut midi_controller);
ctx.handle_input(&mut conductor, &mut midi_controller, &mut input_queue);
}
midi_controller.finish();
}
#[test]
fn test_input() {
let debug_conn = Rc::new(RefCell::new(DebugMidiOutInner {
notes_on: HashMap::new(),
start_timestamp: Instant::now(),
}));
let midi = MidiController::new(DebugMidiOut(debug_conn.clone()));
let conductor = DebugInputConductor {
midi_out: debug_conn,
};
test_conductor_with_input(conductor, midi, input_test_simulation);
}