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

Update fundsp to 0.10 #22

Merged
merged 1 commit into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 1 addition & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ bevy_audio = ["bevy/bevy_audio", "bevy/wav", "rodio"]
oddio = ["bevy_oddio"]

[dependencies]
fundsp = "0.9"
fundsp = "0.10"
cpal = "0.14"
once_cell = "1.13"
rodio = { version = "0.16", default-features = false, features = ["wav"], optional = true }
kira = { version = "0.7", default-features = false, features = ["wav"], optional = true }
ringbuf = "0.3"
parking_lot = "0.12"

[dependencies.uuid]
version = "1.1"
Expand Down Expand Up @@ -101,8 +99,3 @@ required-features = ["oddio"]
name = "oddio_interactive"
path = "examples/oddio/interactive.rs"
required-features = ["oddio"]

[[example]]
name = "oddio_controlled"
path = "examples/oddio/controlled.rs"
required-features = ["oddio"]
52 changes: 0 additions & 52 deletions examples/oddio/controlled.rs

This file was deleted.

16 changes: 12 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
set windows-powershell := true

default: ci

ci: check-fmt clippy test-all

test-all:
cargo test
-cargo test --no-default-features --features bevy_audio
-cargo test --no-default-features --features kira
-cargo test --no-default-features --features oddio
cargo test --no-default-features --features bevy_audio
cargo test --no-default-features --features kira
cargo test --no-default-features --features oddio

check-fmt:
cargo fmt --all -- --check

clippy:
cargo clippy
cargo clippy
cargo clippy --no-default-features --features bevy_audio
cargo clippy --no-default-features --features kira
cargo clippy --no-default-features --features oddio

example feature example:
cargo run --example {{example}} --no-default-features --features {{feature}} --release
20 changes: 2 additions & 18 deletions src/backend/oddio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use std::{cell::RefCell, rc::Rc};
use bevy::prelude::{App, Assets, Handle};
use bevy_oddio::{
frames::{FromFrame, Stereo},
oddio::{Controlled, Frame, Frames, Signal},
oddio::{Frame, Frames, Signal},
output::AudioSink,
Audio, AudioApp, AudioSource, ToSignal,
};

use crate::dsp_source::{DspControl, DspSource, Iter, IterMono, Source, SourceType};
use crate::dsp_source::{DspSource, Iter, Source, SourceType};

use super::{Backend, DspAudioExt};

Expand Down Expand Up @@ -164,19 +164,3 @@ impl DspAudioExt for Audio<Stereo, DspSource> {
self.play(source_handle, settings)
}
}

unsafe impl<'a> Controlled<'a> for Iter {
type Control = DspControl;

unsafe fn make_control(signal: &'a Self) -> Self::Control {
DspControl::new(signal.sender.clone())
}
}

unsafe impl<'a> Controlled<'a> for IterMono {
type Control = DspControl;

unsafe fn make_control(signal: &'a Self) -> Self::Control {
Iter::make_control(&signal.0)
}
}
73 changes: 7 additions & 66 deletions src/dsp_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@

use crate::dsp_graph::DspGraph;
use bevy::reflect::TypeUuid;
use fundsp::{hacker32::AudioUnit32, prelude::Tag, wave::Wave32};
use parking_lot::Mutex;
use ringbuf::{Consumer, HeapRb, Producer};
use fundsp::{hacker32::AudioUnit32, wave::Wave32};
use std::{cell::RefCell, sync::Arc};

type SetTag = (Tag, f64);

