lichen-community-systems / Flocking

Flocking - Creative audio synthesis for the Web
GNU General Public License v2.0
697 stars 60 forks source link

Changing ugens on the fly #128

Closed SelStefan closed 8 years ago

SelStefan commented 8 years ago

Sorry for the newbie questions, but how can you switch a synth while it is running?

colinbdclark commented 8 years ago

Switch a synth in what way? Can you elaborate a bit more?

SelStefan commented 8 years ago

Well what I have litteraly tried is this:

var synth = flock.synth({
    synthDef: {
        id: "carrier",
        ugen: "flock.ugen.sinOsc",
        freq: 440,
        mul: 0.25
    }
});

synth.set("carrier.ugen", "flock.ugen.tri");

I know that was stupid wrong, but I hope you understand what I am trying to accomplish.

Like you're able to flip a switch from a sine wave to a saw wave form in the middle of a decay phase of an ADSR envelope on an analog device.

colinbdclark commented 8 years ago

That wasn't stupid wrong at all! Your code is very close to the real deal. You just need to specify the full unit generator definition in your call to set(), not just the unit generator name itself.

synth.set("carrier", {
    ugen: "flock.ugen.triOsc",
    freq: 440,
    mul: 0.25
});

Unfortunately, the way this works currently means you need to repeat all the basic inputs, like its frequency and its amplitude. That's something I will try to address in the 0.3.0 release.

As an alternative (and more complex) approach, you could also model your analog-style synthesizer as a series of self-contained modules, each of which are synths. You can use Flocking's interconnect buses to wire each of these synth modules together, and you can even do interesting things like modulate the bus input of the flock.ugen.in and flock.ugen.out ugens on the fly. Flocking 0.3.0 will also support much more complex and easier wiring of unit generators without the need for buses, but for now, interconnect buses give you an easy way to manage this kind of modularity.

Here's a dorky example where I've got two different "oscillator synths"(bandlimited saw and square waves), which are outputting to two interconnect buses using flock.ugen.out. Then there's another synth that contains the envelope, and which reads from the interconnect bus using flock.ugen.in. In this case, I'm modulating the value of the input bus using a sequence unit generator.

var sawBus = flock.enviro.shared.acquireNextBus("interconnect"),
    squareBus = flock.enviro.shared.acquireNextBus("interconnect");

var saw = flock.synth({
    synthDef: {
        ugen: "flock.ugen.out",
        bus: sawBus,
        expand: 1,
        sources: {
            id: "carrier",
            ugen: "flock.ugen.saw",
            freq: 220,
            mul: 0.25
       }
    }
});

var square = flock.synth({
    synthDef: {
        ugen: "flock.ugen.out",
        bus: squareBus,
        expand: 1,
        sources: {
            id: "carrier",
            ugen: "flock.ugen.square",
            freq: 220,
            mul: 0.25
        }
    }
});

var env = flock.synth({
    synthDef: {
        id: "envelopeIn",
        ugen: "flock.ugen.in",
        bus: {
            ugen: "flock.ugen.sequence",
            list: [sawBus, squareBus],
            loop: 1,
            freq: 3
        },
        mul: {
            ugen: "flock.ugen.asr",
            gate: {
                ugen: "flock.ugen.mouse.click"
            }
        }
    }
});

Hopefully one of these strategies should work for you. The first case (just directly modifying a synth's unit generator graph) is simple and works when you want to change the sound of a synth based on user input (such as clicking a button), while the second lets you modulate these kinds of changes using audio signals.

Let me know how it goes!

SelStefan commented 8 years ago

Sorry for the delayed response. The bus strategy worked perfectly well and I have found it rather intuitive since it takes the SuperCollider approach(although my knowledge in it is pretty much limited). Also since you have mentioned a new (more direct?) way to address these kinds of problems, I am super excited to see how you will tackle it. To tell you right away, I am making a small web synthesizer utilizing your framework, and with your help it has been pure gold so far. :) Will be posting if I run into any more issues, closing this off for now. cya!

colinbdclark commented 8 years ago

Sounds awesome! I'm glad Flocking been helpful and the lack of documentation hasn't been too painful. Feel free to continue to ask questions here or on the mailing list if anything comes up.