Skip to content

Commit a246805

Browse files
committed
Signals are Send and Sync
1 parent 40c8c41 commit a246805

File tree

19 files changed

+241
-74
lines changed

19 files changed

+241
-74
lines changed

audio-file/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw_audio_file"
3-
version = "0.2.1"
3+
version = "0.3.0"
44
description = "Load audio files for sampling in the caw synthesizer framework"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -10,6 +10,6 @@ documentation = "https://docs.rs/caw_audio_file"
1010
edition = "2021"
1111

1212
[dependencies]
13-
caw_core = { version = "0.3", path = "../core" }
13+
caw_core = { version = "0.4", path = "../core" }
1414
hound = "3.5"
1515
anyhow = "1"

caw/Cargo.toml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
description = "A framework for building software-defined modular synthesizers"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -19,20 +19,20 @@ interactive = ["caw_interactive"]
1919
audio_file = ["caw_audio_file"]
2020

2121
[dependencies]
22-
caw_core = { version = "0.3", path = "../core" }
23-
caw_computer_keyboard = { version = "0.2", path = "../computer-keyboard" }
24-
caw_keyboard = { version = "0.2", path = "../keyboard" }
25-
caw_modules = { version = "0.2", path = "../modules" }
26-
caw_patches = { version = "0.2", path = "../patches" }
27-
caw_utils = { version = "0.2", path = "../utils" }
22+
caw_core = { version = "0.4", path = "../core" }
23+
caw_computer_keyboard = { version = "0.3", path = "../computer-keyboard" }
24+
caw_keyboard = { version = "0.3", path = "../keyboard" }
25+
caw_modules = { version = "0.3", path = "../modules" }
26+
caw_patches = { version = "0.3", path = "../patches" }
27+
caw_utils = { version = "0.3", path = "../utils" }
2828
caw_builder_proc_macros = { version = "0.1", path = "../builder-proc-macros" }
29-
caw_player = { version = "0.4", path = "../player", optional = true }
30-
caw_midi = { version = "0.2", path = "../midi", optional = true }
31-
caw_midi_live = { version = "0.2", path = "../midi-live", optional = true }
32-
caw_midi_file = { version = "0.2", path = "../midi-file", optional = true }
33-
caw_midi_serial = { version = "0.2", path = "../midi-serial", optional = true }
34-
caw_audio_file = { version = "0.2", path = "../audio-file", optional = true }
35-
caw_interactive = { version = "0.4", path = "../interactive", optional = true }
29+
caw_player = { version = "0.5", path = "../player", optional = true }
30+
caw_midi = { version = "0.3", path = "../midi", optional = true }
31+
caw_midi_live = { version = "0.3", path = "../midi-live", optional = true }
32+
caw_midi_file = { version = "0.3", path = "../midi-file", optional = true }
33+
caw_midi_serial = { version = "0.3", path = "../midi-serial", optional = true }
34+
caw_audio_file = { version = "0.3", path = "../audio-file", optional = true }
35+
caw_interactive = { version = "0.5", path = "../interactive", optional = true }
3636

3737
[dev-dependencies]
3838
anyhow = "1.0"

computer-keyboard/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw_computer_keyboard"
3-
version = "0.2.2"
3+
version = "0.3.0"
44
description = "Use a computer keyboard to control caw synthesizer modules"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -10,5 +10,5 @@ documentation = "https://docs.rs/caw_computer_keyboard"
1010
edition = "2021"
1111

1212
[dependencies]
13-
caw_keyboard = { version = "0.2", path = "../keyboard" }
14-
caw_core = { version = "0.3", path = "../core" }
13+
caw_keyboard = { version = "0.3", path = "../keyboard" }
14+
caw_core = { version = "0.4", path = "../core" }

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw_core"
3-
version = "0.3.3"
3+
version = "0.4.0"
44
description = "Core types for caw software-defined modular synthesizer"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"

core/src/frame_sig.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::{Buf, ConstBuf, Filter, Sig, SigCtx, SigT};
22
use std::{
3-
cell::RefCell,
43
fmt::Debug,
5-
rc::Rc,
64
sync::{Arc, RwLock},
75
};
86

@@ -502,7 +500,7 @@ pub struct FrameSigShared<S>
502500
where
503501
S: FrameSigT,
504502
{
505-
shared_cached_sig: Rc<RefCell<FrameSigCached<S>>>,
503+
shared_cached_sig: Arc<RwLock<FrameSigCached<S>>>,
506504
}
507505

508506
impl<S> Clone for FrameSigShared<S>
@@ -511,7 +509,7 @@ where
511509
{
512510
fn clone(&self) -> Self {
513511
FrameSigShared {
514-
shared_cached_sig: Rc::clone(&self.shared_cached_sig),
512+
shared_cached_sig: Arc::clone(&self.shared_cached_sig),
515513
}
516514
}
517515
}
@@ -523,7 +521,7 @@ where
523521
type Item = S::Item;
524522