/// A DSP source similar to `AudioSource` in `bevy_audio`.
///
/// These can be played directly when the [`SourceType`] is dynamic,
Expand Down Expand Up @@ -93,13 +89,9 @@ impl IntoIterator for DspSource {
type IntoIter = Iter;

fn into_iter(self) -> Self::IntoIter {
let (sender, receiver) = HeapRb::new(64).split();

Iter {
sample_rate: self.sample_rate,
audio_unit: RefCell::new(self.dsp_graph.generate_graph()),
sender: Arc::new(Mutex::new(sender)),
receiver: RefCell::new(receiver),
}
}
}
Expand All @@ -111,8 +103,6 @@ impl IntoIterator for DspSource {
pub struct Iter {
pub(crate) sample_rate: f32,
pub(crate) audio_unit: RefCell<Box<dyn AudioUnit32>>,
pub(crate) sender: Arc<Mutex<Producer<SetTag, Arc<HeapRb<SetTag>>>>>,
pub(crate) receiver: RefCell<Consumer<SetTag, Arc<HeapRb<SetTag>>>>,
}

pub(crate) trait Source {
Expand Down Expand Up @@ -145,9 +135,6 @@ impl Source for Iter {
}

fn sample(&self) -> Self::Frame {
while let Some((parameter, value)) = self.receiver.borrow_mut().pop() {
self.audio_unit.borrow_mut().set(parameter, value);
}
let frame = self.audio_unit.borrow_mut().get_stereo();
[frame.0, frame.1]
}
Expand Down Expand Up @@ -175,9 +162,6 @@ impl Source for IterMono {
}

fn sample(&self) -> f32 {
while let Some((parameter, value)) = self.0.receiver.borrow_mut().pop() {
self.0.audio_unit.borrow_mut().set(parameter, value);
}
self.0.audio_unit.borrow_mut().get_mono()
}
}
Expand All @@ -190,55 +174,11 @@ impl Iterator for IterMono {
}
}

/// Handle for controlling playing DSP sources.
///
/// Generally, this is used to get or set the tags of a FunDSP graph.
pub struct DspControl {
sender: Arc<Mutex<Producer<SetTag, Arc<HeapRb<SetTag>>>>>,
}

impl DspControl {
pub(crate) fn new(sender: Arc<Mutex<Producer<SetTag, Arc<HeapRb<SetTag>>>>>) -> Self {
Self { sender }
}

/// Set the tag to the given value.
///
/// See more documentation in [AudioUnit32::set].
///
/// [AudioUnit32::set]: fundsp::audiounit::AudioUnit32::set
pub fn set(&self, tag: Tag, value: f64) {
while self.sender.lock().push((tag, value)).is_err() {}
}
}

pub(crate) trait Controllable {
type Control;

fn control(&self) -> Self::Control;
}

impl Controllable for Iter {
type Control = DspControl;

fn control(&self) -> Self::Control {
DspControl::new(self.sender.clone())
}
}

impl Controllable for IterMono {
type Control = DspControl;

fn control(&self) -> Self::Control {
self.0.control()
}
}

#[cfg(test)]
mod tests {
#![allow(clippy::wildcard_imports)]

use crate::{dsp_source::Controllable, DEFAULT_SAMPLE_RATE};
use crate::DEFAULT_SAMPLE_RATE;

use super::{DspSource, SourceType};
use fundsp::hacker32::*;
Expand Down Expand Up @@ -281,9 +221,10 @@ mod tests {

#[test]
fn constant_controllable() {
const FREQ_ID: Tag = 0;
let frequency = shared(440.0);
let sine_wave_frequency = frequency.clone();

let sine_wave = || tag(FREQ_ID, 440.0);
let sine_wave = move || var(&sine_wave_frequency);

let source = DspSource::new(sine_wave, *DEFAULT_SAMPLE_RATE, SourceType::Dynamic);

Expand All @@ -293,7 +234,7 @@ mod tests {
assert_eq!(iter.next(), Some([440.0, 440.0]));
assert_eq!(iter.next(), Some([440.0, 440.0]));

iter.control().set(FREQ_ID, 880.0);
frequency.set_value(880.0);

assert_eq!(iter.next(), Some([880.0, 880.0]));
assert_eq!(iter.next(), Some([880.0, 880.0]));
Expand All @@ -305,7 +246,7 @@ mod tests {
assert_eq!(iter.next(), Some(880.0));
assert_eq!(iter.next(), Some(880.0));

iter.control().set(FREQ_ID, 440.0);
frequency.set_value(440.0);

assert_eq!(iter.next(), Some(440.0));
assert_eq!(iter.next(), Some(440.0));
Expand Down