Another Threading Issue
Another Threading Issue
- Subject: Another Threading Issue
- From: Jeremy Jurksztowicz <email@hidden>
- Date: Wed, 17 Dec 2003 14:05:12 -0500
I hate to beat a dead horse but...
I have recently ported a windows app to CoreAudio, using the HAL.
My audio supplier class provides PCM wave data from a buffer stored on
memory. The way the data is provided to
the IO proc depends on parameters in the class instance of course. In
the windows code I was doing something like this:
class Provider {
Envelope * env1;
float data1;
// ... Many more variables ...
public:
void pullDataStream (float ** buffs, unsigned int frames, unsigned
int channels) {
Lock lck(sharedMutex);
if(data1 => somethingOrOther)
doThisOrThat();
// ... Get all the data ...
env1->applySectionAndIncrement(buffs,frames,channels);
lck.unlock();
}
void setEnv1 (Envelope* env) {
Lock lck(sharedMutex);
delete env1;
env1 = env;
if(env1) env1->syncronizeWithThis(this); // Complex method to
make sure the envelope is synced.
}
// Blah, Blah, Blah, you get the idea...
};
While this code worked, and still works just fine, I keep seeing posts
about how no blocking calls should be made in the
IO proc, including memory allocations and THREAD LOCKS. Seeing as I
have to pass data to the io thread while it is running,
how do I get it there without locking? So of course I did an exhaustive
search of the mailing list archives, and lo and behold
I get all sorts of stuff on the circular buffer. Great!
BUT! As you can see in the example above, In the protected section of
setEnv() there is more than just a parameter assignment,
there is also some complex code to sync the param (in this case an
envelope) with the rest of the classes sound data. This code
must either:
1-Run in a protected block on the main thread.
2-Run in the IO thread each and every cycle of getting audio data!
The reason behind 2 is that if I can atomicaly change the envelope
parameter, It does me no good (rather harmful, really) if it is
not synced up before ANY MORE audio data is processed. Sure I could put
another member, env1DidChange of boolean type,
and update that as well, but what if the envelope is required between
calls to set it and it's boolean changed flag?
This is an artificial example, but this pattern of behavior is very
common to this class, which can do some wonderful things
because it handles such high level abstractions such as Envelopes,
Filters, etc... rather than having all its parameters low
level floating point primitives.
So my first idea was to change my provider class to an AudioUnit, they
provide auto synchronization... right? ... Right?!
I looked up and down in the AUBase class to see if there was thread
syncing, and eureka! I see something about an
AUElement class, and getting parameters, and AHA! In the AUBase class
there is SafeGetElement()! To my disappointment
this has nothing to do with thread safety (or did I miss something?).
So perhaps some example AudioUnit code will tell me
what I need to know...? No thread syncing in ANY example code I have
downloaded...
So, here are my questions:
1. If I implement audio units to specification, do I have to implement
any thread safety measures if it will only be accessed by the
IO thread AND the main thread. If no syncing is needed, should I
only access my AU through the C AudioUnits API, or can I safely
call its class methods directly? (from the AUBase source code this
seems unlikely)
2. If I decide not to implement an AU and reuse my provider class,
would it be reasonably good practice to pull its audio data in a
feeder thread, locking to my hearts content (only one lock per IO
cylcle is required), and pumping the data through a circular buffer
to the high priority IO thread?
I know that threading issues are common on this list, and am sorry If
my late night archive browsing missed the obvious answers.
Thank you for your help.
Jeremy Jurksztowicz
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.