Skip to content

Commit cd3351e

Browse files
committed
Start providing Sig alternatives to FrameSig
1 parent e36082c commit cd3351e

File tree

20 files changed

+956
-62
lines changed

20 files changed

+956
-62
lines changed

computer-keyboard/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ edition = "2021"
1212
[dependencies]
1313
caw_keyboard = { version = "0.3", path = "../keyboard" }
1414
caw_core = { version = "0.4", path = "../core" }
15+
itertools = "0.14"

computer-keyboard/src/lib.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use caw_core::{FrameSig, FrameSigT};
1+
use caw_core::{Buf, FrameSig, FrameSigT, Sig, SigT};
22
use caw_keyboard::{KeyEvent, KeyEvents, Note};
3+
use itertools::izip;
34

45
#[derive(Debug, Clone, Copy)]
56
pub enum Key {
@@ -313,6 +314,45 @@ fn opinionated_note_by_key(start_note: Note) -> Vec<(Key, Note)> {
313314
.collect::<Vec<_>>()
314315
}
315316

317+
pub fn opinionated_key_events_<S>(
318+
keyboard: &Keyboard<S>,
319+
start_note: Note,
320+
) -> Sig<impl SigT<Item = KeyEvents>>
321+
where
322+
S: SigT<Item = bool> + Clone,
323+
{
324+
let note_by_key = opinionated_note_by_key(start_note);
325+
let mut key_events_by_key = note_by_key
326+
.into_iter()
327+
.map(|(key, note)| {
328+
let mut pressed_state = false;
329+
Sig(keyboard.get(key)).map_mut(move |pressed| {
330+
if pressed == pressed_state {
331+
None
332+
} else {
333+
pressed_state = pressed;
334+
Some(KeyEvent {
335+
note,
336+
pressed,
337+
velocity_01: 1.0,
338+
})
339+
}
340+
})
341+
})
342+
.collect::<Vec<_>>();
343+
Sig::from_buf_fn(move |ctx, buf: &mut Vec<KeyEvents>| {
344+
buf.clear();
345+
buf.resize_with(ctx.num_samples, KeyEvents::empty);
346+
for key_events in &mut key_events_by_key {
347+
for (out, key_event_opt) in
348+
izip! { buf.iter_mut(), key_events.sample(ctx).iter() }
349+
{
350+
out.extend(key_event_opt);
351+
}
352+
}
353+
})
354+
}
355+
316356
pub fn opinionated_key_events<S>(
317357
keyboard: &Keyboard<S>,
318358
start_note: Note,
@@ -354,6 +394,18 @@ where
354394
})
355395
}
356396

397+
impl<K> Keyboard<K>
398+
where
399+
K: SigT<Item = bool> + Clone,
400+
{
401+
pub fn opinionated_key_events_(
402+
self,
403+
start_note: Note,
404+
) -> Sig<impl SigT<Item = KeyEvents>> {
405+
opinionated_key_events_(&self, start_note)
406+
}
407+
}
408+
357409
impl<K> Keyboard<K>
358410
where
359411
K: FrameSigT<Item = bool> + Clone,

core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ pub use frame_sig::{
88
FrameSigT, FrameSigVar, Triggerable,
99
};
1010
pub use sig::{
11-
sig_shared, Buf, ConstBuf, Filter, GateToTrigRisingEdge, Sig, SigAbs,
12-
SigBoxed, SigCtx, SigSampleIntoBufT, SigShared, SigT,
11+
sig_shared, sig_var, Buf, ConstBuf, Filter, GateToTrigRisingEdge, Sig,
12+
SigAbs, SigBoxed, SigCtx, SigSampleIntoBufT, SigShared, SigT, SigVar,
1313
};
1414
pub mod stereo;
1515
pub use stereo::{Channel, Stereo, StereoPair};

