Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sound Effects and Music

Audio model

Digital effects and music are independent channels with separate enable settings. Scene commands can prepare, start, and wait for an effect and can replace the current music sequence. Preparing effect zero releases the retained sample and stops any playback. A host implementation MAY decode into any native sample or synthesizer representation.

Disabling effects MUST make subsequent effect-play commands silent, but MUST NOT stop an effect which is already playing or release its retained sample. While effects are disabled, a wait command uses the 100-unit silent fallback rather than waiting for that physical instance. Audio playback and completion tracking continue while a modal interface pauses the scene scheduler, so re-enabling effects before resuming can observe whether the instance has finished. Disabling music stops or suppresses music without disabling effects. Re-enabling music restarts the currently registered sequence when one exists. Requesting the already current nonzero music identifier is a no-op; requesting identifier zero stops music.

Returning from a scene while music is enabled is also a music-zero request. The active sequence MUST stop and its registered identifier MUST be cleared before the successor scene begins, so that the successor can start even the same numbered resource afresh. When music is disabled, that boundary request is suppressed just like a scene opcode: it MUST NOT discard the retained identifier. Re-enabling music can therefore restart the retained sequence until an enabled boundary or a different enabled music request replaces it.

Effect naming and playback

Effect identifier n selects D%03d.ABT. Opcode 57 prepares that member at the supplied rate; all nonzero calls in shipped scenes use 9,000 Hz. It stops the active effect, releases the preceding decoded buffer, decodes the new member, and asks the digital driver to preformat it, but does not begin playback. Preparing the already retained identifier is a no-op. Identifier and rate both zero stop playback and release the retained sample rather than loading D000.ABT.

Only one retained digital effect is required. Opcode 58 stops any active instance, resets completion state, and starts or restarts the retained preformatted sample. This two-command contract is visible in shipped sequences such as LOGO.BIN, which prepare D003.ABT with 57 and then start it with 58.

The retained sample is scene-owned. Scene initialization stops active playback and releases the prepared buffer before the new scene program runs. Starting a new session performs the same release. An effect prepared by one scene MUST therefore not remain available to opcode 58 in its successor.

With usable digital playback, the wait operation yields and retries while playback remains active. Without usable playback, the wait operation subtracts 100 from the calling script thread’s delay and advances past the command. The scheduler therefore resumes that thread after approximately 35 ms at 2,880 timer units per second. This delay begins at the wait command; it is not a global timer started by the prepare command.

The digital-audio fallback branch jumps if the driver is absent, effects are disabled, driver-state bit 0 is clear, or the explicit fallback word is nonzero. It falls through only when a driver is present, effects are enabled, the state bit is set, and the fallback word is zero. An implementation without a digital playback backend MUST take the branch.

ABT header

An ABT effect begins with nine bytes:

OffsetSizeMeaning
0x002Decoded sample count
0x022Playback rate in hertz
0x041Samples emitted by each delta block
0x051Codec identifier
0x062Auxiliary value; consumed but not used
0x081Initial unsigned PCM sample

The supplied effects use codec 2, 32 samples per delta block, and 9,000 Hz. The decoder MUST use the header fields rather than assuming those population values.

ABT command stream

The initial sample is output first. Commands then produce samples until the declared count is reached:

Control formMeaning
bit 7 setOutput (control << 1) & 0xFF as an absolute sample.
bit 7 clear, bit 6 setRepeat the preceding sample control & 0x3F times.
bits 7 and 6 clearDecode an adaptive delta block.

For a delta block, bits 4 and 5 select mode and the low nibble plus one is the step. Mode 1 uses one-bit codes and deltas [-step, +step]. Mode 2 uses two-bit codes beginning at -2 * step. Modes 0 and 3 use four-bit codes beginning at -8 * step. Build each table by adding step, skipping zero, and retaining signed-byte wraparound.

Packed codes are read most-significant bits first. Add each signed delta to the preceding output sample and clamp the result to 0 through 255. Stop only when the declared output count has been produced. Truncation, output overrun, impossible block geometry, count mismatch, or unused input is a format error.

The result is unsigned eight-bit mono PCM at the header rate.

XMIDI resources

Music identifier n selects either MUS%03d.XMI or IBM%03d.XMI according to the configured music family. The DOS startup selects the IBM family only when bytes 0xD2..0xD4 of the installed SOUND.2 music driver are the ASCII marker IBM; otherwise it selects MUS. A native engine using an original installation SHOULD apply the same marker. Every supplied sequence contains:

FORM XDIR
  INFO
CAT  XMID
  FORM XMID
    TIMB
    EVNT

IFF chunk sizes are big-endian and padded to even boundaries. The two-byte sequence count inside INFO is little-endian. Supplied files declare one sequence and contain one FORM XMID.

TIMB is an even-length array of patch/bank byte pairs. EVNT uses XMIDI’s MIDI-like representation:

  • bytes below 0x80 before an event are additive delays;
  • channel statuses have their standard fixed parameter counts;
  • note-on adds a variable-length duration after note and velocity;
  • system-exclusive and meta events use variable-length payload sizes; and
  • FF 2F 00 ends the track.

An optional zero pad may follow end-of-track. Parameter byte 0xFF occurs in valid supplied data and MUST NOT be rejected by an over-strict generic MIDI validator.

A modern engine MAY convert XMIDI events to another sequencer format or play them directly. Event order, delays, durations, program/bank choices, looping or replacement behavior, and the distinction between the MUS and IBM families must remain compatible.

XMIDI additive delay and duration units use a 120 Hz timebase. Music loops after the sequence completes and remains independent of the digital-effect channel. A native synthesizer MAY use the installed SOUND.4 AIL two-operator timbres, a General MIDI sound set, or another host representation; exact analog OPL waveforms are not required.