Z-machine standard: unclear aspects/ambiguities

Correct: From the blorb spec - One sound will either stop another, or not, depending on whether the sound is stored in AIFF (sampled) or Ogg/MOD (music) format.

Edit: The idea of a separate music channel was added long after Infocom’s time. It’s a shame a better way to distinguish sounds from music wasn’t used, like a different opcode. There is also some ugliness with the way V3 sound behavior depends on data in the sound file (now the looping chunk in a blorb file). That hack lies at Infocom’s feet though.

Argh, must have missed that one somehow. My apologies!

I’m not an audio guy, but AIFF/Ogg formats can apparently also contain embedded loop point data. Are you implying it should be ignored if present?

The question wasn’t related to Z-code but to the Blorb spec itself, in particular why it assigns “sample” usage to AIFF and “music” to Ogg, when it could’ve made that distinction based on additional metadata (e.g. provided in the resource index) instead of the file format. It just seems a bit inconvenient.

In the earlier drafts of Blorb, Ogg wasn’t there. AIFF was samples, MOD/Song was music, which made sense.

After this, Blorb got used as a resource format for other IF systems, none of which care about the difference between sample and music.

When Ogg was added, it was probably just simpler to assign it to one or the other rather than complicate the Blorb format just for z-code, especially as almost nobody has made use of sound/music for z-code games since Blorb was created.

1 Like

I’m not implying anything at all. :grinning: In V5 the sound_effect opcode can specify looping behavior, in V3 it cannot, and The Lurking Horror relied upon metadata in the sound file for this. I have no idea whether or not an interpreter should obey looping info in a sound file for a non-V3 game.

The sound vs. music distinction is a z-machine standard 1.1 thing. Since sound files can also be free-standing (not in a blorb), the only way to distinguish them is by the file type.

That makes sense - I guess those other systems do not need this information because they contain separate commands and/or parameters to determine what channel to use, and other stuff.

S.9 mentions two Infocom games that use sound effects - are those really the only ones? What about third party (e.g. community)-made games with sounds, do they exist?

Hmm. Now that you’ve said that, I think, logically, it would seem possible to combine both, e.g.: if sound_effect asks to loop the sound, then use the looping tags (if present) to determine where to start and end the loop, otherwise, ignore them. Probably the best of both worlds.

2 Likes

Infocom only made two games with sound, yes. As for third-party games, as far as I know it’s limited to “Moments Out of Time” by L. Ross Raszewski, which is a z6 game.

1 Like

I really can’t remember why it’s written that way. The natural thought would be that Ogg behaves the same as AIFF except the files are smaller.

Only two come to mind:

According to the Blorb standard:

Note that in V5 and later, the @sound_effect opcode determines whether a sound loops. The looping chunk is ignored. Therefore, this chunk should not be used at all in Blorb files intended for games which are not V3 Z-machine games.

Zen Speaks sounds (no pun intended!) very promising as a testbed for sound effects support. Definitely going to try it out as soon as I’m able to run V5 story files.

edit:

Well, whether or not the sound loops is one matter, but where to start and end the loop is another. As far as I can see, sound_effect does not provide any information about the latter even in V5, but sound files themselves can.

Yes, the looping chunk is specifically for V3 games and shouldn’t be used for V5+, but Player701 was referring to looping data in the sound formats themselves. This does seem somewhat analogous to the looping info present in Infocom’s original sound file format, but is less clear.

I misread here, not realizing this was about sound files that have embedded looping info as opposed to the Blorb specification.

I’d agree the most flexible thing would be to honor looping info in the sound file itself, if looping is explicitly requested; but unless that behavior is codified, I don’t think I’d ever put any effort into doing that, and consider it unspecified behavior at best.

1 Like

I interpreted this to mean that AIFF should be used for sound-effects, like clanging swords. OGG/MOD should be used for music and background sounds that play continuously.

