mirror of
https://github.com/dredozubov/polyrhythmix.git
synced 2024-12-22 14:25:29 +00:00
First more or less working version
This commit is contained in:
parent
5ea3d27efc
commit
e4e8c5c402
1 changed files with 50 additions and 125 deletions
175
src/midi/core.rs
175
src/midi/core.rs
|
@ -68,22 +68,19 @@ impl Ord for EventType {
|
|||
fn cmp(&self, other: &EventType) -> Ordering {
|
||||
match (self, other) {
|
||||
(EventType::NoteOn(a), EventType::NoteOn(b)) => a.cmp(b),
|
||||
(EventType::NoteOn(_), EventType::NoteOff(_)) => Ordering::Greater,
|
||||
(EventType::NoteOff(_), EventType::NoteOn(_)) => Ordering::Less,
|
||||
(EventType::NoteOn(a), EventType::NoteOff(b)) => match a.cmp(b) {
|
||||
Ordering::Equal => Ordering::Greater,
|
||||
ord => ord
|
||||
},
|
||||
(EventType::NoteOff(a), EventType::NoteOn(b)) => match a.cmp(b) {
|
||||
Ordering::Equal => Ordering::Less,
|
||||
ord => ord
|
||||
},
|
||||
(EventType::NoteOff(a), EventType::NoteOff(b)) => a.cmp(b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventType {
|
||||
fn is_note_on(&self) -> bool {
|
||||
match self {
|
||||
EventType::NoteOn(_) => true,
|
||||
EventType::NoteOff(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
|
||||
pub enum Part {
|
||||
KickDrum,
|
||||
|
@ -104,12 +101,38 @@ impl Part {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Event<T> {
|
||||
tick: T,
|
||||
event_type: EventType,
|
||||
}
|
||||
|
||||
impl<T> PartialOrd for Event<T>
|
||||
where
|
||||
T: PartialOrd + Ord,
|
||||
Event<T>: Ord
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
|
||||
fn lt(&self, other: &Self) -> bool {
|
||||
matches!(self.partial_cmp(other), Some(Ordering::Less))
|
||||
}
|
||||
|
||||
fn le(&self, other: &Self) -> bool {
|
||||
matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
|
||||
}
|
||||
|
||||
fn gt(&self, other: &Self) -> bool {
|
||||
matches!(self.partial_cmp(other), Some(Ordering::Greater))
|
||||
}
|
||||
|
||||
fn ge(&self, other: &Self) -> bool {
|
||||
matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for Event<T>
|
||||
where
|
||||
T: Ord,
|
||||
|
@ -141,8 +164,13 @@ fn test_ord_event_t() {
|
|||
assert_eq!(first_off.cmp(&second_on), Ordering::Less);
|
||||
|
||||
let mut vec1 = vec![second_on, first_off, first_on];
|
||||
let mut vec2 = vec1.clone();
|
||||
|
||||
vec1.sort_by(|x, y| x.cmp(y));
|
||||
assert_eq!(vec1, vec![first_on, first_off, second_on]);
|
||||
|
||||
vec2.sort();
|
||||
assert_eq!(vec2, vec![first_on, first_off, second_on]);
|
||||
}
|
||||
|
||||
// Events are supposed to be sorted by T at all times.
|
||||
|
@ -182,7 +210,6 @@ impl<T: Add<Tick, Output = T> + Clone + Ord + std::fmt::Debug> Add for EventGrid
|
|||
self.events.extend(other_events);
|
||||
// I don't know why sort() doesn't work in the same way.
|
||||
self.events.sort_by(|x, y| x.cmp(y));
|
||||
println!("self.events: {:?}", self.events);
|
||||
self.length = self.length + other.length;
|
||||
self
|
||||
}
|
||||
|
@ -460,8 +487,7 @@ fn flatten_group(
|
|||
}
|
||||
};
|
||||
});
|
||||
// grid.events.sort() is not the same for some reason
|
||||
grid.events.sort_by(|x, y| x.cmp(y));
|
||||
grid.events.sort();
|
||||
cycle_grid(grid, *times)
|
||||
}
|
||||
|
||||
|
@ -607,8 +633,6 @@ impl Iterator for EventIterator {
|
|||
})
|
||||
.collect();
|
||||
|
||||
println!("candidates: {:?}", candidates);
|
||||
|
||||
if let Some((min_part, min_event)) = candidates.iter().min_by_key(|(_,x)| *x) {
|
||||
match min_part {
|
||||
Part::KickDrum => self.kick.next(),
|
||||
|
@ -636,71 +660,7 @@ fn test_event_iterator_impl() {
|
|||
Part::SnareDrum,
|
||||
&mut Tick(0),
|
||||
);
|
||||
let kick2 = flatten_group(
|
||||
&group_or_delimited_group("8xxxxxxxx").unwrap().1,
|
||||
Part::KickDrum,
|
||||
&mut Tick(0),
|
||||
);
|
||||
let snare2 = flatten_group(
|
||||
&group_or_delimited_group("4-x-x").unwrap().1,
|
||||
Part::SnareDrum,
|
||||
&mut Tick(0),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
EventIterator::new(
|
||||
kick2.clone(),
|
||||
snare2.clone(),
|
||||
empty.clone(),
|
||||
empty.clone(),
|
||||
TimeSignature::from_str("4/4").unwrap()
|
||||
)
|
||||
.into_iter()
|
||||
.collect::<Vec<Event<Tick>>>(),
|
||||
vec![
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::KickDrum),
|
||||
tick: Tick(0)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOff(Part::KickDrum),
|
||||
tick: Tick(24)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::KickDrum),
|
||||
tick: Tick(24)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOff(Part::KickDrum),
|
||||
tick: Tick(48)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::SnareDrum),
|
||||
tick: Tick(48)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::KickDrum),
|
||||
tick: Tick(48)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOff(Part::KickDrum),
|
||||
tick: Tick(72)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::KickDrum),
|
||||
tick: Tick(72)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOff(Part::KickDrum),
|
||||
tick: Tick(96)
|
||||
},
|
||||
Event {
|
||||
event_type: EventType::NoteOn(Part::SnareDrum),
|
||||
tick: Tick(96)
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
assert_eq!(
|
||||
EventIterator::new(
|
||||
kick1.clone(),
|
||||
|
@ -718,11 +678,11 @@ fn test_event_iterator_impl() {
|
|||
},
|
||||
Event {
|
||||
tick: Tick(48),
|
||||
event_type: EventType::NoteOn(Part::SnareDrum)
|
||||
event_type: EventType::NoteOff(Part::KickDrum)
|
||||
},
|
||||
Event {
|
||||
tick: Tick(96),
|
||||
event_type: EventType::NoteOff(Part::KickDrum)
|
||||
tick: Tick(48),
|
||||
event_type: EventType::NoteOn(Part::SnareDrum)
|
||||
},
|
||||
Event {
|
||||
tick: Tick(96),
|
||||
|
@ -752,35 +712,6 @@ fn test_event_iterator_impl() {
|
|||
}
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
EventIterator::new(
|
||||
kick1.clone(),
|
||||
empty.clone(),
|
||||
empty.clone(),
|
||||
empty.clone(),
|
||||
TimeSignature::from_str("4/4").unwrap()
|
||||
)
|
||||
.into_iter()
|
||||
.collect::<Vec<Event<Tick>>>(),
|
||||
[
|
||||
Event {
|
||||
tick: Tick(0),
|
||||
event_type: EventType::NoteOn(Part::KickDrum)
|
||||
},
|
||||
Event {
|
||||
tick: Tick(48),
|
||||
event_type: EventType::NoteOff(Part::KickDrum)
|
||||
},
|
||||
Event {
|
||||
tick: Tick(96),
|
||||
event_type: EventType::NoteOn(Part::KickDrum)
|
||||
},
|
||||
Event {
|
||||
tick: Tick(144),
|
||||
event_type: EventType::NoteOff(Part::KickDrum)
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Returns time as a number of ticks from beginning, has to be turned into the midi delta-time.
|
||||
|
@ -847,17 +778,12 @@ fn flatten_and_merge(
|
|||
}
|
||||
None => (EventGrid::empty(), 0),
|
||||
};
|
||||
// let iter = |grid: EventGrid<Tick>, times| grid.into_iter().cycle().take(times).peekable();
|
||||
let iter = |grid: EventGrid<Tick>, times| {
|
||||
[0..times]
|
||||
.iter()
|
||||
.fold(EventGrid::empty(), |acc, _| acc + grid.clone())
|
||||
};
|
||||
|
||||
EventIterator::new(
|
||||
iter(kick_grid, kick_repeats),
|
||||
iter(snare_grid, snare_repeats),
|
||||
iter(hihat_grid, hihat_repeats),
|
||||
iter(crash_grid, crash_repeats),
|
||||
cycle_grid(kick_grid, Times(kick_repeats as u16)),
|
||||
cycle_grid(snare_grid, Times(snare_repeats as u16)),
|
||||
cycle_grid(hihat_grid, Times(hihat_repeats as u16)),
|
||||
cycle_grid(crash_grid, Times(crash_repeats as u16)),
|
||||
time_signature,
|
||||
)
|
||||
}
|
||||
|
@ -898,7 +824,6 @@ fn create_tracks<'a>(
|
|||
events,
|
||||
length: time,
|
||||
};
|
||||
println!("event grid in ticks: {:?}", event_grid_tick);
|
||||
let event_grid = event_grid_tick.to_delta();
|
||||
let mut drums = Vec::new();
|
||||
// let midi_tempo = MidiTempo::from_tempo(Tempo(130)).0;
|
||||
|
|
Loading…
Reference in a new issue