mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
extract transport
This commit is contained in:
parent
449615eea8
commit
5a9ec0a63d
12 changed files with 178 additions and 182 deletions
101
src/model.rs
101
src/model.rs
|
|
@ -5,6 +5,7 @@ pub mod plugin;
|
|||
pub mod sampler;
|
||||
pub mod scene;
|
||||
pub mod track;
|
||||
pub mod transport;
|
||||
|
||||
pub use self::phrase::{Phrase, PhraseData};
|
||||
pub use self::scene::Scene;
|
||||
|
|
@ -12,12 +13,11 @@ pub use self::track::Track;
|
|||
pub use self::sampler::{Sampler, Sample, read_sample_data};
|
||||
pub use self::mixer::Mixer;
|
||||
pub use self::plugin::{Plugin, PluginKind, lv2::LV2Plugin};
|
||||
pub use self::transport::TransportToolbar;
|
||||
|
||||
use crate::{core::*, view::*};
|
||||
|
||||
pub struct App {
|
||||
/// Paths to user directories
|
||||
pub xdg: Option<Arc<XdgApp>>,
|
||||
/// Main JACK client.
|
||||
pub jack: Option<JackClient>,
|
||||
/// Map of external MIDI outs in the jack graph
|
||||
|
|
@ -25,18 +25,6 @@ pub struct App {
|
|||
pub midi_in: Option<Arc<Port<MidiIn>>>,
|
||||
/// Names of ports to connect to main MIDI IN.
|
||||
pub midi_ins: Vec<String>,
|
||||
/// Main audio outputs.
|
||||
pub audio_outs: Vec<Arc<Port<Unowned>>>,
|
||||
/// JACK transport handle.
|
||||
pub transport: Option<Transport>,
|
||||
/// Current transport state
|
||||
pub playing: Option<TransportState>,
|
||||
/// Current position according to transport
|
||||
pub playhead: usize,
|
||||
/// Position of T0 for this playback within global timeline
|
||||
pub play_started: Option<(usize, usize)>,
|
||||
/// Current sample rate and tempo.
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// Display mode of arranger section
|
||||
pub arranger_mode: bool,
|
||||
/// Display mode of chain section
|
||||
|
|
@ -49,10 +37,8 @@ pub struct App {
|
|||
pub modal: Option<Box<dyn Component>>,
|
||||
/// Currently focused section
|
||||
pub section: AppSection,
|
||||
/// Whether the section is focused
|
||||
/// Whether the current focus section has input priority
|
||||
pub entered: bool,
|
||||
/// Current frame
|
||||
pub metronome: bool,
|
||||
/// Display position of cursor within note range
|
||||
pub note_cursor: usize,
|
||||
/// Range of notes to display
|
||||
|
|
@ -67,12 +53,16 @@ pub struct App {
|
|||
pub track_cursor: usize,
|
||||
/// Collection of tracks
|
||||
pub tracks: Vec<Track>,
|
||||
/// Paths to user directories
|
||||
xdg: Option<Arc<XdgApp>>,
|
||||
/// Main audio outputs.
|
||||
audio_outs: Vec<Arc<Port<Unowned>>>,
|
||||
/// Tick enable?
|
||||
metronome: bool,
|
||||
/// Number of frames requested by process callback
|
||||
pub chunk_size: usize,
|
||||
/// Quantization factor
|
||||
pub quant: usize,
|
||||
/// Init callbacks called once after root JACK client has activated.
|
||||
pub callbacks: Vec<Box<dyn (FnOnce(Arc<RwLock<Self>>)->Usually<()>) + Send + Sync>>
|
||||
chunk_size: usize,
|
||||
|
||||
pub transport: TransportToolbar,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
|
@ -80,11 +70,10 @@ impl App {
|
|||
let xdg = Arc::new(microxdg::XdgApp::new("tek")?);
|
||||
let first_run = crate::config::AppPaths::new(&xdg)?.should_create();
|
||||
let jack = JackClient::Inactive(Client::new("tek", ClientOptions::NO_START_SERVER)?.0);
|
||||
let transport = jack.transport();
|
||||
Ok(Self {
|
||||
transport: TransportToolbar::new(Some(jack.transport())),
|
||||
arranger_mode: false,
|
||||
audio_outs: vec![],
|
||||
callbacks: vec![],
|
||||
chain_mode: false,
|
||||
chunk_size: 0,
|
||||
entered: true,
|
||||
|
|
@ -95,35 +84,30 @@ impl App {
|
|||
modal: first_run.then(||crate::config::SetupModal(Some(xdg.clone())).boxed()),
|
||||
note_cursor: 0,
|
||||
note_start: 2,
|
||||
play_started: None,
|
||||
playhead: 0,
|
||||
playing: None,
|
||||
quant: 24,
|
||||
scene_cursor: 1,
|
||||
scenes: vec![],
|
||||
section: AppSection::default(),
|
||||
seq_mode: false,
|
||||
seq_buf: BufferedSequencerView::new(96, 16384),
|
||||
time_cursor: 0,
|
||||
timebase: Arc::new(Timebase::default()),
|
||||
track_cursor: 1,
|
||||
tracks: vec![],
|
||||
transport: Some(transport),
|
||||
xdg: Some(xdg),
|
||||
})
|
||||
}
|
||||
}
|
||||
process!(App |self, _client, scope| {
|
||||
let (
|
||||
reset, current_frames, current_usecs, next_usecs, period_usecs
|
||||
) = self.update_time(&scope);
|
||||
reset, current_frames, chunk_size, current_usecs, next_usecs, period_usecs
|
||||
) = self.transport.update(&scope);
|
||||
self.chunk_size = chunk_size;
|
||||
for track in self.tracks.iter_mut() {
|
||||
track.process(
|
||||
self.midi_in.as_ref().map(|p|p.iter(&scope)),
|
||||
&self.timebase,
|
||||
self.playing,
|
||||
self.play_started,
|
||||
self.quant,
|
||||
&self.transport.timebase,
|
||||
self.transport.playing,
|
||||
self.transport.started,
|
||||
self.transport.quant,
|
||||
reset,
|
||||
&scope,
|
||||
(current_frames as usize, self.chunk_size),
|
||||
|
|
@ -169,51 +153,6 @@ impl App {
|
|||
}
|
||||
Ok(app)
|
||||
}
|
||||
pub fn update_time (&mut self, scope: &ProcessScope) -> (bool, usize, usize, usize, f64) {
|
||||
let CycleTimes {
|
||||
current_frames,
|
||||
current_usecs,
|
||||
next_usecs,
|
||||
period_usecs
|
||||
} = scope.cycle_times().unwrap();
|
||||
self.chunk_size = scope.n_frames() as usize;
|
||||
let transport = self.transport.as_ref().unwrap().query().unwrap();
|
||||
self.playhead = transport.pos.frame() as usize;
|
||||
let mut reset = false;
|
||||
if self.playing != Some(transport.state) {
|
||||
match transport.state {
|
||||
TransportState::Rolling => {
|
||||
self.play_started = Some((
|
||||
current_frames as usize,
|
||||
current_usecs as usize,
|
||||
));
|
||||
},
|
||||
TransportState::Stopped => {
|
||||
self.play_started = None;
|
||||
reset = true;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.playing = Some(transport.state);
|
||||
(
|
||||
reset, current_frames as usize, current_usecs as usize, next_usecs as usize, period_usecs as f64
|
||||
)
|
||||
}
|
||||
pub fn toggle_play (&mut self) -> Usually<()> {
|
||||
self.playing = match self.playing.expect("1st frame has not been processed yet") {
|
||||
TransportState::Stopped => {
|
||||
self.transport.as_ref().unwrap().start()?;
|
||||
Some(TransportState::Starting)
|
||||
},
|
||||
_ => {
|
||||
self.transport.as_ref().unwrap().stop()?;
|
||||
self.transport.as_ref().unwrap().locate(0)?;
|
||||
Some(TransportState::Stopped)
|
||||
},
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue