-
Notifications
You must be signed in to change notification settings - Fork 34
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
Patching a signal to multiple inputs #30
Comments
Hi! You can express it by using a branch: let modulator = (sine_hz(1.0) + 1.0) * 0.5;
let synth = (saw_hz(100.0) | modulator >> (mul(3000.0) ^ mul(0.2))) >> moog(); In a generative spirit, a simple way to accomplish the same is a closure. However, in this case the deterministic pseudorandom phase system will assign different (random) initial phases for the two channels. // Do not use this unless it is okay that frequency and Q have different phases!
let modulator = || (sine_hz(1.0) + 1.0) * 0.5;
let synth = (saw_hz(100.0) | modulator() * 3000.0 | modulator() * 0.2) >> moog(); Envelopes are not influenced by the pseudorandom phase system. A multichannel envelope is also fairly convenient: let modulator = lfo(|t| {
let m = (sin_hz(1.0, t) + 1.0) * 0.5;
(m * 3000.0, m * 0.2)
});
let synth = (saw_hz(100.0) | modulator) >> moog(); As the modulator is consumed when used in an expression, it is not so simple to send it to different nodes altogether. I think duplicating the work by using a closure, maybe one that generates an envelope, is an okay way to get around this restriction: let modulator = || lfo(|t| (sin_hz(1.0, t) + 1.0) * 0.5);
let synth = (saw_hz(100.0) | modulator() * 3000.0 | modulator() * 0.2) >> moog(); |
Thanks for your answer! I guess my main problem with the closure approaches is that we would actually be computing the However, another question then pops to mind: would it be possible to "patch" the |
For two unrelated nodes, it's not possible - some mechanism is needed to coordinate the work done by the |
I could probably solve it like this: fn saw_moog(freq: f64, cutoff: f64, q: f64) -> An<impl AudioNode<Sample = f64, Inputs = U1, Outputs = U1>> {
(saw_hz(freq) | pass() >> (mul(cutoff) ^ mul(q))) >> moog()
}
let modulator = (sine_hz(1.0) + 1.0) * 0.5;
let node = modulator >> (saw_moog(100.0, 3000.0, 0.4 ) ^ saw_moog(200.0, 1000.0, 0.2)) >> join::<U2>(); which I think is actually a very elegant way of expressing a DSP graph |
That's a nice way of expressing it! The let node = modulator >> (saw_moog(100.0, 3000.0, 0.4) & saw_moog(200.0, 1000.0, 0.2)); |
This is even more elegant, thanks! I have one more question: is there a way to achieve single sample feedback circuits? I see that there are the
|
Something like this works (is it doing single sample feedback or block feedback?): dc(440.0) >> feedback(sine() * 100.0) * 0.01; Is there a way to get the output of the EDIT: I should read the docs a little better before posting, here's the solution: dc(440.0) >> feedback2(sine(), mul(100.0)); |
Hi there!
First of all: great work on this library! It's a real joy to use and it definitely pushes DSP development in Rust forward.
I'm sorry to open an issue for this, but I couldn't find an answer in the examples. How could I patch one signal to different inputs of a node (and, if possible, of different nodes)?
Of course Rust comes in by not allowing to use a moved value (
modulator
) on the second occurrence. I wonder: how would I express this using a morefundsp
syntax?The text was updated successfully, but these errors were encountered: