remove unused generic; add Sequencer::player

This commit is contained in:
🪞👃🪞 2024-11-01 00:42:12 +02:00
parent 076be5bcb3
commit 86adf493c8
5 changed files with 32 additions and 30 deletions

View file

@ -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

View file

@ -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);

View file

@ -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,

View file

@ -21,12 +21,16 @@ impl SequencerCli {
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 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()));
}

View file

@ -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.