Getting sound to play after restart

For Kerkerkruip, I wrote a little framework to expose both of the Inform library’s foreground and background sound channels, and to allow for most of the Glulx sound features (such as looping and notification). But I’m running into some trouble, in that the sound invoked in the “play the theme music” phrase below doesn’t play after typing RESTART.

Normally, this would be an issue with not properly resetting Glulx object references on restarting the interpreter. However, that process is handled by the Inform library for gg_foregroundchan and gg_backgroundchan, and I have no reason to believe that there is a problem with the library. So, there must be some small thing wrong with the code below. Can anyone spot what it might be?


[code]The maximum sound volume is a number variable. The maximum sound volume is 10.

A sound-channel is a kind of thing.
A sound-channel has a number called the volume. The volume of a sound-channel is usually 10.

Foreground and background are sound-channels.

To play the theme music:
set up sound channels;
play sound of music in foreground channel, looping.

To set up sound channels:
repeat with item running through sound-channels:
now the ref-number of item is the internal number of item.

To decide what number is internal number of (foreground - a sound-channel):
(- gg_foregroundchan -);

To decide what number is internal number of (background - a sound-channel):
(- gg_backgroundchan -);

To play (sound - a sound-name) in (channel - a sound-channel) channel, looping, with notification:
(- SoundPlay(ResourceIDsOfSounds–>{sound},{channel},{phrase options}); -)

To set simple volume for (channel - a sound-channel) channel to (volume - a number):
(- SetVolume({channel},{volume}); -)

To stop (channel - a sound-channel) channel:
(- SoundCease({channel}); -)

Include (-

[ SoundPlay sound chan loop notify;
if (glk_gestalt(gestalt_Sound,0)) {

[ SetVolume chan vol;
if (glk_gestalt(gestalt_SoundVolume,0)) {
if ((vol <= (+ maximum sound volume +)) && (vol > 0)) {
glk_schannel_set_volume(chan.ref_number, (vol * (65535 / (+ maximum sound volume +)))+1);
else {
glk_schannel_set_volume(chan.ref_number, 0);

[ SoundCease chan;
if (glk_gestalt(gestalt_Sound,0)) {

-) after “Figures.i6t”.[/code]

OK, figured out the problem, at least the main one. It is with this way of referring to entities from phrases:

[code]Foreground and background are sound-channels.

To decide what number is internal number of (foreground - a sound-channel):
(- gg_foregroundchan -);

To decide what number is internal number of (background - a sound-channel):
(- gg_backgroundchan -);[/code]

The issue is the reference to the actual name of an object in to decide phrases, with the intent of distinguishing between objects and applying different outcomes to them. I feel like I have seen this work, but apparently it really doesn’t (only one phrase ever fires).

Okay, that’s good you found it, because I couldn’t reproduce the issue. The code you cited is supposed to work, but there are some bugs about it. They have workarounds; let me see if I can find you pointers.

Incidentally, I think you meant[ SoundPlay sound chan options; if (glk_gestalt(gestalt_Sound,0)) { glk_schannel_play_ext(chan.ref_number, sound, -(options & 1), options & 2); } ]; (WI 25.16).

825 perhaps? The other, 873 looks unrelated.

Edit: No, this is particularly to do with phrases having I6 definitions. Probably the compiler should have complained that it couldn’t write a resolver, though now that resolution is inline it might be able to handle this case. Care to file a bug?

I don’t know if this is the problem, but don’t you need a semicolon after embedded Inform 6 code?

Not for “to decide” phrases – they compile as expressions.

If that were the problem, anyhow, you’d be seeing compilation errors rather than wrong runtime behavior.

Thanks, eu! Bug submitted as (Also includes a workaround, which I got from your report in 00825. It doesn’t seem as though Inform should have any trouble parsing this given that it can do the workaround syntax; perhaps that is also what zarf’s comment implies–I’m not sure what the implications of being compiled as expressions might be.)

There’s another vexing issue here, but it’s particular to the Kerkerkruip code: the sound is being suppressed until after player input for some reason. I’ll have to figure that one next…

By the way, thanks for the bitwise syntax–I actually didn’t know how to use it and was just hoping that it would function as written (it seemed to, at least for loops–notifications probably wouldn’t). WI 25.16 should probably show an example of using the & syntax…

In this case you don’t need phrase paramaters. Wouldn’t “To decide what number is internal number of foreground:” work?

I imagine he plans to store the channel being played through as part of the sound, and the syntax in the OP would allow “the internal number of” a variable.

To decide what number is internal number of (foreground - a sound-channel):
	(- gg_foregroundchan -);

To decide what number is internal number of (background - a sound-channel):
	(- gg_backgroundchan -);

This is bad code to begin with. This is two different definitions for a phrase with the same argument type (sound-channel). The “foreground” and “background” are the parameter – that is, a local variable, not a matching requirement.

…so, to be clear, this will do what you probably want:

To decide what number is internal number of (C - foreground):
	(- gg_foregroundchan -);

To decide what number is internal number of (C - background):
	(- gg_backgroundchan -);

You’ll get runtime errors if you pass any other object than “foreground” or “background”, but I presume you expected that.

Wow, I completely missed that and read it as intended, not as written. But is acceptance of this modified source not a bug anyway? The macro semantics are suddenly lost once the override appears, which rather limits what can be safely done in the I6 definition.

Not accepting the code also limits what can be done in the definition. :slight_smile: The current behavior seems like a good compromise; it only calls the resolver when the phrase cannot be resolved at compile time.

I gather that resolvers are going to appear inline in the next compiler release, so this whole issue may go away.

Okay, fair point. I would ask for documentation, but

I suspect this as well.