Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Bus system to replace naive Arc<Mutex<Buffer>> System #58

Merged
merged 32 commits into from
Jan 16, 2025
Merged
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2bdd62c
Add new channels and example "test" plugin (temp)
exa04 Nov 4, 2024
b8d1c05
Remove old `Arc<Mutex>`'d peak buffer from test
exa04 Nov 4, 2024
761b92e
Add `enqueue_latest` to visualizer buffer
exa04 Nov 5, 2024
0144bae
WIP
exa04 Nov 5, 2024
6985aab
Allow MPMC scenarios via `blinkcast`
exa04 Nov 7, 2024
efecb0c
Add oscilloscope to new example
exa04 Nov 8, 2024
47773e3
Implement new system for RMS buffer
exa04 Nov 11, 2024
7049973
Temporarily remove lots of stuff
exa04 Dec 15, 2024
2f296ed
Start work on "accumulators" system
exa04 Dec 15, 2024
c0c464b
Accumulators progress
exa04 Dec 17, 2024
0e2789c
Re-add meter
exa04 Dec 17, 2024
77bc328
Move inline macros to impl
exa04 Dec 17, 2024
56d5440
Re-add oscilloscope
exa04 Dec 18, 2024
2fad50f
Re-add histogram
exa04 Dec 21, 2024
e7c50ab
Add new benchmark
exa04 Dec 21, 2024
b3587b1
WIP bus
exa04 Jan 4, 2025
011df7d
Add dispatchers for Graph, Meter and Oscilloscope
exa04 Jan 4, 2025
cf7953a
Fix meter size issue
exa04 Jan 4, 2025
84801ff
Implement histogram
exa04 Jan 4, 2025
6ca9884
Add lissajous
exa04 Jan 5, 2025
6aca503
Re-introduce peak graph example
exa04 Jan 5, 2025
48c244d
Rename benchmark
exa04 Jan 6, 2025
715b414
Update oscilloscope on draw
exa04 Jan 7, 2025
6777182
Make visualizers take in an Arc<Bus> directly
exa04 Jan 14, 2025
7421974
Add `subscribe` function to busses
exa04 Jan 14, 2025
b8217f6
Remove `is_empty`
exa04 Jan 14, 2025
7bb836c
Documentation and some re-structuring
exa04 Jan 14, 2025
4e39067
fmt
exa04 Jan 14, 2025
086a067
Update readme
exa04 Jan 16, 2025
7637729
Update screenshots
exa04 Jan 16, 2025
0dacf03
Add spectrum to visualizers example
exa04 Jan 16, 2025
5b34978
Update README.md
exa04 Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Make visualizers take in an Arc<Bus> directly
exa04 committed Jan 14, 2025
commit 6777182f12147297e8e49d17f1743e849f809590
18 changes: 2 additions & 16 deletions examples/peak_graph/src/editor.rs
Original file line number Diff line number Diff line change
@@ -4,27 +4,13 @@ use nih_plug::editor::Editor;
use nih_plug_vizia::{assets, create_vizia_editor, vizia::prelude::*, ViziaState, ViziaTheming};
use std::sync::Arc;

#[derive(Lens, Clone)]
pub(crate) struct Data {
bus: Arc<MonoBus>,
}

impl Data {
pub(crate) fn new(bus: Arc<MonoBus>) -> Self {
Self { bus }
}
}

impl Model for Data {}

pub(crate) fn default_state() -> Arc<ViziaState> {
ViziaState::new(|| (800, 500))
}

pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option<Box<dyn Editor>> {
pub(crate) fn create(editor_state: Arc<ViziaState>, bus: Arc<MonoBus>) -> Option<Box<dyn Editor>> {
create_vizia_editor(editor_state, ViziaTheming::default(), move |cx, _| {
assets::register_noto_sans_light(cx);
editor_data.clone().build(cx);

HStack::new(cx, |cx| {
ZStack::new(cx, |cx| {
@@ -39,7 +25,7 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option

Graph::peak(
cx,
Data::bus,
bus.clone(),
10.0,
50.0,
(-32.0, 8.0),
5 changes: 1 addition & 4 deletions examples/peak_graph/src/lib.rs
Original file line number Diff line number Diff line change
@@ -63,10 +63,7 @@ impl Plugin for PeakGraphPlugin {
}

fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
editor::Data::new(self.bus.clone()),
self.params.editor_state.clone(),
)
editor::create(self.params.editor_state.clone(), self.bus.clone())
}

fn initialize(
39 changes: 14 additions & 25 deletions examples/visualizers/src/editor.rs
Original file line number Diff line number Diff line change
@@ -4,28 +4,17 @@ use nih_plug_vizia::widgets::ResizeHandle;
use nih_plug_vizia::{assets, create_vizia_editor, vizia::prelude::*, ViziaState, ViziaTheming};
use std::sync::Arc;

#[derive(Lens, Clone)]
pub(crate) struct Data {
bus: Arc<MonoBus>,
stereo_bus: Arc<StereoBus>,
}

impl Data {
pub(crate) fn new(bus: Arc<MonoBus>, stereo_bus: Arc<StereoBus>) -> Self {
Self { bus, stereo_bus }
}
}

impl Model for Data {}

pub(crate) fn default_state() -> Arc<ViziaState> {
ViziaState::new(|| (1200, 800))
}

pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option<Box<dyn Editor>> {
pub(crate) fn create(
bus: Arc<MonoBus>,
stereo_bus: Arc<StereoBus>,
editor_state: Arc<ViziaState>,
) -> Option<Box<dyn Editor>> {
create_vizia_editor(editor_state, ViziaTheming::default(), move |cx, _| {
assets::register_noto_sans_light(cx);
editor_data.clone().build(cx);
VStack::new(cx, |cx| {
HStack::new(cx, |cx| {
ZStack::new(cx, |cx| {
@@ -40,7 +29,7 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
.color(Color::rgb(30, 30, 30));
Graph::peak(
cx,
Data::bus,
bus.clone(),
10.0,
50.0,
(-32.0, 8.0),
@@ -50,14 +39,14 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
.background_color(Color::rgba(255, 255, 255, 30));
Graph::rms(
cx,
Data::bus,
bus.clone(),
10.0,
250.0,
(-32.0, 8.0),
ValueScaling::Decibels,
)
.color(Color::rgba(255, 92, 92, 128));
Histogram::new(cx, Data::bus, 250.0, (-32.0, 8.0), ValueScaling::Decibels)
Histogram::new(cx, bus.clone(), 250.0, (-32.0, 8.0), ValueScaling::Decibels)
.width(Pixels(64.0))
.color(Color::rgba(64, 128, 255, 64))
.background_color(Color::rgba(64, 128, 255, 32));
@@ -84,7 +73,7 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
ZStack::new(cx, |cx| {
Meter::rms(
cx,
Data::bus,
bus.clone(),
800.0,
(-32.0, 8.0),
ValueScaling::Decibels,
@@ -93,7 +82,7 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
.background_color(Color::rgba(255, 92, 92, 50));
Meter::peak(
cx,
Data::bus,
bus.clone(),
400.0,
(-32.0, 8.0),
ValueScaling::Decibels,
@@ -102,7 +91,7 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
.background_color(Color::rgba(255, 255, 255, 30));
Meter::peak(
cx,
Data::bus,
bus.clone(),
800.0,
(-32.0, 8.0),
ValueScaling::Decibels,
@@ -122,15 +111,15 @@ pub(crate) fn create(editor_data: Data, editor_state: Arc<ViziaState>) -> Option
LissajousGrid::new(cx)
.background_color(Color::rgb(16, 16, 16))
.color(Color::rgb(48, 48, 48));
Lissajous::new(cx, Data::stereo_bus, 2048)
Lissajous::new(cx, stereo_bus.clone(), 2048)
.color(Color::rgba(255, 255, 255, 40));
})
.width(Pixels(200.0))
.background_color(Color::rgb(16, 16, 16))
.border_width(Pixels(1.0))
.border_color(Color::rgb(48, 48, 48));
ZStack::new(cx, |cx| {
Oscilloscope::new(cx, Data::bus, 4.0, (-1.0, 1.0), ValueScaling::Linear)
VStack::new(cx, |cx| {
Oscilloscope::new(cx, bus.clone(), 4.0, (-1.0, 1.0), ValueScaling::Linear)
.color(Color::rgba(255, 255, 255, 120));
})
.background_color(Color::rgb(16, 16, 16))
3 changes: 2 additions & 1 deletion examples/visualizers/src/lib.rs
Original file line number Diff line number Diff line change
@@ -66,7 +66,8 @@ impl Plugin for VisualizersPlugin {

fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
editor::Data::new(self.bus.clone(), self.stereo_bus.clone()),
self.bus.clone(),
self.stereo_bus.clone(),
self.params.editor_state.clone(),
)
}
75 changes: 38 additions & 37 deletions src/bus/into_bus.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
// use core::slice;
// use std::sync::Arc;
use std::{iter::Map, sync::Arc};

// use super::*;
use super::*;

// #[derive(Clone)]
// pub struct IntoMonoBus<const C: usize, D>
// where
// for<'a> D: Fn([f32; C]) -> f32 + 'static + Copy + Clone,
// {
// pub(crate) bus: MultiChannelBus<C>,
// pub(crate) downmixer: D,
// }
#[derive(Clone)]
pub struct IntoMonoBus<const C: usize, D>
where
for<'a> D: Fn(&'a [f32; C]) -> &'a f32 + 'static + Copy + Clone + Send + Sync,
{
pub(crate) bus: MultiChannelBus<C>,
pub(crate) downmixer: D,
}

// impl<const C: usize, D> Bus<f32> for IntoMonoBus<C, D>
// where
// for<'a> D: Fn([f32; C]) -> f32 + 'static + Copy + Clone,
// {
// type I<'a> = slice::Iter<'a, f32>;
// type O<'a> = <MultiChannelBus<C> as Bus<[f32; C]>>::I<'a>;
impl<const C: usize, D> Bus<f32> for IntoMonoBus<C, D>
where
for<'a> D: Fn(&'a [f32; C]) -> &'a f32 + 'static + Copy + Clone + Send + Sync,
{
type I<'a> = Map<Self::O<'a>, D>;
type O<'a> = <MultiChannelBus<C> as Bus<[f32; C]>>::I<'a>;

// fn register_dispatcher<F: for<'a> Fn(Self::I<'a>) + Sync + Send + 'static>(
// &self,
// dispatcher: F,
// ) -> Arc<dyn for<'a> Fn(Self::O<'a>) + Sync + Send> {
// self.bus.register_dispatcher(move |samples| {
// let mono_samples = samples.map(|x| x.into_iter().sum::<f32>() / C as f32);
// })
// }
fn register_dispatcher<F: for<'a> Fn(Self::I<'a>) + Sync + Send + 'static>(
&self,
dispatcher: F,
) -> Arc<dyn for<'a> Fn(Self::O<'a>) + Sync + Send> {
let downmixer = self.downmixer.clone();
self.bus.register_dispatcher(move |samples| {
let mono_samples = samples.map(downmixer);
dispatcher(mono_samples);
})
}

// fn update(&self) {
// self.bus.update()
// }
fn update(&self) {
self.bus.update()
}

// #[inline]
// fn set_sample_rate(&self, sample_rate: f32) {
// self.bus.set_sample_rate(sample_rate)
// }
#[inline]
fn set_sample_rate(&self, sample_rate: f32) {
self.bus.set_sample_rate(sample_rate)
}

// #[inline]
// fn sample_rate(&self) -> f32 {
// self.bus.sample_rate()
// }
// }
#[inline]
fn sample_rate(&self) -> f32 {
self.bus.sample_rate()
}
}
55 changes: 31 additions & 24 deletions src/bus/multichannel.rs
Original file line number Diff line number Diff line change
@@ -46,38 +46,45 @@ impl<const C: usize> MultiChannelBus<C> {
}
}

nih_dbg!(&array);
self.send(array);
}
}

#[inline]
pub fn send(&self, value: [f32; C]) {
self.channel.0.try_send(value);
let _ = self.channel.0.try_send(value);
}

// pub fn into_mono<D>(self, downmixer: D) -> IntoMonoBus<C, D>
// where
// for<'a> D: Fn([f32; C]) -> f32 + 'static + Copy + Clone,
// {
// IntoMonoBus {
// bus: self,
// downmixer,
// }
// }

// pub fn into_mono_summing(
// self,
// ) -> IntoMonoBus<C, impl Fn([f32; C]) -> f32 + 'static + Copy + Clone> {
// self.into_mono(|sample| sample.into_iter().sum::<f32>() / C as f32)
// }

// pub fn into_mono_from_channel_index(
// self,
// channel: usize,
// ) -> IntoMonoBus<C, impl Fn([f32; C]) -> f32 + 'static + Copy + Clone> {
// self.into_mono(move |sample| sample[channel])
// }
pub fn into_mono<D>(&self, downmixer: D) -> Arc<IntoMonoBus<C, D>>
where
for<'a> D: Fn(&'a [f32; C]) -> &'a f32 + 'static + Copy + Clone + Send + Sync,
{
IntoMonoBus {
bus: self.clone(),
downmixer,
}
.into()
}

pub fn into_mono_summing(
&self,
) -> Arc<IntoMonoBus<C, impl Fn(&[f32; C]) -> &f32 + 'static + Copy + Clone + Send + Sync>>
{
fn downmixer<'a, const C: usize>(sample: &'a [f32; C]) -> &'a f32 {
&sample[0]
}
self.into_mono(downmixer::<C>)
}

pub fn into_mono_from_channel<const CI: usize>(
&self,
) -> Arc<IntoMonoBus<C, impl Fn(&[f32; C]) -> &f32 + 'static + Copy + Clone + Send + Sync>>
{
fn downmixer<'a, const C: usize, const CI: usize>(sample: &'a [f32; C]) -> &'a f32 {
&sample[CI]
}
self.into_mono(downmixer::<C, CI>)
}
}

impl<const C: usize> Bus<[f32; C]> for MultiChannelBus<C> {
Loading