Skip to content

Commit

Permalink
Use AtomicSynth
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed May 2, 2024
1 parent 78c26ee commit 494266e
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 28 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
winit = { version = "0.30", features = ["serde"] }
cpal = "0.15"
fundsp = { version = "0.17", default-features = false }
fundsp = { version = "0.17", default-features = false, git = "https://github.com/SamiPerttu/fundsp.git" }
clap = { version = "4.5", features = ["derive"] }
bitflags = "2.5"
log = "0.4"
Expand Down
7 changes: 5 additions & 2 deletions src/sound/apu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ impl APU {

self.synth.ch3_freq.set_value(65536.0 / (2048.0 - self.ch3.period as f64));
self.synth.ch3_vol.set_value(ch3_vol);
let ch3_wave_arc = Arc::clone(&self.synth.ch3_wave);
*ch3_wave_arc.write().unwrap() = ch3_wave;

for i in 0..ch3_wave.len() {
self.synth.ch3_wave.set(i, ch3_wave[i]);
}

self.synth.ch3_l.set_value(if self.panning.contains(Panning::CH3_LEFT) { 1.0 } else { 0.0 });
self.synth.ch3_r.set_value(if self.panning.contains(Panning::CH3_RIGHT) { 1.0 } else { 0.0 });

Expand Down
32 changes: 9 additions & 23 deletions src/sound/synth.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::sync::{Arc, RwLock};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{Device, FromSample, SizedSample, StreamConfig};
use fundsp::hacker::*;

pub type ChannelWave = Arc<RwLock<[f32; 32]>>;

pub struct Synth {
pub ch1_freq: Shared<f64>,
pub ch1_vol: Shared<f64>,
Expand All @@ -22,7 +20,7 @@ pub struct Synth {

pub ch3_freq: Shared<f64>,
pub ch3_vol: Shared<f64>,
pub ch3_wave: ChannelWave,
pub ch3_wave: Arc<AtomicTable>,
pub ch3_l: Shared<f64>,
pub ch3_r: Shared<f64>,

Expand Down Expand Up @@ -53,7 +51,7 @@ impl Synth {

let ch3_freq = shared(0.0);
let ch3_vol = shared(0.0);
let ch3_wave = Arc::new(RwLock::new([0.0; 32]));
let ch3_wave = Arc::new(AtomicTable::new(&[0.0; 32]));
let ch3_l = shared(0.0);
let ch3_r = shared(0.0);

Expand Down Expand Up @@ -191,7 +189,7 @@ impl Synth {
ch2_r: Shared<f64>,
ch3_freq: Shared<f64>,
ch3_vol: Shared<f64>,
ch3_wave: ChannelWave,
ch3_wave: Arc<AtomicTable>,
ch3_l: Shared<f64>,
ch3_r: Shared<f64>,
ch4_freq: Shared<f64>,
Expand All @@ -209,20 +207,15 @@ impl Synth {
let sample_rate = config.sample_rate.0 as f64;
let channels = config.channels as usize;

let mut ch3 = Net64::new(1, 1);
// Temporarily use a square to set up the network
// Square takes one input and gives one output
// This node will be replaced with the WaveSynth
let id_wavesynth = ch3.chain(Box::new(square()));

let ch1_mono = ((var(&ch1_freq) | var(&ch1_duty)) >> pulse())
* var(&ch1_vol)
* constant(0.25);
let ch2_mono = ((var(&ch2_freq) | var(&ch2_duty)) >> pulse())
* var(&ch2_vol)
* constant(0.25);

let ch3_mono = var(&ch3_freq) >> ch3 * var(&ch3_vol) * constant(0.25);
let ch3_synth = AtomicSynth::new(ch3_wave);
let ch3_mono = var(&ch3_freq) >> An(ch3_synth) * var(&ch3_vol) * constant(0.25);
let ch4_mono = var(&ch4_freq) >> square() * var(&ch4_vol) * constant(0.25);

let ch1_stereo = ch1_mono >> ((pass() * var(&ch1_l)) ^ (pass() * var(&ch1_r)));
Expand All @@ -232,11 +225,10 @@ impl Synth {

let total_stereo = ch1_stereo + ch2_stereo + ch3_stereo + ch4_stereo;

let mut net = total_stereo >> (pass() * var(&global_l) | pass() * var(&global_r));
net.set_sample_rate(sample_rate);
let mut c = total_stereo >> (pass() * var(&global_l) | pass() * var(&global_r));
c.set_sample_rate(sample_rate);

let mut backend = net.backend();
let mut next_value = move || backend.get_stereo();
let mut next_value = move || c.get_stereo();

let err_fn = |err| eprintln!("an error occurred on stream: {}", err);

Expand All @@ -254,12 +246,6 @@ impl Synth {

loop {
thread::sleep(Duration::from_millis(1000));

// TODO: Maybe dont use Box::leak
let ch3_wavetable: &'static Wavetable = Box::leak(Box::new(Wavetable::from_wave(20.0, 20_000.0, 1.0, &*ch3_wave.read().unwrap())));
let ch3_synth: An<WaveSynth<f64, U1>> = An(WaveSynth::new(sample_rate, &ch3_wavetable));
net.replace(id_wavesynth, Box::new(ch3_synth));
net.commit();
}
});
}
Expand Down

0 comments on commit 494266e

Please sign in to comment.