Re: Native CoreAudio plugin for Herrie - proper API usage?
Re: Native CoreAudio plugin for Herrie - proper API usage?
- Subject: Re: Native CoreAudio plugin for Herrie - proper API usage?
- From: Jeff Moore <email@hidden>
- Date: Mon, 18 Jun 2007 12:39:34 -0700
I put my comments inline below.
On Jun 17, 2007, at 3:34 PM, Ed Schouten wrote:
Hello everyone,
I am the maintainer of the command line music player Herrie
(http://herrie.info/). Since late 2006 the application has quite good
support for Mac OS X; I myself own a PowerBook 867 MHz which I use
very
often to hack on the application, so OS X support has been quite good
over the last releases.
Since the initial releases of Herrie that supported OS X I've been
using
libao to make audio output work on OS X. Because libao is quite broken
and has poor performance (both in the sense of CPU usage and
buffering)
I've implemented my own CoreAudio output module that is a lot more
efficient than libao. A nice thing about my module is that pausing the
application will now bring down the CPU usage of the application to
0%,
instead of the 2% that libao seems to generate (it leaves the ioproc
running). By comparison, playing a file on my PowerBook consumes 6-7%
when using libao and only 4.5% when using my own module.
Because I often want to do stuff right, or don't do it at all, I have
some questions about my usage of the CoreAudio API, for a reference
here's the URL to the CoreAudio output module:
http://g-rave.nl/gitweb?p=herrie;a=blob;f=herrie/src/audio_output_coreaudio.c
- The module makes use of two buffers that are 32K (or a different
size
when the device is unable to use 32K buffers) that get swapped in a
critical section. The critical section is kept as small as possible
to
reduce contention as much as possible. This means one buffer can be
processed by CoreAudio and the other buffer can be filled with new
data, without any blockage.
On my PowerBook, even in power savings mode, this method provides a
proper buffering method. I can't seem to create situations in which
the sound starts clicking, etc, even when running compilations on the
background.
Would this buffer mechanism be good enough for real world usage? Are
there any other often-used setups that provide even better
performance?
My biggest concern would be how you are handling the critical section.
It is never a good thing to block inside your IOProc, so you have to
finesse this so that you don't lock any mutexes or spin in a spin lock
(which won't behave correctly on the IO thread anyway).
- When the ioproc detects that the buffer it's about to process is
empty, which means no data gets provided (the application is paused
or
stopped) I stop the ioproc from within the thread itself.
Is it safe to AudioDeviceStop() from within the IOProc?
Yes. In fact, calling AudioDeviceStop() inside your IOProc has the
added benefit of guaranteeing that your IOProc won't get called again.
Calling it off of the IO thread has no guarantees about how many times
your IOProc might get called before it is stopped.
So for a lot of apps, this is the perfect way to call AudioDeviceStop().
If so, is it
safe to make multiple calls of AudioDeviceStop() and
AudioDeviceStart()? Should I keep track of what I called before?
AudioDeviceStart() and AudioDeviceStop() are not reference counted and
you can call them as much as you like provided you understand that
there action will take effect immediately. That is, if you call
AudioDeviceStop(), the IOProc will get stopped regardless of how many
times you called AudioDeviceStart() on it.
Any comments about the implementation itself are also very welcome. I
hope the next release of Herrie will contain support for OS X that
will
just work flawless. Thanks for your time. :-)
So far, what you have described seems pretty reasonable. My only
concern would be about being sure to not block on the IO thread.
--
Jeff Moore
Core Audio
Apple
_______________________________________________
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