mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +01:00
184 lines
6.3 KiB
Rust
184 lines
6.3 KiB
Rust
#![feature(trait_alias)]
|
|
|
|
pub(crate) use ::{
|
|
tek_engine::*,
|
|
tek_engine::tengri::{
|
|
Usually, Perhaps, Has, MaybeHas, has, maybe_has, from,
|
|
input::*,
|
|
output::*,
|
|
tui::*,
|
|
tui::ratatui,
|
|
tui::ratatui::widgets::{Widget, canvas::{Canvas, Line}},
|
|
tui::ratatui::prelude::{Rect, Style, Stylize, Buffer, Color::{self, *}},
|
|
},
|
|
std::{
|
|
cmp::Ord,
|
|
ffi::OsString,
|
|
fmt::{Debug, Formatter},
|
|
fs::File,
|
|
path::PathBuf,
|
|
sync::{Arc, RwLock, atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed}},
|
|
}
|
|
};
|
|
|
|
#[cfg(feature = "sampler")] pub(crate) use symphonia::{
|
|
core::{
|
|
formats::Packet,
|
|
codecs::{Decoder, CODEC_TYPE_NULL},
|
|
//errors::Error as SymphoniaError,
|
|
io::MediaSourceStream,
|
|
probe::Hint,
|
|
audio::SampleBuffer,
|
|
},
|
|
default::get_codecs,
|
|
};
|
|
|
|
#[cfg(feature = "lv2")] use std::thread::{spawn, JoinHandle};
|
|
|
|
#[cfg(feature = "lv2_gui")] use ::winit::{
|
|
application::ApplicationHandler,
|
|
event::WindowEvent,
|
|
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
|
|
window::{Window, WindowId},
|
|
platform::x11::EventLoopBuilderExtX11
|
|
};
|
|
|
|
/// Define a type alias for iterators of sized items (columns).
|
|
macro_rules! def_sizes_iter {
|
|
($Type:ident => $($Item:ty),+) => {
|
|
pub trait $Type<'a> =
|
|
Iterator<Item=(usize, $(&'a $Item,)+ usize, usize)> + Send + Sync + 'a;
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "arranger")] mod arranger; #[cfg(feature = "arranger")] pub use self::arranger::*;
|
|
#[cfg(feature = "browse")] mod browse; #[cfg(feature = "browse")] pub use self::browse::*;
|
|
#[cfg(feature = "clap")] mod clap; #[cfg(feature = "clap")] pub use self::clap::*;
|
|
#[cfg(feature = "clip")] mod clip; #[cfg(feature = "clip")] pub use self::clip::*;
|
|
#[cfg(feature = "clock")] mod clock; #[cfg(feature = "clock")] pub use self::clock::*;
|
|
#[cfg(feature = "editor")] mod editor; #[cfg(feature = "editor")] pub use self::editor::*;
|
|
#[cfg(feature = "lv2")] mod lv2; #[cfg(feature = "lv2")] pub use self::lv2::*;
|
|
#[cfg(feature = "meter")] mod meter; #[cfg(feature = "meter")] pub use self::meter::*;
|
|
#[cfg(feature = "mixer")] mod mixer; #[cfg(feature = "mixer")] pub use self::mixer::*;
|
|
#[cfg(feature = "pool")] mod pool; #[cfg(feature = "pool")] pub use self::pool::*;
|
|
#[cfg(feature = "port")] mod port; #[cfg(feature = "port")] pub use self::port::*;
|
|
#[cfg(feature = "sampler")] mod sampler; #[cfg(feature = "sampler")] pub use self::sampler::*;
|
|
#[cfg(feature = "scene")] mod scene; #[cfg(feature = "scene")] pub use self::scene::*;
|
|
#[cfg(feature = "select")] mod select; #[cfg(feature = "select")] pub use self::select::*;
|
|
#[cfg(feature = "sequencer")] mod sequencer; #[cfg(feature = "sequencer")] pub use self::sequencer::*;
|
|
#[cfg(feature = "sf2")] mod sf2; #[cfg(feature = "sf2")] pub use self::sf2::*;
|
|
#[cfg(feature = "track")] mod track; #[cfg(feature = "track")] pub use self::track::*;
|
|
#[cfg(feature = "vst2")] mod vst2; #[cfg(feature = "vst2")] pub use self::vst2::*;
|
|
#[cfg(feature = "vst3")] mod vst3; #[cfg(feature = "vst3")] pub use self::vst3::*;
|
|
|
|
pub fn swap_value <T: Clone + PartialEq, U> (
|
|
target: &mut T, value: &T, returned: impl Fn(T)->U
|
|
) -> Perhaps<U> {
|
|
if *target == *value {
|
|
Ok(None)
|
|
} else {
|
|
let mut value = value.clone();
|
|
std::mem::swap(target, &mut value);
|
|
Ok(Some(returned(value)))
|
|
}
|
|
}
|
|
|
|
pub fn toggle_bool <U> (
|
|
target: &mut bool, value: &Option<bool>, returned: impl Fn(Option<bool>)->U
|
|
) -> Perhaps<U> {
|
|
let mut value = value.unwrap_or(!*target);
|
|
if value == *target {
|
|
Ok(None)
|
|
} else {
|
|
std::mem::swap(target, &mut value);
|
|
Ok(Some(returned(Some(value))))
|
|
}
|
|
}
|
|
|
|
pub fn device_kinds () -> &'static [&'static str] {
|
|
&[
|
|
#[cfg(feature = "sampler")] "Sampler",
|
|
#[cfg(feature = "lv2")] "Plugin (LV2)",
|
|
]
|
|
}
|
|
|
|
impl<T: Has<Vec<Device>>> HasDevices for T {
|
|
fn devices (&self) -> &Vec<Device> {
|
|
self.get()
|
|
}
|
|
fn devices_mut (&mut self) -> &mut Vec<Device> {
|
|
self.get_mut()
|
|
}
|
|
}
|
|
|
|
pub trait HasDevices {
|
|
fn devices (&self) -> &Vec<Device>;
|
|
fn devices_mut (&mut self) -> &mut Vec<Device>;
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Device {
|
|
#[cfg(feature = "sampler")]
|
|
Sampler(Sampler),
|
|
#[cfg(feature = "lv2")] // TODO
|
|
Lv2(Lv2),
|
|
#[cfg(feature = "vst2")] // TODO
|
|
Vst2,
|
|
#[cfg(feature = "vst3")] // TODO
|
|
Vst3,
|
|
#[cfg(feature = "clap")] // TODO
|
|
Clap,
|
|
#[cfg(feature = "sf2")] // TODO
|
|
Sf2,
|
|
}
|
|
|
|
impl Device {
|
|
pub fn name (&self) -> &str {
|
|
match self {
|
|
Self::Sampler(sampler) => sampler.name.as_ref(),
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
pub fn midi_ins (&self) -> &[MidiInput] {
|
|
match self {
|
|
//Self::Sampler(Sampler { midi_in, .. }) => &[midi_in],
|
|
_ => todo!()
|
|
}
|
|
}
|
|
pub fn midi_outs (&self) -> &[MidiOutput] {
|
|
match self {
|
|
Self::Sampler(_) => &[],
|
|
_ => todo!()
|
|
}
|
|
}
|
|
pub fn audio_ins (&self) -> &[AudioInput] {
|
|
match self {
|
|
Self::Sampler(Sampler { audio_ins, .. }) => audio_ins.as_slice(),
|
|
_ => todo!()
|
|
}
|
|
}
|
|
pub fn audio_outs (&self) -> &[AudioOutput] {
|
|
match self {
|
|
Self::Sampler(Sampler { audio_outs, .. }) => audio_outs.as_slice(),
|
|
_ => todo!()
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct DeviceAudio<'a>(pub &'a mut Device);
|
|
|
|
audio!(|self: DeviceAudio<'a>, client, scope|{
|
|
use Device::*;
|
|
match self.0 {
|
|
#[cfg(feature = "sampler")] Sampler(sampler) => sampler.process(client, scope),
|
|
#[cfg(feature = "lv2")] Lv2(lv2) => lv2.process(client, scope),
|
|
#[cfg(feature = "vst2")] Vst2 => { todo!() }, // TODO
|
|
#[cfg(feature = "vst3")] Vst3 => { todo!() }, // TODO
|
|
#[cfg(feature = "clap")] Clap => { todo!() }, // TODO
|
|
#[cfg(feature = "sf2")] Sf2 => { todo!() }, // TODO
|
|
}
|
|
});
|
|
|
|
def_command!(DeviceCommand: |device: Device| {});
|
|
//take!(DeviceCommand|state: Arrangement, iter|state.selected_device().as_ref()
|
|
//.map(|t|Take::take(t, iter)).transpose().map(|x|x.flatten()));
|