mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
MidiPlayer -> Sequencer; connect sequencer to sampler in groovebox mode
This commit is contained in:
parent
c5586c3a35
commit
5fab1af138
10 changed files with 120 additions and 81 deletions
|
|
@ -469,7 +469,7 @@ impl<'state> Context<'state, SamplerCommand> for App {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
fn stop (app: &mut App, index: usize) -> Perhaps<Self> {
|
fn stop (app: &mut App, index: usize) -> Perhaps<Self> {
|
||||||
app.tracks[index].player.enqueue_next(None);
|
app.tracks[index].sequencer.enqueue_next(None);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
fn add (app: &mut App) -> Perhaps<Self> {
|
fn add (app: &mut App) -> Perhaps<Self> {
|
||||||
|
|
@ -535,7 +535,7 @@ impl<'state> Context<'state, SamplerCommand> for App {
|
||||||
}
|
}
|
||||||
fn enqueue (app: &mut App, a: usize, b: usize) -> Perhaps<Self> {
|
fn enqueue (app: &mut App, a: usize, b: usize) -> Perhaps<Self> {
|
||||||
//(Enqueue [t: usize, s: usize]
|
//(Enqueue [t: usize, s: usize]
|
||||||
//cmd!(app.tracks[t].player.enqueue_next(app.scenes[s].clips[t].as_ref())))
|
//cmd!(app.tracks[t].sequencer.enqueue_next(app.scenes[s].clips[t].as_ref())))
|
||||||
//("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
|
//("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ audio!(
|
||||||
// Update track sequencers and devices
|
// Update track sequencers and devices
|
||||||
for track in self.tracks.iter_mut() {
|
for track in self.tracks.iter_mut() {
|
||||||
if Control::Quit == PlayerAudio(
|
if Control::Quit == PlayerAudio(
|
||||||
track.player_mut(), &mut self.note_buf, &mut self.midi_buf
|
track.sequencer_mut(), &mut self.note_buf, &mut self.midi_buf
|
||||||
).process(client, scope) {
|
).process(client, scope) {
|
||||||
return Control::Quit
|
return Control::Quit
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ impl App {
|
||||||
let mut track = Track {
|
let mut track = Track {
|
||||||
width: (name.len() + 2).max(12),
|
width: (name.len() + 2).max(12),
|
||||||
color: color.unwrap_or_else(ItemTheme::random),
|
color: color.unwrap_or_else(ItemTheme::random),
|
||||||
player: MidiPlayer::new(
|
sequencer: Sequencer::new(
|
||||||
&format!("{name}"),
|
&format!("{name}"),
|
||||||
self.jack(),
|
self.jack(),
|
||||||
Some(self.clock()),
|
Some(self.clock()),
|
||||||
|
|
@ -141,7 +141,7 @@ impl App {
|
||||||
let exists = self.tracks().get(index).is_some();
|
let exists = self.tracks().get(index).is_some();
|
||||||
if exists {
|
if exists {
|
||||||
let track = self.tracks_mut().remove(index);
|
let track = self.tracks_mut().remove(index);
|
||||||
let Track { player: MidiPlayer { midi_ins, midi_outs, .. }, .. } = track;
|
let Track { sequencer: Sequencer { midi_ins, midi_outs, .. }, .. } = track;
|
||||||
for port in midi_ins.into_iter() {
|
for port in midi_ins.into_iter() {
|
||||||
port.close()?;
|
port.close()?;
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +196,7 @@ impl App {
|
||||||
/// Enqueue clips from a scene across all tracks
|
/// Enqueue clips from a scene across all tracks
|
||||||
pub fn scene_enqueue (&mut self, scene: usize) {
|
pub fn scene_enqueue (&mut self, scene: usize) {
|
||||||
for track in 0..self.tracks.len() {
|
for track in 0..self.tracks.len() {
|
||||||
self.tracks[track].player.enqueue_next(self.scenes[scene].clips[track].as_ref());
|
self.tracks[track].sequencer.enqueue_next(self.scenes[scene].clips[track].as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,7 +315,7 @@ impl App {
|
||||||
/// Stop all playing clips
|
/// Stop all playing clips
|
||||||
pub(crate) fn stop_all (&mut self) {
|
pub(crate) fn stop_all (&mut self) {
|
||||||
for track in 0..self.tracks.len() {
|
for track in 0..self.tracks.len() {
|
||||||
self.tracks[track].player.enqueue_next(None);
|
self.tracks[track].sequencer.enqueue_next(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,14 +324,14 @@ impl App {
|
||||||
use Selection::*;
|
use Selection::*;
|
||||||
match self.selected {
|
match self.selected {
|
||||||
Track(t) => {
|
Track(t) => {
|
||||||
self.tracks[t].player.enqueue_next(None)
|
self.tracks[t].sequencer.enqueue_next(None)
|
||||||
},
|
},
|
||||||
TrackClip { track, scene } => {
|
TrackClip { track, scene } => {
|
||||||
self.tracks[track].player.enqueue_next(self.scenes[scene].clips[track].as_ref())
|
self.tracks[track].sequencer.enqueue_next(self.scenes[scene].clips[track].as_ref())
|
||||||
},
|
},
|
||||||
Scene(s) => {
|
Scene(s) => {
|
||||||
for t in 0..self.tracks.len() {
|
for t in 0..self.tracks.len() {
|
||||||
self.tracks[t].player.enqueue_next(self.scenes[s].clips[t].as_ref())
|
self.tracks[t].sequencer.enqueue_next(self.scenes[s].clips[t].as_ref())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -417,7 +417,7 @@ impl App {
|
||||||
|
|
||||||
fn device_add_sampler (&mut self) -> Usually<()> {
|
fn device_add_sampler (&mut self) -> Usually<()> {
|
||||||
let name = self.jack.with_client(|c|c.name().to_string());
|
let name = self.jack.with_client(|c|c.name().to_string());
|
||||||
let midi = self.track().expect("no active track").player.midi_outs[0].name();
|
let midi = self.track().expect("no active track").sequencer.midi_outs[0].name();
|
||||||
let sampler = if let Ok(sampler) = Sampler::new(
|
let sampler = if let Ok(sampler) = Sampler::new(
|
||||||
&self.jack,
|
&self.jack,
|
||||||
&format!("{}/Sampler", &self.track().expect("no active track").name),
|
&format!("{}/Sampler", &self.track().expect("no active track").name),
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ impl Scene {
|
||||||
Some(c) => tracks
|
Some(c) => tracks
|
||||||
.get(track_index)
|
.get(track_index)
|
||||||
.map(|track|{
|
.map(|track|{
|
||||||
if let Some((_, Some(clip))) = track.player().play_clip() {
|
if let Some((_, Some(clip))) = track.sequencer().play_clip() {
|
||||||
*clip.read().unwrap() == *c.read().unwrap()
|
*clip.read().unwrap() == *c.read().unwrap()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use crate::*;
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
/// Identifying color of track
|
/// Identifying color of track
|
||||||
pub color: ItemTheme,
|
pub color: ItemTheme,
|
||||||
/// MIDI player state
|
/// MIDI sequencer state
|
||||||
pub player: MidiPlayer,
|
pub sequencer: Sequencer,
|
||||||
/// Device chain
|
/// Device chain
|
||||||
pub devices: Vec<Device>,
|
pub devices: Vec<Device>,
|
||||||
/// Inputs of 1st device
|
/// Inputs of 1st device
|
||||||
|
|
@ -17,52 +17,60 @@ use crate::*;
|
||||||
pub audio_outs: Vec<JackAudioOut>,
|
pub audio_outs: Vec<JackAudioOut>,
|
||||||
}
|
}
|
||||||
|
|
||||||
has_clock!(|self: Track|self.player.clock);
|
has_clock!(|self: Track|self.sequencer.clock);
|
||||||
|
|
||||||
has_player!(|self: Track|self.player);
|
has_sequencer!(|self: Track|self.sequencer);
|
||||||
|
|
||||||
impl Track {
|
impl Track {
|
||||||
pub const MIN_WIDTH: usize = 9;
|
/// Create a new track with only the default [Sequencer].
|
||||||
/// Create a new track with only the default [MidiPlayer].
|
pub fn new (
|
||||||
pub fn new () -> Self {
|
name: &impl AsRef<str>,
|
||||||
Self::default()
|
color: Option<ItemTheme>,
|
||||||
|
jack: &Jack,
|
||||||
|
clock: Option<&Clock>,
|
||||||
|
midi_from: &[PortConnect],
|
||||||
|
midi_to: &[PortConnect],
|
||||||
|
) -> Usually<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
name: name.as_ref().into(),
|
||||||
|
color: color.unwrap_or_default(),
|
||||||
|
sequencer: Sequencer::new(
|
||||||
|
format!("{}/sequencer", name.as_ref()),
|
||||||
|
jack,
|
||||||
|
clock,
|
||||||
|
None,
|
||||||
|
midi_from,
|
||||||
|
midi_to
|
||||||
|
)?,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/// Create a new track connecting the [MidiPlayer] to a [Sampler].
|
/// Create a new track connecting the [Sequencer] to a [Sampler].
|
||||||
pub fn new_with_sampler (
|
pub fn new_with_sampler (
|
||||||
|
name: &impl AsRef<str>,
|
||||||
|
color: Option<ItemTheme>,
|
||||||
jack: &Jack,
|
jack: &Jack,
|
||||||
|
clock: Option<&Clock>,
|
||||||
midi_from: &[PortConnect],
|
midi_from: &[PortConnect],
|
||||||
|
midi_to: &[PortConnect],
|
||||||
audio_from: &[&[PortConnect];2],
|
audio_from: &[&[PortConnect];2],
|
||||||
audio_to: &[&[PortConnect];2],
|
audio_to: &[&[PortConnect];2],
|
||||||
) -> Usually<Self> {
|
) -> Usually<Self> {
|
||||||
let mut track = Self::new_sequencer();
|
let mut track = Self::new(
|
||||||
let name = jack.with_client(|c|c.name().to_string());
|
name, color, jack, clock, midi_from, midi_to
|
||||||
let midi = track.player.midi_outs[0].name();
|
)?;
|
||||||
let port = PortConnect::exact(format!("{name}:{midi}"));
|
track.devices.push(Device::Sampler(Sampler::new(
|
||||||
let sampler = Sampler::new(jack, &"sampler", &[port], audio_from, audio_to)?;
|
jack,
|
||||||
track.devices.push(Device::Sampler(sampler));
|
&"sampler",
|
||||||
|
&[PortConnect::exact(format!("{}:{}",
|
||||||
|
jack.with_client(|c|c.name().to_string()),
|
||||||
|
track.sequencer.midi_outs[0].name()
|
||||||
|
))],
|
||||||
|
audio_from,
|
||||||
|
audio_to
|
||||||
|
)?));
|
||||||
Ok(track)
|
Ok(track)
|
||||||
}
|
}
|
||||||
pub fn width_inc (&mut self) {
|
|
||||||
self.width += 1;
|
|
||||||
}
|
|
||||||
pub fn width_dec (&mut self) {
|
|
||||||
if self.width > Track::MIN_WIDTH {
|
|
||||||
self.width -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn sequencer (&self, mut nth: usize) -> Option<&MidiPlayer> {
|
|
||||||
for device in self.devices.iter() {
|
|
||||||
match device {
|
|
||||||
Device::Sequencer(s) => if nth == 0 {
|
|
||||||
return Some(s);
|
|
||||||
} else {
|
|
||||||
nth -= 1;
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
||||||
for device in self.devices.iter() {
|
for device in self.devices.iter() {
|
||||||
match device {
|
match device {
|
||||||
|
|
@ -91,6 +99,26 @@ impl Track {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HasWidth {
|
||||||
|
const MIN_WIDTH: usize;
|
||||||
|
/// Increment track width.
|
||||||
|
fn width_inc (&mut self);
|
||||||
|
/// Decrement track width, down to a hardcoded minimum of [Self::MIN_WIDTH].
|
||||||
|
fn width_dec (&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasWidth for Track {
|
||||||
|
const MIN_WIDTH: usize = 9;
|
||||||
|
fn width_inc (&mut self) {
|
||||||
|
self.width += 1;
|
||||||
|
}
|
||||||
|
fn width_dec (&mut self) {
|
||||||
|
if self.width > Track::MIN_WIDTH {
|
||||||
|
self.width -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
fn midi_ins (&self) -> &Vec<JackMidiIn>;
|
fn midi_ins (&self) -> &Vec<JackMidiIn>;
|
||||||
fn midi_outs (&self) -> &Vec<JackMidiOut>;
|
fn midi_outs (&self) -> &Vec<JackMidiOut>;
|
||||||
|
|
@ -117,14 +145,14 @@ pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync
|
||||||
fn track_toggle_record (&mut self) {
|
fn track_toggle_record (&mut self) {
|
||||||
if let Some(t) = self.selected().track() {
|
if let Some(t) = self.selected().track() {
|
||||||
let tracks = self.tracks_mut();
|
let tracks = self.tracks_mut();
|
||||||
tracks[t-1].player.recording = !tracks[t-1].player.recording;
|
tracks[t-1].sequencer.recording = !tracks[t-1].sequencer.recording;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Toggle track monitoring
|
/// Toggle track monitoring
|
||||||
fn track_toggle_monitor (&mut self) {
|
fn track_toggle_monitor (&mut self) {
|
||||||
if let Some(t) = self.selected().track() {
|
if let Some(t) = self.selected().track() {
|
||||||
let tracks = self.tracks_mut();
|
let tracks = self.tracks_mut();
|
||||||
tracks[t-1].player.monitoring = !tracks[t-1].player.monitoring;
|
tracks[t-1].sequencer.monitoring = !tracks[t-1].sequencer.monitoring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,8 +336,8 @@ impl<'a> ArrangerView<'a> {
|
||||||
self.width_mid,
|
self.width_mid,
|
||||||
||self.tracks_with_sizes_scrolled(),
|
||self.tracks_with_sizes_scrolled(),
|
||||||
move|t, track|{
|
move|t, track|{
|
||||||
let rec = track.player.recording;
|
let rec = track.sequencer.recording;
|
||||||
let mon = track.player.monitoring;
|
let mon = track.sequencer.monitoring;
|
||||||
let rec = if rec { White } else { track.color.darkest.rgb };
|
let rec = if rec { White } else { track.color.darkest.rgb };
|
||||||
let mon = if mon { White } else { track.color.darkest.rgb };
|
let mon = if mon { White } else { track.color.darkest.rgb };
|
||||||
let bg = if self.track_selected == Some(t) {
|
let bg = if self.track_selected == Some(t) {
|
||||||
|
|
@ -377,10 +377,10 @@ impl<'a> ArrangerView<'a> {
|
||||||
let label = Align::ne("Next clip:");
|
let label = Align::ne("Next clip:");
|
||||||
Tryptich::top(2).left(self.width_side, label).middle(self.width_mid, per_track_top(
|
Tryptich::top(2).left(self.width_side, label).middle(self.width_mid, per_track_top(
|
||||||
self.width_mid, ||self.tracks_with_sizes_scrolled(), |t, track|{
|
self.width_mid, ||self.tracks_with_sizes_scrolled(), |t, track|{
|
||||||
let queued = track.player.next_clip.is_some();
|
let queued = track.sequencer.next_clip.is_some();
|
||||||
let queued_blank = Thunk::new(||Tui::bg(Reset, " ------ "));
|
let queued_blank = Thunk::new(||Tui::bg(Reset, " ------ "));
|
||||||
let queued_clip = Thunk::new(||{
|
let queued_clip = Thunk::new(||{
|
||||||
Tui::bg(Reset, if let Some((_, clip)) = track.player.next_clip.as_ref() {
|
Tui::bg(Reset, if let Some((_, clip)) = track.sequencer.next_clip.as_ref() {
|
||||||
if let Some(clip) = clip {
|
if let Some(clip) = clip {
|
||||||
clip.read().unwrap().name.clone()
|
clip.read().unwrap().name.clone()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1224,7 +1224,7 @@ impl std::fmt::Debug for PianoHorizontal {
|
||||||
}
|
}
|
||||||
// Update sequencer playhead indicator
|
// Update sequencer playhead indicator
|
||||||
//self.now().set(0.);
|
//self.now().set(0.);
|
||||||
//if let Some((ref started_at, Some(ref playing))) = self.player.play_clip {
|
//if let Some((ref started_at, Some(ref playing))) = self.sequencer.play_clip {
|
||||||
//let clip = clip.read().unwrap();
|
//let clip = clip.read().unwrap();
|
||||||
//if *playing.read().unwrap() == *clip {
|
//if *playing.read().unwrap() == *clip {
|
||||||
//let pulse = self.current().pulse.get();
|
//let pulse = self.current().pulse.get();
|
||||||
|
|
|
||||||
|
|
@ -136,11 +136,22 @@ impl Cli {
|
||||||
},
|
},
|
||||||
tracks: match mode {
|
tracks: match mode {
|
||||||
LaunchMode::Sequencer => vec![
|
LaunchMode::Sequencer => vec![
|
||||||
Track::new()
|
Track::new(
|
||||||
|
&name,
|
||||||
|
None,
|
||||||
|
jack,
|
||||||
|
None,
|
||||||
|
midi_froms.as_slice(),
|
||||||
|
midi_tos.as_slice()
|
||||||
|
)?
|
||||||
],
|
],
|
||||||
LaunchMode::Groovebox | LaunchMode::Sampler => vec![
|
LaunchMode::Groovebox | LaunchMode::Sampler => vec![
|
||||||
Track::new_with_sampler(
|
Track::new_with_sampler(
|
||||||
|
&name,
|
||||||
|
None,
|
||||||
jack,
|
jack,
|
||||||
|
None,
|
||||||
|
midi_froms.as_slice(),
|
||||||
midi_froms.as_slice(),
|
midi_froms.as_slice(),
|
||||||
audio_froms,
|
audio_froms,
|
||||||
audio_tos,
|
audio_tos,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Device {
|
pub enum Device {
|
||||||
#[cfg(feature = "sequencer")] Sequencer(MidiPlayer),
|
#[cfg(feature = "sequencer")] Sequencer(Sequencer),
|
||||||
#[cfg(feature = "sampler")] Sampler(Sampler),
|
#[cfg(feature = "sampler")] Sampler(Sampler),
|
||||||
#[cfg(feature = "lv2")] Lv2(Lv2), // TODO
|
#[cfg(feature = "lv2")] Lv2(Lv2), // TODO
|
||||||
#[cfg(feature = "vst2")] Vst2, // TODO
|
#[cfg(feature = "vst2")] Vst2, // TODO
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,6 @@ mod seq_view; pub use self::seq_view::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_midi_play () {
|
#[cfg(test)] #[test] fn test_midi_play () {
|
||||||
let player = MidiPlayer::default();
|
let sequencer = Sequencer::default();
|
||||||
println!("{player:?}");
|
println!("{sequencer:?}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
//! MIDI player
|
//! MIDI sequencer
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use tek_engine::jack::*;
|
use tek_engine::jack::*;
|
||||||
|
|
||||||
pub trait HasPlayer {
|
pub trait HasSequencer {
|
||||||
fn player (&self) -> &impl MidiPlayerApi;
|
fn sequencer (&self) -> &impl MidiPlayerApi;
|
||||||
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
fn sequencer_mut (&mut self) -> &mut impl MidiPlayerApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! has_player {
|
#[macro_export] macro_rules! has_sequencer {
|
||||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? {
|
impl $(<$($L),*$($T $(: $U)?),*>)? HasSequencer for $Struct $(<$($L),*$($T),*>)? {
|
||||||
fn player (&$self) -> &impl MidiPlayerApi { &$cb }
|
fn sequencer (&$self) -> &impl MidiPlayerApi { &$cb }
|
||||||
fn player_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb }
|
fn sequencer_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
||||||
|
|
||||||
impl MidiPlayerApi for MidiPlayer {}
|
impl MidiPlayerApi for Sequencer {}
|
||||||
|
|
||||||
/// Contains state for playing a clip
|
/// Contains state for playing a clip
|
||||||
pub struct MidiPlayer {
|
pub struct Sequencer {
|
||||||
/// State of clock and playhead
|
/// State of clock and playhead
|
||||||
pub clock: Clock,
|
pub clock: Clock,
|
||||||
/// Start time and clip being played
|
/// Start time and clip being played
|
||||||
|
|
@ -48,7 +48,7 @@ pub struct MidiPlayer {
|
||||||
pub note_buf: Vec<u8>,
|
pub note_buf: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MidiPlayer {
|
impl Default for Sequencer {
|
||||||
fn default () -> Self {
|
fn default () -> Self {
|
||||||
Self {
|
Self {
|
||||||
play_clip: None,
|
play_clip: None,
|
||||||
|
|
@ -69,7 +69,7 @@ impl Default for MidiPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MidiPlayer {
|
impl Sequencer {
|
||||||
pub fn new (
|
pub fn new (
|
||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
jack: &Jack,
|
jack: &Jack,
|
||||||
|
|
@ -97,9 +97,9 @@ impl MidiPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for MidiPlayer {
|
impl std::fmt::Debug for Sequencer {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
f.debug_struct("MidiPlayer")
|
f.debug_struct("Sequencer")
|
||||||
.field("clock", &self.clock)
|
.field("clock", &self.clock)
|
||||||
.field("play_clip", &self.play_clip)
|
.field("play_clip", &self.play_clip)
|
||||||
.field("next_clip", &self.next_clip)
|
.field("next_clip", &self.next_clip)
|
||||||
|
|
@ -107,20 +107,20 @@ impl std::fmt::Debug for MidiPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
has_clock!(|self: MidiPlayer|self.clock);
|
has_clock!(|self: Sequencer|self.clock);
|
||||||
|
|
||||||
impl HasMidiIns for MidiPlayer {
|
impl HasMidiIns for Sequencer {
|
||||||
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
|
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
|
||||||
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> { &mut self.midi_ins }
|
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> { &mut self.midi_ins }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasMidiOuts for MidiPlayer {
|
impl HasMidiOuts for Sequencer {
|
||||||
fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs }
|
fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs }
|
||||||
fn midi_outs_mut (&mut self) -> &mut Vec<JackMidiOut> { &mut self.midi_outs }
|
fn midi_outs_mut (&mut self) -> &mut Vec<JackMidiOut> { &mut self.midi_outs }
|
||||||
fn midi_note (&mut self) -> &mut Vec<u8> { &mut self.note_buf }
|
fn midi_note (&mut self) -> &mut Vec<u8> { &mut self.note_buf }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hosts the JACK callback for a single MIDI player
|
/// Hosts the JACK callback for a single MIDI sequencer
|
||||||
pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
||||||
/// Player
|
/// Player
|
||||||
pub &'a mut T,
|
pub &'a mut T,
|
||||||
|
|
@ -130,7 +130,7 @@ pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
||||||
pub &'a mut Vec<Vec<Vec<u8>>>,
|
pub &'a mut Vec<Vec<Vec<u8>>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// JACK process callback for a sequencer's clip player/recorder.
|
/// JACK process callback for a sequencer's clip sequencer/recorder.
|
||||||
impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
|
impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
|
||||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||||
let model = &mut self.0;
|
let model = &mut self.0;
|
||||||
|
|
@ -157,7 +157,7 @@ impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MidiRecordApi for MidiPlayer {
|
impl MidiRecordApi for Sequencer {
|
||||||
fn recording (&self) -> bool {
|
fn recording (&self) -> bool {
|
||||||
self.recording
|
self.recording
|
||||||
}
|
}
|
||||||
|
|
@ -181,13 +181,13 @@ impl MidiRecordApi for MidiPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MidiPlaybackApi for MidiPlayer {
|
impl MidiPlaybackApi for Sequencer {
|
||||||
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||||
&self.notes_out
|
&self.notes_out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasPlayClip for MidiPlayer {
|
impl HasPlayClip for Sequencer {
|
||||||
fn reset (&self) -> bool {
|
fn reset (&self) -> bool {
|
||||||
self.reset
|
self.reset
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue