Skip to content

Commit 388d739

Browse files
committed
Allow visualization options for owned player
1 parent b651d7c commit 388d739

File tree

4 files changed

+81
-25
lines changed

4 files changed

+81
-25
lines changed

caw/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"
3-
version = "0.6.0"
3+
version = "0.7.0"
44
description = "A framework for building software-defined modular synthesizers"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"
@@ -26,13 +26,13 @@ caw_modules = { version = "0.3", path = "../modules" }
2626
caw_patches = { version = "0.3", path = "../patches" }
2727
caw_utils = { version = "0.3", path = "../utils" }
2828
caw_builder_proc_macros = { version = "0.1", path = "../builder-proc-macros" }
29-
caw_player = { version = "0.5", path = "../player", optional = true }
29+
caw_player = { version = "0.6", path = "../player", optional = true }
3030
caw_midi = { version = "0.3", path = "../midi", optional = true }
3131
caw_midi_live = { version = "0.3", path = "../midi-live", optional = true }
3232
caw_midi_file = { version = "0.3", path = "../midi-file", optional = true }
3333
caw_midi_serial = { version = "0.3", path = "../midi-serial", optional = true }
3434
caw_audio_file = { version = "0.3", path = "../audio-file", optional = true }
35-
caw_interactive = { version = "0.5", path = "../interactive", optional = true }
35+
caw_interactive = { version = "0.6", path = "../interactive", optional = true }
3636

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

interactive/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_interactive"
3-
version = "0.5.0"
3+
version = "0.6.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,7 +11,7 @@ edition = "2021"
1111

1212
[dependencies]
1313
anyhow = "1.0"
14-
caw_player = { version = "0.5", path = "../player" }
14+
caw_player = { version = "0.6", path = "../player" }
1515
caw_core = { version = "0.4", path = "../core" }
1616
caw_computer_keyboard = { version = "0.3", path = "../computer-keyboard" }
1717
line_2d = "0.5"

player/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_player"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
description = "Play audio from the caw synthesizer framework"
55
authors = ["Stephen Sherratt <[email protected]>"]
66
license = "MIT"

player/src/lib.rs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ impl Default for ConfigSync {
3939
}
4040
}
4141

42+
#[derive(Debug, Clone, Copy)]
43+
pub enum VisualizationDataPolicy {
44+
LatestOnly,
45+
All,
46+
}
47+
48+
#[derive(Debug, Clone, Copy)]
49+
pub struct ConfigOwned {
50+
/// default: 0.01
51+
pub system_latency_s: f32,
52+
pub visualization_data_policy: Option<VisualizationDataPolicy>,
53+
}
54+
55+
impl Default for ConfigOwned {
56+
fn default() -> Self {
57+
Self {
58+
system_latency_s: 0.01,
59+
visualization_data_policy: None,
60+
}
61+
}
62+
}
63+
4264
pub struct Player {
4365
device: Device,
4466
}
@@ -481,7 +503,7 @@ impl Player {
481503
pub fn into_owned_stereo<SL, SR>(
482504
self,
483505
mut sig: Stereo<SL, SR>,
484-
config: ConfigSync,
506+
config: ConfigOwned,
485507
) -> anyhow::Result<PlayerOwned>
486508
where
487509
SL: SigSampleIntoBufT<Item = f32> + Send + Sync + 'static,
@@ -497,10 +519,10 @@ impl Player {
497519
num_samples: 0,
498520
};
499521
let channels = stream_config.channels;
500-
let data_copy = Arc::new(RwLock::new(Vec::new()));
522+
let data_for_visualization = Arc::new(RwLock::new(Vec::new()));
501523
assert!(channels >= 2);
502524
let stream = {
503-
let data_copy = Arc::clone(&data_copy);
525+
let data_for_visualization = Arc::clone(&data_for_visualization);
504526
self.device.build_output_stream(
505527
&stream_config,
506528
move |data: &mut [f32], _: &OutputCallbackInfo| {
@@ -518,11 +540,20 @@ impl Player {
518540
1,
519541
data,
520542
);
521-
{
522-
// copy the data out so it can be visualized
523-
let mut data_copy = data_copy.write().unwrap();
524-
data_copy.resize(data.len(), 0.0);
525-
data_copy.copy_from_slice(data);
543+
// copy the data out so it can be visualized
544+
match config.visualization_data_policy {
545+
None => (),
546+
Some(VisualizationDataPolicy::LatestOnly) => {
547+
let mut data_for_visualization =
548+
data_for_visualization.write().unwrap();
549+
data_for_visualization.resize(data.len(), 0.0);
550+
data_for_visualization.copy_from_slice(data);
551+
}
552+
Some(VisualizationDataPolicy::All) => {
553+
let mut data_for_visualization =
554+
data_for_visualization.write().unwrap();
555+
data_for_visualization.extend_from_slice(data);
556+
}
526557
}
527558
},
528559
|err| eprintln!("stream error: {}", err),
@@ -532,14 +563,14 @@ impl Player {
532563
stream.play()?;
533564
Ok(PlayerOwned {
534565
stream,
535-
data: data_copy,
566+
data_for_visualization,
536567
})
537568
}
538569

539570
pub fn into_owned_mono<S>(
540571
self,
541572
mut sig: S,
542-
config: ConfigSync,
573+
config: ConfigOwned,
543574
) -> anyhow::Result<PlayerOwned>
544575
where
545576
S: SigSampleIntoBufT<Item = f32> + Send + Sync + 'static,
@@ -554,24 +585,39 @@ impl Player {
554585
num_samples: 0,
555586
};
556587
let channels = stream_config.channels;
557-
let data_copy = Arc::new(RwLock::new(Vec::new()));
588+
let mut data_tmp = Vec::new();
589+
let data_for_visualization = Arc::new(RwLock::new(Vec::new()));
558590
let stream = {
559-
let data_copy = Arc::clone(&data_copy);
591+
let data_for_visualization = Arc::clone(&data_for_visualization);
560592
self.device.build_output_stream(
561593
&stream_config,
562594
move |data: &mut [f32], _: &OutputCallbackInfo| {
563595
ctx.batch_index += 1;
564596
ctx.num_samples = data.len() / channels as usize;
565-
let mut data_copy = data_copy.write().unwrap();
566-
sig.sample_into_buf(&ctx, &mut data_copy);
597+
sig.sample_into_buf(&ctx, &mut data_tmp);
567598
for (chunks, sample) in data
568599
.chunks_exact_mut(channels as usize)
569-
.zip(data_copy.iter())
600+
.zip(data_tmp.iter())
570601
{
571602
for out in chunks {
572603
*out = *sample;
573604
}
574605
}
606+
// copy the data out so it can be visualized
607+
match config.visualization_data_policy {
608+
None => (),
609+
Some(VisualizationDataPolicy::LatestOnly) => {
610+
let mut data_for_visualization =
611+
data_for_visualization.write().unwrap();
612+
data_for_visualization.resize(data_tmp.len(), 0.0);
613+
data_for_visualization.copy_from_slice(&data_tmp);
614+
}
615+
Some(VisualizationDataPolicy::All) => {
616+
let mut data_for_visualization =
617+
data_for_visualization.write().unwrap();
618+
data_for_visualization.extend_from_slice(&data_tmp);
619+
}
620+
}
575621
},
576622
|err| eprintln!("stream error: {}", err),
577623
None,
@@ -580,23 +626,33 @@ impl Player {
580626
stream.play()?;
581627
Ok(PlayerOwned {
582628
stream,
583-
data: data_copy,
629+
data_for_visualization,
584630
})
585631
}
586632
}
587633

588634
pub struct PlayerOwned {
589635
#[allow(unused)]
590636
stream: Stream,
591-
data: Arc<RwLock<Vec<f32>>>,
637+
data_for_visualization: Arc<RwLock<Vec<f32>>>,
592638
}
593639

594640
impl PlayerOwned {
595-
pub fn with_latest_data<F>(&self, mut f: F)
641+
pub fn with_visualization_data<F>(&self, mut f: F)
642+
where
643+
F: FnMut(&[f32]),
644+
{
645+
f(&self.data_for_visualization.read().unwrap());
646+
}
647+
648+
pub fn with_visualization_data_and_clear<F>(&self, mut f: F)
596649
where
597650
F: FnMut(&[f32]),
598651
{
599-
f(&self.data.read().unwrap());
652+
let mut data_for_visualization =
653+
self.data_for_visualization.write().unwrap();
654+
f(&data_for_visualization);
655+
data_for_visualization.clear();
600656
}
601657
}
602658

0 commit comments

Comments
 (0)