525523
fn frame_sample(&mut self, ctx: &SigCtx) -> Self::Item {
526-
self.shared_cached_sig.borrow_mut().frame_sample(ctx)
524+
self.shared_cached_sig.write().unwrap().frame_sample(ctx)
527525
}
528526
}
529527

@@ -532,7 +530,7 @@ where
532530
S: FrameSigT,
533531
{
534532
FrameSig(FrameSigShared {
535-
shared_cached_sig: Rc::new(RefCell::new(FrameSigCached::new(sig))),
533+
shared_cached_sig: Arc::new(RwLock::new(FrameSigCached::new(sig))),
536534
})
537535
}
538536

core/src/sig.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
use std::{cell::RefCell, fmt::Debug, iter, marker::PhantomData, rc::Rc};
1+
use std::{
2+
fmt::Debug,
3+
iter,
4+
marker::PhantomData,
5+
sync::{Arc, RwLock},
6+
};
27

38
use crate::arith::signed_to_01;
49

5-
#[derive(Clone, Copy)]
10+
#[derive(Clone, Copy, Debug)]
611
pub struct SigCtx {
712
pub sample_rate_hz: f32,
813
pub batch_index: u64,
@@ -27,6 +32,18 @@ where
2732
out.push(x.clone());
2833
}
2934
}
35+
36+
/// Clone each sample into a slice with a given offset and stride. This is intended to be used
37+
/// to populate a single channel worth of samples into an audio buffer containing multiple
38+
/// interleaved channels.
39+
fn clone_to_slice(&self, stride: usize, offset: usize, out: &mut [T]) {
40+
let out_offset = &mut out[offset..];
41+
for (sample, out_chunk) in
42+
self.iter().zip(out_offset.chunks_mut(stride))
43+
{
44+
out_chunk[0] = sample;
45+
}
46+
}
3047
}
3148

3249
impl<T> Buf<T> for &Vec<T>
@@ -232,6 +249,14 @@ pub trait SigSampleIntoBufT {
232249
type Item: Clone;
233250

234251
fn sample_into_buf(&mut self, ctx: &SigCtx, buf: &mut Vec<Self::Item>);
252+
253+
fn sample_into_slice(
254+
&mut self,
255+
ctx: &SigCtx,
256+
stride: usize,
257+
offset: usize,
258+
out: &mut [Self::Item],
259+
);
235260
}
236261

237262
impl SigT for f32 {
@@ -291,9 +316,22 @@ impl<S: SigT> SigSampleIntoBufT for Sig<S> {
291316
let buf_internal = self.0.sample(ctx);
292317
buf_internal.clone_to_vec(buf);
293318
}
319+
320+
fn sample_into_slice(
321+
&mut self,
322+
ctx: &SigCtx,
323+
stride: usize,
324+
offset: usize,
325+
out: &mut [Self::Item],
326+
) {
327+
let buf_internal = self.0.sample(ctx);
328+
buf_internal.clone_to_slice(stride, offset, out);
329+
}
294330
}
295331

296-
pub struct SigBoxed<T>(Box<dyn SigSampleIntoBufT<Item = T>>)
332+
pub struct SigBoxed<T>(
333+
Box<dyn SigSampleIntoBufT<Item = T> + Send + Sync + 'static>,
334+
)
297335
where
298336
T: Clone;
299337

@@ -306,6 +344,16 @@ where
306344
fn sample_into_buf(&mut self, ctx: &SigCtx, buf: &mut Vec<Self::Item>) {
307345
self.0.sample_into_buf(ctx, buf);
308346
}
347+
348+
fn sample_into_slice(
349+
&mut self,
350+
ctx: &SigCtx,
351+
stride: usize,
352+
offset: usize,
353+
out: &mut [Self::Item],
354+
) {
355+
self.0.sample_into_slice(ctx, stride, offset, out);
356+
}
309357
}
310358

311359
impl<S> Sig<S>
@@ -379,7 +427,7 @@ where
379427