core/src/sig.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ where
840840
pub struct SigBufFn<F, T>
841841
where
842842
F: FnMut(&SigCtx, &mut Vec<T>),
843-
T: Clone + Default,
843+
T: Clone,
844844
{
845845
f: F,
846846
buf: Vec<T>,
@@ -849,12 +849,11 @@ where
849849
impl<F, T> SigT for SigBufFn<F, T>
850850
where
851851
F: FnMut(&SigCtx, &mut Vec<T>),
852-
T: Clone + Default,
852+
T: Clone,
853853
{
854854
type Item = T;
855855

856856
fn sample(&mut self, ctx: &SigCtx) -> impl Buf<Self::Item> {
857-
self.buf.resize_with(ctx.num_samples, Default::default);
858857
(self.f)(ctx, &mut self.buf);
859858
&self.buf
860859
}
@@ -863,9 +862,46 @@ where
863862
impl<F, T> Sig<SigBufFn<F, T>>
864863
where
865864
F: FnMut(&SigCtx, &mut Vec<T>),
866-
T: Clone + Default,
865+
T: Clone,
867866
{
868867
pub fn from_buf_fn(f: F) -> Self {
869868
Self(SigBufFn { f, buf: Vec::new() })
870869
}
871870
}
871+
872+
#[derive(Default)]
873+
pub struct SigVar<T>(Arc<RwLock<T>>);
874+
875+
impl<T> SigVar<T> {
876+
pub fn new(value: T) -> Self {
877+
Self(Arc::new(RwLock::new(value)))
878+
}
879+
880+
pub fn set(&self, value: T) {
881+
*self.0.write().unwrap() = value;
882+
}
883+
}
884+
885+
pub fn sig_var<T: Clone>(value: T) -> Sig<SigVar<T>> {
886+
Sig(SigVar::new(value))
887+
}
888+
889+
impl<T> Clone for SigVar<T> {
890+
fn clone(&self) -> Self {
891+
Self(Arc::clone(&self.0))
892+
}
893+
}
894+
895+
impl<T> SigT for SigVar<T>
896+
where
897+
T: Clone,
898+
{
899+
type Item = T;
900+
901+
fn sample(&mut self, ctx: &SigCtx) -> impl Buf<Self::Item> {
902+
ConstBuf {
903+
count: ctx.num_samples,
904+
value: self.0.read().unwrap().clone(),
905+
}
906+
}
907+
}

interactive/examples/keyboard_and_mouse_interactive.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
use caw_core::*;
2-
use caw_interactive::{Input, MouseButton, Visualization, Window};
3-
use caw_keyboard::{IntoNoteFreqHz, KeyEventsT, MonoVoice, Note};
2+
use caw_interactive::{Input_, MouseButton, Visualization, Window};
3+
use caw_keyboard::{IntoNoteFreqHz_, KeyEventsT_, MonoVoice_, Note};
44
use caw_modules::*;
55

6-
fn sig(input: Input, channel: Channel) -> Sig<impl SigT<Item = f32> + Send> {
7-
let MonoVoice {
6+
fn sig(input: Input_, channel: Channel) -> Sig<impl SigT<Item = f32> + Send> {
7+
let MonoVoice_ {
88
note,
99
key_down_gate,
1010
key_press_trig,
1111
..
12-
} = input.keyboard.opinionated_key_events(Note::B0).mono_voice();
12+
} = input
13+
.keyboard
14+
.opinionated_key_events_(Note::B0)
15+
.debug(|x| {
16+
if !x.is_empty() {
17+
//println!("{:?}", x);
18+
}
19+
})
20+
.mono_voice();
1321
let key_press_trig = key_press_trig.shared();
1422
let key_down_gate = key_down_gate | input.mouse.button(MouseButton::Left);
1523
let env = adsr_linear_01(key_down_gate)
@@ -47,7 +55,7 @@ fn main() -> anyhow::Result<()> {
4755
.line_width(2)
4856
.scale(4.)
4957
.build();
50-
let input = window.input();
58+
let input = window.input_();
5159
window.play_stereo(
5260
Stereo::new_fn_channel(|channel| sig(input.clone(), channel)),
5361
Default::default(),

interactive/examples/keyboard_and_mouse_polyphonic_interactive.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
use caw_core::*;
2-
use caw_interactive::{Input, Visualization, Window};
3-
use caw_keyboard::{IntoNoteFreqHz, KeyEventsT, MonoVoice, Note};
2+
use caw_interactive::{Input_, Visualization, Window};
3+
use caw_keyboard::{IntoNoteFreqHz_, KeyEventsT_, MonoVoice_, Note};
44
use caw_modules::*;
55

6-
fn sig(input: Input, ch: Channel) -> Sig<impl SigT<Item = f32> + Send> {
6+
fn sig(input: Input_, ch: Channel) -> Sig<impl SigT<Item = f32> + Send> {
77
input
88
.clone()
99
.keyboard
10-
.opinionated_key_events(Note::B2)
10+
.opinionated_key_events_(Note::B2)
1111
.poly_voices(12)
1212
.into_iter()
1313
.map(
14-
move |MonoVoice {
14+
move |MonoVoice_ {
1515
note,
1616
key_down_gate,
1717
key_press_trig,
@@ -64,7 +64,7 @@ fn main() -> anyhow::Result<()> {
6464
.scale(0.7)
6565
.stride(2)
6666
.build();
67-
let input = window.input();
67+
let input = window.input_();
6868
window.play_stereo(
6969
Stereo::new_fn_channel(|ch| sig(input.clone(), ch)),
7070
Default::default(),

interactive/examples/midi_file_interactive.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use caw_core::*;
2-
use caw_interactive::{Input, MouseButton, Visualization, Window};
3-
use caw_keyboard::{IntoNoteFreqHz, KeyEventsT, MonoVoice};
2+
use caw_interactive::{Input_, MouseButton, Visualization, Window};
3+
use caw_keyboard::{IntoNoteFreqHz_, KeyEventsT_, MonoVoice_};
44
use caw_midi_file::*;
55
use caw_modules::*;
66
use clap::Parser;
77

88
fn sig(
9-
input: Input,
10-
midi_messages: FrameSig<impl FrameSigT<Item = MidiMessages>>,
9+
input: Input_,
10+
midi_messages: Sig<impl SigT<Item = MidiMessages>>,
1111
channel: Channel,
1212
) -> Sig<impl SigT<Item = f32>> {
1313
midi_messages
1414
.key_events()
1515
.poly_voices(48)
1616
.into_iter()
1717
.map(
18-
|MonoVoice {
18+
|MonoVoice_ {
1919
note,
2020
key_down_gate,
2121
key_press_trig,
@@ -56,14 +56,15 @@ fn main() -> anyhow::Result<()> {
5656
env_logger::init();
5757
let args = Args::parse();
5858
let midi_file = MidiFile::read(args.name)?;
59-
let midi_messages = midi_file.track(0, 1.0)?.into_midi_messages(0).shared();
59+
let midi_messages =
60+
midi_file.track(0, 1.0)?.into_midi_messages_(0).shared();
6061
let window = Window::builder()
6162
.sane_default()
6263
.visualization(Visualization::StereoOscillographics)
6364
.line_width(2)
6465
.fade(true)
6566
.build();
66-
let input = window.input();
67+
let input = window.input_();
6768
window.play_stereo(
6869
Stereo::new_fn_channel(|channel| {
6970
sig(input.clone(), midi_messages.clone(), channel)

interactive/examples/midi_live_interactive_chorus.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
use caw_core::*;
22
use caw_interactive::{Input, Visualization, Window};
3-
use caw_keyboard::{IntoNoteFreqHz, KeyEvents, KeyEventsT, MonoVoice, Note};
3+
use caw_keyboard::{IntoNoteFreqHz_, KeyEvents, KeyEventsT_, MonoVoice_, Note};
44
use caw_midi::*;
55
use caw_midi_live::*;
66
use caw_modules::*;
77
use clap::{Parser, Subcommand};
88

99
fn sig(
1010
input: Input,
11-
key_events: FrameSig<impl FrameSigT<Item = KeyEvents>>,
12-
_pitch_bend_freq_mult: FrameSig<FrameSigShared<impl FrameSigT<Item = f32>>>,
13-
controllers: MidiControllers<impl FrameSigT<Item = MidiMessages>>,
11+
key_events: Sig<impl SigT<Item = KeyEvents>>,
12+
_pitch_bend_freq_mult: Sig<SigShared<impl SigT<Item = f32>>>,
13+
controllers: MidiControllers_<impl SigT<Item = MidiMessages>>,
1414
channel: Channel,
1515
) -> Sig<impl SigT<Item = f32>> {
1616
input
1717
.keyboard
18-
.opinionated_key_events(Note::B0)
19-
.merge(FrameSig(key_events))
18+
.opinionated_key_events_(Note::B0)
19+
.merge(Sig(key_events))
2020
.poly_voices(48)
2121
.into_iter()
2222
.map(
23-
|MonoVoice {
23+
|MonoVoice_ {
2424
note,
2525
key_down_gate,
2626
key_press_trig,
@@ -86,9 +86,7 @@ enum Commands {
8686
},
8787
}
8888

89-
fn run(
90-
midi_events: FrameSig<impl FrameSigT<Item = MidiMessages>>,
91-
) -> anyhow::Result<()> {
89+
fn run(midi_events: Sig<impl SigT<Item = MidiMessages>>) -> anyhow::Result<()> {
9290
let window = Window::builder()
9391
.sane_default()
9492
.visualization(Visualization::StereoOscillographics)
@@ -127,7 +125,7 @@ fn main() -> anyhow::Result<()> {
127125
}
128126
Commands::Play { midi_port } => {
129127
let connection = midi_live.connect(midi_port)?;
130-
run(connection.channel(0))?;
128+
run(connection.channel_(0))?;
131129
}
132130
}
133131
Ok(())

0 commit comments

Comments
 (0)