mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
refactor: compact
This commit is contained in:
parent
abee6cc2c8
commit
60627ac3e5
43 changed files with 923 additions and 780 deletions
4
.misc/_sequence/audio.rs
Normal file
4
.misc/_sequence/audio.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub struct Sample {
|
||||
samples: Vec<Vec<u64>>,
|
||||
cuepoints: Vec<Vec<Vec<u64>>>,
|
||||
}
|
||||
114
.misc/_sequence/midi.rs
Normal file
114
.misc/_sequence/midi.rs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
use crate::sequence::{Frame, Time};
|
||||
|
||||
/// Pulses per quarter note
|
||||
pub const PPQ: usize = 96;
|
||||
|
||||
pub struct Message {
|
||||
bytes: Vec<u8>
|
||||
}
|
||||
|
||||
pub struct MIDISequence {
|
||||
name: String,
|
||||
length: usize,
|
||||
events: Vec<(Frame, MIDIEvent)>,
|
||||
notes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl MIDISequence {
|
||||
pub fn new (name: &str, length: usize) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
length,
|
||||
events: vec![],
|
||||
notes: vec![],
|
||||
}
|
||||
}
|
||||
pub fn add (&mut self, time: usize, event: MIDIEvent) -> &mut Self {
|
||||
let mut sort = false;
|
||||
match &event {
|
||||
MIDIEvent::NoteOn(pitch, _velocity) => {
|
||||
if !self.notes.contains(pitch) {
|
||||
self.notes.push(*pitch);
|
||||
sort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if sort {
|
||||
self.notes.sort();
|
||||
}
|
||||
self.events.push((time, event));
|
||||
self
|
||||
}
|
||||
pub fn render (&self, stdout: &mut std::io::Stdout, resolution: usize)
|
||||
-> Result<(), Box<dyn std::error::Error>>
|
||||
{
|
||||
use crossterm::{*, style::Stylize};
|
||||
let (col, row) = cursor::position()?;
|
||||
let unit = PPQ / resolution;
|
||||
let length = self.length / unit;
|
||||
let mut header = String::from(" ");
|
||||
for i in 0..length {
|
||||
if i % 8 == 0 {
|
||||
header.push('┍');
|
||||
} else {
|
||||
header.push('━');
|
||||
}
|
||||
}
|
||||
header.push('┑');
|
||||
let mut tracks: Vec<(String, String)> = vec![];
|
||||
for note in self.notes.iter().rev() {
|
||||
let mut row_header = format!(" {note:3} ");
|
||||
let mut row = String::new();
|
||||
for beat in 0..length {
|
||||
let mut active = false;
|
||||
for (frame, event) in self.events.iter() {
|
||||
match event {
|
||||
MIDIEvent::NoteOn(pitch, _) => {
|
||||
if pitch == note
|
||||
&& *frame >= beat * unit
|
||||
&& *frame < (beat + 1) * unit
|
||||
{
|
||||
active = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if active {
|
||||
row.push('⯀')
|
||||
} else if beat == 0 {
|
||||
row.push('│');
|
||||
} else if beat % 8 == 0 {
|
||||
row.push('┆');
|
||||
} else {
|
||||
row.push('·');
|
||||
}
|
||||
}
|
||||
tracks.push((row_header, row));
|
||||
}
|
||||
stdout.queue(style::PrintStyledContent(header.grey()))?;
|
||||
for (row_header, row) in tracks.into_iter() {
|
||||
stdout
|
||||
.queue(cursor::MoveDown(1))?
|
||||
.queue(cursor::MoveToColumn(col))?
|
||||
.queue(style::PrintStyledContent(row_header.grey()))?
|
||||
.queue(style::PrintStyledContent(row.clone().white()))?
|
||||
.queue(style::PrintStyledContent(row.clone().yellow()))?
|
||||
.queue(style::PrintStyledContent(row.white()))?;
|
||||
}
|
||||
//stdout
|
||||
//.queue(cursor::MoveDown(1))?
|
||||
//.queue(cursor::MoveToColumn(col))?
|
||||
//.queue(style::PrintStyledContent(footer.grey()))?;
|
||||
//.queue(style::PrintStyledContent("················".grey()))?
|
||||
//.queue(style::PrintStyledContent("│".yellow()))?
|
||||
//.queue(cursor::MoveDown(1))?
|
||||
//.queue(cursor::MoveLeft(18))?
|
||||
//.queue(style::PrintStyledContent("└────────────────┘".yellow()))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub enum MIDIEvent {
|
||||
NoteOn(u8, u8)
|
||||
}
|
||||
80
.misc/_sequence/mod.rs
Normal file
80
.misc/_sequence/mod.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
pub mod audio;
|
||||
pub mod midi;
|
||||
pub mod osc;
|
||||
pub mod time;
|
||||
|
||||
pub type Frame = usize;
|
||||
|
||||
pub enum Time {
|
||||
Fixed(Frame),
|
||||
Synced(usize),
|
||||
}
|
||||
|
||||
//enum Event {
|
||||
//Trigger,
|
||||
//Gate,
|
||||
//MIDI(MIDIEvent),
|
||||
//Audio,
|
||||
//OSC,
|
||||
//Text,
|
||||
//Sequence
|
||||
//}
|
||||
|
||||
//struct Clip {
|
||||
//name: String,
|
||||
//length: u64,
|
||||
//start: u64,
|
||||
//end: u64,
|
||||
//clips: Sequence<Event<Clip>>,
|
||||
//markers: Sequence<Event<Marker>>,
|
||||
//audio: Sequence<Event<audio::Sample>>,
|
||||
//midi: Sequence<Event<midi::Message>>,
|
||||
//osc: Sequence<Event<osc::Command>>,
|
||||
//}
|
||||
|
||||
//enum ClipData {
|
||||
//Trigger,
|
||||
//Gate,
|
||||
//MIDI,
|
||||
//Audio,
|
||||
//OSC,
|
||||
//Text,
|
||||
//Clip
|
||||
//}
|
||||
|
||||
//impl Clip {
|
||||
//fn new (name: &str, length: u64) -> Self {
|
||||
//Self {
|
||||
//name: name.into(),
|
||||
//length,
|
||||
//start: 0,
|
||||
//end: length,
|
||||
//clips: Sequence::new(),
|
||||
//markers: Sequence::new(),
|
||||
//audio: Sequence::new(),
|
||||
//midi: Sequence::new(),
|
||||
//osc: Sequence::new(),
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
|
||||
//struct Sequence<T> {
|
||||
//events: Vec<Event<T>>,
|
||||
//next: usize,
|
||||
//}
|
||||
|
||||
//impl<T> Sequence<T> {
|
||||
//fn new () -> Self {
|
||||
//Self { events: vec![], next: 0 }
|
||||
//}
|
||||
//}
|
||||
|
||||
//struct Event<T> {
|
||||
//time: u64,
|
||||
//data: T,
|
||||
//}
|
||||
|
||||
//struct Marker {
|
||||
//name: String,
|
||||
//}
|
||||
|
||||
4
.misc/_sequence/osc.rs
Normal file
4
.misc/_sequence/osc.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub struct Command {
|
||||
name: String,
|
||||
args: Vec<String>,
|
||||
}
|
||||
0
.misc/_sequence/time.rs
Normal file
0
.misc/_sequence/time.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue