From 97e2d89e6193f09d6a3ca85598d694a2a9301b12 Mon Sep 17 00:00:00 2001 From: Vasilii Milovidov Date: Thu, 21 Sep 2023 04:32:31 +0400 Subject: [PATCH] implementing delay --- packages/desktopbridge/webaudiobridge.mjs | 3 +- src-tauri/src/superdough.rs | 57 +++++++++++++++++++---- src-tauri/src/webaudiobridge.rs | 8 +++- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/packages/desktopbridge/webaudiobridge.mjs b/packages/desktopbridge/webaudiobridge.mjs index 87e060a48..fd5724a4a 100644 --- a/packages/desktopbridge/webaudiobridge.mjs +++ b/packages/desktopbridge/webaudiobridge.mjs @@ -85,7 +85,7 @@ export const desktopAudio = async (value, deadline, hapDuration) => { const packages = { loop: [loop, loopBegin, loopEnd], - delay: [delay, delayfeedback, delaytime], + delay: [delay, delaytime, delayfeedback], lpf: [cutoff, resonance], hpf: [hcutoff, hresonance], bpf: [bandf, bandq], @@ -110,6 +110,7 @@ export const desktopAudio = async (value, deadline, hapDuration) => { duration: hapDuration, velocity: velocity, delay: packages.delay, + orbit: orbit, speed: speed, begin: begin, end: end, diff --git a/src-tauri/src/superdough.rs b/src-tauri/src/superdough.rs index 56d6d7659..4259cde34 100644 --- a/src-tauri/src/superdough.rs +++ b/src-tauri/src/superdough.rs @@ -1,14 +1,14 @@ use std::fs::File; use web_audio_api::context::{AudioContext, BaseAudioContext}; -use web_audio_api::node::{AudioBufferSourceNode, AudioNode, AudioScheduledSourceNode, BiquadFilterNode, BiquadFilterType, GainNode, OscillatorNode, OscillatorType}; +use web_audio_api::node::{AudioBufferSourceNode, AudioNode, AudioScheduledSourceNode, BiquadFilterNode, BiquadFilterType, DelayNode, GainNode, OscillatorNode, OscillatorType}; use web_audio_api::node::BiquadFilterType::{Bandpass, Highpass, Lowpass}; use crate::webaudiobridge::WebAudioMessage; #[derive(Clone, Copy, Debug)] pub struct Delay { - pub wet: f64, - pub delay_time: f64, - pub feedback: f64, + pub wet: f32, + pub delay_time: f32, + pub feedback: f32, } #[derive(Clone, Copy, Debug)] @@ -57,6 +57,7 @@ pub struct FilterADSR { pub fn superdough(message: &WebAudioMessage, context: &mut AudioContext) { let now = context.current_time(); let mut chain: Vec<&dyn AudioNode> = Vec::new(); + let env = context.create_gain(); // Play synth or sample match message.waveform.as_str() { @@ -69,12 +70,46 @@ pub fn superdough(message: &WebAudioMessage, context: &mut AudioContext) { for f in &filters { chain.push(f); } - let env = context.create_gain(); chain.push(&env); + let mut delays = Vec::new(); + for _ in 0..=message.orbit { + delays.push(context.create_delay(1.)); + } + + if message.delay.wet > 0.0 { + let output = context.create_gain(); + output.connect(&context.destination()); + + let delay = delays.get(message.orbit).unwrap(); + delay.delay_time().set_value(message.delay.delay_time); + delay.connect(&output); + + let feedback = context.create_gain(); + feedback.gain().set_value(message.delay.feedback); + feedback.connect(delay); + delay.connect(&feedback); + + let pre_gain = context.create_gain(); + pre_gain.gain().set_value(message.delay.wet); + pre_gain.connect(&feedback); + + let input = context.create_gain(); + input.connect(&pre_gain); + input.connect(&context.destination()); // direct sound + env.connect(&input); + } + // Connect nodes and play synth connect_nodes(chain, context); - play_synth(&message, now, osc, filters, &env); + let osc= play_synth(&message, now, osc, filters, &env); + + osc.set_onended(move |_| { + for d in &delays { + d.disconnect(); + } + }); + } _ => { match File::open(format!("samples/{}/{}.wav", message.bank, message.waveform)) { @@ -104,7 +139,7 @@ pub fn superdough(message: &WebAudioMessage, context: &mut AudioContext) { } } -fn play_synth(message: &&WebAudioMessage, now: f64, osc: OscillatorNode, filters: Vec ,env: &GainNode) { +fn play_synth(message: &&WebAudioMessage, now: f64, osc: OscillatorNode, filters: Vec, env: &GainNode) -> OscillatorNode { osc.set_type(create_osc_type(&message)); osc.frequency().set_value(message.note); osc.start(); @@ -116,6 +151,8 @@ fn play_synth(message: &&WebAudioMessage, now: f64, osc: OscillatorNode, filters apply_filter_adsr(&f, message, &f.type_(), now); } osc.stop_at(now + message.duration + message.adsr.release); + + osc } fn create_osc_type(message: &WebAudioMessage) -> OscillatorType { @@ -251,8 +288,8 @@ fn apply_adsr( sustain * message.velocity, now + attack + decay, ) - .set_value_at_time(sustain * message.velocity, now + message.duration) - .linear_ramp_to_value_at_time(0.0, now + message.duration + release); + .set_value_at_time(sustain * message.velocity, now + attack + decay) + .linear_ramp_to_value_at_time(0.0, now + attack + decay + release); } fn apply_synth_adsr(envelope: &GainNode, message: &WebAudioMessage, now: f64) { @@ -268,7 +305,7 @@ fn apply_synth_adsr(envelope: &GainNode, message: &WebAudioMessage, now: f64) { } fn apply_default_synth_adsr(envelope: &GainNode, message: &WebAudioMessage, now: f64) { - apply_adsr(envelope, message, now, 0.001, message.velocity, 0.05, 0.001); + apply_adsr(envelope, message, now, 0.001, message.velocity, 0.5, 0.1); } fn apply_drum_adsr(envelope: &GainNode, message: &WebAudioMessage, now: f64) { diff --git a/src-tauri/src/webaudiobridge.rs b/src-tauri/src/webaudiobridge.rs index 2b3ed19d9..02d0d0183 100644 --- a/src-tauri/src/webaudiobridge.rs +++ b/src-tauri/src/webaudiobridge.rs @@ -12,6 +12,7 @@ use web_audio_api::{ context::{AudioContext, AudioContextLatencyCategory, AudioContextOptions}, node::AudioNode }; +use web_audio_api::context::BaseAudioContext; use crate::superdough::{ADSR, BPF, Delay, FilterADSR, HPF, Loop, LPF, superdough}; @@ -28,6 +29,7 @@ pub struct WebAudioMessage { pub duration: f64, pub velocity: f32, pub delay: Delay, + pub orbit: usize, pub speed: f32, pub begin: f64, pub end: f64, @@ -92,7 +94,7 @@ pub fn init( return true; }; - superdough(message.clone(), &mut audio_context); + superdough(message.clone(), &mut audio_context); return false; }); @@ -123,7 +125,8 @@ pub struct MessageFromJS { bpf: (f32, f32), duration: f64, velocity: f32, - delay: (f64, f64, f64), + delay: (f32, f32, f32), + orbit: usize, speed: f32, begin: f64, end: f64, @@ -169,6 +172,7 @@ pub async fn sendwebaudio( delay_time: m.delay.1, feedback: m.delay.2, }, + orbit: m.orbit, speed: m.speed, begin: m.begin, end: m.end,