mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-09-18 12:56:42 +02:00
This commit is contained in:
parent
a4931d8e4f
commit
def7a1b210
17 changed files with 2209 additions and 1790 deletions
|
|
@ -8,12 +8,28 @@ pub(crate) use symphonia::{
|
|||
},
|
||||
};
|
||||
|
||||
pub trait HasSampler: AsRef<Sampler> + AsMut<Sampler> {
|
||||
fn sampler (&self) -> &Sampler {
|
||||
self.as_ref()
|
||||
}
|
||||
fn sampler_mut (&mut self) -> &mut Sampler {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<Sampler> + AsMut<Sampler>> HasSampler for T {}
|
||||
|
||||
#[tek_proc::commands(SamplerCommand = "sampler")]
|
||||
impl Sampler {
|
||||
pub trait SamplerController: HasSampler
|
||||
+ for<'a> Namespace<'a, usize>
|
||||
{
|
||||
|
||||
#[command(RecordToggle = "rec-toggle")]
|
||||
fn record_toggle (&mut self, slot: usize) -> Perhaps<SamplerCommand> {
|
||||
let recording = self.recording.as_ref().map(|x|x.0);
|
||||
fn record_toggle (&mut self, slot: usize) -> Perhaps<SamplerCommand>
|
||||
where Self: Sized
|
||||
{
|
||||
let sampler = self.sampler_mut();
|
||||
let recording = sampler.recording.as_ref().map(|x|x.0);
|
||||
let _ = SamplerCommand::RecordFinish.act(self)?;
|
||||
// autoslice: continue recording at next slot
|
||||
if recording != Some(slot) {
|
||||
|
|
@ -25,10 +41,11 @@ impl Sampler {
|
|||
|
||||
#[command(RecordBegin = "rec-begin")]
|
||||
fn record_begin (&mut self, slot: usize) -> Perhaps<SamplerCommand> {
|
||||
self.recording = Some((
|
||||
let sampler = self.sampler_mut();
|
||||
sampler.recording = Some((
|
||||
slot,
|
||||
Some(Arc::new(RwLock::new(Sample::new(
|
||||
"Sample", 0, 0, vec![vec![];self.audio_ins.len()]
|
||||
"Sample", 0, 0, vec![vec![]; sampler.audio_ins.len()]
|
||||
))))
|
||||
));
|
||||
Ok(None)
|
||||
|
|
@ -36,8 +53,9 @@ impl Sampler {
|
|||
|
||||
#[command(RecordFinish = "rec-finish")]
|
||||
fn record_finish (&mut self) -> Perhaps<SamplerCommand> {
|
||||
let _prev_sample = self.recording.as_mut().map(|(index, sample)|{
|
||||
std::mem::swap(sample, &mut self.samples.0[*index]);
|
||||
let sampler = self.sampler_mut();
|
||||
let _prev_sample = sampler.recording.as_mut().map(|(index, sample)|{
|
||||
std::mem::swap(sample, &mut sampler.samples.0[*index]);
|
||||
sample
|
||||
}); // TODO: undo
|
||||
Ok(None)
|
||||
|
|
@ -45,14 +63,15 @@ impl Sampler {
|
|||
|
||||
#[command(RecordCancel = "rec-cancel")]
|
||||
fn record_cancel (&mut self) -> Perhaps<SamplerCommand> {
|
||||
self.recording = None;
|
||||
self.sampler_mut().recording = None;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[command(PlaySample = "sample-play")]
|
||||
fn sample_play (&mut self, slot: usize) -> Perhaps<SamplerCommand> {
|
||||
if let Some(ref sample) = self.samples.0[slot] {
|
||||
self.voices.write().unwrap().push(Sample::play(sample, 0, &u7::from(128)));
|
||||
let sampler = self.sampler_mut();
|
||||
if let Some(ref sample) = sampler.samples.0[slot] {
|
||||
sampler.voices.write().unwrap().push(Sample::play(sample, 0, &u7::from(128)));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
|
@ -730,3 +749,95 @@ impl SampleAdd {
|
|||
fn read_sample_data (_: &str) -> Usually<(usize, Vec<Vec<f32>>)> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
pub fn view_sample_info (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
||||
when(sample.is_some(), draw(move|to: &mut Tui|{
|
||||
let sample = sample.unwrap().read().unwrap();
|
||||
let theme = sample.color;
|
||||
east!(
|
||||
field_h(theme, "Name", format!("{:<10}", sample.name.clone())),
|
||||
field_h(theme, "Length", format!("{:<8}", sample.channels[0].len())),
|
||||
field_h(theme, "Start", format!("{:<8}", sample.start)),
|
||||
field_h(theme, "End", format!("{:<8}", sample.end)),
|
||||
field_h(theme, "Trans", "0"),
|
||||
field_h(theme, "Gain", format!("{}", sample.gain)),
|
||||
).draw(to)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn view_sample_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
||||
let a = draw(move|to: &mut Tui|{
|
||||
let sample = sample.unwrap().read().unwrap();
|
||||
let theme = sample.color;
|
||||
south!(
|
||||
field_h(theme, "Name ", format!("{:<10}", sample.name.clone())) .align_w().full_w(),
|
||||
field_h(theme, "Length", format!("{:<8}", sample.channels[0].len())).align_w().full_w(),
|
||||
field_h(theme, "Start ", format!("{:<8}", sample.start)) .align_w().full_w(),
|
||||
field_h(theme, "End ", format!("{:<8}", sample.end)) .align_w().full_w(),
|
||||
field_h(theme, "Trans ", "0") .align_w().full_w(),
|
||||
field_h(theme, "Gain ", format!("{}", sample.gain)) .align_w().full_w(),
|
||||
).exact_w(20).draw(to)
|
||||
});
|
||||
|
||||
let b = draw(|to: &mut Tui|fg(Red, south!(
|
||||
bold(true, "× No sample."),
|
||||
"[r] record",
|
||||
"[Shift-F9] import",
|
||||
)).draw(to));
|
||||
|
||||
either(sample.is_some(), a, b)
|
||||
}
|
||||
|
||||
pub fn view_sample_status (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> {
|
||||
bold(true, fg(g(224), sample
|
||||
.map(|sample|{
|
||||
let sample = sample.read().unwrap();
|
||||
format!("Sample {}-{}", sample.start, sample.end)
|
||||
})
|
||||
.unwrap_or_else(||"No sample".to_string())))
|
||||
}
|
||||
|
||||
#[cfg(feature = "track")]
|
||||
impl Track {
|
||||
/// Create a new track connecting the [Sequencer] to a [Sampler].
|
||||
pub fn new_with_sampler (
|
||||
name: &impl AsRef<str>,
|
||||
color: Option<ItemTheme>,
|
||||
jack: &Jack<'static>,
|
||||
clock: Option<&Clock>,
|
||||
clip: Option<&Arc<RwLock<MidiClip>>>,
|
||||
midi_from: &[Connect],
|
||||
midi_to: &[Connect],
|
||||
audio_from: &[&[Connect];2],
|
||||
audio_to: &[&[Connect];2],
|
||||
) -> Usually<Self> {
|
||||
let mut track = Self::new(name, color, jack, clock, clip, midi_from, midi_to)?;
|
||||
let client_name = jack.with_client(|c|c.name().to_string());
|
||||
let port_name = track.sequencer.midi_outs[0].port_name();
|
||||
let connect = [Connect::exact(format!("{client_name}:{}", port_name))];
|
||||
track.devices.push(Device::Sampler(Sampler::new(
|
||||
jack, &format!("{}/sampler", name.as_ref()), &connect, audio_from, audio_to
|
||||
)?));
|
||||
Ok(track)
|
||||
}
|
||||
|
||||
pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
||||
for device in self.devices.iter() {
|
||||
match device {
|
||||
Device::Sampler(s) => if nth == 0 { return Some(s); } else { nth -= 1; },
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn sampler_mut (&mut self, mut nth: usize) -> Option<&mut Sampler> {
|
||||
for device in self.devices.iter_mut() {
|
||||
match device {
|
||||
Device::Sampler(s) => if nth == 0 { return Some(s); } else { nth -= 1; },
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue