#![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 + 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 ( target: &mut T, value: &T, returned: impl Fn(T)->U ) -> Perhaps { 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 ( target: &mut bool, value: &Option, returned: impl Fn(Option)->U ) -> Perhaps { 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>> HasDevices for T { fn devices (&self) -> &Vec { self.get() } fn devices_mut (&mut self) -> &mut Vec { self.get_mut() } } pub trait HasDevices { fn devices (&self) -> &Vec; fn devices_mut (&mut self) -> &mut Vec; } #[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()));