380428
impl<S> Sig<S>
381429
where
382-
S: SigT + 'static,
430+
S: SigT + Send + Sync + 'static,
383431
{
384432
pub fn boxed(self) -> SigBoxed<S::Item> {
385433
SigBoxed(Box::new(self))
@@ -710,7 +758,7 @@ pub struct SigShared<S>
710758
where
711759
S: SigT,
712760
{
713-
shared_cached_sig: Rc<RefCell<SigCached<S>>>,
761+
shared_cached_sig: Arc<RwLock<SigCached<S>>>,
714762
buf: Vec<S::Item>,
715763
}
716764

@@ -720,7 +768,7 @@ where
720768
{
721769
fn clone(&self) -> Self {
722770
SigShared {
723-
shared_cached_sig: Rc::clone(&self.shared_cached_sig),
771+
shared_cached_sig: Arc::clone(&self.shared_cached_sig),
724772
buf: self.buf.clone(),
725773
}
726774
}
@@ -733,7 +781,7 @@ where
733781
type Item = S::Item;
734782

735783
fn sample(&mut self, ctx: &SigCtx) -> impl Buf<Self::Item> {
736-
let mut shared_cached_sig = self.shared_cached_sig.borrow_mut();
784+
let mut shared_cached_sig = self.shared_cached_sig.write().unwrap();
737785
// This will only actually run the underlying signal if it hasn't been computed yet this
738786
// frame. If it has already been computed this frame then the already-populated buffer will
739787
// be returned. We still need to copy the buffer to the buffer inside `self` so that the
@@ -749,7 +797,7 @@ where
749797
S: SigT,
750798
{
751799
Sig(SigShared {
752-
shared_cached_sig: Rc::new(RefCell::new(SigCached::new(sig))),
800+
shared_cached_sig: Arc::new(RwLock::new(SigCached::new(sig))),
753801
buf: Vec::new(),
754802
})
755803
}

interactive/Cargo.toml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw_interactive"
3-
version = "0.4.0"
3+
version = "0.5.0"
44
description = "Interactive keyboard and mouse control, and visualization for the caw synthesizer framework"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -11,23 +11,23 @@ edition = "2021"
1111

1212
[dependencies]
1313
anyhow = "1.0"
14-
caw_player = { version = "0.4", path = "../player" }
15-
caw_core = { version = "0.3", path = "../core" }
16-
caw_computer_keyboard = { version = "0.2", path = "../computer-keyboard" }
14+
caw_player = { version = "0.5", path = "../player" }
15+
caw_core = { version = "0.4", path = "../core" }
16+
caw_computer_keyboard = { version = "0.3", path = "../computer-keyboard" }
1717
line_2d = "0.5"
1818
rgb_int = "0.1"
1919
sdl2 = "0.37"
2020

2121
[dev-dependencies]
22-
caw_keyboard = { version = "0.2", path = "../keyboard" }
23-
caw_midi = { version = "0.2", path = "../midi" }
24-
caw_midi_live = { version = "0.2", path = "../midi-live" }
25-
caw_midi_file = { version = "0.2", path = "../midi-file" }
26-
caw_midi_serial = { version = "0.2", path = "../midi-serial" }
27-
caw_modules = { version = "0.2", path = "../modules" }
28-
caw_patches = { version = "0.2", path = "../patches" }
29-
caw_utils = { version = "0.2", path = "../utils" }
30-
caw_audio_file = { version = "0.2", path = "../audio-file" }
22+
caw_keyboard = { version = "0.3", path = "../keyboard" }
23+
caw_midi = { version = "0.3", path = "../midi" }
24+
caw_midi_live = { version = "0.3", path = "../midi-live" }
25+
caw_midi_file = { version = "0.3", path = "../midi-file" }
26+
caw_midi_serial = { version = "0.3", path = "../midi-serial" }
27+
caw_modules = { version = "0.3", path = "../modules" }
28+
caw_patches = { version = "0.3", path = "../patches" }
29+
caw_utils = { version = "0.3", path = "../utils" }
30+
caw_audio_file = { version = "0.3", path = "../audio-file" }
3131
env_logger = "0.11"
3232
rand = "0.8"
3333
wide = "0.7"

interactive/examples/keyboard_and_mouse_interactive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use caw_interactive::{Input, MouseButton, Visualization, Window};
33
use caw_keyboard::{IntoNoteFreqHz, KeyEventsT, MonoVoice, Note};
44
use caw_modules::*;
55

6-
fn sig(input: Input, channel: Channel) -> Sig<impl SigT<Item = f32>> {
6+
fn sig(input: Input, channel: Channel) -> Sig<impl SigT<Item = f32> + Send> {
77
let MonoVoice {
88
note,
99
key_down_gate,

interactive/examples/keyboard_and_mouse_polyphonic_interactive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use caw_interactive::{Input, Visualization, Window};
33
use caw_keyboard::{IntoNoteFreqHz, KeyEventsT, MonoVoice, Note};
44
use caw_modules::*;
55

6-
fn sig(input: Input, ch: Channel) -> Sig<impl SigT<Item = f32>> {
6+
fn sig(input: Input, ch: Channel) -> Sig<impl SigT<Item = f32> + Send> {
77
input
88
.clone()
99
.keyboard

keyboard/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "caw_keyboard"
3-
version = "0.2.3"
3+
version = "0.3.0"
44
description = "Abstract representation of a (musical) keyboard for the caw synthesizer framework"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -13,7 +13,7 @@ edition = "2021"
1313
web = ["getrandom/js"]
1414

1515
[dependencies]
16-
caw_core = { version = "0.3", path = "../core" }
16+
caw_core = { version = "0.4", path = "../core" }
1717
smallvec = ">=1.6.1,<2"
1818
log = "0.4"
1919
rand = "0.8"

0 commit comments

Comments
 (0)