mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
remove unused generic; add Sequencer::player
This commit is contained in:
parent
076be5bcb3
commit
86adf493c8
5 changed files with 32 additions and 30 deletions
|
|
@ -55,7 +55,7 @@ pub struct Arrangement<E: Engine> {
|
|||
/// Collection of phrases.
|
||||
pub phrases: Arc<RwLock<PhrasePool<E>>>,
|
||||
/// Collection of tracks.
|
||||
pub tracks: Vec<ArrangementTrack<E>>,
|
||||
pub tracks: Vec<ArrangementTrack>,
|
||||
/// Collection of scenes.
|
||||
pub scenes: Vec<Scene>,
|
||||
/// Currently selected element.
|
||||
|
|
@ -70,13 +70,13 @@ pub struct Arrangement<E: Engine> {
|
|||
pub size: Measure<E>,
|
||||
}
|
||||
/// Represents a track in the arrangement
|
||||
pub struct ArrangementTrack<E: Engine> {
|
||||
pub struct ArrangementTrack {
|
||||
/// Name of track
|
||||
pub name: Arc<RwLock<String>>,
|
||||
/// Inputs
|
||||
pub inputs: Vec<Port<MidiIn>>,
|
||||
/// MIDI player/recorder
|
||||
pub player: PhrasePlayer<E>,
|
||||
pub player: PhrasePlayer,
|
||||
/// Outputs
|
||||
pub outputs: Vec<Port<MidiIn>>,
|
||||
/// Preferred width of track column
|
||||
|
|
@ -374,10 +374,10 @@ impl<E: Engine> Arrangement<E> {
|
|||
}
|
||||
/// Methods for tracks in arrangement
|
||||
impl<E: Engine> Arrangement<E> {
|
||||
pub fn track (&self) -> Option<&ArrangementTrack<E>> {
|
||||
pub fn track (&self) -> Option<&ArrangementTrack> {
|
||||
self.selected.track().map(|t|self.tracks.get(t)).flatten()
|
||||
}
|
||||
pub fn track_mut (&mut self) -> Option<&mut ArrangementTrack<E>> {
|
||||
pub fn track_mut (&mut self) -> Option<&mut ArrangementTrack> {
|
||||
self.selected.track().map(|t|self.tracks.get_mut(t)).flatten()
|
||||
}
|
||||
pub fn track_width_inc (&mut self) { self.track_mut().map(|t|t.width_inc()); }
|
||||
|
|
@ -386,7 +386,7 @@ impl<E: Engine> Arrangement<E> {
|
|||
pub fn track_prev (&mut self) { self.selected.track_prev() }
|
||||
pub fn track_add (
|
||||
&mut self, name: Option<&str>, color: Option<Color>
|
||||
) -> Usually<&mut ArrangementTrack<E>> {
|
||||
) -> Usually<&mut ArrangementTrack> {
|
||||
self.tracks.push(name.map_or_else(
|
||||
|| ArrangementTrack::new(&self.clock, &self.track_default_name(), color),
|
||||
|name| ArrangementTrack::new(&self.clock, name, color),
|
||||
|
|
@ -449,10 +449,10 @@ impl<E: Engine> Arrangement<E> {
|
|||
}
|
||||
/// Methods for phrases in arrangement
|
||||
impl<E: Engine> Arrangement<E> {
|
||||
pub fn sequencer (&self) -> Option<&ArrangementTrack<E>> {
|
||||
pub fn sequencer (&self) -> Option<&ArrangementTrack> {
|
||||
self.selected.track().map(|track|self.tracks.get(track)).flatten()
|
||||
}
|
||||
pub fn sequencer_mut (&mut self) -> Option<&mut ArrangementTrack<E>> {
|
||||
pub fn sequencer_mut (&mut self) -> Option<&mut ArrangementTrack> {
|
||||
self.selected.track().map(|track|self.tracks.get_mut(track)).flatten()
|
||||
}
|
||||
pub fn phrase (&self) -> Option<Arc<RwLock<Phrase>>> {
|
||||
|
|
@ -511,7 +511,7 @@ impl<E: Engine> Arrangement<E> {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<E: Engine> ArrangementTrack<E> {
|
||||
impl ArrangementTrack {
|
||||
pub fn new (clock: &Arc<TransportTime>, name: &str, color: Option<Color>) -> Self {
|
||||
Self {
|
||||
name: Arc::new(RwLock::new(name.into())),
|
||||
|
|
@ -533,7 +533,7 @@ impl<E: Engine> ArrangementTrack<E> {
|
|||
impl ArrangementFocus {
|
||||
pub fn description <E: Engine> (
|
||||
&self,
|
||||
tracks: &Vec<ArrangementTrack<E>>,
|
||||
tracks: &Vec<ArrangementTrack>,
|
||||
scenes: &Vec<Scene>,
|
||||
) -> String {
|
||||
format!("Selected: {}", match self {
|
||||
|
|
@ -646,7 +646,7 @@ impl Scene {
|
|||
})
|
||||
}
|
||||
/// Returns true if all phrases in the scene are currently playing
|
||||
pub fn is_playing <E: Engine> (&self, tracks: &[ArrangementTrack<E>]) -> bool {
|
||||
pub fn is_playing (&self, tracks: &[ArrangementTrack]) -> bool {
|
||||
self.clips.iter().any(|clip|clip.is_some()) && self.clips.iter().enumerate()
|
||||
.all(|(track_index, clip)|match clip {
|
||||
Some(clip) => tracks
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
|
|||
let Self(state, factor) = self;
|
||||
let cols = state.track_widths();
|
||||
let rows = Scene::ppqs(state.scenes.as_slice(), *factor);
|
||||
let tracks = state.tracks.as_ref() as &[ArrangementTrack<Tui>];
|
||||
let tracks = state.tracks.as_ref() as &[ArrangementTrack];
|
||||
let scenes = state.scenes.as_ref();
|
||||
let bg = state.color;
|
||||
let clip_bg = Color::Rgb(40, 50, 30);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ pub struct Sequencer<E: Engine> {
|
|||
pub phrases: Arc<RwLock<PhrasePool<E>>>,
|
||||
/// Phrase editor view
|
||||
pub editor: PhraseEditor<E>,
|
||||
/// Phrase player
|
||||
pub player: PhrasePlayer,
|
||||
}
|
||||
/// Sections in the sequencer app that may be focused
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
|
|
@ -113,8 +115,7 @@ pub struct PhraseEditor<E: Engine> {
|
|||
pub height: AtomicUsize,
|
||||
}
|
||||
/// Phrase player.
|
||||
pub struct PhrasePlayer<E: Engine> {
|
||||
_engine: PhantomData<E>,
|
||||
pub struct PhrasePlayer {
|
||||
/// Global timebase
|
||||
pub clock: Arc<TransportTime>,
|
||||
/// Start time and phrase being played
|
||||
|
|
@ -371,10 +372,9 @@ impl std::cmp::PartialEq for Phrase {
|
|||
fn eq (&self, other: &Self) -> bool { self.uuid == other.uuid }
|
||||
}
|
||||
impl Eq for Phrase {}
|
||||
impl<E: Engine> PhrasePlayer<E> {
|
||||
impl PhrasePlayer {
|
||||
pub fn new (clock: &Arc<TransportTime>) -> Self {
|
||||
Self {
|
||||
_engine: Default::default(),
|
||||
clock: clock.clone(),
|
||||
phrase: None,
|
||||
started: None,
|
||||
|
|
|
|||
|
|
@ -18,15 +18,19 @@ pub struct SequencerCli {
|
|||
|
||||
impl SequencerCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
let jack = Client::new("tek_arranger", ClientOptions::NO_START_SERVER)?.0;
|
||||
let jack = JackClient::Inactive(jack);
|
||||
let jack = Client::new("tek_arranger", ClientOptions::NO_START_SERVER)?.0;
|
||||
let jack = JackClient::Inactive(jack);
|
||||
let transport = Arc::new(RwLock::new(TransportToolbar::new(None, Some(jack.transport()))));
|
||||
let focus_cursor = (1, 1);
|
||||
let clock = transport.read().unwrap().clock.clone();
|
||||
let transport = self.transport.then_some(transport);
|
||||
let editor = PhraseEditor::new();
|
||||
let phrases = Arc::new(RwLock::new(PhrasePool::new()));
|
||||
let sequencer = Sequencer { jack: None, focus_cursor, clock, transport, editor, phrases };
|
||||
let clock = transport.read().unwrap().clock.clone();
|
||||
let sequencer = Sequencer {
|
||||
jack: None,
|
||||
focus_cursor: (1, 1),
|
||||
phrases: Arc::new(RwLock::new(PhrasePool::new())),
|
||||
editor: PhraseEditor::new(),
|
||||
player: PhrasePlayer::new(&clock),
|
||||
transport: self.transport.then_some(transport),
|
||||
clock,
|
||||
};
|
||||
if let Some(_) = self.name.as_ref() {
|
||||
// TODO: sequencer.name = Arc::new(RwLock::new(name.clone()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ impl<E: Engine> Audio for Sequencer<E> {
|
|||
if let Some(ref transport) = self.transport {
|
||||
transport.write().unwrap().process(client, scope);
|
||||
}
|
||||
self.player.process(client, scope);
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
impl<E: Engine> Audio for PhrasePlayer<E> {
|
||||
impl Audio for PhrasePlayer {
|
||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
let frame0 = scope.last_frame_time() as usize;
|
||||
let frames = scope.n_frames() as usize;
|
||||
|
|
@ -94,7 +95,7 @@ impl<E: Engine> Audio for PhrasePlayer<E> {
|
|||
Control::Continue
|
||||
}
|
||||
}
|
||||
impl<E: Engine> PhrasePlayer<E> {
|
||||
impl PhrasePlayer {
|
||||
pub fn has_midi_inputs (&self) -> bool { self.midi_inputs.len() > 0 }
|
||||
pub fn has_midi_outputs (&self) -> bool { self.midi_outputs.len() > 0 }
|
||||
/// Clear the section of the output buffer that we will be using
|
||||
|
|
@ -103,10 +104,7 @@ impl<E: Engine> PhrasePlayer<E> {
|
|||
}
|
||||
/// Emit "all notes off" at start of buffer if requested
|
||||
pub fn reset_midi_out_buf (&mut self, force_reset: bool) {
|
||||
if self.reset || force_reset {
|
||||
all_notes_off(&mut self.midi_out_buf);
|
||||
self.reset = false;
|
||||
}
|
||||
if self.reset || force_reset { all_notes_off(&mut self.midi_out_buf); self.reset = false; }
|
||||
}
|
||||
}
|
||||
/// Add "all notes off" to the start of a buffer.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue