SCUMM/Technical Reference/iMuse data
iMuse
iMuse is the system used for the music. It main feature is to allow perfect integration of the music; with some talent, the game music can appear as a continuous soundtrack to the player.
SCUMM interface
Imuse is a subsystem of the SCUMM engine with its own set of commands. From a SCUMM script the following functions are avaible:
- startSound(snd)
- stopSound(snd)
- startMusic(m)
- isSoundRunning(snd)
- soundKludge([cmd_list])
As you can see, that is pretty spartan: all the power is in the soundKludge function. This will need some pretty good abstraction in the compiler, probably by adding a block similar to inline asm in C.
Command list
- 0x0006 : imSetMasterVolume(volume)
volume : [0-127]
- 0x0007 : imGetMasterVolume()
- 0x0008 : imStartSound(sound)
- 0x0009 : imStopSound(sound)
- 0x000A : imStopAllSounds() ???
- 0x000B : imStopAllSounds()
- 0x000C : imPlayerSet(player, ???, cmd, params ...)
Used in S&M
- 0x000D : imGetSoundStatus(sound)
sound == -1 returns the first active sound
- 0x000E : imFadeSound(player, ????, fader_p1, fader_p2, fader_p3)
S&M only ?
- 0x000F : imMaybeHook(player, ????, param)
S&M
- 0x0010 : imSetVolchan(sound,volchan)
- 0x0011 : imSetChannelVolume(chan,volume)
In S&M: set/clear trigger
- 0x0012 : imSetVolchanEntry(volchan,val)
S&M: ImCheckTrigger
- 0x0013 : imClearTrigger(a,b)
- 0x0100 : imPlayerGetParam(player,param,chan)
In DOTT this is often called with only 2 args, in that case it seems to default to chan=0. S&M: Beat suff
- 0x0101 : imPlayerSetPriority(player,prio)
- 0x0102 : imPlayerSetVolume(player,volume)
volume : [0:127]
- 0x0103 : imPlayerSetPan(player,pan)
- 0x0104 : imPlayerSetTranspose(player,relative,val)
val : [-24:24]
- 0x0105 : imPlayerSetDetune(player,detune)
- 0x0106 : imPlayerSetSpeed(player,speed)
- 0x0107 : imPlayerJump(player,track,beat,tick)
- 0x0108 : imPlayerScan(player,toTrack,toBeat,toTick)
- 0x0109 : imPlayerSetLoop(player,count,toBeat,toTick,fromBeat,fromTick)
- 0x010A : imPlayerClearLoop(player)
- 0x010B : imPlayerSetOnOff(player,chan,status)
- 0x010C : imPlayerSetHook(player,type,value,chan)
- 0x010D : imPlayerFade(player,target,time)
- 0x010E : imQueueTrigger(a,b)
- 0x010F : imQueueCommand(cmd,arg1,arg2,arg3,arg4,arg5,arg6)
- 0x0110 : imClearQueue()
- 0x0111 : ??? Live MIDI ON
- 0x0112 : ??? Live MIDI OFF
- 0x0113 : imPlayerGetParam(player,param,chan)
- 0x0114 : imPlayerSetHook(player,type,value,chan)
- 0x0115 : ???
- 0x0116 : imPlayerSetVolume(player,part,vol)
- 0x0117 : imQueryQueue(param)
- param:
- 0: trigger count
- 1: last trigger type
- 2: last trigger sound
- param:
- 0x0118 : ???
Player parameters
- 0x00: priority
- 0x01: volume
- 0x02: pan
- 0x03: transpose
- 0x04: detune
- 0x05: speed
- 0x06: track index
- 0x07: beat index
- 0x08: tick index
- 0x09: loop counter
- 0x0A: loop to beat
- 0x0B: loop to tick
- 0x0C: loop from tick
- 0x0D: loop from tick
- 0x0E: part on
- 0x0F: part vol
- 0x10: part instrument
- 0x11: part transpose
- 0x12: jump hook
- 0x13: transpose hook
- 0x14: part onoff hook
- 0x15: part volume hook
- 0x16: part program hook
- 0x17: part transpose hook
Hook types
- 0x00: jump
- 0x01: transpose
- 0x02: chan on/off (0x0F == all)
- 0x03: chan volume (0x0F == all)
- 0x04: chan part program
- 0x05: chan transpose
MIDI SysEx
The MIDI data fed to iMUSE can contain (and to some extent needs) some special SysEx commands. The manufacturer ID 0x7D is used for these SysExes and the first byte indicates the command.
In the SysEx data, only the first 7 bits are significant (value in the 0x80-0xFF range are used for real-time messages among other things), so values larger than 7 bits use 1 nibble per byte in big endian order (most significant nibble first). In the following descriptions, each line corresponds to one or more bytes of data.
The relevant code in ScummVM 0.9 is in engines/scumm/imuse/sysex_scumm.cpp and engines/scumm/imuse/imuse_player.cpp.
- 0x00: Allocate new part
part : 4 unknown : 7 flags : 2 bit 0 turn the part on/off bit 1 turn the reverb on/off priority : 7 volume : 8 pan : 8 flags2 : 7 bit 3 set percussion mode pitchbend : 8 program : 8
- 0x01: Shut down a part
part : 4
- 0x02: Start of song
This command is ignored by ScummVM 0.9.
- 0x10: Adlib instrument definition (Part)
part : 4 hw type : 7 adlib data : 60*8
- 0x11: Adlib instrument definition (Global)
unknown : 7 hw type : 7 intrument : 7 adlib data : 60*8
- 0x21: Parameter adjust
part : 4 hw type : 7 param : 16be value : 16be
- 0x30: Hook - jump
unknown : 7 cmd : 8 track : 16be beat : 16be tick : 16be
- 0x31: Hook - global transpose
unknown : 7 cmd : 8 relative : 8 value : s8
- 0x32: Hook - part on/off
chan : 4 cmd : 8 value : 8
- 0x33: Hook - set volume
chan : 4 cmd : 8 value : 8
- 0x34: Hook - set program
chan : 4 cmd : 8 value : 8
- 0x35: Hook - set transpose
chan : 4 cmd : 8 relative : 8 value : s8
- 0x40: Marker
unknown : 7 marker : 7*n
- 0x50: Set loop
unknown : 7 count : 16be tobeat : 16be totick : 16be frombeat : 16be fromtick : 16be
- 0x51: Clear loop
No arguments (or at least unused by ScummVM).
- 0x60: Set instrument
chan : 4 instrument : 16be
Adlib instrument
See some Adlib/Soundblaster documentation: http://www.shipbrook.com/jeff/sb.html
operators : 8*5*2 characteristic : 8 (port 0x20) scalingOutputLevel : 8 (port 0x40) attackDecay : 8 (port 0x60) sustainRelease : 8 (port 0x80) waveformSelect : 8 (port 0xE0) feedback : 8 (port 0xC0) flags_a : 8 extra_a : 8*8 flags_b : 8 extra_b : 8*8 duration : 8