Thanks for all the responses!
Gregory - the setup you describe is somewhat similar to how my envelope is set up - all I am really doing with my "decay()", etc. functions is changing the increment/direction of the amplitude and reseting a counter....but I can see how putting it all in one function might clear up the problem. Though part of the problem is what happens when "release()" is called while the envelope is still in the "attack" phase.
It sounds like both Morgan and Mark are talking about the same type of solution, and though I haven't had a chance to dig in to that link and see how that works, it seems promising (and daunting!).
Morgan, if you are willing to share a simple example of what that looks like, I would be grateful. What exactly goes into the queue? Function pointers?
Thanks again, Ben
On Jan 30, 2012, at 2:39 PM, Gregory Wieber wrote: Yeesh. Sorry, Case 0 (attacking)
On Mon, Jan 30, 2012 at 2:38 PM, Gregory Wieber <email@hidden> wrote:
And, yep, typo:
That Case statement would obviously be "Case 1"
On Mon, Jan 30, 2012 at 2:37 PM, Gregory Wieber <email@hidden> wrote:
Perhaps instead of having attack and decay as functions, maybe you could do your ADSR using a switch/case statement that uses an integer to indicate which portion of the envelope you're in, and a sampleCount that is incremented and causes the envelope to go into the next boundary when the right number of samples have elapsed.
Eg, (I wrote this hastily, meant to be taken as pseudo code)
int ADSRIndex = 0; // attacking
...
nextBoundary = SAMPLE_RATE * attackInSeconds;
...
switch (ADSRIndex) { case: { if (++sampleCount > nextBoundary)
{ ADSRIndex+= 1; // now its decaying } else amplitude+= amplitudeIncrement; }
... etc
}
On Mon, Jan 30, 2012 at 1:30 PM, ben kamen <email@hidden> wrote:
Hello,
I have an iOS synth app and I am running into a problem that I think needs to be resolved through thread management or through some sort of locking system.
I have an envelope generator, a c++ object, to which I call "attack()" "decay()" from an audio controller object. The envelope objects calls "decay()" and "sustain()" to itself within the render loop at appropriate times.
I've noticed that the "attack()" and "release()" functions get called on different threads than the "sustain()" and "decay()" functions, which sometimes (though not terribly often) results in the messages occuring out of order, and causes notes to get stuck on.
After some research my thinking is that I need a way to ensure that the audio controller only can call "attack()" or "release()" between render callbacks, or even better, in between processing each frame. Is there a design pattern or preferred method that can help me ensure that that will happen? A code example would be incredibly helpful.
I realize this could also be a DSP question, but I'm pretty sure that is not my issue here. I'm interested in knowing what the proper way to avoid this kind of situation is.
Thanks in advance!
Ben
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
|