In addition to that reimplementation of Uninvited, I made a “Sound Test” game (https://gitlab.com/DavidGriffith/soundtest) for debugging sound support in Unix Frotz and exploring how sound works with the Z-machine and Glulx.

SOUNDTEST
An interactive noisemaker by David Griffith
Release 0 / Serial number 230924 / Inform v6.41 Library v6.12.6 SD

Test Room
You're in a small, nondescript room. In the middle of the room is a table.

On the table are a leaflet, a Commodore 64, a Commodore Amiga and a little
handheld device.

>turn on Amiga 
You turn on the Commodore Amiga and it immedately begins playing an old time MOD
file.

>look at device
It's about the size of a pack of cards. There are four buttons on it: a red one,
a blue one, a green one, and one marked "off". There is also a dial with
settings from 1 to 8 and is currently set to 8.

>press green button
You press the green button.

>

The Lurking Horror and Sherlock, sure… but technically Infocom’s z6 games use sound, right? When checking Zork Zero, it uses <SOUND 1> many times… That comes from the blorb file, right? Does that count?

No, sound 1 and sound 2 are just beeps. Predefined, no blorb file needed.

1 Like

Sounds 1 and 2 don’t use sound files and are simple beep or bell sound of different pitches. AMFV uses them as well.

Regarding bleeps, the standard says:

  • “In Version 6, the interpreter should set bit 5 of ‘Flags 1’ if it can provide sound effects beyond a bleep.”
  • “In Version 5 and later, a game should have bit 7 of ‘Flags 2’ set in its story file if it wants to use sound effects beyond a bleep.”
  • “Sound effects (other than bleeps) can be played at any volume level…”
  • “Bleeps are immediate and brief. Other sound effects take place in the background…”

Together these suggest games/interpreters don’t need to announce sound support for bleeps and the additional operands for volume/repeats, and ending routine (sound interrupts) are not used with them.
Indeed this is how Infocom used them, and they didn’t use bleeps if other sounds were available.

But this does raise an interesting question:
What happens if those additional operands are used with bleeps? Are they illegal? Also, does playing a bleep interrupt sampled sounds or music? I highly doubt any game has used them in this manner (definitely no Infocom game has).

1 Like

I think the sensible way to handle it is to ignore the operands if they’re not valid, and to make sure beeps don’t interrupt proper sounds.
If the interpreter can beep without stopping the sound, it should. Otherwise, don’t beep.

2 Likes

This is exactly how I planned to design my own implementation.

S.9.4 says (emphasis mine):

Bleeps are immediate and brief.

As far as I can understand, this means that when a bleep happens, execution is suspended, and when the bleep has finished, execution resumes. Ergo, there is no need for the ending interrupt. And because such behavior is obviously acceptable only if the bleep is very short (otherwise it might suspend execution for too long so the user would notice), it’s probably unwise to support looping as well.

Regarding legality, this raises an even more interesting question. It is technically possible for an instruction with a variable number of operands (in this case sound_effect, but it may be any one) to have more operands than expected. Since evaluating these extra operands may change the current Z-machine state by popping the evaluation stack, observable behavior of the Z-machine may differ depending on whether such operands are evaluated or ignored.

This becomes much more important especially in cases like sound_effect, where the presence or absence of additional operands depends on the value of a preceding operand.

Another scenario to consider is when an instruction is expected to have an extra operand only in a certain version (e.g. set_cursor, set_colour et al.), and this extra operand is often optional. My implementation is probably not 100% technically correct, as it only takes version into account when parsing the opcode to determine its availability - so it would consider e.g. a set_colour instruction with three operands as legal in version 5, provided the third operand’s value is within acceptable range. I probably need to fix this, although I’m not sure if there will actually be any difference unless such instructions actually appear in the wild (i.e. not in specially-crafted samples).

Yes, this is the obvious interpretation. My interest was regarding what is the expected behavior if those operands appeared in a context where they are not expected, i.e. bleeps with volume/repeat, or interrupt, and also in how bleeps should interact with other sound types. None of that has ever been hinted at, let alone specified as far as I know, because it’s never been used.

The operands must always be decoded precisely because doing so has side effects. The method is described in Section 4 and is not overridden just because an opcode doesn’t need or expect a particular operand.

Edit: Obviously having extra operands is a form of error, but failing to load an operand that is present would cause the program counter to be in the wrong location, almost certainly causing a fatal crash.