mod transpose;
use std::{
convert::TryFrom,
io,
ops::{Deref, DerefMut},
};
use midly::{live::LiveEvent, num::u4, MetaMessage, MidiMessage, TrackEventKind};
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct Moment {
pub events: Vec<Event>,
}
impl Deref for Moment {
type Target = Vec<Event>;
fn deref(&self) -> &Self::Target {
&self.events
}
}
impl DerefMut for Moment {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.events
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum Event {
Tempo(u32),
TimeSignature(u8, u8, u8, u8),
KeySignature(i8, bool),
Midi(MidiEvent),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct MidiEvent {
pub channel: u4,
pub message: MidiMessage,
}
impl MidiEvent {
pub fn write<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
let msg = LiveEvent::Midi {
channel: self.channel,
message: self.message,
};
msg.write_std(w)
}
}
impl TryFrom<TrackEventKind<'_>> for Event {
type Error = &'static str;
fn try_from(event: TrackEventKind<'_>) -> Result<Self, Self::Error> {
Ok(match event {
TrackEventKind::Midi { channel, message } => Self::Midi(MidiEvent { channel, message }),
TrackEventKind::Meta(MetaMessage::Tempo(n)) => Self::Tempo(u32::from(n)),
TrackEventKind::Meta(MetaMessage::TimeSignature(a, b, c, d)) => {
Self::TimeSignature(a, b, c, d)
}
TrackEventKind::Meta(MetaMessage::KeySignature(a, b)) => Self::KeySignature(a, b),
_ => return Err("not a valid event"),
})
}
}