I guess I've been making a lot of noise about this lately, fact is I'm kind
of bored!  Anyway, as most of you know, I've put some code out recently and
got quite a bit of feedback.  Reading some of the comments I realized I
hadn't thought this through as much as I had initially thought.  In this
e-mail I'm going to put forth some ideas for the reimplementation of NSSound
and would really appreciate the community's opinion to make a better
decision on the way to go.  I know it's long, sorry but I do have a tendency
of doing that!

INPUT
I think this one is pretty obvious, I moved the code to libsndfile from
libaudiofile.  Since version 1.12 libsndfile has provided a method to read
directly from memory allowing NSSound to read NSData objects, and since
version 1.18 has supposed Vorbis and FLAC decoding.

Please read "OTHER CONSIDERATIONS" before commenting on this choice.

OUTPUT
This has probably been my biggest mistake so far.  I'm providing a list of
all possible audio output libraries/servers that I've researched below.
Please keep in mind NSSound is very simple in design, so it does not need an
all powerful output API.

* JACK - Pros: JACK2 is cross-platform, very powerful API, low latency,
plays well with other JACK apps, is a sound server.  Cons: JACK1 (the
current stable release) only works on POSIX systems, is a relatively large
library (many unneeded features), requires floating point data, JACK2 is
still experimental.

* PulseAudio - Pros: Cross-platform, Powerful/large API, used by the GNOME
project, a simple API is available, is a sound server.  Cons: Requires a
dedicated mainloop for the asynch API, I still don't understand how it works
(the asynch API, the simple API is pretty straight forward).

* OpenAL - Pros: Cross-platform, powerful and simple API, asynchronous by
design.  Cons: Asynchronous (I know it's here twice, but it can also be a
bad thing if you're trying to stream data), requires 8 or 16 bit PCM data.

* Libao - Pros: Cross-platform, extremely simple API.  Cons: can only stream
data.

* Rolling our own / gnustep_sndd - Pros: GNUstep has full control of the
API.  Cons: Gnustep_sndd reinvents the wheel, any other approach would
require GNUstep to implement and maintain working code for at least ALSA,
OSS and WINMM/DirectSound.

* Honorable mentions: ESD (UNIX-based systems only, on it's way out), aRts
(on it's way out), PortAudio (David C. has mentioned it's quite unusable
anywhere but Linux), SDL and NAS (seems to be a great sound server and API,
but only works on *nix or requires Cgywin).

REQUIREMENTS
Obviously, the main requirement here is API compatibility with OS X 10.5.

David A. also mentioned the possibility of a streaming architecture, which I
like because it makes NSSound a lot more useful.  With current NSSound code,
and my original submission, NSSound simply read the file/data whole, storing
it in a NSData object and later playing that.  Streaming would allow us to
keep nothing but a pointer to the file/data (still in a NSData object) and
decoding it as we're playing.  This is the design of all sound applications
I've had the pleasure of using.

OTHER CONSIDERATIONS
* Loadable bundles/plug-ins - I thought this would be a great idea.  Allow
for loadable input and output bundles so that we can read from virtually any
file format and output to virtually anything.  Could eventually take us in
the "roll our own" backend model, but I'm not sure this is a bad thing, yet.

* Raw data reading - This seemed like a popular suggestion, and does sound
useful for anyone trying to play something like a CD using NSSound.  Apple
seems solves this problem by having CoreAudio and QT there to pickup the
slack, but we just don't have that option.

* Per NSSound volume control - This is probably the hardest thing to do.
Most of the libraries mentioned above do not support it.  Some hacking can
be done, but it won't be pretty.

* Fallback if libsndfile not present - This really isn't a problem if a
plug-in method is use.

MY OPINION
No matter what I do, it looks like a separate thread is going to have to be
spawned to do the streaming.  Problem there is that I've never programmed
with threads before, interesting for me since it'll be a learning
experience.  The easiest library to use is libao, it includes output every
thing out there (from ALSA to PulseAudio to WINMM).  OpenAL is also very
nice, but it's asynchronous by design and doesn't lend it self very well for
streaming.  I also really like the idea of loadable bundles/plug-ins, this
would allow quite a bit of flexibility, not only to GNUstep but to the
application programmer.  Lastly, moving the code to GNUstep-back, like
suggested by David C., seems like a good idea (specially with the plug-in
based setup) removing the dependency on the -gui library but pushing it over
to -back.

I appreciate any and all comments/suggestions.
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to