Comments (7)
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();
from fundsp.
Thanks for your answer!
I guess my main problem with the closure approaches is that we would actually be computing the modulator()
sample twice, when only one sine
would be sufficient. So, for this case, I would probably use your first example.
However, another question then pops to mind: would it be possible to "patch" the modulator
to the inputs of two unrelated nodes?
from fundsp.
For two unrelated nodes, it's not possible - some mechanism is needed to coordinate the work done by the modulator
in computing samples.
from fundsp.
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
from fundsp.
That's a nice way of expressing it! The join
in the last line averages together the channels. If it's okay to sum instead, then it can be simplified a bit by using the bus operator:
let node = modulator >> (saw_moog(100.0, 3000.0, 0.4) & saw_moog(200.0, 1000.0, 0.2));
from fundsp.
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 feedback
and tick
operators, but how would I feed the output of the feedback back to, for example, the frequency of the oscillator?
sine(440) ---> feedback ---> * 100
^ |
| |
------------------------------
from fundsp.
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 sine()
instead of the feedback
? This way I wouldn't have to scale the amplitude down.
EDIT:
I should read the docs a little better before posting, here's the solution:
dc(440.0) >> feedback2(sine(), mul(100.0));
from fundsp.
Related Issues (15)
- the beep example is not working for windows 10 HOT 3
- Tags and Tagged example request HOT 1
- Provide `hacker` in 32-bit "mode" HOT 3
- option to increase buffer size HOT 2
- ADSR Envelope HOT 3
- Tags on crates.io HOT 1
- Unwanted noise when mixing HOT 2
- cargo run --example sequence ... could not compile `fundsp` due to previous error HOT 2
- Architecture for mixing multiple Waves HOT 2
- Load wave from bytes HOT 3
- Asymmetric Bell Filter at Lower Frequencies HOT 1
- Feature request: Time Stretching HOT 1
- Replacing a node in a network resets its sample rate HOT 1
- Unintuitive adsr behaviour
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fundsp.