Wow wow wow. This is the sound driver I always wanted to write as a kid, but somehow I just couldn't hack it. Today, after a conversation with Lucas, I sat down and wrote it in a roughly 10-hour stretch. I just couldn't believe it, when everything started passing testing.
New Stuff!
This is the same library as before, it will play an infinitely long sound with its Oversampler-ripoff engine. But now it manages and plays one-shot sounds for you, with the following new and exciting C calls:
int loadOneSound( char *path );
Whereas *path is a GS/OS path and not really a c-string again. The int returned, is a libsound Sound ID number that you will use to refer to the sample later in soundPlayShort(). Libsound takes care of allocating RAM for the sample with the Memory Manager handle you gave it during soundInit(), and of course it uses GS/OS to load the sample into that allocated memory.
int soundPlayShort( int soundid, int rate );
soundid is the Sound ID number that loadOneSound() gave you earlier, rate is the Ensoniq DOC playback rate, (32 * sample rate in hz) / 1645. You do not have to worry about DOC RAM position or generator number. Libsound manages a pool of 8 generators and 32K of DOC RAM for you. When asked to play a sound, an unused generator is found, and DOC RAM is allocated with a granularity of $100 (one page). When the sample finishes playing, you don't have to do anything -- the sound MIRQ handler will automatically deallocate the generator and the pages of DOC RAM for you. Hell yes.
Limitations
There are some completely arbitrary limits. They are:
- Only 32 one-shot sounds may be managed. This isn't a design limitation, it is completely arbitrary and can be bumped up (to 64?) if need be.
- Only 8 sound generators are used to play one-shot sounds. This really shouldn't be a problem, as games generally do not play 8 one-shot sounds at a time. But it also is not a design limitation and could easily come up to 16 or more.
Changes
I don't do any error handling anymore. If I get a carry bit set on return from GSOS or the Toolbox, I do my very best to return to you immediately with the error number still in A, and the carry bit set. If a GSOS error occurs during long-sound playback, the file is closed and the DOC voices are halted. I promise I don't dump you to the rolling-apple anymore.
Also, the soundPlayStart function has added more parameters. The prototype is now thus:
int soundPlayStart( char *path, int rate, int oversample, int echodelay );
Whereas oversample = 0 is what you may call 'normal' operation,
oversample = 1 is "2X oversampling", where the sound data is double through interpolation (every other byte is an average of the two around it). In this case, double 'rate' as well.
oversample = 2 is "4X oversampling", which quadruples the size of the sound data, so you should quadruple the playback rate as well.
Oversampling can sometimes add perceived fidelity to the song being played, but you're more likely to just ignore it.
'echodelay' is the delay (in VBL intervals of 1/60th of a sec) between starting playback on L and R channels, to create a faux stereo effect.
These two effects were present in the Oversampler program when I reverse-engineered it and when I refactored it, so I'm putting them in your hands too.
Future Directions
soundPlayShort() will probably get more parameters in the next revision, to allow playback to occur on L, R, or both channels, per sound. There may also be a volume parameter to allow samples to play more softly or loudly.
In Other News
A RAMFast-D and AppleCD 300e are arriving within the next few days (where do I get all these toys!), and I'll be running some tests on the AppleCD 300e with both RAMFast and Apple non-highspeed SCSI cards, to see how well a SCSI CDROM works with the Oversampler engine. If it works well even without a fancy RAMFast, I'm more likely to consider mastering my finished product as an HFS CDROM, as well as .hdv image and/or CF card images.
Click the title for the download link.
-Chris