mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
phrase 0; stop all; loop_on->looped; remove trailers
This commit is contained in:
parent
ce523d9e45
commit
775fea2c08
8 changed files with 23 additions and 14 deletions
|
|
@ -117,7 +117,7 @@ pub struct Phrase {
|
||||||
/// Notes in phrase
|
/// Notes in phrase
|
||||||
pub notes: PhraseData,
|
pub notes: PhraseData,
|
||||||
/// Whether to loop the phrase or play it once
|
/// Whether to loop the phrase or play it once
|
||||||
pub loop_on: bool,
|
pub looped: bool,
|
||||||
/// Start of loop
|
/// Start of loop
|
||||||
pub loop_start: usize,
|
pub loop_start: usize,
|
||||||
/// Length of loop
|
/// Length of loop
|
||||||
|
|
@ -134,7 +134,7 @@ pub type PhraseData = Vec<Vec<MidiMessage>>;
|
||||||
impl Phrase {
|
impl Phrase {
|
||||||
pub fn new (
|
pub fn new (
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
loop_on: bool,
|
looped: bool,
|
||||||
length: usize,
|
length: usize,
|
||||||
notes: Option<PhraseData>,
|
notes: Option<PhraseData>,
|
||||||
color: Option<ItemPalette>,
|
color: Option<ItemPalette>,
|
||||||
|
|
@ -145,7 +145,7 @@ impl Phrase {
|
||||||
ppq: PPQ,
|
ppq: PPQ,
|
||||||
length,
|
length,
|
||||||
notes: notes.unwrap_or(vec![Vec::with_capacity(16);length]),
|
notes: notes.unwrap_or(vec![Vec::with_capacity(16);length]),
|
||||||
loop_on,
|
looped,
|
||||||
loop_start: 0,
|
loop_start: 0,
|
||||||
loop_length: length,
|
loop_length: length,
|
||||||
percussive: true,
|
percussive: true,
|
||||||
|
|
@ -161,7 +161,7 @@ impl Phrase {
|
||||||
clone.uuid = uuid::Uuid::new_v4();
|
clone.uuid = uuid::Uuid::new_v4();
|
||||||
clone
|
clone
|
||||||
}
|
}
|
||||||
pub fn toggle_loop (&mut self) { self.loop_on = !self.loop_on; }
|
pub fn toggle_loop (&mut self) { self.looped = !self.looped; }
|
||||||
pub fn record_event (&mut self, pulse: usize, message: MidiMessage) {
|
pub fn record_event (&mut self, pulse: usize, message: MidiMessage) {
|
||||||
if pulse >= self.length { panic!("extend phrase first") }
|
if pulse >= self.length { panic!("extend phrase first") }
|
||||||
self.notes[pulse].push(message);
|
self.notes[pulse].push(message);
|
||||||
|
|
@ -180,7 +180,16 @@ impl Phrase {
|
||||||
|
|
||||||
impl Default for Phrase {
|
impl Default for Phrase {
|
||||||
fn default () -> Self {
|
fn default () -> Self {
|
||||||
Self::new("null", false, 0, None, Some(ItemColor::from(Color::Rgb(0, 0, 0)).into()))
|
Self::new(
|
||||||
|
"Stop",
|
||||||
|
false,
|
||||||
|
1,
|
||||||
|
Some(vec![vec![MidiMessage::Controller {
|
||||||
|
controller: 123.into(),
|
||||||
|
value: 0.into()
|
||||||
|
}]]),
|
||||||
|
Some(ItemColor::from(Color::Rgb(32, 32, 32)).into())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ pub enum Align<L> {
|
||||||
/// Draw at upper left corner of contaier
|
/// Draw at upper left corner of contaier
|
||||||
NW(L),
|
NW(L),
|
||||||
/// Draw at center of upper edge of container
|
/// Draw at center of upper edge of container
|
||||||
N(L),
|
N(L),
|
||||||
/// Draw at right left corner of contaier
|
/// Draw at right left corner of contaier
|
||||||
NE(L),
|
NE(L),
|
||||||
/// Draw at center of left edge of container
|
/// Draw at center of left edge of container
|
||||||
W(L),
|
W(L),
|
||||||
/// Draw at center of right edge of container
|
/// Draw at center of right edge of container
|
||||||
E(L),
|
E(L),
|
||||||
/// Draw at lower left corner of container
|
/// Draw at lower left corner of container
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub trait LayoutMinMax<E: Engine> {
|
||||||
Min::X(x, w)
|
Min::X(x, w)
|
||||||
}
|
}
|
||||||
fn min_y <W: Render<E>> (y: E::Unit, w: W) -> Min<E, W> {
|
fn min_y <W: Render<E>> (y: E::Unit, w: W) -> Min<E, W> {
|
||||||
Min::Y(y, w)
|
Min::Y(y, w)
|
||||||
}
|
}
|
||||||
fn min_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Min<E, W> {
|
fn min_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Min<E, W> {
|
||||||
Min::XY(x, y, w)
|
Min::XY(x, y, w)
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ impl Tui {
|
||||||
//selected.wrap(TransportFocus::Bpm, &Outset::X(1u16, {
|
//selected.wrap(TransportFocus::Bpm, &Outset::X(1u16, {
|
||||||
//row! {
|
//row! {
|
||||||
//"BPM ",
|
//"BPM ",
|
||||||
//format!("{}.{:03}", *bpm as usize, (bpm * 1000.0) % 1000.0)
|
//format!("{}.{:03}", *bpm as usize, (bpm * 1000.0) % 1000.0)
|
||||||
//}
|
//}
|
||||||
//})),
|
//})),
|
||||||
//selected.wrap(TransportFocus::Sync, &Outset::X(1u16, row! {
|
//selected.wrap(TransportFocus::Sync, &Outset::X(1u16, row! {
|
||||||
|
|
|
||||||
|
|
@ -1288,7 +1288,7 @@ impl ArrangerSelection {
|
||||||
match self {
|
match self {
|
||||||
Clip(_, s) => Some(*s),
|
Clip(_, s) => Some(*s),
|
||||||
Scene(s) => Some(*s),
|
Scene(s) => Some(*s),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ impl AddSampleModal {
|
||||||
voices: voices.clone(),
|
voices: voices.clone(),
|
||||||
_search: None
|
_search: None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn rescan (&mut self) -> Usually<()> {
|
fn rescan (&mut self) -> Usually<()> {
|
||||||
scan(&self.dir).map(|(subdirs, files)|{
|
scan(&self.dir).map(|(subdirs, files)|{
|
||||||
self.subdirs = subdirs;
|
self.subdirs = subdirs;
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ impl std::fmt::Debug for PhraseEditorModel {
|
||||||
pub struct PhraseEditStatus<'a>(pub &'a PhraseEditorModel);
|
pub struct PhraseEditStatus<'a>(pub &'a PhraseEditorModel);
|
||||||
render!(|self:PhraseEditStatus<'a>|row!(|add|{
|
render!(|self:PhraseEditStatus<'a>|row!(|add|{
|
||||||
let (color, name, length, looped) = if let Some(phrase) = self.0.phrase().as_ref().map(|p|p.read().unwrap()) {
|
let (color, name, length, looped) = if let Some(phrase) = self.0.phrase().as_ref().map(|p|p.read().unwrap()) {
|
||||||
(phrase.color, phrase.name.clone(), phrase.length, phrase.loop_on)
|
(phrase.color, phrase.name.clone(), phrase.length, phrase.looped)
|
||||||
} else {
|
} else {
|
||||||
(ItemPalette::from(TuiTheme::g(64)), String::new(), 0, false)
|
(ItemPalette::from(TuiTheme::g(64)), String::new(), 0, false)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ render!(|self: PhraseListView<'a>|{
|
||||||
let mut row2 = format!(" {name}");
|
let mut row2 = format!(" {name}");
|
||||||
if let Some(PhraseListMode::Rename(phrase, _)) = mode {
|
if let Some(PhraseListMode::Rename(phrase, _)) = mode {
|
||||||
if i == *phrase {
|
if i == *phrase {
|
||||||
row2 = format!("{row2}▄");
|
row2 = format!("{row2}▄");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
row2
|
row2
|
||||||
|
|
@ -310,7 +310,7 @@ impl PhraseSelector {
|
||||||
(time, name.clone(), color)
|
(time, name.clone(), color)
|
||||||
} else if let Some((_, Some(phrase))) = state.play_phrase() {
|
} else if let Some((_, Some(phrase))) = state.play_phrase() {
|
||||||
let phrase = phrase.read().unwrap();
|
let phrase = phrase.read().unwrap();
|
||||||
if phrase.loop_on {
|
if phrase.looped {
|
||||||
(" ".into(), phrase.name.clone(), phrase.color.clone())
|
(" ".into(), phrase.name.clone(), phrase.color.clone())
|
||||||
} else {
|
} else {
|
||||||
(" ".into(), " ".into(), TuiTheme::g(64).into())
|
(" ".into(), " ".into(), TuiTheme::g(64).into())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue