[I6] Best practice for multi-channel sound in Glulx games

I am writing a game using Inform 6 that is compiled for a Glulx interpreter. It has graphics and sound. This is the first time I’ve written a game with sound, so I’m a bit uncertain about some things. It currently has two channels, one for theme music played at the beginning and end (though I may add some more, depending on the client) and one channel for sound effects (only one at this stage, but, once again, I may add some more).

It has SOUND ON and SOUND OFF commands to (surprise, surprise) turn sounds on and off. The approach I’ve taken here is that SOUND OFF uses glk_schannel_pause() for the background channel and glk_schannel_stop() for the foreground channel. SOUND ON uses glk_schannel_unpause() for the background channel and nothing for the foreground channel.

Everything works like a charm using Glulxe on Windows, but I’m worried that this approach may not work on other interpreters. I understand, from what I’ve read on the forum, that pause and unpause are only available from a certain version of Glk onwards (1.7.3 if I recall correctly). I also believe that I can use glk_gestalt(gestalt_Sound,0) and glk_gestalt(gestalt_Sound2,0) to distinguish between versions.

My questions are:

  1. Are there any good tutorials around that describe best practice for implementing two-channel sound?
  2. How do I implement SOUND ON/OFF if pause/unpause is not available on the interpreter?

Thanks in advance for any help you can provide.

How are you using these commands? I’m very interested in getting into the Standard Library some sort of standardized means of producing sound with Inform6 for both Z-machine and Glulx targets.

I define a couple of constants for the sound handles (or rocks, as zarf calls them), a couple of global variables for the sound channels, sound file ids and a boolean to indicate whether sound is currently on or off; include infglk.h so that I can use its convenience wrappers to hide all the ugly @glk stuff; test for sound support and initialise the sound channels in the Initialise routine; define entry point routines for IdentifyGlkObject() and HandleGlkEvent() and define a routine to PlaySound().

Although it’s friggin’ hard to work out what to do based on the available sources, I think it’s a fairly standard approach from what I’ve seen.

My main references were Adam Cadre’s Gull (which is pretty old and doesn’t cover the newer stuff such as gestalt_Sound2, pause/unpause, support for ogg files and so on) and Andrew Plotkin’s Glk API spec (which is primarily targeted at interpreter developers).

Oh, and I defined the grammar and actions for sound on and sound off.

Something in the standard library would certainly make life easier. You’re welcome to take a look at my code if it helps, but I’d prefer to get my second question answered first. I’ve got an idea on how to do it, but I didn’t try it once I’d discovered pause/unpause. The latter is a much cleaner approach to what I had in mind, as this literally pauses and resumes, whereas the alternative restarts the sound when sound is turned back on. Incidentally both approaches need to account for the sound being changed when the sound is paused.