Skip to content
jamesu edited this page Oct 16, 2010 · 3 revisions

iMuse

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

  • 0×0006 : imSetMasterVolume(volume)
      volume      : [0-127]
  • 0×0007 : imGetMasterVolume()
  • 0×0008 : imStartSound(sound)
  • 0×0009 : imStopSound(sound)
  • 0×000A : imStopAllSounds() ???
  • 0×000B : imStopAllSounds()
  • 0×000C : imPlayerSet(player, ???, cmd, params …)
    Used in S&M
  • 0×000D : imGetSoundStatus(sound)
    sound == -1 returns the first active sound
  • 0×000E : imFadeSound(player, ????, fader_p1, fader_p2, fader_p3)
    S&M only ?
  • 0×000F : imMaybeHook(player, ????, param)
    S&M
  • 0×0010 : imSetVolchan(sound,volchan)
  • 0×0011 : imSetChannelVolume(chan,volume)
    In S&M: set/clear trigger
  • 0×0012 : imSetVolchanEntry(volchan,val)
    S&M: ImCheckTrigger
  • 0×0013 : imClearTrigger(a,b)
  • 0×0100 : 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
  • 0×0101 : imPlayerSetPriority(player,prio)
  • 0×0102 : imPlayerSetVolume(player,volume)
      volume      : [0:127]
  • 0×0103 : imPlayerSetPan(player,pan)
  • 0×0104 : imPlayerSetTranspose(player,relative,val)
      val         : [-24:24]
  • 0×0105 : imPlayerSetDetune(player,detune)
  • 0×0106 : imPlayerSetSpeed(player,speed)
  • 0×0107 : imPlayerJump(player,track,beat,tick)
  • 0×0108 : imPlayerScan(player,toTrack,toBeat,toTick)
  • 0×0109 : imPlayerSetLoop(player,count,toBeat,toTick,fromBeat,fromTick)
  • 0×010A : imPlayerClearLoop(player)
  • 0×010B : imPlayerSetOnOff(player,chan,status)
  • 0×010C : imPlayerSetHook(player,type,value,chan)
  • 0×010D : imPlayerFade(player,target,time)
  • 0×010E : imQueueTrigger(a,b)
  • 0×010F : imQueueCommand(cmd,arg1,arg2,arg3,arg4,arg5,arg6)
  • 0×0110 : imClearQueue()
  • 0×0111 : ??? Live MIDI ON
  • 0×0112 : ??? Live MIDI OFF
  • 0×0113 : imPlayerGetParam(player,param,chan)
  • 0×0114 : imPlayerSetHook(player,type,value,chan)
  • 0×0115 : ???
  • 0×0116 : imPlayerSetVolume(player,part,vol)
  • 0×0117 : imQueryQueue(param)
    • param:
      • 0: trigger count
      • 1: last trigger type
      • 2: last trigger sound
  • 0×0118 : ???

Player parameters

  • 0×00: priority
  • 0×01: volume
  • 0×02: pan
  • 0×03: transpose
  • 0×04: detune
  • 0×05: speed
  • 0×06: track index
  • 0×07: beat index
  • 0×08: tick index
  • 0×09: loop counter
  • 0×0A: loop to beat
  • 0×0B: loop to tick
  • 0×0C: loop from tick
  • 0×0D: loop from tick
  • 0×0E: part on
  • 0×0F: part vol
  • 0×10: part instrument
  • 0×11: part transpose
  • 0×12: jump hook
  • 0×13: transpose hook
  • 0×14: part onoff hook
  • 0×15: part volume hook
  • 0×16: part program hook
  • 0×17: part transpose hook

Hook types

  • 0×00: jump
  • 0×01: transpose
  • 0×02: chan on/off (0×0F == all)
  • 0×03: chan volume (0×0F == all)
  • 0×04: chan part program
  • 0×05: chan transpose

MIDI SysEx

The MIDI data fed to iMUSE can contain (and to some extent needs) some special SysEx commands. The manufacturer ID 0×7D 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 0×80-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.

  • 0×00: 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
    
  • 0×01: Shut down a part
      part        : 4
  • 0×02: Start of song
    This command is ignored by ScummVM 0.9.
  • 0×10: Adlib instrument definition (Part)
      part        : 4
      hw type     : 7
      adlib data  : 60*8
    
  • 0×11: Adlib instrument definition (Global)
      unknown     : 7
      hw type     : 7
      intrument   : 7
      adlib data  : 60*8
    
  • 0×21: Parameter adjust
      part        : 4
      hw type     : 7
      param       : 16be
      value       : 16be
    
  • 0×30: Hook – jump
      unknown     : 7
      cmd         : 8
      track       : 16be
      beat        : 16be
      tick        : 16be
    
  • 0×31: Hook – global transpose
      unknown     : 7
      cmd         : 8
      relative    : 8
      value       : s8
    
  • 0×32: Hook – part on/off
      chan        : 4
      cmd         : 8
      value       : 8
    
  • 0×33: Hook – set volume
      chan        : 4
      cmd         : 8
      value       : 8
    
  • 0×34: Hook – set program
      chan        : 4
      cmd         : 8
      value       : 8
    
  • 0×35: Hook – set transpose
      chan        : 4
      cmd         : 8
      relative    : 8
      value       : s8
    
  • 0×40: Marker
      unknown     : 7
      marker      : 7*n
    
  • 0×50: Set loop
      unknown     : 7
      count       : 16be
      tobeat      : 16be
      totick      : 16be
      frombeat    : 16be
      fromtick    : 16be
    
  • 0×51: Clear loop
    No arguments (or at least unused by ScummVM).
  • 0×60: 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