TonicAudio / Tonic

Easy and efficient audio synthesis in C++
The Unlicense
523 stars 63 forks source link

Multiple outputs from a single ControlGenerator (or Generator?) #184

Open Dewb opened 11 years ago

Dewb commented 11 years ago

Use cases:

morganpackard commented 11 years ago

Couldn't this be achieved with a simple getter method that returns a generator or controlgenerator? Not sure we need to make any core changes to enable this.

Sent from my iPhone

On Jun 12, 2013, at 2:04 PM, Michael Dewberry notifications@github.com wrote:

Use cases:

— Reply to this email directly or view it on GitHubhttps://github.com/TonicAudio/Tonic/issues/184 .

ndonald2 commented 11 years ago

Yep, I think if a generator is responsible for ticking/updating its sub-generator outputs, then you can just use a getter to pass it along to another input:

// Trigger an envelope when another one finishes
// ADSR::finished() returns a ControlGenerator that is triggered when envelope is done
ADSR env1 = ADSR(0.001, 0.5, 0.0, 0.01).trigger(someTrigger);
ADSR env2 = ADSR(0.001, 0.5, 0.0, 0.01).trigger(env1.finished());
ndonald2 commented 11 years ago

@dewb for that envelope example if you're up for trying that out, go for it. I would say that the "finished()" output should be a ControlTrigger that goes true when the envelope finishes.

Dewb commented 11 years ago

Yeah, that would work, I'll give it a shot. Similarly, a Klee-style sequencer could have .pitchA(), .pitchB(), .gate1(), .gate2() control generator methods.

Dewb commented 11 years ago

Is this the strategy you mentioned in #178? Wasn't sure if you had something more elaborate in mind.

ndonald2 commented 11 years ago

Yeah, that's it.

Re: the sequencer idea - I think in that case it might be worth it to make another base class for Tonic objects that manage a series of explicit generator outputs, but don't produce output themselves. Otherwise, there is no compile-time check to prevent someone from trying to use that object as a generator directly, which doesn't make sense.

The sequencer could also be made more generic by initializing it with a desired number of steps, and getting each output by passing in the index, so gate(1) gate(2) rather than gate1(), gate2()

Dewb commented 9 years ago

@morganpackard I see you just added a finishedTrigger to BufferPlayer; looks like I could follow your example to add the same feature to ADSR, if you weren't already planning on doing that.

morganpackard commented 9 years ago

Hold off on that. I have that in a commit that I'll be merging in to dev soon.

Dewb commented 9 years ago

Cool, I suspected as much. Thanks!