mod note;
pub use note::Note;
#[derive(Debug, PartialEq, Clone)]
pub struct SimpleMidiFile<'src> {
pub header: MidiHeader,
pub tracks: Vec<Track<'src>>,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct MidiHeader {
pub format: MidiFormat,
pub division: Division,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum MidiFormat {
SingleTrack,
MultipleTrack(u16),
MultipleSong(u16),
}
impl MidiFormat {
pub fn count(&self) -> u16 {
match *self {
MidiFormat::SingleTrack => 1,
MidiFormat::MultipleTrack(ref n) => *n,
MidiFormat::MultipleSong(ref n) => *n,
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Division {
Metrical(u16),
Timecode {
fps: Fps,
res: u8,
},
}
#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(u8)]
pub enum Fps {
TwentyFour = 24,
TwentyFive = 25,
TwentyNine = 29,
Thirty = 30,
}
impl Into<u8> for Fps {
fn into(self) -> u8 {
self as u8
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Track<'src> {
pub events: Vec<Event<'src>>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Event<'src> {
pub delta_time: u32,
pub event: EventType<'src>,
}
#[derive(Debug, PartialEq, Clone)]
pub enum EventType<'src> {
Midi(MidiEvent),
SystemExclusive(SystemExclusiveEvent<'src>),
EscapeSequence(EscapeSequence<'src>),
Meta(MetaEvent<'src>),
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct MidiEvent {
pub channel: u8,
pub event: MidiEventType,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum MidiEventType {
NoteOff(Note, u8),
NoteOn(Note, u8),
PolyphonicPressure(Note, u8),
Controller(u8, u8),
ProgramChange(u8),
ChannelPressure(u8),
PitchBend(u8, u8),
}
#[derive(Debug, PartialEq, Clone)]
pub struct SystemExclusiveEvent<'src>(pub &'src [u8]);
#[derive(Debug, PartialEq, Clone)]
pub struct EscapeSequence<'src>(pub &'src [u8]);
#[derive(Debug, PartialEq, Clone)]
pub enum MetaEvent<'src> {
SequenceNumber(u16),
Text(&'src [u8]),
Copyright(&'src [u8]),
SequenceOrTrackName(&'src [u8]),
InstrumentName(&'src [u8]),
Lyric(&'src [u8]),
Marker(&'src [u8]),
CuePoint(&'src [u8]),
ProgramName(&'src [u8]),
DeviceName(&'src [u8]),
MidiChannelPrefix(u8), MidiPort(u8), EndOfTrack,
Tempo(u32), SMPTEOffset(SMPTEOffset),
TimeSignature(TimeSignature),
KeySignature(KeySignature),
SequencerSpecificEvent(&'src [u8]),
Unknown(u8, &'src [u8]),
}
#[derive(Debug, PartialEq, Clone)]
pub struct SMPTEOffset {
pub fps: Fps,
pub hour: u8, pub minute: u8, pub second: u8, pub no_frames: u8, pub no_fractional_frames: u8,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct TimeSignature {
pub top: u8,
pub bottom: u8,
pub ticks_per_metronome_click: u8,
pub number_32nd_in_quarter: u8,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum KeySignature {
CMajor,
GMajor,
DMajor,
AMajor,
EMajor,
BMajor,
FSharpMajor,
CSharpMajor,
FMajor,
BFlatMajor,
EFlatMajor,
AFlatMajor,
DFlatMajor,
GFlatMajor,
CFlatMajor,
AMinor,
EMinor,
BMinor,
FSharpMinor,
CSharpMinor,
GSharpMinor,
DSharpMinor,
ASharpMinor,
DMinor,
GMinor,
CMinor,
FMinor,
BFlatMinor,
EFlatMinor,
AFlatMinor,
}
impl KeySignature {
pub fn count(&self) -> u8 {
use self::KeySignature::*;
match *self {
CMajor | AMinor => 0,
GMajor | FMajor | EMinor | DMinor => 1,
DMajor | BFlatMajor | BMinor | GMinor => 2,
AMajor | EFlatMajor | FSharpMinor | CMinor => 3,
EMajor | AFlatMajor | CSharpMinor | FMinor => 4,
BMajor | DFlatMajor | GSharpMinor | BFlatMinor => 5,
FSharpMajor | GFlatMajor | DSharpMinor | EFlatMinor => 6,
CSharpMajor | CFlatMajor | ASharpMinor | AFlatMinor => 7,
}
}
fn is_sharps_unchecked(&self) -> bool {
use self::KeySignature::*;
match *self {
GMajor | DMajor | AMajor | EMajor | BMajor | FSharpMajor | CSharpMajor | EMinor
| BMinor | FSharpMinor | CSharpMinor | GSharpMinor | DSharpMinor | ASharpMinor => true,
_ => false,
}
}
pub fn is_sharps(&self) -> bool {
use self::KeySignature::*;
match *self {
CMajor | AMinor => panic!("No sharps or flats"),
_ => self.is_sharps_unchecked(),
}
}
pub fn for_display(&self) -> (u8, bool) {
(self.count(), self.is_sharps_unchecked())
}
}