From 97920d706305a1f3edbad607211014ee071fbed6 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 28 Dec 2024 18:06:17 +0100 Subject: [PATCH] record sample (y no playback?) --- Justfile | 2 +- crates/tek/src/groovebox.rs | 8 +++--- crates/tek/src/sampler/sampler_audio.rs | 33 +++++++++++++++++++------ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Justfile b/Justfile index c657edd1..83b7e30f 100644 --- a/Justfile +++ b/Justfile @@ -80,7 +80,7 @@ groovebox-release-ext: -l "Komplete Audio 6 Pro:capture_AUX1" \ -r "Komplete Audio 6 Pro:capture_AUX1" \ -L "Komplete Audio 6 Pro:playback_AUX1" \ - -R "Komplete Audio 6 Pro:playback_AUX1" + -R "Komplete Audio 6 Pro:playback_AUX2" sequencer: reset diff --git a/crates/tek/src/groovebox.rs b/crates/tek/src/groovebox.rs index 3266a170..97e7e3c6 100644 --- a/crates/tek/src/groovebox.rs +++ b/crates/tek/src/groovebox.rs @@ -112,7 +112,7 @@ render!(|self: GrooveboxSamples<'a>|{ } } Tui::bg(bg, if let Some(sample) = &self.0.sampler.mapped[note] { - todo!() + Tui::fg(fg, format!("{note:3} ????? ")) } else { Tui::fg(fg, format!("{note:3} (none) ")) }) @@ -153,9 +153,11 @@ input_to_command!(GrooveboxCommand: |state: GrooveboxTui, input|match input // 0: Enqueue phrase 0 (stop all) key_pat!(Char('0')) => Enqueue(Some(state.pool.phrases()[0].clone())), - key_pat!(Shift-Char('R')) => Sampler( + key_pat!(Shift-Char('R')) => Sampler(if state.sampler.recording.is_some() { + SamplerCommand::RecordFinish + } else { SamplerCommand::RecordBegin(u7::from(state.editor.note_point() as u8)) - ), + }), // e: Toggle between editing currently playing or other phrase key_pat!(Char('e')) => if let Some((_, Some(playing))) = state.player.play_phrase() { diff --git a/crates/tek/src/sampler/sampler_audio.rs b/crates/tek/src/sampler/sampler_audio.rs index 8b9ca5e4..c7558455 100644 --- a/crates/tek/src/sampler/sampler_audio.rs +++ b/crates/tek/src/sampler/sampler_audio.rs @@ -11,22 +11,39 @@ audio!(|self: SamplerAudio<'a>, _client, scope|{ self.0.clear_output_buffer(); self.0.process_audio_out(scope); self.0.write_output_buffer(scope); - self.0.update_input_meter(scope); + self.0.process_audio_in(scope); Control::Continue }); impl Sampler { - pub fn update_input_meter (&mut self, scope: &ProcessScope) { - let Sampler { audio_ins, input_meter, .. } = self; + pub fn process_audio_in (&mut self, scope: &ProcessScope) { + let Sampler { audio_ins, input_meter, recording, .. } = self; if audio_ins.len() != input_meter.len() { *input_meter = vec![0.0;audio_ins.len()]; } - for (input, meter) in audio_ins.iter().zip(input_meter) { - let slice = input.as_slice(scope); - let total: f32 = slice.iter().map(|x|x.abs()).sum(); - let count = slice.len() as f32; - *meter = 10. * (total / count).log10(); + if let Some((_, sample)) = recording { + if sample.channels.len() != audio_ins.len() { + panic!("channel count mismatch"); + } + let iterator = audio_ins.iter().zip(input_meter).zip(sample.channels.iter_mut()); + let mut length = 0; + for ((input, meter), channel) in iterator { + let slice = input.as_slice(scope); + length = length.max(slice.len()); + let total: f32 = slice.iter().map(|x|x.abs()).sum(); + let count = slice.len() as f32; + *meter = 10. * (total / count).log10(); + channel.extend_from_slice(slice); + } + sample.end += length; + } else { + for (input, meter) in audio_ins.iter().zip(input_meter) { + let slice = input.as_slice(scope); + let total: f32 = slice.iter().map(|x|x.abs()).sum(); + let count = slice.len() as f32; + *meter = 10. * (total / count).log10(); + } } }