Z-machine sound

Z-machine sound seems to be a bit magic, and I’m not sure the specification is complete. Some games loop, and the interpreter should just know which. But in z5 the sound_effect opcode can also specify looping. Can there still be sounds that will loop even without this being specified with the sound_effect opcode? And there’s one channel for music and another for sound effects. Was the music channel used in any of the Infocom games? Is all music repeating?

Is there anyone here who has added sound support to an interpreter and can tell me about some of the pitfalls?

Any additional information (or links to such) about how to make sound work correctly for the Z-machine are appreciated too.

Wasn’t music something that was added after the demise of Infocom? The Z-Machine 1.1 standards proposal [1] it says that

The Blorb specification effectively revised Standard 1.0, as follows:

“Sound” is split into two classes - “music” (eg Blorb SONG and MOD) and “effects” (eg Infocom .SND or Blorb AIFF).

The Blorb specification says that SONG is deprecated, and I think MOD handles looping all by itself?

The only thing I’ve ever seen about music in Infocom adventure was the back of the Journey box, where it says that “Color graphics and theme music bring the action to life as the tale unfolds on your screen.” But no one - not even Marc Blank - seems to know what that was about.

(The link to the draft specification, or at least an earlier version, worked for me without having to use the Wayback Machine, but it stopped working for me while I was writing this.)

[1] https://web.archive.org/web/20140821080356/http://www.jczorkmid.net/~jpenney/ZSpec11-draft7.txt

1 Like

I haven’t really delved into interpreter development, so I don’t know if it’s going in the direction you’re looking for, but I remember reading about @DavidG implementing sound support in Frotz.

Here are some links to threads which contain further links:

1 Like

This is most helpful, @eriktorbjorn and @StJohnLimbo . Thank you!

1 Like

Audio was done by Infocom only for “Lurking Horror” (only for Amiga) and “Sherlock” (Macintosh and Amiga(?)). The audio was in the form of uncompressed samples.

Yes; the Infocom sound format included a flag meaning “loop forever”. Blorb files have a looping chunk which provides the same information. With this, interpreters shouldn’t need to have knowledge of which samples to loop in the Lurking Horror (which is the only place this “auto-looping” is used, as far as I know).

Is there anyone here who has added sound support to an interpreter and can tell me about some of the pitfalls?

Dealing with the Lurking Horror hack (described in the remarks of §9 of the Standard) is a bit annoying.

One interesting thing I found is that there is a sequence that goes something like this:

@sound_effect 11 2 8
@sound_effect 16 2 8
@sound_effect 16 3

Which is to say, start sound 11, start sound 16, stop sound 16. This is one of the reasons for the “queued sounds” hack: sound 11 needs to play once, so sound 16 must be queued up. But the last instruction there stops sound 16. So, depending on how you implement things, you’ll get a stop request that comes in while sound 16 isn’t running. No big deal, maybe, because you want to hear sound 16 anyway. But sound 16 is marked as a looping sound, so unless you handle this somehow, you could end up with sound 16 going forever (since the “stop” request was too early).

I also decided to not bother with checking “is this the second sound effect that happened since the last user input” (which is a proxy for figuring out whether there were two successive @sound_effect calls that need to be spaced out), but instead I check for whether the game is The Lurking Horror, and if the sound effect is 9 or 16, since these are the two cases where the sound needs to be queued. The end result is effectively the same, but only applies to one game, whereas implementing the Standard’s recommendation applies to all games.

1 Like

You’re touching on another audio pitfall there. In Lurking Horror, there are a few places where multiple samples are fired off in quick succession. The timing assumes an Amiga 1000. For a modern terp on a modern host, this is too quick and so some samples stomp on others. I have been able to mitigate some of this in Frotz and am working on the rest.

1 Like