DEADSOFTWARE

restored fmod sound driver
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Thu, 7 Apr 2016 06:31:03 +0000 (09:31 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Thu, 7 Apr 2016 06:41:01 +0000 (09:41 +0300)
build.bat
src/engine/e_sound.pas
src/engine/e_sound_fmod.inc [new file with mode: 0644]
src/engine/e_sound_sdl.inc [new file with mode: 0644]
src/game/Doom2DF.dpr
src/game/g_main.pas
src/lib/fmod/fmod.inc [new file with mode: 0644]
src/lib/fmod/fmod.pas [new file with mode: 0644]
src/lib/fmod/fmoderrors.pas [new file with mode: 0644]
src/lib/fmod/fmodpresets.pas [new file with mode: 0644]
src/lib/fmod/fmodtypes.pas [new file with mode: 0644]

index 4c682e849dbb639bae92891cd8cc74433c20bfd1..dbb5a2acd1ba614a9431ca0e93b85fdf2f0b323a 100644 (file)
--- a/build.bat
+++ b/build.bat
@@ -1,5 +1,5 @@
 @echo off
 cd "./src/game"
-fpc -MDELPHI -O2 -FE../../bin -FU../../tmp Doom2DF.dpr
+fpc -dUSE_FMOD -MDELPHI -O2 -FE../../bin -FU../../tmp Doom2DF.dpr
 cd ".."
 pause
\ No newline at end of file
index 857101a017105c165b4ecdb5bd8db29e9533cd20..221c5ea5613159404d92c4fa8816d14e5185e2e1 100644 (file)
@@ -1,921 +1,7 @@
 unit e_sound;
 
-interface
-
-uses
-  sdl2,
-  SDL2_mixer,
-  e_log,
-  SysUtils;
-
-type
-  TSoundRec = record
-    Data: Pointer;
-    Sound: PMix_Chunk;
-    Music: PMix_Music;
-    isMusic: Boolean;
-    nRefs: Integer;
-  end;
-
-  TBasicSound = class (TObject)
-  private
-    FChanNum: Integer; // <0: no channel allocated
-
-  protected
-    FID: DWORD;
-    FMusic: Boolean;
-    FPosition: DWORD;
-    FPriority: Integer;
-
-    function RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
-    function GetChan (): Integer;
-
-    property Channel: Integer read GetChan;
-
-  public
-    constructor Create();
-    destructor Destroy(); override;
-    procedure SetID(ID: DWORD);
-    procedure FreeSound();
-    function IsPlaying(): Boolean;
-    procedure Stop();
-    function IsPaused(): Boolean;
-    procedure Pause(Enable: Boolean);
-    function GetVolume(): Single;
-    procedure SetVolume(Volume: Single);
-    function GetPan(): Single;
-    procedure SetPan(Pan: Single);
-    function IsMuted(): Boolean;
-    procedure Mute(Enable: Boolean);
-    function GetPosition(): DWORD;
-    procedure SetPosition(aPos: DWORD);
-    procedure SetPriority(priority: Integer);
-  end;
-
-const
-  NO_SOUND_ID = DWORD(-1);
-
-function e_InitSoundSystem(): Boolean;
-
-function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean): Boolean;
-function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
-
-// returns channel number or -1
-function e_PlaySound(ID: DWORD): Integer;
-function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
-function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
-function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
-
-procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
-procedure e_MuteChannels(Enable: Boolean);
-procedure e_StopChannels();
-
-procedure e_DeleteSound(ID: DWORD);
-procedure e_RemoveAllSounds();
-procedure e_ReleaseSoundSystem();
-procedure e_SoundUpdate();
-
-var
-  e_SoundsArray: array of TSoundRec = nil;
-
-implementation
-
-uses
-  g_window, g_options, BinEditor;
-
-const
-  N_CHANNELS = 512;
-  N_MUSCHAN = N_CHANNELS+42;
-
-type
-  TChanInfo = record
-    id: DWORD; // sound id
-    muted: Boolean;
-    oldvol: Integer; // for muted
-    pan: Single;
-  end;
-
-var
-  SoundMuted: Boolean = False;
-  SoundInitialized: Boolean = False;
-  ChanSIds: array[0..N_CHANNELS] of TChanInfo;
-  MusVolume: Integer = MIX_MAX_VOLUME;
-
-
-procedure chanFinished (chan: Integer); cdecl;
-begin
-  //e_WriteLog(Format('chanFinished: %d', [chan]), MSG_NOTIFY);
-  if (chan >= 0) and (chan < N_CHANNELS) then
-  begin
-    if ChanSIds[chan].id <> NO_SOUND_ID then
-    begin
-      if (ChanSIds[chan].id <= High(e_SoundsArray)) and (e_SoundsArray[ChanSIds[chan].id].nRefs > 0) then
-      begin
-        Dec(e_SoundsArray[ChanSIds[chan].id].nRefs);
-      end;
-      ChanSIds[chan].id := NO_SOUND_ID;
-    end;
-  end;
-end;
-
-
-procedure dumpMusicType (ms: PMix_Music);
-begin
-  if ms = nil then
-  begin
-    e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY);
-  end
-  else
-  begin
-    case Mix_GetMusicType(ms^) of
-      TMix_MusicType.MUS_NONE:
-        e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY);
-      TMix_MusicType.MUS_CMD:
-        e_WriteLog('MUSIC FORMAT: CMD', MSG_NOTIFY);
-      TMix_MusicType.MUS_WAV:
-        e_WriteLog('MUSIC FORMAT: WAV', MSG_NOTIFY);
-      TMix_MusicType.MUS_MOD:
-        e_WriteLog('MUSIC FORMAT: MOD', MSG_NOTIFY);
-      TMix_MusicType.MUS_MID:
-        e_WriteLog('MUSIC FORMAT: MID', MSG_NOTIFY);
-      TMix_MusicType.MUS_OGG:
-        e_WriteLog('MUSIC FORMAT: OGG', MSG_NOTIFY);
-      TMix_MusicType.MUS_MP3:
-        e_WriteLog('MUSIC FORMAT: MP3', MSG_NOTIFY);
-      TMix_MusicType.MUS_MP3_MAD:
-        e_WriteLog('MUSIC FORMAT: MP3_MAD', MSG_NOTIFY);
-      TMix_MusicType.MUS_FLAC:
-        e_WriteLog('MUSIC FORMAT: FLAC', MSG_NOTIFY);
-      TMix_MusicType.MUS_MODPLUG:
-        e_WriteLog('MUSIC FORMAT: MODPLUG', MSG_NOTIFY);
-      otherwise
-        e_WriteLog('MUSIC FORMAT: UNKNOWN', MSG_NOTIFY);
-    end;
-  end;
-end;
-
-function e_InitSoundSystem(): Boolean;
-var
-  res, i: Integer;
-begin
-  if SoundInitialized then begin Result := true; Exit end;
-
-  Result := False;
-  SoundInitialized := False;
-
-  // wow, this is actually MIDI player!
-  // we need module player
-  res := Mix_Init(MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MODPLUG or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH);
-  e_WriteLog(Format('SDL: res=0x%x', [res]), MSG_NOTIFY);
-  if (res and MIX_INIT_FLAC) <> 0 then e_WriteLog('SDL: FLAC playback is active', MSG_NOTIFY);
-  if (res and MIX_INIT_MOD) <> 0 then e_WriteLog('SDL: MOD playback is active', MSG_NOTIFY);
-  if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', MSG_NOTIFY);
-  if (res and MIX_INIT_MP3) <> 0 then e_WriteLog('SDL: MP3 playback is active', MSG_NOTIFY);
-  if (res and MIX_INIT_OGG) <> 0 then e_WriteLog('SDL: OGG playback is active', MSG_NOTIFY);
-  if (res and MIX_INIT_FLUIDSYNTH) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', MSG_NOTIFY);
-
-  res := Mix_OpenAudio(48000, AUDIO_S16LSB, 2, 2048);
-  if res = -1 then res := Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 2048);
-  if res = -1 then
-  begin
-    e_WriteLog('Error initializing SDL mixer:', MSG_FATALERROR);
-    e_WriteLog(Mix_GetError(), MSG_FATALERROR);
-    Exit;
-  end;
-
-  Mix_AllocateChannels(N_CHANNELS);
-  Mix_ChannelFinished(chanFinished);
-
-  for i := 0 to N_CHANNELS-1 do
-  begin
-    ChanSIds[i].id := NO_SOUND_ID;
-    ChanSIds[i].muted := SoundMuted;
-    ChanSIds[i].oldvol := MIX_MAX_VOLUME;
-    ChanSIds[i].pan := 1.0;
-  end;
-  MusVolume := MIX_MAX_VOLUME;
-
-  SoundInitialized := True;
-  Result := True;
-end;
-
-function e_isMusic (id: DWORD): Boolean;
-begin
-  Result := False;
-  if (e_SoundsArray <> nil) and (id <= High(e_SoundsArray)) then
-  begin
-    Result := (e_SoundsArray[id].Music <> nil);
-  end;
-end;
-
-function e_isSound (id: DWORD): Boolean;
-begin
-  Result := False;
-  if (e_SoundsArray <> nil) and (id <= High(e_SoundsArray)) then
-  begin
-    Result := (e_SoundsArray[id].Sound <> nil);
-  end;
-end;
-
-function FindESound(): DWORD;
-var
-  i: Integer;
-begin
-  if e_SoundsArray <> nil then
-  begin
-    for i := 0 to High(e_SoundsArray) do
-      if (e_SoundsArray[i].Sound = nil) and (e_SoundsArray[i].Music = nil) then
-      begin
-        Result := i;
-        Exit;
-      end;
-  end;
-  if e_SoundsArray = nil then
-  begin
-    SetLength(e_SoundsArray, 16);
-    Result := 0;
-  end
-  else
-  begin
-    Result := High(e_SoundsArray) + 1;
-    SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
-  end;
-  for i := Result to High(e_SoundsArray) do
-  begin
-    e_SoundsArray[i].Sound := nil;
-    e_SoundsArray[i].Music := nil;
-    e_SoundsArray[i].Data := nil;
-    e_SoundsArray[i].isMusic := False;
-    e_SoundsArray[i].nRefs := 0;
-  end;
-end;
-
-function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean): Boolean;
-var
-  find_id: DWORD;
-begin
-  ID := NO_SOUND_ID;
-  Result := False;
-  if not SoundInitialized then Exit;
-
-  if isMusic then e_WriteLog('Loading music '+FileName+'...', MSG_NOTIFY)
-  else e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
-
-  {
-  if isMusic then
-  begin
-    e_WriteLog('IGNORING MUSIC FROM FILE', MSG_WARNING);
-    Exit;
-  end;
-  }
-
-  find_id := FindESound();
-
-  e_SoundsArray[find_id].Data := nil;
-  e_SoundsArray[find_id].isMusic := isMusic;
-  e_SoundsArray[find_id].nRefs := 0;
-
-  if isMusic then
-  begin
-    e_WriteLog(Format('  MUSIC SLOT: %u', [find_id]), MSG_NOTIFY);
-    e_SoundsArray[find_id].Music := Mix_LoadMUS(PAnsiChar(FileName));
-    if e_SoundsArray[find_id].Music = nil then
-    begin
-      e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING);
-      e_WriteLog(Mix_GetError(), MSG_WARNING);
-      Exit;
-    end;
-    dumpMusicType(e_SoundsArray[find_id].Music);
-  end
-  else
-  begin
-    e_SoundsArray[find_id].Sound := Mix_LoadWAV(PAnsiChar(FileName));
-    if e_SoundsArray[find_id].Sound = nil then Exit;
-  end;
-
-  ID := find_id;
-
-  Result := True;
-end;
-
-function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
-var
-  find_id: DWORD;
-  rw: PSDL_RWops;
-  //pc: PChar;
-  isid3: Boolean;
-begin
-  ID := NO_SOUND_ID;
-  Result := False;
-  if not SoundInitialized then Exit;
-  isid3 := False;
-
-  {
-  if isMusic then
-  begin
-    e_WriteLog('IGNORING MUSIC FROM MEMORY', MSG_WARNING);
-    Exit;
-  end;
-  }
-
-  //FIXME: correctly skip ID3
-  {
-  pc := PChar(pData);
-  if (Length > $400) and (pc[0] = 'I') and (pc[1] = 'D') and (pc[2] = '3') then
-  begin
-    isid3 := True;
-    Inc(pc, $400);
-    pData := Pointer(pc);
-    Dec(Length, $400);
-    e_WriteLog('MUSIC: MP3 ID3 WORKAROUND APPLIED!', MSG_WARNING);
-  end;
-  }
-
-  rw := SDL_RWFromConstMem(pData, Length);
-  if rw = nil then Exit;
-
-  find_id := FindESound();
-
-  e_SoundsArray[find_id].Data := pData;
-  if isid3 then e_SoundsArray[find_id].Data := nil;
-  e_SoundsArray[find_id].isMusic := isMusic;
-  e_SoundsArray[find_id].nRefs := 0;
-
-  if isMusic then
-  begin
-    e_WriteLog(Format('  MUSIC SLOT: %u', [find_id]), MSG_NOTIFY);
-    e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0);
-    if e_SoundsArray[find_id].Music = nil then
-    begin
-      e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING);
-      e_WriteLog(Mix_GetError(), MSG_WARNING);
-    end
-    else
-    begin
-      dumpMusicType(e_SoundsArray[find_id].Music);
-    end;
-    //SDL_FreeRW(rw);
-    {
-    if e_SoundsArray[find_id].Music <> nil then
-    begin
-      Mix_FreeMusic(e_SoundsArray[find_id].Music);
-    end;
-    e_SoundsArray[find_id].Music := nil;
-    Exit;
-    }
-  end
-  else
-  begin
-    e_SoundsArray[find_id].Sound := Mix_LoadWAV_RW(rw, 0);
-  end;
-  //SDL_FreeRW(rw); // somehow it segfaults...
-  if (e_SoundsArray[find_id].Sound = nil) and (e_SoundsArray[find_id].Music = nil) then
-  begin
-    e_SoundsArray[find_id].Data := nil;
-    Exit;
-  end;
-
-  ID := find_id;
-
-  Result := True;
-end;
-
-function e_PlaySound (ID: DWORD): Integer;
-var
-  res: Integer = -1;
-begin
-  Result := -1;
-  if not SoundInitialized then Exit;
-
-  if e_isSound(ID) then
-  begin
-    if e_SoundsArray[ID].nRefs >= gMaxSimSounds then Exit;
-    Inc(e_SoundsArray[ID].nRefs);
-    res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
-    if res >= 0 then
-    begin
-      ChanSIds[res].id := ID;
-      ChanSIds[res].muted := SoundMuted;
-      if SoundMuted then Mix_Volume(res, 0) else Mix_Volume(res, ChanSIds[res].oldvol);
-      {
-      if e_SoundsArray[ID].isMusic then
-        res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, -1)
-      else
-        res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
-      }
-    end;
-  end
-  else
-  begin
-    if not e_isMusic(ID) then Exit;
-    Mix_HaltMusic();
-    res := Mix_PlayMusic(e_SoundsArray[ID].Music, -1);
-    if res >= 0 then res := N_MUSCHAN;
-    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
-    Result := res;
-  end;
-
-  Result := res;
-end;
-
-function e_chanSetPan (chan: Integer; Pan: Single): Boolean;
-var
-  l, r: UInt8;
-begin
-  Result := True;
-  if chan = N_MUSCHAN then
-  begin
-    // no panning for music
-  end
-  else if chan >= 0 then
-  begin
-    if Pan < -1.0 then Pan := -1.0 else if Pan > 1.0 then Pan := 1.0;
-    Pan := Pan+1.0; // 0..2
-    l := trunc(127.0*(2.0-Pan));
-    r := trunc(127.0*Pan);
-    Mix_SetPanning(chan, l, r);
-    ChanSIds[chan].pan := Pan;
-  end
-  else
-  begin
-    Result := False;
-  end;
-end;
-
-function e_chanSetVol (chan: Integer; Volume: Single): Boolean;
-var
-  vol: Integer;
-begin
-  Result := True;
-  if Volume < 0 then Volume := 0 else if Volume > 1 then Volume := 1;
-  vol := trunc(Volume*MIX_MAX_VOLUME);
-  if chan = N_MUSCHAN then
-  begin
-    MusVolume := vol;
-    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(vol);
-  end
-  else if chan >= 0 then
-  begin
-    ChanSIds[chan].oldvol := vol;
-    if ChanSIds[chan].muted then Mix_Volume(chan, 0) else Mix_Volume(chan, vol);
-  end
-  else
-  begin
-    Result := False;
-  end;
-end;
-
-function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
-var
-  chan: Integer;
-begin
-  Result := -1;
-  chan := e_PlaySound(ID);
-  e_chanSetPan(chan, Pan);
-  Result := chan;
-end;
-
-function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
-var
-  chan: Integer;
-begin
-  Result := -1;
-  chan := e_PlaySound(ID);
-  e_chanSetVol(chan, Volume);
-  Result := chan;
-end;
-
-function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
-var
-  chan: Integer;
-begin
-  Result := -1;
-  chan := e_PlaySound(ID);
-  e_chanSetPan(chan, Pan);
-  e_chanSetVol(chan, Volume);
-  Result := chan;
-end;
-
-procedure e_DeleteSound(ID: DWORD);
-var
-  i: Integer;
-begin
-  if ID > High(e_SoundsArray) then Exit;
-  if (e_SoundsArray[ID].Sound = nil) and (e_SoundsArray[ID].Music = nil) then Exit;
-
-  for i := 0 to N_CHANNELS-1 do
-  begin
-    if ChanSIds[i].id = ID then
-    begin
-      ChanSIds[i].id := NO_SOUND_ID;
-      Mix_HaltChannel(i);
-    end;
-  end;
-
-  if e_SoundsArray[ID].Sound <> nil then Mix_FreeChunk(e_SoundsArray[ID].Sound);
-  if e_SoundsArray[ID].Music <> nil then Mix_FreeMusic(e_SoundsArray[ID].Music);
-  if e_SoundsArray[ID].Data <> nil then FreeMem(e_SoundsArray[ID].Data);
-
-  e_SoundsArray[ID].Sound := nil;
-  e_SoundsArray[ID].Music := nil;
-  e_SoundsArray[ID].Data := nil;
-  e_SoundsArray[ID].nRefs := 0;
-end;
-
-procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
-var
-  i: Integer;
-  vol: Single;
-  ovol: Integer;
-begin
-  for i := 0 to N_CHANNELS-1 do
-  begin
-    ovol := ChanSIds[i].oldvol;
-    if setMode then
-    begin
-      vol := SoundMod;
-    end
-    else
-    begin
-      vol := (MIX_MAX_VOLUME+0.0)/ovol;
-      vol := vol*SoundMod;
-    end;
-    if vol < 0 then vol := 0 else if vol > 1 then vol := 1;
-    ChanSIds[i].oldvol := trunc(vol*MIX_MAX_VOLUME);
-    //if i = 0 then e_WriteLog(Format('modifying volumes: vol=%f; newvol=%d', [vol, ChanSIds[i].oldvol]), MSG_WARNING);
-    if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol);
-  end;
-  ovol := Mix_VolumeMusic(-1);
-  if ovol >= 0 then
-  begin
-    if setMode then
-    begin
-      vol := SoundMod;
-    end
-    else
-    begin
-      vol := (MIX_MAX_VOLUME+0.0)/ovol;
-      vol := vol * SoundMod;
-    end;
-    if vol < 0 then vol := 0 else if vol > 1 then vol := 1;
-    MusVolume := trunc(vol*MIX_MAX_VOLUME);
-    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
-  end;
-end;
-
-procedure e_MuteChannels(Enable: Boolean);
-var
-  i: Integer;
-begin
-  //if Enable = SoundMuted then Exit;
-  SoundMuted := Enable;
-  for i := 0 to N_CHANNELS-1 do
-  begin
-    if ChanSIds[i].muted <> SoundMuted then
-    begin
-      ChanSIds[i].muted := SoundMuted;
-      //e_WriteLog(Format('gmuting sound for channel %d', [i]), MSG_WARNING);
-      if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol);
-    end;
-  end;
-  //if SoundMuted then e_WriteLog('muting music', MSG_NOTIFY) else e_WriteLog(Format('unmuting music (%d)', [MusVolume]), MSG_NOTIFY);
-  if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
-end;
-
-procedure e_StopChannels();
-var
-  i: Integer;
-begin
-  Mix_HaltChannel(-1);
-  Mix_HaltMusic();
-  for i := 0 to High(e_SoundsArray) do e_SoundsArray[i].nRefs := 0;
-  for i := 0 to N_CHANNELS-1 do ChanSIds[i].id := NO_SOUND_ID;
-end;
-
-procedure e_RemoveAllSounds();
-var
-  i: Integer;
-begin
-  if SoundInitialized then e_StopChannels();
-  for i := 0 to High(e_SoundsArray) do e_DeleteSound(i);
-  SetLength(e_SoundsArray, 0);
-  e_SoundsArray := nil;
-end;
-
-procedure e_ReleaseSoundSystem();
-begin
-  e_RemoveAllSounds();
-  if SoundInitialized then
-  begin
-    Mix_CloseAudio();
-    SoundInitialized := False;
-  end;
-end;
-
-procedure e_SoundUpdate();
-begin
-  //FMOD_System_Update(F_System);
-end;
-
-
-{ TBasicSound: }
-
-constructor TBasicSound.Create();
-begin
-  FID := NO_SOUND_ID;
-  FMusic := False;
-  FChanNum := -1;
-  FPosition := 0;
-  FPriority := 128;
-end;
-
-destructor TBasicSound.Destroy();
-begin
-  FreeSound();
-  inherited;
-end;
-
-function TBasicSound.GetChan (): Integer;
-begin
-  if (FID <> NO_SOUND_ID) and (FChanNum >= 0) and (FChanNum < N_CHANNELS) then
-  begin
-    if ChanSIds[FChanNum].id <> FID then FChanNum := -1;
-  end
-  else if e_isMusic(FID) then
-  begin
-    FChanNum := N_MUSCHAN;
-  end;
-  Result := FChanNum;
-end;
-
-procedure TBasicSound.FreeSound();
-begin
-  if FID = NO_SOUND_ID then Exit;
-  Stop();
-  FID := NO_SOUND_ID;
-  FMusic := False;
-  FPosition := 0;
-  FChanNum := -1;
-end;
-
-// aPos: msecs
-function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
-begin
-  Result := False;
-  if (FID = NO_SOUND_ID) or not SoundInitialized then Exit;
-  FChanNum := e_PlaySoundPanVolume(FID, Pan, Volume);
-  Result := (FChanNum >= 0);
-  //if e_isMusic(FID) then e_WriteLog(Format('playing music (%u)', [FID]), MSG_NOTIFY);
-  //TODO: aPos
-end;
-
-procedure TBasicSound.SetID(ID: DWORD);
-begin
-  FreeSound();
-  FID := ID;
-  if ID <> NO_SOUND_ID then
-  begin
-    FMusic := e_SoundsArray[ID].isMusic;
-  end;
-  FChanNum := -1;
-end;
-
-function TBasicSound.IsPlaying(): Boolean;
-var
-  chan: Integer;
-begin
-  Result := False;
-  if e_isSound(FID) then
-  begin
-    //e_WriteLog(Format('IsPlaying: FID=%u; FChanNum=%d', [FID, FChanNum]), MSG_WARNING);
-    chan := Channel;
-    if chan < 0 then
-    begin
-      //e_WriteLog(Format('IsPlaying: FID=%u; ONA', [FID]), MSG_WARNING);
-      Exit;
-    end;
-    //Result := (Mix_Playing(chan) > 0)
-    //e_WriteLog(Format('IsPlaying: FID=%u; TAN', [FID]), MSG_WARNING);
-    Result := True;
-  end
-  else if e_isMusic(FID) then
-  begin
-    Result := (Mix_PlayingMusic() > 0);
-  end;
-end;
-
-procedure TBasicSound.Stop();
-var
-  chan: Integer;
-begin
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan >= 0 then
-    begin
-      //GetPosition();
-      Mix_HaltChannel(chan);
-    end;
-  end
-  else if e_isMusic(FID) then
-  begin
-    Mix_HaltMusic();
-  end;
-  FChanNum := -1;
-end;
-
-function TBasicSound.IsPaused(): Boolean;
-var
-  chan: Integer;
-begin
-  Result := False;
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    Result := (Mix_Paused(chan) > 0);
-  end
-  else if e_isMusic(FID) then
-  begin
-    Result := (Mix_PausedMusic() > 0);
-  end;
-end;
-
-procedure TBasicSound.Pause(Enable: Boolean);
-var
-  chan: Integer;
-  pl: Boolean;
-begin
-  Enable := not Enable; // fuckin' double negation
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    pl := not (Mix_Paused(chan) > 0);
-    if pl <> Enable then
-    begin
-      if Enable then Mix_Resume(chan) else Mix_Pause(chan);
-    end;
-  end
-  else if e_isMusic(FID) then
-  begin
-    pl := not (Mix_PausedMusic() > 0);
-    if pl <> Enable then
-    begin
-      if Enable then Mix_ResumeMusic() else Mix_PauseMusic();
-    end;
-  end;
-  {
-  if Enable then
-  begin
-    res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
-    if res <> FMOD_OK then
-    begin
-    end;
-  end;
-  }
-end;
-
-function TBasicSound.GetVolume(): Single;
-var
-  chan: Integer;
-begin
-  Result := 0.0;
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    Result := (ChanSIds[chan].oldvol+0.0)/(MIX_MAX_VOLUME+0.0);
-  end
-  else if e_isMusic(FID) then
-  begin
-    Result := (MusVolume+0.0)/(MIX_MAX_VOLUME+0.0);
-  end;
-end;
-
-procedure TBasicSound.SetVolume(Volume: Single);
-var
-  chan: Integer;
-begin
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    //e_WriteLog(Format('SetVolume: chan=%d; Volume=%f', [chan, Volume]), MSG_WARNING);
-    e_chanSetVol(chan, Volume);
-  end
-  else if e_isMusic(FID) then
-  begin
-    //e_WriteLog(Format('SetVolume: chan=MUSIC; Volume=%f', [Volume]), MSG_WARNING);
-    e_chanSetVol(N_MUSCHAN, Volume);
-  end;
-end;
-
-function TBasicSound.GetPan(): Single;
-var
-  chan: Integer;
-begin
-  Result := 1.0;
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    Result := ChanSIds[chan].pan;
-  end;
-end;
-
-procedure TBasicSound.SetPan(Pan: Single);
-var
-  chan: Integer;
-begin
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    e_chanSetPan(chan, Pan);
-  end;
-end;
-
-function TBasicSound.IsMuted(): Boolean;
-var
-  chan: Integer;
-begin
-  Result := False;
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    Result := ChanSIds[chan].muted;
-  end
-  else if e_isMusic(FID) then
-  begin
-    Result := SoundMuted;
-  end;
-end;
-
-procedure TBasicSound.Mute(Enable: Boolean);
-var
-  chan: Integer;
-begin
-  if e_isSound(FID) then
-  begin
-    chan := Channel;
-    if chan < 0 then Exit;
-    if ChanSIds[chan].muted <> Enable then
-    begin
-      //e_WriteLog(Format('muting sound for channel %d', [cnan]), MSG_WARNING);
-      ChanSIds[chan].muted := Enable;
-      if ChanSIds[chan].muted then Mix_Volume(chan, 0) else Mix_Volume(chan, ChanSIds[chan].oldvol);
-    end;
-  end
-  else if e_isMusic(FID) then
-  begin
-    if Enable then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
-  end;
-end;
-
-//TODO
-function TBasicSound.GetPosition(): DWORD;
-begin
-  Result := 0;
-{
-  if FChanNum < 0 then Exit;
-  res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
-  if res <> FMOD_OK then
-  begin
-    Exit;
-  end;
-  Result := FPosition;
-}
-end;
-
-//TODO
-procedure TBasicSound.SetPosition(aPos: DWORD);
-begin
-  FPosition := aPos;
-{
-  if FChanNum < 0 then Exit;
-  res := FMOD_Channel_SetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
-  if res <> FMOD_OK then
-  begin
-  end;
-}
-end;
-
-//TODO
-procedure TBasicSound.SetPriority(priority: Integer);
-begin
-{
-  if (FChanNum <> nil) and (FPriority <> priority) and
-     (priority >= 0) and (priority <= 256) then
-  begin
-    FPriority := priority;
-    res := FMOD_Channel_SetPriority(FChanNum, priority);
-    if res <> FMOD_OK then
-    begin
-    end;
-  end;
-}
-end;
-
-end.
+{$IFDEF USE_SDLMIXER}
+  {$I e_sound_sdl.inc}
+{$ELSE}
+  {$I e_sound_fmod.inc}
+{$ENDIF}
diff --git a/src/engine/e_sound_fmod.inc b/src/engine/e_sound_fmod.inc
new file mode 100644 (file)
index 0000000..ceb0c0f
--- /dev/null
@@ -0,0 +1,1017 @@
+interface
+
+uses
+  fmod,
+  fmodtypes,
+  fmoderrors,
+  e_log,
+  SysUtils;
+
+type
+  TSoundRec = record
+    Data: Pointer;
+    Sound: FMOD_SOUND;
+    isMusic: Boolean;
+    nRefs: Integer;
+  end;
+
+  TBasicSound = class (TObject)
+  private
+    FChannel: FMOD_CHANNEL;
+
+  protected
+    FID: DWORD;
+    FMusic: Boolean;
+    FPosition: DWORD;
+    FPriority: Integer;
+
+    function RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+    procedure SetID(ID: DWORD);
+    procedure FreeSound();
+    function IsPlaying(): Boolean;
+    procedure Stop();
+    function IsPaused(): Boolean;
+    procedure Pause(Enable: Boolean);
+    function GetVolume(): Single;
+    procedure SetVolume(Volume: Single);
+    function GetPan(): Single;
+    procedure SetPan(Pan: Single);
+    function IsMuted(): Boolean;
+    procedure Mute(Enable: Boolean);
+    function GetPosition(): DWORD;
+    procedure SetPosition(aPos: DWORD);
+    procedure SetPriority(priority: Integer);
+  end;
+
+const
+  NO_SOUND_ID = DWORD(-1);
+
+function e_InitSoundSystem(): Boolean;
+
+function e_LoadSound(FileName: string; var ID: DWORD; bLoop: Boolean): Boolean;
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
+
+function e_PlaySound(ID: DWORD): Integer;
+function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
+function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
+function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
+
+procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
+procedure e_MuteChannels(Enable: Boolean);
+procedure e_StopChannels();
+
+procedure e_DeleteSound(ID: DWORD);
+procedure e_RemoveAllSounds();
+procedure e_ReleaseSoundSystem();
+procedure e_SoundUpdate();
+
+var
+  e_SoundsArray: array of TSoundRec = nil;
+
+implementation
+
+uses
+  g_window, g_options, BinEditor;
+
+const
+  N_CHANNELS = 512;
+
+var
+  F_System: FMOD_SYSTEM = nil;
+  SoundMuted: Boolean = False;
+
+
+function Channel_Callback(channel: FMOD_CHANNEL; callbacktype: FMOD_CHANNEL_CALLBACKTYPE;
+                          commanddata1: Pointer; commanddata2: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+var
+  res: FMOD_RESULT;
+  sound: FMOD_SOUND;
+  ud: Pointer;
+  id: DWORD;
+
+begin
+  res := FMOD_OK;
+
+  if callbacktype = FMOD_CHANNEL_CALLBACKTYPE_END then
+  begin
+    res := FMOD_Channel_GetCurrentSound(channel, sound);
+    if res = FMOD_OK then
+    begin
+      res := FMOD_Sound_GetUserData(sound, ud);
+      if res = FMOD_OK then
+      begin
+        id := DWORD(ud^);
+        if id < DWORD(Length(e_SoundsArray)) then
+          if e_SoundsArray[id].nRefs > 0 then
+            Dec(e_SoundsArray[id].nRefs);
+      end;
+    end;
+  end;
+
+  Result := res;
+end;
+
+function TryInitWithOutput(Output: FMOD_OUTPUTTYPE; OutputName: String): FMOD_RESULT;
+begin
+  e_WriteLog('Trying with ' + OutputName + '...', MSG_WARNING);
+  Result := FMOD_System_SetOutput(F_System, Output);
+  if Result <> FMOD_OK then
+  begin
+    e_WriteLog('Error setting FMOD output to ' + OutputName + '!', MSG_WARNING);
+    e_WriteLog(FMOD_ErrorString(Result), MSG_WARNING);
+    Exit;
+  end;
+  Result := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
+  if Result <> FMOD_OK then
+  begin
+    e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
+    e_WriteLog(FMOD_ErrorString(Result), MSG_WARNING);
+    Exit;
+  end;
+end;
+
+function e_TrySS (Freq: Integer; forceNoSound: Boolean): Boolean;
+var
+  res: FMOD_RESULT;
+  ver: Cardinal;
+  output: FMOD_OUTPUTTYPE;
+  drv: Integer;
+
+begin
+  Result := False;
+  e_WriteLog(Format('Trying to initialize FMOD with %d', [Freq]), MSG_NOTIFY);
+
+  res := FMOD_System_Create(F_System);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error creating FMOD system:', MSG_FATALERROR);
+    e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
+    Exit;
+  end;
+
+  res := FMOD_System_GetVersion(F_System, ver);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error getting FMOD version:', MSG_FATALERROR);
+    e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
+    Exit;
+  end;
+
+  if ver < FMOD_VERSION then
+  begin
+    e_WriteLog('FMOD library version is too old! Need '+IntToStr(FMOD_VERSION), MSG_FATALERROR);
+    Exit;
+  end;
+
+  res := FMOD_System_SetSoftwareFormat(F_System, Freq, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error setting FMOD software format!', MSG_FATALERROR);
+    e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
+    Exit;
+  end;
+
+  res := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
+    e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
+
+    {$IFDEF LINUX}
+    res := TryInitWithOutput(FMOD_OUTPUTTYPE_ALSA, 'OUTPUTTYPE_ALSA');
+    if res <> FMOD_OK then
+      res := TryInitWithOutput(FMOD_OUTPUTTYPE_OSS, 'OUTPUTTYPE_OSS');
+    {$ENDIF}
+    if (res <> FMOD_OK) and not forceNoSound then Exit;
+    if res <> FMOD_OK then
+      res := TryInitWithOutput(FMOD_OUTPUTTYPE_NOSOUND, 'OUTPUTTYPE_NOSOUND');
+    if res <> FMOD_OK then
+    begin
+      e_WriteLog('FMOD: Giving up, can''t init any output.', MSG_FATALERROR);
+      Exit;
+    end;
+  end;
+
+  res := FMOD_System_GetOutput(F_System, output);
+  if res <> FMOD_OK then
+    e_WriteLog('Error getting FMOD output!', MSG_WARNING)
+  else
+    case output of
+      FMOD_OUTPUTTYPE_NOSOUND: e_WriteLog('FMOD Output Method: NOSOUND', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_NOSOUND_NRT: e_WriteLog('FMOD Output Method: NOSOUND_NRT', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_DSOUND: e_WriteLog('FMOD Output Method: DSOUND', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_WINMM: e_WriteLog('FMOD Output Method: WINMM', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_OPENAL: e_WriteLog('FMOD Output Method: OPENAL', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_WASAPI: e_WriteLog('FMOD Output Method: WASAPI', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_ASIO: e_WriteLog('FMOD Output Method: ASIO', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_OSS:  e_WriteLog('FMOD Output Method: OSS', MSG_NOTIFY);
+      FMOD_OUTPUTTYPE_ALSA: e_Writelog('FMOD Output Method: ALSA', MSG_NOTIFY);
+      else e_WriteLog('FMOD Output Method: Unknown', MSG_NOTIFY);
+    end;
+
+  res := FMOD_System_GetDriver(F_System, drv);
+  if res <> FMOD_OK then
+    e_WriteLog('Error getting FMOD driver!', MSG_WARNING)
+  else
+    e_WriteLog('FMOD driver id: '+IntToStr(drv), MSG_NOTIFY);
+
+  Result := True;
+end;
+
+function e_InitSoundSystem(): Boolean;
+begin
+  Result := e_TrySS(48000, False);
+  if not Result then Result := e_TrySS(44100, True);
+end;
+
+function FindESound(): DWORD;
+var
+  i: Integer;
+
+begin
+  if e_SoundsArray <> nil then
+    for i := 0 to High(e_SoundsArray) do
+      if e_SoundsArray[i].Sound = nil then
+      begin
+        Result := i;
+        Exit;
+      end;
+
+  if e_SoundsArray = nil then
+    begin
+      SetLength(e_SoundsArray, 16);
+      Result := 0;
+    end
+  else
+    begin
+      Result := High(e_SoundsArray) + 1;
+      SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
+    end;
+end;
+
+function e_LoadSound(FileName: String; var ID: DWORD; bLoop: Boolean): Boolean;
+var
+  find_id: DWORD;
+  res: FMOD_RESULT;
+  bt: Cardinal;
+  ud: Pointer;
+
+begin
+  Result := False;
+
+  e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
+
+  find_id := FindESound();
+
+  if bLoop then
+    bt := FMOD_LOOP_NORMAL
+  else
+    bt := FMOD_LOOP_OFF;
+
+  if not bLoop then
+    res := FMOD_System_CreateSound(F_System, PAnsiChar(FileName),
+             bt + FMOD_2D + FMOD_HARDWARE,
+             nil, e_SoundsArray[find_id].Sound)
+  else
+    res := FMOD_System_CreateStream(F_System, PAnsiChar(FileName),
+             bt + FMOD_2D + FMOD_HARDWARE,
+             nil, e_SoundsArray[find_id].Sound);
+  if res <> FMOD_OK then
+  begin
+    e_SoundsArray[find_id].Sound := nil;
+    Exit;
+  end;
+
+  GetMem(ud, SizeOf(DWORD));
+  DWORD(ud^) := find_id;
+  res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
+  if res <> FMOD_OK then
+  begin
+    e_SoundsArray[find_id].Sound := nil;
+    Exit;
+  end;
+
+  e_SoundsArray[find_id].Data := nil;
+  e_SoundsArray[find_id].isMusic := bLoop;
+  e_SoundsArray[find_id].nRefs := 0;
+
+  ID := find_id;
+
+  Result := True;
+end;
+
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
+var
+  find_id: DWORD;
+  res: FMOD_RESULT;
+  sz: Integer;
+  bt: Cardinal;
+  soundExInfo: FMOD_CREATESOUNDEXINFO;
+  ud: Pointer;
+
+begin
+  Result := False;
+
+  find_id := FindESound();
+
+  sz := SizeOf(FMOD_CREATESOUNDEXINFO);
+  FillMemory(@soundExInfo, sz, 0);
+  soundExInfo.cbsize := sz;
+  soundExInfo.length := Length;
+
+  if bLoop then
+    bt := FMOD_LOOP_NORMAL
+  else
+    bt := FMOD_LOOP_OFF;
+
+  if not bLoop then
+    res := FMOD_System_CreateSound(F_System, pData,
+             bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
+             @soundExInfo, e_SoundsArray[find_id].Sound)
+  else
+    res := FMOD_System_CreateStream(F_System, pData,
+             bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
+             @soundExInfo, e_SoundsArray[find_id].Sound);
+  if res <> FMOD_OK then
+  begin
+    e_SoundsArray[find_id].Sound := nil;
+    Exit;
+  end;
+
+  GetMem(ud, SizeOf(DWORD));
+  DWORD(ud^) := find_id;
+  res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
+  if res <> FMOD_OK then
+  begin
+    e_SoundsArray[find_id].Sound := nil;
+    Exit;
+  end;
+
+  e_SoundsArray[find_id].Data := pData;
+  e_SoundsArray[find_id].isMusic := bLoop;
+  e_SoundsArray[find_id].nRefs := 0;
+
+  ID := find_id;
+
+  Result := True;
+end;
+
+function e_PlaySound(ID: DWORD): Integer;
+var
+  res: FMOD_RESULT;
+  Chan: FMOD_CHANNEL;
+
+begin
+  if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  Result := -1;
+
+  res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
+           e_SoundsArray[ID].Sound, False, Chan);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if SoundMuted then
+  begin
+    res := FMOD_Channel_SetMute(Chan, True);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+
+  Inc(e_SoundsArray[ID].nRefs);
+  Result := 0;
+end;
+
+function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
+var
+  res: FMOD_RESULT;
+  Chan: FMOD_CHANNEL;
+
+begin
+  if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  Result := -1;
+
+  res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
+           e_SoundsArray[ID].Sound, False, Chan);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  res := FMOD_Channel_SetPan(Chan, Pan);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if SoundMuted then
+  begin
+    res := FMOD_Channel_SetMute(Chan, True);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+
+  Inc(e_SoundsArray[ID].nRefs);
+  Result := 0;
+end;
+
+function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
+var
+  res: FMOD_RESULT;
+  Chan: FMOD_CHANNEL;
+
+begin
+  if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  Result := -1;
+
+  res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
+           e_SoundsArray[ID].Sound, False, Chan);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  res := FMOD_Channel_SetVolume(Chan, Volume);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if SoundMuted then
+  begin
+    res := FMOD_Channel_SetMute(Chan, True);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+
+  Inc(e_SoundsArray[ID].nRefs);
+  Result := 0;
+end;
+
+function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
+var
+  res: FMOD_RESULT;
+  Chan: FMOD_CHANNEL;
+
+begin
+  if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  Result := -1;
+
+  res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
+           e_SoundsArray[ID].Sound, False, Chan);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  res := FMOD_Channel_SetPan(Chan, Pan);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetVolume(Chan, Volume);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if SoundMuted then
+  begin
+    res := FMOD_Channel_SetMute(Chan, True);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+
+  Inc(e_SoundsArray[ID].nRefs);
+  Result := 0;
+end;
+
+procedure e_DeleteSound(ID: DWORD);
+var
+  res: FMOD_RESULT;
+  ud: Pointer;
+
+begin
+  if e_SoundsArray[ID].Sound = nil then
+    Exit;
+
+  if e_SoundsArray[ID].Data <> nil then
+    FreeMem(e_SoundsArray[ID].Data);
+
+  res := FMOD_Sound_GetUserData(e_SoundsArray[ID].Sound, ud);
+  if res = FMOD_OK then
+  begin
+    FreeMem(ud);
+  end;
+
+  res := FMOD_Sound_Release(e_SoundsArray[ID].Sound);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error releasing sound:', MSG_WARNING);
+    e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
+  end;
+
+  e_SoundsArray[ID].Sound := nil;
+  e_SoundsArray[ID].Data := nil;
+end;
+
+procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
+var
+  res: FMOD_RESULT;
+  i: Integer;
+  Chan: FMOD_CHANNEL;
+  vol: Single;
+
+begin
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    Chan := nil;
+    res := FMOD_System_GetChannel(F_System, i, Chan);
+
+    if (res = FMOD_OK) and (Chan <> nil) then
+    begin
+      res := FMOD_Channel_GetVolume(Chan, vol);
+
+      if res = FMOD_OK then
+      begin
+        if setMode then
+          vol := SoundMod
+        else
+          vol := vol * SoundMod;
+
+        res := FMOD_Channel_SetVolume(Chan, vol);
+
+        if res <> FMOD_OK then
+        begin
+        end;
+      end;
+    end;
+  end;
+end;
+
+procedure e_MuteChannels(Enable: Boolean);
+var
+  res: FMOD_RESULT;
+  i: Integer;
+  Chan: FMOD_CHANNEL;
+
+begin
+  if Enable = SoundMuted then
+    Exit;
+
+  SoundMuted := Enable;
+
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    Chan := nil;
+    res := FMOD_System_GetChannel(F_System, i, Chan);
+
+    if (res = FMOD_OK) and (Chan <> nil) then
+    begin
+      res := FMOD_Channel_SetMute(Chan, Enable);
+
+      if res <> FMOD_OK then
+      begin
+      end;
+    end;
+  end;
+end;
+
+procedure e_StopChannels();
+var
+  res: FMOD_RESULT;
+  i: Integer;
+  Chan: FMOD_CHANNEL;
+
+begin
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    Chan := nil;
+    res := FMOD_System_GetChannel(F_System, i, Chan);
+
+    if (res = FMOD_OK) and (Chan <> nil) then
+    begin
+      res := FMOD_Channel_Stop(Chan);
+
+      if res <> FMOD_OK then
+      begin
+      end;
+    end;
+  end;
+end;
+
+procedure e_RemoveAllSounds();
+var
+  i: Integer;
+
+begin
+  for i := 0 to High(e_SoundsArray) do
+    if e_SoundsArray[i].Sound <> nil then
+      e_DeleteSound(i);
+
+  SetLength(e_SoundsArray, 0);
+  e_SoundsArray := nil;
+end;
+
+procedure e_ReleaseSoundSystem();
+var
+  res: FMOD_RESULT;
+
+begin
+  e_RemoveAllSounds();
+
+  res := FMOD_System_Close(F_System);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error closing FMOD system!', MSG_FATALERROR);
+    e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
+    Exit;
+  end;
+
+  res := FMOD_System_Release(F_System);
+  if res <> FMOD_OK then
+  begin
+    e_WriteLog('Error releasing FMOD system!', MSG_FATALERROR);
+    e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
+  end;
+end;
+
+procedure e_SoundUpdate();
+begin
+  FMOD_System_Update(F_System);
+end;
+
+{ TBasicSound: }
+
+constructor TBasicSound.Create();
+begin
+  FID := NO_SOUND_ID;
+  FMusic := False;
+  FChannel := nil;
+  FPosition := 0;
+  FPriority := 128;
+end;
+
+destructor TBasicSound.Destroy();
+begin
+  FreeSound();
+  inherited;
+end;
+
+procedure TBasicSound.FreeSound();
+begin
+  if FID = NO_SOUND_ID then
+    Exit;
+
+  Stop();
+  FID := NO_SOUND_ID;
+  FMusic := False;
+  FPosition := 0;
+end;
+
+function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
+var
+  res: FMOD_RESULT;
+
+begin
+  if e_SoundsArray[FID].nRefs >= gMaxSimSounds then
+  begin
+    Result := True;
+    Exit;
+  end;
+
+  Result := False;
+
+  if FID = NO_SOUND_ID then
+    Exit;
+
+  res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
+           e_SoundsArray[FID].Sound, False, FChannel);
+  if res <> FMOD_OK then
+  begin
+    FChannel := nil;
+    Exit;
+  end;
+
+  res := FMOD_Channel_SetPosition(FChannel, aPos, FMOD_TIMEUNIT_MS);
+  if res <> FMOD_OK then
+    begin
+      FPosition := 0;
+    end
+  else
+    FPosition := aPos;
+
+  res := FMOD_Channel_SetPan(FChannel, Pan);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetVolume(FChannel, Volume);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  res := FMOD_Channel_SetCallback(FChannel, Channel_Callback);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if SoundMuted then
+  begin
+    res := FMOD_Channel_SetMute(FChannel, True);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+
+  Inc(e_SoundsArray[FID].nRefs);
+  Result := True;
+end;
+
+procedure TBasicSound.SetID(ID: DWORD);
+begin
+  FreeSound();
+  FID := ID;
+  FMusic := e_SoundsArray[ID].isMusic;
+end;
+
+function TBasicSound.IsPlaying(): Boolean;
+var
+  res: FMOD_RESULT;
+  b: LongBool;
+
+begin
+  Result := False;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_IsPlaying(FChannel, b);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := b;
+end;
+
+procedure TBasicSound.Stop();
+var
+  res: FMOD_RESULT;
+
+begin
+  if FChannel = nil then
+    Exit;
+
+  GetPosition();
+
+  res := FMOD_Channel_Stop(FChannel);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  FChannel := nil;
+end;
+
+function TBasicSound.IsPaused(): Boolean;
+var
+  res: FMOD_RESULT;
+  b: LongBool;
+
+begin
+  Result := False;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_GetPaused(FChannel, b);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := b;
+end;
+
+procedure TBasicSound.Pause(Enable: Boolean);
+var
+  res: FMOD_RESULT;
+
+begin
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_SetPaused(FChannel, Enable);
+  if res <> FMOD_OK then
+  begin
+  end;
+
+  if Enable then
+  begin
+    res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+end;
+
+function TBasicSound.GetVolume(): Single;
+var
+  res: FMOD_RESULT;
+  vol: Single;
+
+begin
+  Result := 0.0;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_GetVolume(FChannel, vol);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := vol;
+end;
+
+procedure TBasicSound.SetVolume(Volume: Single);
+var
+  res: FMOD_RESULT;
+
+begin
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_SetVolume(FChannel, Volume);
+  if res <> FMOD_OK then
+  begin
+  end;
+end;
+
+function TBasicSound.GetPan(): Single;
+var
+  res: FMOD_RESULT;
+  pan: Single;
+
+begin
+  Result := 0.0;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_GetPan(FChannel, pan);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := pan;
+end;
+
+procedure TBasicSound.SetPan(Pan: Single);
+var
+  res: FMOD_RESULT;
+
+begin
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_SetPan(FChannel, Pan);
+  if res <> FMOD_OK then
+  begin
+  end;
+end;
+
+function TBasicSound.IsMuted(): Boolean;
+var
+  res: FMOD_RESULT;
+  b: LongBool;
+
+begin
+  Result := False;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_GetMute(FChannel, b);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := b;
+end;
+
+procedure TBasicSound.Mute(Enable: Boolean);
+var
+  res: FMOD_RESULT;
+
+begin
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_SetMute(FChannel, Enable);
+  if res <> FMOD_OK then
+  begin
+  end;
+end;
+
+function TBasicSound.GetPosition(): DWORD;
+var
+  res: FMOD_RESULT;
+
+begin
+  Result := 0;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+
+  Result := FPosition;
+end;
+
+procedure TBasicSound.SetPosition(aPos: DWORD);
+var
+  res: FMOD_RESULT;
+
+begin
+  FPosition := aPos;
+
+  if FChannel = nil then
+    Exit;
+
+  res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
+  if res <> FMOD_OK then
+  begin
+  end;
+end;
+
+procedure TBasicSound.SetPriority(priority: Integer);
+var
+  res: FMOD_RESULT;
+
+begin
+  if (FChannel <> nil) and (FPriority <> priority) and
+     (priority >= 0) and (priority <= 256) then
+  begin
+    FPriority := priority;
+    res := FMOD_Channel_SetPriority(FChannel, priority);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+end;
+
+end.
diff --git a/src/engine/e_sound_sdl.inc b/src/engine/e_sound_sdl.inc
new file mode 100644 (file)
index 0000000..eb039a2
--- /dev/null
@@ -0,0 +1,919 @@
+interface
+
+uses
+  sdl2,
+  SDL2_mixer,
+  e_log,
+  SysUtils;
+
+type
+  TSoundRec = record
+    Data: Pointer;
+    Sound: PMix_Chunk;
+    Music: PMix_Music;
+    isMusic: Boolean;
+    nRefs: Integer;
+  end;
+
+  TBasicSound = class (TObject)
+  private
+    FChanNum: Integer; // <0: no channel allocated
+
+  protected
+    FID: DWORD;
+    FMusic: Boolean;
+    FPosition: DWORD;
+    FPriority: Integer;
+
+    function RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
+    function GetChan (): Integer;
+
+    property Channel: Integer read GetChan;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+    procedure SetID(ID: DWORD);
+    procedure FreeSound();
+    function IsPlaying(): Boolean;
+    procedure Stop();
+    function IsPaused(): Boolean;
+    procedure Pause(Enable: Boolean);
+    function GetVolume(): Single;
+    procedure SetVolume(Volume: Single);
+    function GetPan(): Single;
+    procedure SetPan(Pan: Single);
+    function IsMuted(): Boolean;
+    procedure Mute(Enable: Boolean);
+    function GetPosition(): DWORD;
+    procedure SetPosition(aPos: DWORD);
+    procedure SetPriority(priority: Integer);
+  end;
+
+const
+  NO_SOUND_ID = DWORD(-1);
+
+function e_InitSoundSystem(): Boolean;
+
+function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean): Boolean;
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
+
+// returns channel number or -1
+function e_PlaySound(ID: DWORD): Integer;
+function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
+function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
+function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
+
+procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
+procedure e_MuteChannels(Enable: Boolean);
+procedure e_StopChannels();
+
+procedure e_DeleteSound(ID: DWORD);
+procedure e_RemoveAllSounds();
+procedure e_ReleaseSoundSystem();
+procedure e_SoundUpdate();
+
+var
+  e_SoundsArray: array of TSoundRec = nil;
+
+implementation
+
+uses
+  g_window, g_options, BinEditor;
+
+const
+  N_CHANNELS = 512;
+  N_MUSCHAN = N_CHANNELS+42;
+
+type
+  TChanInfo = record
+    id: DWORD; // sound id
+    muted: Boolean;
+    oldvol: Integer; // for muted
+    pan: Single;
+  end;
+
+var
+  SoundMuted: Boolean = False;
+  SoundInitialized: Boolean = False;
+  ChanSIds: array[0..N_CHANNELS] of TChanInfo;
+  MusVolume: Integer = MIX_MAX_VOLUME;
+
+
+procedure chanFinished (chan: Integer); cdecl;
+begin
+  //e_WriteLog(Format('chanFinished: %d', [chan]), MSG_NOTIFY);
+  if (chan >= 0) and (chan < N_CHANNELS) then
+  begin
+    if ChanSIds[chan].id <> NO_SOUND_ID then
+    begin
+      if (ChanSIds[chan].id <= High(e_SoundsArray)) and (e_SoundsArray[ChanSIds[chan].id].nRefs > 0) then
+      begin
+        Dec(e_SoundsArray[ChanSIds[chan].id].nRefs);
+      end;
+      ChanSIds[chan].id := NO_SOUND_ID;
+    end;
+  end;
+end;
+
+
+procedure dumpMusicType (ms: PMix_Music);
+begin
+  if ms = nil then
+  begin
+    e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY);
+  end
+  else
+  begin
+    case Mix_GetMusicType(ms^) of
+      TMix_MusicType.MUS_NONE:
+        e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY);
+      TMix_MusicType.MUS_CMD:
+        e_WriteLog('MUSIC FORMAT: CMD', MSG_NOTIFY);
+      TMix_MusicType.MUS_WAV:
+        e_WriteLog('MUSIC FORMAT: WAV', MSG_NOTIFY);
+      TMix_MusicType.MUS_MOD:
+        e_WriteLog('MUSIC FORMAT: MOD', MSG_NOTIFY);
+      TMix_MusicType.MUS_MID:
+        e_WriteLog('MUSIC FORMAT: MID', MSG_NOTIFY);
+      TMix_MusicType.MUS_OGG:
+        e_WriteLog('MUSIC FORMAT: OGG', MSG_NOTIFY);
+      TMix_MusicType.MUS_MP3:
+        e_WriteLog('MUSIC FORMAT: MP3', MSG_NOTIFY);
+      TMix_MusicType.MUS_MP3_MAD:
+        e_WriteLog('MUSIC FORMAT: MP3_MAD', MSG_NOTIFY);
+      TMix_MusicType.MUS_FLAC:
+        e_WriteLog('MUSIC FORMAT: FLAC', MSG_NOTIFY);
+      TMix_MusicType.MUS_MODPLUG:
+        e_WriteLog('MUSIC FORMAT: MODPLUG', MSG_NOTIFY);
+      otherwise
+        e_WriteLog('MUSIC FORMAT: UNKNOWN', MSG_NOTIFY);
+    end;
+  end;
+end;
+
+function e_InitSoundSystem(): Boolean;
+var
+  res, i: Integer;
+begin
+  if SoundInitialized then begin Result := true; Exit end;
+
+  Result := False;
+  SoundInitialized := False;
+
+  // wow, this is actually MIDI player!
+  // we need module player
+  res := Mix_Init(MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MODPLUG or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH);
+  e_WriteLog(Format('SDL: res=0x%x', [res]), MSG_NOTIFY);
+  if (res and MIX_INIT_FLAC) <> 0 then e_WriteLog('SDL: FLAC playback is active', MSG_NOTIFY);
+  if (res and MIX_INIT_MOD) <> 0 then e_WriteLog('SDL: MOD playback is active', MSG_NOTIFY);
+  if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', MSG_NOTIFY);
+  if (res and MIX_INIT_MP3) <> 0 then e_WriteLog('SDL: MP3 playback is active', MSG_NOTIFY);
+  if (res and MIX_INIT_OGG) <> 0 then e_WriteLog('SDL: OGG playback is active', MSG_NOTIFY);
+  if (res and MIX_INIT_FLUIDSYNTH) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', MSG_NOTIFY);
+
+  res := Mix_OpenAudio(48000, AUDIO_S16LSB, 2, 2048);
+  if res = -1 then res := Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 2048);
+  if res = -1 then
+  begin
+    e_WriteLog('Error initializing SDL mixer:', MSG_FATALERROR);
+    e_WriteLog(Mix_GetError(), MSG_FATALERROR);
+    Exit;
+  end;
+
+  Mix_AllocateChannels(N_CHANNELS);
+  Mix_ChannelFinished(chanFinished);
+
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    ChanSIds[i].id := NO_SOUND_ID;
+    ChanSIds[i].muted := SoundMuted;
+    ChanSIds[i].oldvol := MIX_MAX_VOLUME;
+    ChanSIds[i].pan := 1.0;
+  end;
+  MusVolume := MIX_MAX_VOLUME;
+
+  SoundInitialized := True;
+  Result := True;
+end;
+
+function e_isMusic (id: DWORD): Boolean;
+begin
+  Result := False;
+  if (e_SoundsArray <> nil) and (id <= High(e_SoundsArray)) then
+  begin
+    Result := (e_SoundsArray[id].Music <> nil);
+  end;
+end;
+
+function e_isSound (id: DWORD): Boolean;
+begin
+  Result := False;
+  if (e_SoundsArray <> nil) and (id <= High(e_SoundsArray)) then
+  begin
+    Result := (e_SoundsArray[id].Sound <> nil);
+  end;
+end;
+
+function FindESound(): DWORD;
+var
+  i: Integer;
+begin
+  if e_SoundsArray <> nil then
+  begin
+    for i := 0 to High(e_SoundsArray) do
+      if (e_SoundsArray[i].Sound = nil) and (e_SoundsArray[i].Music = nil) then
+      begin
+        Result := i;
+        Exit;
+      end;
+  end;
+  if e_SoundsArray = nil then
+  begin
+    SetLength(e_SoundsArray, 16);
+    Result := 0;
+  end
+  else
+  begin
+    Result := High(e_SoundsArray) + 1;
+    SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
+  end;
+  for i := Result to High(e_SoundsArray) do
+  begin
+    e_SoundsArray[i].Sound := nil;
+    e_SoundsArray[i].Music := nil;
+    e_SoundsArray[i].Data := nil;
+    e_SoundsArray[i].isMusic := False;
+    e_SoundsArray[i].nRefs := 0;
+  end;
+end;
+
+function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean): Boolean;
+var
+  find_id: DWORD;
+begin
+  ID := NO_SOUND_ID;
+  Result := False;
+  if not SoundInitialized then Exit;
+
+  if isMusic then e_WriteLog('Loading music '+FileName+'...', MSG_NOTIFY)
+  else e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
+
+  {
+  if isMusic then
+  begin
+    e_WriteLog('IGNORING MUSIC FROM FILE', MSG_WARNING);
+    Exit;
+  end;
+  }
+
+  find_id := FindESound();
+
+  e_SoundsArray[find_id].Data := nil;
+  e_SoundsArray[find_id].isMusic := isMusic;
+  e_SoundsArray[find_id].nRefs := 0;
+
+  if isMusic then
+  begin
+    e_WriteLog(Format('  MUSIC SLOT: %u', [find_id]), MSG_NOTIFY);
+    e_SoundsArray[find_id].Music := Mix_LoadMUS(PAnsiChar(FileName));
+    if e_SoundsArray[find_id].Music = nil then
+    begin
+      e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING);
+      e_WriteLog(Mix_GetError(), MSG_WARNING);
+      Exit;
+    end;
+    dumpMusicType(e_SoundsArray[find_id].Music);
+  end
+  else
+  begin
+    e_SoundsArray[find_id].Sound := Mix_LoadWAV(PAnsiChar(FileName));
+    if e_SoundsArray[find_id].Sound = nil then Exit;
+  end;
+
+  ID := find_id;
+
+  Result := True;
+end;
+
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
+var
+  find_id: DWORD;
+  rw: PSDL_RWops;
+  //pc: PChar;
+  isid3: Boolean;
+begin
+  ID := NO_SOUND_ID;
+  Result := False;
+  if not SoundInitialized then Exit;
+  isid3 := False;
+
+  {
+  if isMusic then
+  begin
+    e_WriteLog('IGNORING MUSIC FROM MEMORY', MSG_WARNING);
+    Exit;
+  end;
+  }
+
+  //FIXME: correctly skip ID3
+  {
+  pc := PChar(pData);
+  if (Length > $400) and (pc[0] = 'I') and (pc[1] = 'D') and (pc[2] = '3') then
+  begin
+    isid3 := True;
+    Inc(pc, $400);
+    pData := Pointer(pc);
+    Dec(Length, $400);
+    e_WriteLog('MUSIC: MP3 ID3 WORKAROUND APPLIED!', MSG_WARNING);
+  end;
+  }
+
+  rw := SDL_RWFromConstMem(pData, Length);
+  if rw = nil then Exit;
+
+  find_id := FindESound();
+
+  e_SoundsArray[find_id].Data := pData;
+  if isid3 then e_SoundsArray[find_id].Data := nil;
+  e_SoundsArray[find_id].isMusic := isMusic;
+  e_SoundsArray[find_id].nRefs := 0;
+
+  if isMusic then
+  begin
+    e_WriteLog(Format('  MUSIC SLOT: %u', [find_id]), MSG_NOTIFY);
+    e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0);
+    if e_SoundsArray[find_id].Music = nil then
+    begin
+      e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING);
+      e_WriteLog(Mix_GetError(), MSG_WARNING);
+    end
+    else
+    begin
+      dumpMusicType(e_SoundsArray[find_id].Music);
+    end;
+    //SDL_FreeRW(rw);
+    {
+    if e_SoundsArray[find_id].Music <> nil then
+    begin
+      Mix_FreeMusic(e_SoundsArray[find_id].Music);
+    end;
+    e_SoundsArray[find_id].Music := nil;
+    Exit;
+    }
+  end
+  else
+  begin
+    e_SoundsArray[find_id].Sound := Mix_LoadWAV_RW(rw, 0);
+  end;
+  //SDL_FreeRW(rw); // somehow it segfaults...
+  if (e_SoundsArray[find_id].Sound = nil) and (e_SoundsArray[find_id].Music = nil) then
+  begin
+    e_SoundsArray[find_id].Data := nil;
+    Exit;
+  end;
+
+  ID := find_id;
+
+  Result := True;
+end;
+
+function e_PlaySound (ID: DWORD): Integer;
+var
+  res: Integer = -1;
+begin
+  Result := -1;
+  if not SoundInitialized then Exit;
+
+  if e_isSound(ID) then
+  begin
+    if e_SoundsArray[ID].nRefs >= gMaxSimSounds then Exit;
+    Inc(e_SoundsArray[ID].nRefs);
+    res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
+    if res >= 0 then
+    begin
+      ChanSIds[res].id := ID;
+      ChanSIds[res].muted := SoundMuted;
+      if SoundMuted then Mix_Volume(res, 0) else Mix_Volume(res, ChanSIds[res].oldvol);
+      {
+      if e_SoundsArray[ID].isMusic then
+        res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, -1)
+      else
+        res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
+      }
+    end;
+  end
+  else
+  begin
+    if not e_isMusic(ID) then Exit;
+    Mix_HaltMusic();
+    res := Mix_PlayMusic(e_SoundsArray[ID].Music, -1);
+    if res >= 0 then res := N_MUSCHAN;
+    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
+    Result := res;
+  end;
+
+  Result := res;
+end;
+
+function e_chanSetPan (chan: Integer; Pan: Single): Boolean;
+var
+  l, r: UInt8;
+begin
+  Result := True;
+  if chan = N_MUSCHAN then
+  begin
+    // no panning for music
+  end
+  else if chan >= 0 then
+  begin
+    if Pan < -1.0 then Pan := -1.0 else if Pan > 1.0 then Pan := 1.0;
+    Pan := Pan+1.0; // 0..2
+    l := trunc(127.0*(2.0-Pan));
+    r := trunc(127.0*Pan);
+    Mix_SetPanning(chan, l, r);
+    ChanSIds[chan].pan := Pan;
+  end
+  else
+  begin
+    Result := False;
+  end;
+end;
+
+function e_chanSetVol (chan: Integer; Volume: Single): Boolean;
+var
+  vol: Integer;
+begin
+  Result := True;
+  if Volume < 0 then Volume := 0 else if Volume > 1 then Volume := 1;
+  vol := trunc(Volume*MIX_MAX_VOLUME);
+  if chan = N_MUSCHAN then
+  begin
+    MusVolume := vol;
+    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(vol);
+  end
+  else if chan >= 0 then
+  begin
+    ChanSIds[chan].oldvol := vol;
+    if ChanSIds[chan].muted then Mix_Volume(chan, 0) else Mix_Volume(chan, vol);
+  end
+  else
+  begin
+    Result := False;
+  end;
+end;
+
+function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
+var
+  chan: Integer;
+begin
+  Result := -1;
+  chan := e_PlaySound(ID);
+  e_chanSetPan(chan, Pan);
+  Result := chan;
+end;
+
+function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
+var
+  chan: Integer;
+begin
+  Result := -1;
+  chan := e_PlaySound(ID);
+  e_chanSetVol(chan, Volume);
+  Result := chan;
+end;
+
+function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
+var
+  chan: Integer;
+begin
+  Result := -1;
+  chan := e_PlaySound(ID);
+  e_chanSetPan(chan, Pan);
+  e_chanSetVol(chan, Volume);
+  Result := chan;
+end;
+
+procedure e_DeleteSound(ID: DWORD);
+var
+  i: Integer;
+begin
+  if ID > High(e_SoundsArray) then Exit;
+  if (e_SoundsArray[ID].Sound = nil) and (e_SoundsArray[ID].Music = nil) then Exit;
+
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    if ChanSIds[i].id = ID then
+    begin
+      ChanSIds[i].id := NO_SOUND_ID;
+      Mix_HaltChannel(i);
+    end;
+  end;
+
+  if e_SoundsArray[ID].Sound <> nil then Mix_FreeChunk(e_SoundsArray[ID].Sound);
+  if e_SoundsArray[ID].Music <> nil then Mix_FreeMusic(e_SoundsArray[ID].Music);
+  if e_SoundsArray[ID].Data <> nil then FreeMem(e_SoundsArray[ID].Data);
+
+  e_SoundsArray[ID].Sound := nil;
+  e_SoundsArray[ID].Music := nil;
+  e_SoundsArray[ID].Data := nil;
+  e_SoundsArray[ID].nRefs := 0;
+end;
+
+procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
+var
+  i: Integer;
+  vol: Single;
+  ovol: Integer;
+begin
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    ovol := ChanSIds[i].oldvol;
+    if setMode then
+    begin
+      vol := SoundMod;
+    end
+    else
+    begin
+      vol := (MIX_MAX_VOLUME+0.0)/ovol;
+      vol := vol*SoundMod;
+    end;
+    if vol < 0 then vol := 0 else if vol > 1 then vol := 1;
+    ChanSIds[i].oldvol := trunc(vol*MIX_MAX_VOLUME);
+    //if i = 0 then e_WriteLog(Format('modifying volumes: vol=%f; newvol=%d', [vol, ChanSIds[i].oldvol]), MSG_WARNING);
+    if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol);
+  end;
+  ovol := Mix_VolumeMusic(-1);
+  if ovol >= 0 then
+  begin
+    if setMode then
+    begin
+      vol := SoundMod;
+    end
+    else
+    begin
+      vol := (MIX_MAX_VOLUME+0.0)/ovol;
+      vol := vol * SoundMod;
+    end;
+    if vol < 0 then vol := 0 else if vol > 1 then vol := 1;
+    MusVolume := trunc(vol*MIX_MAX_VOLUME);
+    if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
+  end;
+end;
+
+procedure e_MuteChannels(Enable: Boolean);
+var
+  i: Integer;
+begin
+  //if Enable = SoundMuted then Exit;
+  SoundMuted := Enable;
+  for i := 0 to N_CHANNELS-1 do
+  begin
+    if ChanSIds[i].muted <> SoundMuted then
+    begin
+      ChanSIds[i].muted := SoundMuted;
+      //e_WriteLog(Format('gmuting sound for channel %d', [i]), MSG_WARNING);
+      if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol);
+    end;
+  end;
+  //if SoundMuted then e_WriteLog('muting music', MSG_NOTIFY) else e_WriteLog(Format('unmuting music (%d)', [MusVolume]), MSG_NOTIFY);
+  if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
+end;
+
+procedure e_StopChannels();
+var
+  i: Integer;
+begin
+  Mix_HaltChannel(-1);
+  Mix_HaltMusic();
+  for i := 0 to High(e_SoundsArray) do e_SoundsArray[i].nRefs := 0;
+  for i := 0 to N_CHANNELS-1 do ChanSIds[i].id := NO_SOUND_ID;
+end;
+
+procedure e_RemoveAllSounds();
+var
+  i: Integer;
+begin
+  if SoundInitialized then e_StopChannels();
+  for i := 0 to High(e_SoundsArray) do e_DeleteSound(i);
+  SetLength(e_SoundsArray, 0);
+  e_SoundsArray := nil;
+end;
+
+procedure e_ReleaseSoundSystem();
+begin
+  e_RemoveAllSounds();
+  if SoundInitialized then
+  begin
+    Mix_CloseAudio();
+    SoundInitialized := False;
+  end;
+end;
+
+procedure e_SoundUpdate();
+begin
+  //FMOD_System_Update(F_System);
+end;
+
+
+{ TBasicSound: }
+
+constructor TBasicSound.Create();
+begin
+  FID := NO_SOUND_ID;
+  FMusic := False;
+  FChanNum := -1;
+  FPosition := 0;
+  FPriority := 128;
+end;
+
+destructor TBasicSound.Destroy();
+begin
+  FreeSound();
+  inherited;
+end;
+
+function TBasicSound.GetChan (): Integer;
+begin
+  if (FID <> NO_SOUND_ID) and (FChanNum >= 0) and (FChanNum < N_CHANNELS) then
+  begin
+    if ChanSIds[FChanNum].id <> FID then FChanNum := -1;
+  end
+  else if e_isMusic(FID) then
+  begin
+    FChanNum := N_MUSCHAN;
+  end;
+  Result := FChanNum;
+end;
+
+procedure TBasicSound.FreeSound();
+begin
+  if FID = NO_SOUND_ID then Exit;
+  Stop();
+  FID := NO_SOUND_ID;
+  FMusic := False;
+  FPosition := 0;
+  FChanNum := -1;
+end;
+
+// aPos: msecs
+function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
+begin
+  Result := False;
+  if (FID = NO_SOUND_ID) or not SoundInitialized then Exit;
+  FChanNum := e_PlaySoundPanVolume(FID, Pan, Volume);
+  Result := (FChanNum >= 0);
+  //if e_isMusic(FID) then e_WriteLog(Format('playing music (%u)', [FID]), MSG_NOTIFY);
+  //TODO: aPos
+end;
+
+procedure TBasicSound.SetID(ID: DWORD);
+begin
+  FreeSound();
+  FID := ID;
+  if ID <> NO_SOUND_ID then
+  begin
+    FMusic := e_SoundsArray[ID].isMusic;
+  end;
+  FChanNum := -1;
+end;
+
+function TBasicSound.IsPlaying(): Boolean;
+var
+  chan: Integer;
+begin
+  Result := False;
+  if e_isSound(FID) then
+  begin
+    //e_WriteLog(Format('IsPlaying: FID=%u; FChanNum=%d', [FID, FChanNum]), MSG_WARNING);
+    chan := Channel;
+    if chan < 0 then
+    begin
+      //e_WriteLog(Format('IsPlaying: FID=%u; ONA', [FID]), MSG_WARNING);
+      Exit;
+    end;
+    //Result := (Mix_Playing(chan) > 0)
+    //e_WriteLog(Format('IsPlaying: FID=%u; TAN', [FID]), MSG_WARNING);
+    Result := True;
+  end
+  else if e_isMusic(FID) then
+  begin
+    Result := (Mix_PlayingMusic() > 0);
+  end;
+end;
+
+procedure TBasicSound.Stop();
+var
+  chan: Integer;
+begin
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan >= 0 then
+    begin
+      //GetPosition();
+      Mix_HaltChannel(chan);
+    end;
+  end
+  else if e_isMusic(FID) then
+  begin
+    Mix_HaltMusic();
+  end;
+  FChanNum := -1;
+end;
+
+function TBasicSound.IsPaused(): Boolean;
+var
+  chan: Integer;
+begin
+  Result := False;
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    Result := (Mix_Paused(chan) > 0);
+  end
+  else if e_isMusic(FID) then
+  begin
+    Result := (Mix_PausedMusic() > 0);
+  end;
+end;
+
+procedure TBasicSound.Pause(Enable: Boolean);
+var
+  chan: Integer;
+  pl: Boolean;
+begin
+  Enable := not Enable; // fuckin' double negation
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    pl := not (Mix_Paused(chan) > 0);
+    if pl <> Enable then
+    begin
+      if Enable then Mix_Resume(chan) else Mix_Pause(chan);
+    end;
+  end
+  else if e_isMusic(FID) then
+  begin
+    pl := not (Mix_PausedMusic() > 0);
+    if pl <> Enable then
+    begin
+      if Enable then Mix_ResumeMusic() else Mix_PauseMusic();
+    end;
+  end;
+  {
+  if Enable then
+  begin
+    res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+  }
+end;
+
+function TBasicSound.GetVolume(): Single;
+var
+  chan: Integer;
+begin
+  Result := 0.0;
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    Result := (ChanSIds[chan].oldvol+0.0)/(MIX_MAX_VOLUME+0.0);
+  end
+  else if e_isMusic(FID) then
+  begin
+    Result := (MusVolume+0.0)/(MIX_MAX_VOLUME+0.0);
+  end;
+end;
+
+procedure TBasicSound.SetVolume(Volume: Single);
+var
+  chan: Integer;
+begin
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    //e_WriteLog(Format('SetVolume: chan=%d; Volume=%f', [chan, Volume]), MSG_WARNING);
+    e_chanSetVol(chan, Volume);
+  end
+  else if e_isMusic(FID) then
+  begin
+    //e_WriteLog(Format('SetVolume: chan=MUSIC; Volume=%f', [Volume]), MSG_WARNING);
+    e_chanSetVol(N_MUSCHAN, Volume);
+  end;
+end;
+
+function TBasicSound.GetPan(): Single;
+var
+  chan: Integer;
+begin
+  Result := 1.0;
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    Result := ChanSIds[chan].pan;
+  end;
+end;
+
+procedure TBasicSound.SetPan(Pan: Single);
+var
+  chan: Integer;
+begin
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    e_chanSetPan(chan, Pan);
+  end;
+end;
+
+function TBasicSound.IsMuted(): Boolean;
+var
+  chan: Integer;
+begin
+  Result := False;
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    Result := ChanSIds[chan].muted;
+  end
+  else if e_isMusic(FID) then
+  begin
+    Result := SoundMuted;
+  end;
+end;
+
+procedure TBasicSound.Mute(Enable: Boolean);
+var
+  chan: Integer;
+begin
+  if e_isSound(FID) then
+  begin
+    chan := Channel;
+    if chan < 0 then Exit;
+    if ChanSIds[chan].muted <> Enable then
+    begin
+      //e_WriteLog(Format('muting sound for channel %d', [cnan]), MSG_WARNING);
+      ChanSIds[chan].muted := Enable;
+      if ChanSIds[chan].muted then Mix_Volume(chan, 0) else Mix_Volume(chan, ChanSIds[chan].oldvol);
+    end;
+  end
+  else if e_isMusic(FID) then
+  begin
+    if Enable then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
+  end;
+end;
+
+//TODO
+function TBasicSound.GetPosition(): DWORD;
+begin
+  Result := 0;
+{
+  if FChanNum < 0 then Exit;
+  res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
+  if res <> FMOD_OK then
+  begin
+    Exit;
+  end;
+  Result := FPosition;
+}
+end;
+
+//TODO
+procedure TBasicSound.SetPosition(aPos: DWORD);
+begin
+  FPosition := aPos;
+{
+  if FChanNum < 0 then Exit;
+  res := FMOD_Channel_SetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
+  if res <> FMOD_OK then
+  begin
+  end;
+}
+end;
+
+//TODO
+procedure TBasicSound.SetPriority(priority: Integer);
+begin
+{
+  if (FChanNum <> nil) and (FPriority <> priority) and
+     (priority >= 0) and (priority <= 256) then
+  begin
+    FPriority := priority;
+    res := FMOD_Channel_SetPriority(FChanNum, priority);
+    if res <> FMOD_OK then
+    begin
+    end;
+  end;
+}
+end;
+
+end.
index afade36c5be2ef804791907e9f9eb6a953f17a70..8b2ec19d63b1b45171056b45cf53aa07d2fd5556 100644 (file)
@@ -4,11 +4,29 @@ program Doom2DF;
 {$ENDIF}
 {$HINTS OFF}
 
+{$UNDEF XXX}
+{$IFDEF USE_SDLMIXER}
+ {$DEFINE XXX}
+{$ENDIF}
+{$IFDEF USE_FMOD}
+ {$IFDEF XXX}
+  {$ERROR define one of USE_SDLMIXER or USE_FMOD}
+ {$ELSE}
+  {$DEFINE XXX}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFNDEF XXX}
+  {$ERROR define USE_SDLMIXER or USE_FMOD}
+{$ENDIF}
+
 uses
   GL,
   GLExt,
   SDL2 in '../lib/sdl2/sdl2.pas',
+{$IFDEF USE_SDLMIXER}
   SDL2_mixer in '../lib/sdl2/SDL2_mixer.pas',
+{$ENDIF}
   ENet in '../lib/enet/enet.pp',
   ENetTypes in '../lib/enet/enettypes.pp',
   ENetList in '../lib/enet/enetlist.pp',
@@ -54,6 +72,12 @@ uses
   g_weapons in 'g_weapons.pas',
   g_window in 'g_window.pas',
   sysutils,
+{$IFDEF USE_FMOD}
+  fmod in '../lib/FMOD/fmod.pas',
+  fmoderrors in '../lib/FMOD/fmoderrors.pas',
+  fmodpresets in '../lib/FMOD/fmodpresets.pas',
+  fmodtypes in '../lib/FMOD/fmodtypes.pas',
+{$ENDIF}
   BinEditor in '../shared/BinEditor.pas',
   g_panel in 'g_panel.pas',
   g_language in 'g_language.pas';
index 102a05e7d216de3c7a07349d8bb1362b37e92e94..5c6067ba154f4fde8561eaf18fad985151f5744a 100644 (file)
@@ -49,7 +49,11 @@ begin
   e_WriteLog(gLanguage, MSG_NOTIFY);
   g_Language_Set(gLanguage);
 
+{$IFDEF USE_SDLMIXER}
+  if SDL_Init({SDL_INIT_JOYSTICK or SDL_INIT_TIMER or SDL_INIT_VIDEO or SDL_INIT_AUDIO}SDL_INIT_EVERYTHING) < 0 then
+{$ELSE}
   if SDL_Init(SDL_INIT_JOYSTICK or SDL_INIT_TIMER or SDL_INIT_VIDEO) < 0 then
+{$ENDIF}
     raise Exception.Create('SDL: Init failed: ' + SDL_GetError());
     
   SDL_StartTextInput();
@@ -82,7 +86,7 @@ begin
 
   if not gNoSound then
   begin
-    e_WriteLog('Initializing SDL2 mixer', MSG_NOTIFY);
+    e_WriteLog('Initializing sound system', MSG_NOTIFY);
     e_InitSoundSystem();
   end;
 
diff --git a/src/lib/fmod/fmod.inc b/src/lib/fmod/fmod.inc
new file mode 100644 (file)
index 0000000..b0421d7
--- /dev/null
@@ -0,0 +1,23 @@
+{$IFDEF WIN32}
+{$DEFINE MSWINDOWS}
+{$ENDIF}
+
+{$IFDEF FPC}
+  {$MODE DELPHI}
+  {$PACKRECORDS C}
+{$ENDIF}
+
+{$IFDEF VER110}
+  {$DEFINE DELPHI_5_OR_LOWER}
+{$ELSE}
+  {$IFDEF VER120}
+    {$DEFINE DELPHI_5_OR_LOWER}
+  {$ELSE}
+    {$IFDEF VER130}
+      {$DEFINE DELPHI_5_OR_LOWER}
+    {$ENDIF}
+  {$ENDIF}
+{$ENDIF}
+
+(* Force four-byte enums *)
+{$Z4}
diff --git a/src/lib/fmod/fmod.pas b/src/lib/fmod/fmod.pas
new file mode 100644 (file)
index 0000000..038ecad
--- /dev/null
@@ -0,0 +1,1004 @@
+(* ============================================================================================= *)
+(* FMOD Ex - Main Pascal header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2008. *)
+(*                                                                                               *)
+(* This header is for statically linking to the FMOD library.                                    *)
+(*                                                                                               *)
+(* ============================================================================================= *)
+
+unit fmod;
+
+{$I fmod.inc}
+
+interface
+
+uses
+  fmodtypes;
+
+(* ========================================================================================== *)
+(* FUNCTION PROTOTYPES                                                                        *)
+(* ========================================================================================== *)
+
+(*
+    FMOD System memory functions (optional).
+*)
+
+function FMOD_Memory_Initialize           (poolmem: Pointer; poollen: Integer; useralloc: FMOD_MEMORY_ALLOCCALLBACK; userrealloc: FMOD_MEMORY_REALLOCCALLBACK; userfree: FMOD_MEMORY_FREECALLBACK): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Memory_GetStats             (var currentalloced: Integer; var maxalloced: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    FMOD System factory functions.  Use this to create an FMOD System Instance.  below you will see FMOD_System_Init/Close to get started.
+*)
+
+function FMOD_System_Create               (var system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Release              (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'System' API
+*)
+
+(*
+     Pre-init functions.
+*)
+
+function FMOD_System_SetOutput              (system: FMOD_SYSTEM; output: FMOD_OUTPUTTYPE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetOutput              (system: FMOD_SYSTEM; var output: FMOD_OUTPUTTYPE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetNumDrivers          (system: FMOD_SYSTEM; var numdrivers: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_GetDriverName          (system: FMOD_SYSTEM; id: Integer; name: PChar; namelen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetDriverCaps          (system: FMOD_SYSTEM; id: Integer; var caps: Cardinal; var minfrequency, maxfrequency: Integer; var controlpanelspeakermode: FMOD_SPEAKERMODE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetDriver              (system: FMOD_SYSTEM; driver: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetDriver              (system: FMOD_SYSTEM; var driver: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetHardwareChannels    (system: FMOD_SYSTEM; min2d: Integer; max2d: Integer; min3d: Integer; max3d: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetHardwareChannels    (system: FMOD_SYSTEM; var numhw2d: Integer; var numhw3d: Integer; var total: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetSoftwareChannels    (system: FMOD_SYSTEM; numsoftwarechannels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetSoftwareChannels    (system: FMOD_SYSTEM; var numsoftwarechannels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetSoftwareFormat      (system: FMOD_SYSTEM; samplerate: Integer; format: FMOD_SOUND_FORMAT; numoutputchannels: Integer; maxinputchannels: Integer; resamplemethod: FMOD_DSP_RESAMPLER): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetSoftwareFormat      (system: FMOD_SYSTEM; var samplerate: Integer; var format: FMOD_SOUND_FORMAT; var numoutputchannels: Integer; var maxinputchannels: Integer; var bits: Integer; var resamplemethod: FMOD_DSP_RESAMPLER): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetDSPBufferSize       (system: FMOD_SYSTEM; bufferlength: Cardinal; numbuffers: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetDSPBufferSize       (system: FMOD_SYSTEM; var bufferlength: Cardinal; var numbuffers: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetFileSystem          (system: FMOD_SYSTEM; useropen: FMOD_FILE_OPENCALLBACK; userclose: FMOD_FILE_CLOSECALLBACK; userread: FMOD_FILE_READCALLBACK; userseek: FMOD_FILE_SEEKCALLBACK): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_AttachFileSystem       (system: FMOD_SYSTEM; useropen: FMOD_FILE_OPENCALLBACK; userclose: FMOD_FILE_CLOSECALLBACK; userread: FMOD_FILE_READCALLBACK; userseek: FMOD_FILE_SEEKCALLBACK): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetAdvancedSettings    (system: FMOD_SYSTEM; var settings:FMOD_ADVANCEDSETTINGS): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetAdvancedSettings    (system: FMOD_SYSTEM; var settings:FMOD_ADVANCEDSETTINGS): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetSpeakerMode         (system: FMOD_SYSTEM; speakermode: FMOD_SPEAKERMODE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetSpeakerMode         (system: FMOD_SYSTEM; var speakermode: FMOD_SPEAKERMODE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Plug-in support
+*)
+
+function FMOD_System_SetPluginPath          (system: FMOD_SYSTEM; const path: PChar): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_LoadPlugin             (system: FMOD_SYSTEM; const filename: PChar; var plugintype: FMOD_PLUGINTYPE; var index: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetNumPlugins          (system: FMOD_SYSTEM; plugintype: FMOD_PLUGINTYPE; var numplugins: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetPluginInfo          (system: FMOD_SYSTEM; plugintype: FMOD_PLUGINTYPE; index: Integer; name: PChar; namelen: Integer; version: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_UnloadPlugin           (system: FMOD_SYSTEM; plugintype: FMOD_PLUGINTYPE; index: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetOutputByPlugin      (system: FMOD_SYSTEM; index: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetOutputByPlugin      (system: FMOD_SYSTEM; var index: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_CreateCodec            (system: FMOD_SYSTEM; description:FMOD_CODEC_DESCRIPTION): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Init/Close
+*)
+
+function FMOD_System_Init                   (system: FMOD_SYSTEM; maxchannels: Integer; flags: Cardinal; const extradriverdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Close                  (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     General post-init system functions
+*)
+
+function FMOD_System_Update                 (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_UpdateFinished         (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_System_Set3DSettings          (system: FMOD_SYSTEM; dopplerscale, distancefactor, rolloffscale: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Get3DSettings          (system: FMOD_SYSTEM; var dopplerscale: Single; var distancefactor: Single; var rolloffscale: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Set3DNumListeners      (system: FMOD_SYSTEM; numlisteners: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Get3DNumListeners      (system: FMOD_SYSTEM; var numlisteners: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Set3DListenerAttributes(system: FMOD_SYSTEM; listener: Integer; const pos: FMOD_VECTOR; const vel: FMOD_VECTOR; const forward_: FMOD_VECTOR; const up: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_Get3DListenerAttributes(system: FMOD_SYSTEM; listener: Integer; var pos: FMOD_VECTOR; var vel: FMOD_VECTOR; var forward_: FMOD_VECTOR; var up: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+// function FMOD_System_SetSpeakerPosition     (system: FMOD_SYSTEM; speaker: FMOD_SPEAKER; x:Single; y:Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_GetSpeakerPosition     (system: FMOD_SYSTEM; speaker: FMOD_SPEAKER; var x:Single; var y:Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetStreamBufferSize    (system: FMOD_SYSTEM; filebuffersize: Cardinal; filebuffersizetype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetStreamBufferSize    (system: FMOD_SYSTEM; var filebuffersize: Cardinal; filebuffersizetype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     System information functions.
+*)
+
+function FMOD_System_GetVersion             (system: FMOD_SYSTEM; var version: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetOutputHandle        (system: FMOD_SYSTEM; var handle: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetChannelsPlaying     (system: FMOD_SYSTEM; var channels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetCPUUsage            (system: FMOD_SYSTEM; var dsp, stream, update, total: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetSoundRAM            (system: FMOD_SYSTEM; var currentalloced: Integer; var maxalloced: Integer; var total: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetNumCDROMDrives      (system: FMOD_SYSTEM; var num: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetCDROMDriveName      (system: FMOD_SYSTEM; drivenum: Integer; name: PChar; namelen: Integer; scsiaddr: PChar; scsiaddrlen: Integer; devicename: PChar; devicenamelen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetSpectrum            (system: FMOD_SYSTEM; var spectrumarray: Single; numvalues: Integer; channeloffset: Integer; windowtype: FMOD_DSP_FFT_WINDOW): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetWaveData            (system: FMOD_SYSTEM; var wavearray: Single; numvalues: Integer; channeloffset: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Sound/DSP/Channel/FX creation and retrieval.
+*)
+
+function FMOD_System_CreateSound            (system: FMOD_SYSTEM; const name_or_data: PChar; mode: Cardinal; exinfo: PFMOD_CREATESOUNDEXINFO; var sound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_CreateStream           (system: FMOD_SYSTEM; const name_or_data: PChar; mode: Cardinal; exinfo: PFMOD_CREATESOUNDEXINFO; var sound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_CreateDSP              (system: FMOD_SYSTEM; const description: FMOD_DSP_DESCRIPTION; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_CreateDSPByType        (system: FMOD_SYSTEM; type_: FMOD_DSP_TYPE; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_CreateDSPByIndex       (system: FMOD_SYSTEM; index: Integer; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_CreateChannelGroup     (system: FMOD_SYSTEM; const name: PChar; var channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_System_PlaySound              (system: FMOD_SYSTEM; channelid: Integer; sound: FMOD_SOUND; paused: FMOD_BOOL; var channel: FMOD_CHANNEL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_PlayDSP                (system: FMOD_SYSTEM; channelid: Integer; dsp: FMOD_DSP; paused: FMOD_BOOL; var channel: FMOD_CHANNEL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetChannel             (system: FMOD_SYSTEM; channelid: Integer; var channel: FMOD_CHANNEL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetMasterChannelGroup  (system: FMOD_SYSTEM; var channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Reverb API
+*)
+
+function FMOD_System_SetReverbProperties    (system: FMOD_SYSTEM; const prop: FMOD_REVERB_PROPERTIES): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetReverbProperties    (system: FMOD_SYSTEM; var prop: FMOD_REVERB_PROPERTIES): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+Function FMOD_System_SetReverbAmbientProperties(system:FMOD_SYSTEM; var prop:FMOD_REVERB_PROPERTIES):FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     System level DSP access.
+*)
+
+function FMOD_System_GetDSPHead             (system: FMOD_SYSTEM; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_AddDSP                 (system: FMOD_SYSTEM; dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_LockDSP                (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_UnlockDSP              (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Recording API
+*)
+
+// function FMOD_System_SetRecordDriver        (system: FMOD_SYSTEM; driver: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_GetRecordDriver        (system: FMOD_SYSTEM; var driver: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetRecordNumDrivers    (system: FMOD_SYSTEM; var numdrivers: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_System_GetRecordDriverName    (system: FMOD_SYSTEM; id: Integer; name: PChar; namelen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetRecordPosition      (system: FMOD_SYSTEM; var position: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_System_RecordStart            (system: FMOD_SYSTEM; sound: FMOD_SOUND; loop: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_RecordStop             (system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_IsRecording            (system: FMOD_SYSTEM; var recording: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Geometry API.
+*)
+
+function FMOD_System_CreateGeometry         (system: FMOD_SYSTEM; maxPolygons: Integer; maxVertices: Integer; var geometry: FMOD_GEOMETRY): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetGeometrySettings    (system: FMOD_SYSTEM; maxWorldSize: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetGeometrySettings    (system: FMOD_SYSTEM; var maxWorldSize: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_LoadGeometry           (system: FMOD_SYSTEM; data: Pointer; dataSize: Integer; var geometry: FMOD_GEOMETRY): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Network functions.
+*)
+
+function FMOD_System_SetNetworkProxy        (system: FMOD_SYSTEM; const proxy: PChar): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetNetworkProxy        (system: FMOD_SYSTEM; proxy: PChar; proxylen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_SetNetworkTimeout      (system: FMOD_SYSTEM; timeout: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetNetworkTimeout      (system: FMOD_SYSTEM; var timeout: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_System_SetUserData            (system: FMOD_SYSTEM; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_System_GetUserData            (system: FMOD_SYSTEM; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'Sound' API
+*)
+
+function FMOD_Sound_Release                 (sound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetSystemObject         (sound: FMOD_SOUND; var system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Standard sound manipulation functions.
+*)
+
+function FMOD_Sound_Lock                    (sound: FMOD_SOUND; offset, length: Cardinal; var ptr1: Pointer; var ptr2: Pointer; var len1: Cardinal; var len2: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Unlock                  (sound: FMOD_SOUND; ptr1, ptr2: Pointer; len1, len2: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetDefaults             (sound: FMOD_SOUND; frequency, volume, pan: Single; const levels: Single; priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetDefaults             (sound: FMOD_SOUND; var frequency: Single; var volume: Single; var pan: Single; var priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetVariations           (sound: FMOD_SOUND; frequency, volume, pan: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetVariations           (sound: FMOD_SOUND; var frequency: Single; var volume: Single; var pan: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Set3DMinMaxDistance     (sound: FMOD_SOUND; min, max: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Get3DMinMaxDistance     (sound: FMOD_SOUND; var min: Single; var max: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Set3DConeSettings       (sound: FMOD_SOUND; insideconeangle: Single; outsideconeangle: Single; outsidevolume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Get3DConeSettings       (sound: FMOD_SOUND; var insideconeangle: Single; var outsideconeangle: Single; var outsidevolume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Set3DCustomRolloff      (sound: FMOD_SOUND; points: FMOD_VECTOR; numpoints: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_Get3DCustomRolloff      (sound: FMOD_SOUND; var points: FMOD_VECTOR; var numpoints: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetSubSound             (sound: FMOD_SOUND; index: Integer; subsound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetSubSound             (sound: FMOD_SOUND; index: Integer; var subsound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetSubSoundSentence     (sound: FMOD_SOUND; var subsoundlist: Integer; numsubsounds: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetName                 (sound: FMOD_SOUND; name: PChar; namelen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetLength               (sound: FMOD_SOUND; var length: Cardinal; lengthtype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetFormat               (sound: FMOD_SOUND; var type_: FMOD_SOUND_TYPE; var format: FMOD_SOUND_FORMAT; var channels: Integer; var bits: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetNumSubSounds         (sound: FMOD_SOUND; var numsubsounds: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetNumTags              (sound: FMOD_SOUND; var numtags: Integer; var numtagsupdated: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetTag                  (sound: FMOD_SOUND; const name: PChar; index: Integer; var tag: FMOD_TAG): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetOpenState            (sound: FMOD_SOUND; var openstate: FMOD_OPENSTATE; var percentbuffered: Cardinal; var starving: Boolean): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_ReadData                (sound: FMOD_SOUND; buffer: Pointer; lenbytes: Cardinal; var read: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SeekData                (sound: FMOD_SOUND; pcm: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Synchronization point API.  These points can come from markers embedded in wav files, and can also generate channel callbacks.
+*)
+
+function FMOD_Sound_GetNumSyncPoints        (sound: FMOD_SOUND; var numsyncpoints: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetSyncPoint            (sound: FMOD_SOUND; index: Integer; var point: FMOD_SYNCPOINT): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetSyncPointInfo        (sound: FMOD_SOUND; point: FMOD_SYNCPOINT; name: PChar; namelen: Integer; offset: Cardinal; offsettype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_AddSyncPoint            (sound: FMOD_SOUND; offset: Cardinal; offsettype: Cardinal; name: PChar; var point: FMOD_SYNCPOINT): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_DeleteSyncPoint         (sound: FMOD_SOUND; point: FMOD_SYNCPOINT): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time.
+*)
+
+function FMOD_Sound_SetMode                 (sound: FMOD_SOUND; mode: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetMode                 (sound: FMOD_SOUND; var mode: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetLoopCount            (sound: FMOD_SOUND; loopcount: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetLoopCount            (sound: FMOD_SOUND; var loopcount: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_SetLoopPoints           (sound: FMOD_SOUND; loopstart: Cardinal; loopstarttype: Cardinal; loopend: Cardinal; loopendtype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetLoopPoints           (sound: FMOD_SOUND; var loopstart: Cardinal; loopstarttype: Cardinal; var loopend: Cardinal; loopendtype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Sound_SetUserData             (sound: FMOD_SOUND; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Sound_GetUserData             (sound: FMOD_SOUND; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'Channel' API
+*)
+
+function FMOD_Channel_GetSystemObject       (channel: FMOD_CHANNEL; var system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_Channel_Stop                  (channel: FMOD_CHANNEL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetPaused             (channel: FMOD_CHANNEL; paused: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetPaused             (channel: FMOD_CHANNEL; var paused: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetVolume             (channel: FMOD_CHANNEL; volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetVolume             (channel: FMOD_CHANNEL; var volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetFrequency          (channel: FMOD_CHANNEL; frequency: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetFrequency          (channel: FMOD_CHANNEL; var frequency: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetPan                (channel: FMOD_CHANNEL; pan: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetPan                (channel: FMOD_CHANNEL; var pan: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetDelay              (channel: FMOD_CHANNEL; startdelay: Cardinal; enddelay: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetDelay              (channel: FMOD_CHANNEL; var startdelay: Cardinal; var enddelay: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetSpeakerMix         (channel: FMOD_CHANNEL; frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetSpeakerMix         (channel: FMOD_CHANNEL; var frontleft: Single; var frontright: Single; var center: Single; var lfe: Single; var backleft: Single; var backright: Single; var sideleft: Single; var sideright: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetSpeakerLevels      (channel: FMOD_CHANNEL; speaker: FMOD_SPEAKER; const levels: Single; numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetSpeakerLevels      (channel: FMOD_CHANNEL; speaker: FMOD_SPEAKER; var levels: Single; var numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetMute               (channel: FMOD_CHANNEL; mute: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetMute               (channel: FMOD_CHANNEL; var mute: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetPriority           (channel: FMOD_CHANNEL; priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetPriority           (channel: FMOD_CHANNEL; var priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetPosition           (channel: FMOD_CHANNEL; position: Cardinal; postype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetPosition           (channel: FMOD_CHANNEL; var position: Cardinal; postype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetReverbProperties   (channel: FMOD_CHANNEL; const prop: FMOD_REVERB_CHANNELPROPERTIES): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetReverbProperties   (channel: FMOD_CHANNEL; var prop: FMOD_REVERB_CHANNELPROPERTIES): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetChannelGroup       (channel: FMOD_CHANNEL; channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetChannelGroup       (channel: FMOD_CHANNEL; var channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetCallback           (channel: FMOD_CHANNEL; callback: FMOD_CHANNEL_CALLBACK): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     3D functionality.
+*)
+
+function FMOD_Channel_Set3DAttributes       (channel: FMOD_CHANNEL; const pos: FMOD_VECTOR; const vel: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DAttributes       (channel: FMOD_CHANNEL; var pos: FMOD_VECTOR; var vel: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DMinMaxDistance   (channel: FMOD_CHANNEL; mindistance, maxdistance: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DMinMaxDistance   (channel: FMOD_CHANNEL; var mindistance: Single; var maxdistance: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DConeSettings     (channel: FMOD_CHANNEL; insideconeangle: Single; outsideconeangle: Single; outsidevolume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DConeSettings     (channel: FMOD_CHANNEL; var insideconeangle: Single; var outsideconeangle: Single; var outsidevolume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DConeOrientation  (channel: FMOD_CHANNEL; var orientation: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DConeOrientation  (channel: FMOD_CHANNEL; var orientation: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DCustomRolloff    (channel: FMOD_CHANNEL; points: FMOD_VECTOR; numpoints: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DCustomRolloff    (channel: FMOD_CHANNEL; var points: FMOD_VECTOR; var numpoints: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DOcclusion        (channel: FMOD_CHANNEL; directOcclusion: Single; reverbOcclusion: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DOcclusion        (channel: FMOD_CHANNEL; var directOcclusion: Single; var reverbOcclusion: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DSpread           (channel: FMOD_CHANNEL; angle: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DSpread           (channel: FMOD_CHANNEL; var angle: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Set3DPanLevel         (channel: FMOD_CHANNEL; level: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_Get3DPanLevel         (channel: FMOD_CHANNEL; var level: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     DSP functionality only for channels playing sounds created with FMOD_SOFTWARE.
+*)
+
+function FMOD_Channel_GetDSPHead            (channel: FMOD_CHANNEL; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_AddDSP                (channel: FMOD_CHANNEL; dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Information only functions.
+*)
+
+function FMOD_Channel_IsPlaying             (channel: FMOD_CHANNEL; var isplaying: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_IsVirtual             (channel: FMOD_CHANNEL; var isvirtual: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetAudibility         (channel: FMOD_CHANNEL; var audibility: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetCurrentSound       (channel: FMOD_CHANNEL; var sound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetSpectrum           (channel: FMOD_CHANNEL; spectrumarray: PSingle; numvalues: Integer; channeloffset: Integer; windowtype: FMOD_DSP_FFT_WINDOW): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetWaveData           (channel: FMOD_CHANNEL; var wavearray: Single; numvalues: Integer; channeloffset: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetIndex              (channel: FMOD_CHANNEL; var index: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Functions also found in Sound class but here they can be set per channel.
+*)
+
+function FMOD_Channel_SetMode               (channel: FMOD_CHANNEL; mode: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetMode               (channel: FMOD_CHANNEL; var mode: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetLoopCount          (channel: FMOD_CHANNEL; loopcount: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetLoopCount          (channel: FMOD_CHANNEL; var loopcount: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_SetLoopPoints         (channel: FMOD_CHANNEL; loopstart: Cardinal; loopstarttype: Cardinal; loopend: Cardinal; loopendtype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetLoopPoints         (channel: FMOD_CHANNEL; var loopstart: Cardinal; loopstarttype: Cardinal; var loopend: Cardinal; loopendtype: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Channel_SetUserData           (channel: FMOD_CHANNEL; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Channel_GetUserData           (channel: FMOD_CHANNEL; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'ChannelGroup' API
+*)
+
+function FMOD_ChannelGroup_Release          (channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetSystemObject  (channelgroup: FMOD_CHANNELGROUP; var system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Channelgroup scale values.  (scales the current volume or pitch of all channels and channel groups, DOESN'T overwrite)
+*)
+
+function FMOD_ChannelGroup_SetVolume        (channelgroup: FMOD_CHANNELGROUP; volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetVolume        (channelgroup: FMOD_CHANNELGROUP; var volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_SetPitch         (channelgroup: FMOD_CHANNELGROUP; pitch: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetPitch         (channelgroup: FMOD_CHANNELGROUP; var pitch: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Channelgroup override values.  (recursively overwrites whatever settings the channels had)
+*)
+
+function FMOD_ChannelGroup_Stop                    (channelgroup: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_ChannelGroup_OverridePaused          (channelgroup: FMOD_CHANNELGROUP; paused: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_OverrideVolume          (channelgroup: FMOD_CHANNELGROUP; volume : Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_OverrideFrequency       (channelgroup: FMOD_CHANNELGROUP; frequency: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_OverridePan             (channelgroup: FMOD_CHANNELGROUP; pan: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_ChannelGroup_OverrideMute            (channelgroup: FMOD_CHANNELGROUP; mute: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_OverrideReverbProperties(channelgroup: FMOD_CHANNELGROUP; const prop: FMOD_REVERB_CHANNELPROPERTIES): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_Override3DAttributes    (channelgroup: FMOD_CHANNELGROUP; const pos: FMOD_VECTOR; const vel: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_OverrideSpeakerMix      (channelgroup: FMOD_CHANNELGROUP; frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Nested channel groups.
+*)
+
+function FMOD_ChannelGroup_AddGroup         (channelgroup: FMOD_CHANNELGROUP; group: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetNumGroups     (channelgroup: FMOD_CHANNELGROUP; var numgroups: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetGroup         (channelgroup: FMOD_CHANNELGROUP; index: Integer; var group: FMOD_CHANNELGROUP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     DSP functionality only for channel groups playing sounds created with FMOD_SOFTWARE.
+*)
+
+function FMOD_ChannelGroup_GetDSPHead       (channelgroup: FMOD_CHANNELGROUP; var dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_AddDSP           (channelgroup: FMOD_CHANNELGROUP; dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Information only functions.
+*)
+
+function FMOD_ChannelGroup_GetName          (channelgroup: FMOD_CHANNELGROUP; name: PChar; namelen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetNumChannels   (channelgroup: FMOD_CHANNELGROUP; var numchannels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetChannel       (channelgroup: FMOD_CHANNELGROUP; index: Integer; var channel: FMOD_CHANNEL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetSpectrum      (channelgroup: FMOD_CHANNELGROUP; var spectrumarray: Single; numvalues: Integer; channeloffset: Integer; windowtype: FMOD_DSP_FFT_WINDOW ): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetWaveData      (channelgroup: FMOD_CHANNELGROUP; var wavearray: Single; numvalues: Integer; channeloffset: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_ChannelGroup_SetUserData      (channelgroup: FMOD_CHANNELGROUP; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_ChannelGroup_GetUserData      (channelgroup: FMOD_CHANNELGROUP; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'DSP' API
+*)
+
+function FMOD_DSP_Release                   (dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetSystemObject           (dsp: FMOD_DSP; var system: FMOD_SYSTEM): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Connection / disconnection / input and output enumeration.
+*)
+
+function FMOD_DSP_AddInput                  (dsp, target: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_DisconnectFrom            (dsp, target: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_Remove                    (dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetNumInputs              (dsp: FMOD_DSP; var numinputs: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetNumOutputs             (dsp: FMOD_DSP; var numoutputs: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetInput                  (dsp: FMOD_DSP; index: Integer; var input: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetOutput                 (dsp: FMOD_DSP; index: Integer; var output: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_SetInputMix               (dsp: FMOD_DSP; index: Integer; volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_GetInputMix               (dsp: FMOD_DSP; index: Integer; var volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_SetInputLevels            (dsp: FMOD_DSP; index: Integer; speaker: FMOD_SPEAKER; const levels: Single; numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_GetInputLevels            (dsp: FMOD_DSP; index: Integer; speaker: FMOD_SPEAKER; const levels: Single; numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_SetOutputMix              (dsp: FMOD_DSP; index: Integer; volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_GetOutputMix              (dsp: FMOD_DSP; index: Integer; var volume: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_SetOutputLevels           (dsp: FMOD_DSP; index: Integer; speaker: FMOD_SPEAKER; const levels: Single; numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+// function FMOD_DSP_GetOutputLevels           (dsp: FMOD_DSP; index: Integer; speaker: FMOD_SPEAKER; const levels: Single; numlevels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     DSP unit control
+*)
+
+function FMOD_DSP_SetActive                 (dsp: FMOD_DSP; active: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetActive                 (dsp: FMOD_DSP; var active: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_SetBypass                 (dsp: FMOD_DSP; bypass: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetBypass                 (dsp: FMOD_DSP; var bypass: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_Reset                     (dsp: FMOD_DSP): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     DSP parameter control
+*)
+
+function FMOD_DSP_SetParameter              (dsp: FMOD_DSP; index: Integer; value: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetParameter              (dsp: FMOD_DSP; index: Integer; var value: Single; valuestr: PChar; valuestrlen: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetNumParameters          (dsp: FMOD_DSP; var numparams: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetParameterInfo          (dsp: FMOD_DSP; index: Integer; name: PChar; plabel: PChar; description: PChar; descriptionlen: Integer; var min: Single; var max: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_ShowConfigDialog          (dsp: FMOD_DSP; hwnd: Pointer; show: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     DSP attributes.
+*)
+
+function FMOD_DSP_GetInfo                   (dsp: FMOD_DSP; name:PChar; var version: cardinal; var channels:integer; var configwidth:integer; var configheight:integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_SetDefaults               (dsp: FMOD_DSP; frequency: Single; volume: Single; pan: Single; var levels: Single; priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetDefaults               (dsp: FMOD_DSP; var frequency: Single; var volume: Single; var pan: Single; var priority: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_DSP_SetUserData               (dsp: FMOD_DSP; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_DSP_GetUserData               (dsp: FMOD_DSP; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+    'Geometry' API
+*)
+
+function FMOD_Geometry_Release              (geometry: FMOD_GEOMETRY): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_Geometry_AddPolygon           (geometry: FMOD_GEOMETRY; directOcclusion: Single; reverbOcclusion: Single; doubleSided: FMOD_BOOL; numVertices: Integer; vertices: PFMOD_VECTOR; var polygonIndex: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetNumPolygons       (geometry: FMOD_GEOMETRY; var numPolygons: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetMaxPolygons       (geometry: FMOD_GEOMETRY; var maxPolygons: Integer; maxVertices: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetPolygonNumVertices(geometry: FMOD_GEOMETRY; polygonIndex: Integer; var numVertices: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_SetPolygonVertex     (geometry: FMOD_GEOMETRY; polygonIndex: Integer; vertexIndex: Integer; var vertex: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetPolygonVertex     (geometry: FMOD_GEOMETRY; polygonIndex: Integer; vertexIndex: Integer; var vertex: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_SetPolygonAttributes (geometry: FMOD_GEOMETRY; polygonIndex: Integer; directOcclusion: Single; reverbOcclusion: Single; doubleSided: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetPolygonAttributes (geometry: FMOD_GEOMETRY; polygonIndex: Integer; var directOcclusion: Single; var reverbOcclusion: Single; var doubleSided: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_Geometry_SetActive            (geometry: FMOD_GEOMETRY; active: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetActive            (geometry: FMOD_GEOMETRY; var active: FMOD_BOOL): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_SetRotation          (geometry: FMOD_GEOMETRY; var forward: FMOD_VECTOR; var up: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetRotation          (geometry: FMOD_GEOMETRY; var forward: FMOD_VECTOR; var up: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_SetPosition          (geometry: FMOD_GEOMETRY; var position: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetPosition          (geometry: FMOD_GEOMETRY; var position: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_SetScale             (geometry: FMOD_GEOMETRY; var scale: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetScale             (geometry: FMOD_GEOMETRY; var scale: FMOD_VECTOR): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_Save                 (geometry: FMOD_GEOMETRY; data: Pointer; var datasize: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Geometry_SetUserData          (geometry: FMOD_GEOMETRY; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Geometry_GetUserData          (geometry: FMOD_GEOMETRY; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+function FMOD_Load                          (const libname: PChar): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function FMOD_Unload                        (): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+implementation
+
+const
+{$IFDEF MSWINDOWS}
+  FMOD_DLL = 'fmodex.dll';
+{$ELSE}
+{$IFDEF LINUX}
+  FMOD_DLL = 'libfmodex.so';
+{$ENDIF}
+{$ENDIF}
+
+function FMOD_Load(const libname: PChar): FMOD_RESULT;
+begin
+  FMOD_Load := FMOD_OK;
+end;
+
+function FMOD_Unload(): FMOD_RESULT;
+begin
+  FMOD_Unload := FMOD_OK;
+end;
+
+(*
+    FMOD System memory functions (optional).
+*)
+
+function FMOD_Memory_Initialize             ; external FMOD_DLL;
+function FMOD_Memory_GetStats               ; external FMOD_DLL;
+
+(*
+    FMOD System factory functions.  Use this to create an FMOD System Instance.  below you will see FMOD_System_Init/Close to get started.
+*)
+
+function FMOD_System_Create                 ; external FMOD_DLL;
+function FMOD_System_Release                ; external FMOD_DLL;
+
+(*
+    'System' API
+*)
+
+(*
+     Pre-init functions.
+*)
+
+function FMOD_System_SetOutput              ; external FMOD_DLL;
+function FMOD_System_GetOutput              ; external FMOD_DLL;
+function FMOD_System_GetNumDrivers          ; external FMOD_DLL;
+// function FMOD_System_GetDriverName          ; external FMOD_DLL;
+function FMOD_System_GetDriverCaps          ; external FMOD_DLL;
+function FMOD_System_SetDriver              ; external FMOD_DLL;
+function FMOD_System_GetDriver              ; external FMOD_DLL;
+function FMOD_System_SetHardwareChannels    ; external FMOD_DLL;
+function FMOD_System_GetHardwareChannels    ; external FMOD_DLL;
+function FMOD_System_SetSoftwareChannels    ; external FMOD_DLL;
+function FMOD_System_GetSoftwareChannels    ; external FMOD_DLL;
+function FMOD_System_SetSoftwareFormat      ; external FMOD_DLL;
+function FMOD_System_GetSoftwareFormat      ; external FMOD_DLL;
+function FMOD_System_SetDSPBufferSize       ; external FMOD_DLL;
+function FMOD_System_GetDSPBufferSize       ; external FMOD_DLL;
+function FMOD_System_SetFileSystem          ; external FMOD_DLL;
+function FMOD_System_AttachFileSystem       ; external FMOD_DLL;
+function FMOD_System_SetAdvancedSettings    ; external FMOD_DLL;
+function FMOD_System_GetAdvancedSettings    ; external FMOD_DLL;
+function FMOD_System_SetSpeakerMode         ; external FMOD_DLL;
+function FMOD_System_GetSpeakerMode         ; external FMOD_DLL;
+
+(*
+     Plug-in support
+*)
+
+function FMOD_System_SetPluginPath          ; external FMOD_DLL;
+function FMOD_System_LoadPlugin             ; external FMOD_DLL;
+function FMOD_System_GetNumPlugins          ; external FMOD_DLL;
+function FMOD_System_GetPluginInfo          ; external FMOD_DLL;
+function FMOD_System_UnloadPlugin           ; external FMOD_DLL;
+function FMOD_System_SetOutputByPlugin      ; external FMOD_DLL;
+function FMOD_System_GetOutputByPlugin      ; external FMOD_DLL;
+// function FMOD_System_CreateCodec            ; external FMOD_DLL;
+
+(*
+     Init/Close
+*)
+
+function FMOD_System_Init                   ; external FMOD_DLL;
+function FMOD_System_Close                  ; external FMOD_DLL;
+
+(*
+     General post-init system functions
+*)
+
+function FMOD_System_Update                 ; external FMOD_DLL;
+// function FMOD_System_UpdateFinished         ; external FMOD_DLL;
+
+function FMOD_System_Set3DSettings          ; external FMOD_DLL;
+function FMOD_System_Get3DSettings          ; external FMOD_DLL;
+function FMOD_System_Set3DNumListeners      ; external FMOD_DLL;
+function FMOD_System_Get3DNumListeners      ; external FMOD_DLL;
+function FMOD_System_Set3DListenerAttributes; external FMOD_DLL;
+function FMOD_System_Get3DListenerAttributes; external FMOD_DLL;
+
+// function FMOD_System_SetSpeakerPosition     ; external FMOD_DLL;
+// function FMOD_System_GetSpeakerPosition     ; external FMOD_DLL;
+function FMOD_System_SetStreamBufferSize    ; external FMOD_DLL;
+function FMOD_System_GetStreamBufferSize    ; external FMOD_DLL;
+
+(*
+     System information functions.
+*)
+
+function FMOD_System_GetVersion             ; external FMOD_DLL;
+function FMOD_System_GetOutputHandle        ; external FMOD_DLL;
+function FMOD_System_GetChannelsPlaying     ; external FMOD_DLL;
+function FMOD_System_GetCPUUsage            ; external FMOD_DLL;
+function FMOD_System_GetSoundRAM            ; external FMOD_DLL;
+function FMOD_System_GetNumCDROMDrives      ; external FMOD_DLL;
+function FMOD_System_GetCDROMDriveName      ; external FMOD_DLL;
+function FMOD_System_GetSpectrum            ; external FMOD_DLL;
+function FMOD_System_GetWaveData            ; external FMOD_DLL;
+
+(*
+     Sound/DSP/Channel/FX creation and retrieval.
+*)
+
+function FMOD_System_CreateSound            ; external FMOD_DLL;
+function FMOD_System_CreateStream           ; external FMOD_DLL;
+function FMOD_System_CreateDSP              ; external FMOD_DLL;
+function FMOD_System_CreateDSPByType        ; external FMOD_DLL;
+// function FMOD_System_CreateDSPByIndex       ; external FMOD_DLL;
+function FMOD_System_CreateChannelGroup     ; external FMOD_DLL;
+
+function FMOD_System_PlaySound              ; external FMOD_DLL;
+function FMOD_System_PlayDSP                ; external FMOD_DLL;
+function FMOD_System_GetChannel             ; external FMOD_DLL;
+function FMOD_System_GetMasterChannelGroup  ; external FMOD_DLL;
+
+(*
+     Reverb API
+*)
+
+function FMOD_System_SetReverbProperties    ; external FMOD_DLL;
+function FMOD_System_GetReverbProperties    ; external FMOD_DLL;
+Function FMOD_System_SetReverbAmbientProperties; external fmod_dll;
+(*
+     System level DSP access.
+*)
+
+function FMOD_System_GetDSPHead             ; external FMOD_DLL;
+function FMOD_System_AddDSP                 ; external FMOD_DLL;
+function FMOD_System_LockDSP                ; external FMOD_DLL;
+function FMOD_System_UnlockDSP              ; external FMOD_DLL;
+
+(*
+     Recording API
+*)
+
+// function FMOD_System_SetRecordDriver        ; external FMOD_DLL;
+// function FMOD_System_GetRecordDriver        ; external FMOD_DLL;
+function FMOD_System_GetRecordNumDrivers    ; external FMOD_DLL;
+// function FMOD_System_GetRecordDriverName    ; external FMOD_DLL;
+function FMOD_System_GetRecordPosition      ; external FMOD_DLL;
+
+function FMOD_System_RecordStart            ; external FMOD_DLL;
+function FMOD_System_RecordStop             ; external FMOD_DLL;
+function FMOD_System_IsRecording            ; external FMOD_DLL;
+
+(*
+     Geometry API.
+*)
+
+function FMOD_System_CreateGeometry         ; external FMOD_DLL;
+function FMOD_System_SetGeometrySettings    ; external FMOD_DLL;
+function FMOD_System_GetGeometrySettings    ; external FMOD_DLL;
+function FMOD_System_LoadGeometry           ; external FMOD_DLL;
+
+(*
+     Network functions
+*)
+
+function FMOD_System_SetNetworkProxy        ; external FMOD_DLL;
+function FMOD_System_GetNetworkProxy        ; external FMOD_DLL;
+function FMOD_System_SetNetworkTimeout      ; external FMOD_DLL;
+function FMOD_System_GetNetworkTimeout      ; external FMOD_DLL;
+
+(*
+     Userdata set/get
+*)
+
+function FMOD_System_SetUserData            ; external FMOD_DLL;
+function FMOD_System_GetUserData            ; external FMOD_DLL;
+
+(*
+    'Sound' API
+*)
+
+function FMOD_Sound_Release                 ; external FMOD_DLL;
+function FMOD_Sound_GetSystemObject         ; external FMOD_DLL;
+
+(*
+     Standard sound manipulation functions.
+*)
+
+function FMOD_Sound_Lock                    ; external FMOD_DLL;
+function FMOD_Sound_Unlock                  ; external FMOD_DLL;
+function FMOD_Sound_SetDefaults             ; external FMOD_DLL;
+function FMOD_Sound_GetDefaults             ; external FMOD_DLL;
+function FMOD_Sound_SetVariations           ; external FMOD_DLL;
+function FMOD_Sound_GetVariations           ; external FMOD_DLL;
+function FMOD_Sound_Set3DMinMaxDistance     ; external FMOD_DLL;
+function FMOD_Sound_Get3DMinMaxDistance     ; external FMOD_DLL;
+function FMOD_Sound_Set3DConeSettings       ; external FMOD_DLL;
+function FMOD_Sound_Get3DConeSettings       ; external FMOD_DLL;
+function FMOD_Sound_Set3DCustomRolloff      ; external FMOD_DLL;
+function FMOD_Sound_Get3DCustomRolloff      ; external FMOD_DLL;
+function FMOD_Sound_SetSubSound             ; external FMOD_DLL;
+function FMOD_Sound_GetSubSound             ; external FMOD_DLL;
+function FMOD_Sound_SetSubSoundSentence     ; external FMOD_DLL;
+function FMOD_Sound_GetName                 ; external FMOD_DLL;
+function FMOD_Sound_GetLength               ; external FMOD_DLL;
+function FMOD_Sound_GetFormat               ; external FMOD_DLL;
+function FMOD_Sound_GetNumSubSounds         ; external FMOD_DLL;
+function FMOD_Sound_GetNumTags              ; external FMOD_DLL;
+function FMOD_Sound_GetTag                  ; external FMOD_DLL;
+function FMOD_Sound_GetOpenState            ; external FMOD_DLL;
+function FMOD_Sound_ReadData                ; external FMOD_DLL;
+function FMOD_Sound_SeekData                ; external FMOD_DLL;
+
+(*
+     Synchronization point API.  These points can come from markers embedded in wav files, and can also generate channel callbacks.
+*)
+
+function FMOD_Sound_GetNumSyncPoints        ; external FMOD_DLL;
+function FMOD_Sound_GetSyncPoint            ; external FMOD_DLL;
+function FMOD_Sound_GetSyncPointInfo        ; external FMOD_DLL;
+function FMOD_Sound_AddSyncPoint            ; external FMOD_DLL;
+function FMOD_Sound_DeleteSyncPoint         ; external FMOD_DLL;
+
+(*
+     Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time.
+*)
+
+function FMOD_Sound_SetMode                 ; external FMOD_DLL;
+function FMOD_Sound_GetMode                 ; external FMOD_DLL;
+function FMOD_Sound_SetLoopCount            ; external FMOD_DLL;
+function FMOD_Sound_GetLoopCount            ; external FMOD_DLL;
+function FMOD_Sound_SetLoopPoints           ; external FMOD_DLL;
+function FMOD_Sound_GetLoopPoints           ; external FMOD_DLL;
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Sound_SetUserData             ; external FMOD_DLL;
+function FMOD_Sound_GetUserData             ; external FMOD_DLL;
+
+(*
+    'Channel' API
+*)
+
+function FMOD_Channel_GetSystemObject       ; external FMOD_DLL;
+
+function FMOD_Channel_Stop                  ; external FMOD_DLL;
+function FMOD_Channel_SetPaused             ; external FMOD_DLL;
+function FMOD_Channel_GetPaused             ; external FMOD_DLL;
+function FMOD_Channel_SetVolume             ; external FMOD_DLL;
+function FMOD_Channel_GetVolume             ; external FMOD_DLL;
+function FMOD_Channel_SetFrequency          ; external FMOD_DLL;
+function FMOD_Channel_GetFrequency          ; external FMOD_DLL;
+function FMOD_Channel_SetPan                ; external FMOD_DLL;
+function FMOD_Channel_GetPan                ; external FMOD_DLL;
+function FMOD_Channel_SetDelay              ; external FMOD_DLL;
+function FMOD_Channel_GetDelay              ; external FMOD_DLL;
+function FMOD_Channel_SetSpeakerMix         ; external FMOD_DLL;
+function FMOD_Channel_GetSpeakerMix         ; external FMOD_DLL;
+function FMOD_Channel_SetSpeakerLevels      ; external FMOD_DLL;
+function FMOD_Channel_GetSpeakerLevels      ; external FMOD_DLL;
+function FMOD_Channel_SetMute               ; external FMOD_DLL;
+function FMOD_Channel_GetMute               ; external FMOD_DLL;
+function FMOD_Channel_SetPriority           ; external FMOD_DLL;
+function FMOD_Channel_GetPriority           ; external FMOD_DLL;
+function FMOD_Channel_SetPosition           ; external FMOD_DLL;
+function FMOD_Channel_GetPosition           ; external FMOD_DLL;
+function FMOD_Channel_SetReverbProperties   ; external FMOD_DLL;
+function FMOD_Channel_GetReverbProperties   ; external FMOD_DLL;
+function FMOD_Channel_SetChannelGroup       ; external FMOD_DLL;
+function FMOD_Channel_GetChannelGroup       ; external FMOD_DLL;
+function FMOD_Channel_SetCallback           ; external FMOD_DLL;
+
+(*
+     3D functionality.
+*)
+
+function FMOD_Channel_Set3DAttributes       ; external FMOD_DLL;
+function FMOD_Channel_Get3DAttributes       ; external FMOD_DLL;
+function FMOD_Channel_Set3DMinMaxDistance   ; external FMOD_DLL;
+function FMOD_Channel_Get3DMinMaxDistance   ; external FMOD_DLL;
+function FMOD_Channel_Set3DConeSettings     ; external FMOD_DLL;
+function FMOD_Channel_Get3DConeSettings     ; external FMOD_DLL;
+function FMOD_Channel_Set3DConeOrientation  ; external FMOD_DLL;
+function FMOD_Channel_Get3DConeOrientation  ; external FMOD_DLL;
+function FMOD_Channel_Set3DCustomRolloff    ; external FMOD_DLL;
+function FMOD_Channel_Get3DCustomRolloff    ; external FMOD_DLL;
+function FMOD_Channel_Set3DOcclusion        ; external FMOD_DLL;
+function FMOD_Channel_Get3DOcclusion        ; external FMOD_DLL;
+function FMOD_Channel_Set3DSpread           ; external FMOD_DLL;
+function FMOD_Channel_Get3DSpread           ; external FMOD_DLL;
+function FMOD_Channel_Set3DPanLevel         ; external FMOD_DLL;
+function FMOD_Channel_Get3DPanLevel         ; external FMOD_DLL;
+
+(*
+     DSP functionality only for channels playing sounds created with FMOD_SOFTWARE.
+*)
+
+function FMOD_Channel_GetDSPHead            ; external FMOD_DLL;
+function FMOD_Channel_AddDSP                ; external FMOD_DLL;
+
+(*
+     Information only functions.
+*)
+
+function FMOD_Channel_IsPlaying             ; external FMOD_DLL;
+function FMOD_Channel_IsVirtual             ; external FMOD_DLL;
+function FMOD_Channel_GetAudibility         ; external FMOD_DLL;
+function FMOD_Channel_GetCurrentSound       ; external FMOD_DLL;
+function FMOD_Channel_GetSpectrum           ; external FMOD_DLL;
+function FMOD_Channel_GetWaveData           ; external FMOD_DLL;
+function FMOD_Channel_GetIndex              ; external FMOD_DLL;
+
+(*
+     Functions also found in Sound class but here they can be set per channel.
+*)
+
+function FMOD_Channel_SetMode               ; external FMOD_DLL;
+function FMOD_Channel_GetMode               ; external FMOD_DLL;
+function FMOD_Channel_SetLoopCount          ; external FMOD_DLL;
+function FMOD_Channel_GetLoopCount          ; external FMOD_DLL;
+function FMOD_Channel_SetLoopPoints         ; external FMOD_DLL;
+function FMOD_Channel_GetLoopPoints         ; external FMOD_DLL;
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Channel_SetUserData           ; external FMOD_DLL;
+function FMOD_Channel_GetUserData           ; external FMOD_DLL;
+
+(*
+    'ChannelGroup' API
+*)
+
+function FMOD_ChannelGroup_Release          ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetSystemObject  ; external FMOD_DLL;
+
+(*
+     Channelgroup scale values.  (scales the current volume or pitch of all channels and channel groups, DOESN'T overwrite)
+*)
+
+function FMOD_ChannelGroup_SetVolume        ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetVolume        ; external FMOD_DLL;
+function FMOD_ChannelGroup_SetPitch         ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetPitch         ; external FMOD_DLL;
+
+(*
+     Channelgroup override values.  (recursively overwrites whatever settings the channels had)
+*)
+
+function FMOD_ChannelGroup_Stop                    ; external FMOD_DLL;
+// function FMOD_ChannelGroup_OverridePaused          ; external FMOD_DLL;
+function FMOD_ChannelGroup_OverrideVolume          ; external FMOD_DLL;
+function FMOD_ChannelGroup_OverrideFrequency       ; external FMOD_DLL;
+function FMOD_ChannelGroup_OverridePan             ; external FMOD_DLL;
+// function FMOD_ChannelGroup_OverrideMute            ; external FMOD_DLL;
+function FMOD_ChannelGroup_OverrideReverbProperties; external FMOD_DLL;
+function FMOD_ChannelGroup_Override3DAttributes    ; external FMOD_DLL;
+function FMOD_ChannelGroup_OverrideSpeakerMix      ; external FMOD_DLL;
+
+(*
+     Nested channel groups.
+*)
+
+function FMOD_ChannelGroup_AddGroup         ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetNumGroups     ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetGroup         ; external FMOD_DLL;
+
+(*
+     DSP functionality only for channel groups playing sounds created with FMOD_SOFTWARE.
+*)
+
+function FMOD_ChannelGroup_GetDSPHead       ; external FMOD_DLL;
+function FMOD_ChannelGroup_AddDSP           ; external FMOD_DLL;
+
+(*
+     Information only functions.
+*)
+
+function FMOD_ChannelGroup_GetName          ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetNumChannels   ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetChannel       ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetSpectrum      ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetWaveData      ; external FMOD_DLL;
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_ChannelGroup_SetUserData      ; external FMOD_DLL;
+function FMOD_ChannelGroup_GetUserData      ; external FMOD_DLL;
+
+(*
+    'DSP' API
+*)
+
+function FMOD_DSP_Release                   ; external FMOD_DLL;
+function FMOD_DSP_GetSystemObject           ; external FMOD_DLL;
+
+(*
+     Connection / disconnection / input and output enumeration.
+*)
+
+function FMOD_DSP_AddInput                  ; external FMOD_DLL;
+function FMOD_DSP_DisconnectFrom            ; external FMOD_DLL;
+function FMOD_DSP_Remove                    ; external FMOD_DLL;
+function FMOD_DSP_GetNumInputs              ; external FMOD_DLL;
+function FMOD_DSP_GetNumOutputs             ; external FMOD_DLL;
+function FMOD_DSP_GetInput                  ; external FMOD_DLL;
+function FMOD_DSP_GetOutput                 ; external FMOD_DLL;
+// function FMOD_DSP_SetInputMix               ; external FMOD_DLL;
+// function FMOD_DSP_GetInputMix               ; external FMOD_DLL;
+// function FMOD_DSP_SetInputLevels            ; external FMOD_DLL;
+// function FMOD_DSP_GetInputLevels            ; external FMOD_DLL;
+// function FMOD_DSP_SetOutputMix              ; external FMOD_DLL;
+// function FMOD_DSP_GetOutputMix              ; external FMOD_DLL;
+// function FMOD_DSP_SetOutputLevels           ; external FMOD_DLL;
+// function FMOD_DSP_GetOutputLevels           ; external FMOD_DLL;
+
+(*
+     DSP unit control
+*)
+
+function FMOD_DSP_SetActive                 ; external FMOD_DLL;
+function FMOD_DSP_GetActive                 ; external FMOD_DLL;
+function FMOD_DSP_SetBypass                 ; external FMOD_DLL;
+function FMOD_DSP_GetBypass                 ; external FMOD_DLL;
+function FMOD_DSP_Reset                     ; external FMOD_DLL;
+
+(*
+     DSP parameter control
+*)
+
+function FMOD_DSP_SetParameter              ; external FMOD_DLL;
+function FMOD_DSP_GetParameter              ; external FMOD_DLL;
+function FMOD_DSP_GetNumParameters          ; external FMOD_DLL;
+function FMOD_DSP_GetParameterInfo          ; external FMOD_DLL;
+function FMOD_DSP_ShowConfigDialog          ; external FMOD_DLL;
+
+(*
+     DSP attributes.
+*)
+
+function FMOD_DSP_GetInfo                   ; external FMOD_DLL;
+function FMOD_DSP_SetDefaults               ; external FMOD_DLL;
+function FMOD_DSP_GetDefaults               ; external FMOD_DLL;
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_DSP_SetUserData               ; external FMOD_DLL;
+function FMOD_DSP_GetUserData               ; external FMOD_DLL;
+
+(*
+    'Geometry' API
+*)
+
+function FMOD_Geometry_Release              ; external FMOD_DLL;
+
+function FMOD_Geometry_AddPolygon           ; external FMOD_DLL;
+function FMOD_Geometry_GetNumPolygons       ; external FMOD_DLL;
+function FMOD_Geometry_GetMaxPolygons       ; external FMOD_DLL;
+function FMOD_Geometry_GetPolygonNumVertices; external FMOD_DLL;
+function FMOD_Geometry_SetPolygonVertex     ; external FMOD_DLL;
+function FMOD_Geometry_GetPolygonVertex     ; external FMOD_DLL;
+function FMOD_Geometry_SetPolygonAttributes ; external FMOD_DLL;
+function FMOD_Geometry_GetPolygonAttributes ; external FMOD_DLL;
+
+function FMOD_Geometry_SetActive            ; external FMOD_DLL;
+function FMOD_Geometry_GetActive            ; external FMOD_DLL;
+function FMOD_Geometry_SetRotation          ; external FMOD_DLL;
+function FMOD_Geometry_GetRotation          ; external FMOD_DLL;
+function FMOD_Geometry_SetPosition          ; external FMOD_DLL;
+function FMOD_Geometry_GetPosition          ; external FMOD_DLL;
+function FMOD_Geometry_SetScale             ; external FMOD_DLL;
+function FMOD_Geometry_GetScale             ; external FMOD_DLL;
+function FMOD_Geometry_Save                 ; external FMOD_DLL;
+
+(*
+     Userdata set/get.
+*)
+
+function FMOD_Geometry_SetUserData          ; external FMOD_DLL;
+function FMOD_Geometry_GetUserData          ; external FMOD_DLL;
+
+end.
diff --git a/src/lib/fmod/fmoderrors.pas b/src/lib/fmod/fmoderrors.pas
new file mode 100644 (file)
index 0000000..2b497bc
--- /dev/null
@@ -0,0 +1,125 @@
+(* ============================================================================================== *)
+(* FMOD Ex - Error string header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2008. *)
+(*                                                                                                *)
+(* Use this header if you want to store or display a string version / english explanation of      *)
+(* the FMOD error codes.                                                                          *)
+(*                                                                                                *)
+(* ============================================================================================== *)
+
+unit fmoderrors;
+
+{$I fmod.inc}
+
+interface
+
+uses
+  fmodtypes;
+
+function FMOD_ErrorString(errcode: FMOD_RESULT): PChar;
+
+implementation
+
+function FMOD_ErrorString(errcode: FMOD_RESULT): PChar;
+begin
+  case errcode of
+    FMOD_ERR_ALREADYLOCKED:          Result := 'Tried to call lock a second time before unlock was called. ';
+    FMOD_ERR_BADCOMMAND:             Result := 'Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound). ';
+    FMOD_ERR_CDDA_DRIVERS:           Result := 'Neither NTSCSI nor ASPI could be initialised. ';
+    FMOD_ERR_CDDA_INIT:              Result := 'An error occurred while initialising the CDDA subsystem. ';
+    FMOD_ERR_CDDA_INVALID_DEVICE:    Result := 'Couldnt find the specified device. ';
+    FMOD_ERR_CDDA_NOAUDIO:           Result := 'No audio tracks on the specified disc. ';
+    FMOD_ERR_CDDA_NODEVICES:         Result := 'No CD/DVD devices were found. ';
+    FMOD_ERR_CDDA_NODISC:            Result := 'No disc present in the specified drive. ';
+    FMOD_ERR_CDDA_READ:              Result := 'A CDDA read error occurred. ';
+    FMOD_ERR_CHANNEL_ALLOC:          Result := 'Error trying to allocate a channel. ';
+    FMOD_ERR_CHANNEL_STOLEN:         Result := 'The specified channel has been reused to play another sound. ';
+    FMOD_ERR_COM:                    Result := 'A Win32 COM related error occured. COM failed to initialize or a QueryInterface failed meaning a Windows codec or driver was not installed properly. ';
+    FMOD_ERR_DMA:                    Result := 'DMA Failure.  See debug output for more information. ';
+    FMOD_ERR_DSP_CONNECTION:         Result := 'DSP connection error.  Connection possibly caused a cyclic dependancy.  Or tried to connect a tree too many units deep (more than 128). ';
+    FMOD_ERR_DSP_FORMAT:             Result := 'DSP Format error.  A DSP unit may have attempted to connect to this network with the wrong format. ';
+    FMOD_ERR_DSP_NOTFOUND:           Result := 'DSP connection error.  Couldnt find the DSP unit specified. ';
+    FMOD_ERR_DSP_RUNNING:            Result := 'DSP error.  Cannot perform this operation while the network is in the middle of running.  This will most likely happen if a connection or disconnection is attempted in a DSP callback. ';
+    FMOD_ERR_DSP_TOOMANYCONNECTIONS: Result := 'DSP connection error.  The unit being connected to or disconnected should only have 1 input or output. ';
+    FMOD_ERR_EVENT_ALREADY_LOADED:   Result := 'The specified project has already been loaded. Having multiple copies of the same project loaded simultaneously is forbidden. ';
+    FMOD_ERR_EVENT_FAILED:           Result := 'An Event failed to be retrieved, most likely due to just fail being specified as the max playbacks behavior. ';
+    FMOD_ERR_EVENT_GUIDCONFLICT:     Result := 'An event with the same GUID already exists. ';
+    FMOD_ERR_EVENT_INFOONLY:         Result := 'Cant execute this command on an EVENT_INFOONLY event. ';
+    FMOD_ERR_EVENT_INTERNAL:         Result := 'An error occured that wasnt supposed to.  See debug log for reason. ';
+    FMOD_ERR_EVENT_MAXSTREAMS:       Result := 'Event failed because Max streams was hit when FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified. ';
+    FMOD_ERR_EVENT_MISMATCH:         Result := 'FSB mismatches the FEV it was compiled with, the stream/sample mode it was meant to be created with was different, or the FEV was built for a different platform. ';
+    FMOD_ERR_EVENT_NAMECONFLICT:     Result := 'A category with the same name already exists. ';
+    FMOD_ERR_EVENT_NEEDSSIMPLE:      Result := 'Tried to call a function on a complex event thats only supported by simple events. ';
+    FMOD_ERR_EVENT_NOTFOUND:         Result := 'The requested event, event group, event category or event property could not be found. ';
+    FMOD_ERR_FILE_BAD:               Result := 'Error loading file. ';
+    FMOD_ERR_FILE_COULDNOTSEEK:      Result := 'Couldnt perform seek operation.  This is a limitation of the medium (ie netstreams) or the file format. ';
+    FMOD_ERR_FILE_DISKEJECTED:       Result := 'Media was ejected while reading. ';
+    FMOD_ERR_FILE_EOF:               Result := 'End of file unexpectedly reached while trying to read essential data (truncated data?). ';
+    FMOD_ERR_FILE_NOTFOUND:          Result := 'File not found. ';
+    FMOD_ERR_FILE_UNWANTED:          Result := 'Unwanted file access occured. ';
+    FMOD_ERR_FORMAT:                 Result := 'Unsupported file or audio format. ';
+    FMOD_ERR_HTTP:                   Result := 'A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere. ';
+    FMOD_ERR_HTTP_ACCESS:            Result := 'The specified resource requires authentication or is forbidden. ';
+    FMOD_ERR_HTTP_PROXY_AUTH:        Result := 'Proxy authentication is required to access the specified resource. ';
+    FMOD_ERR_HTTP_SERVER_ERROR:      Result := 'A HTTP server error occurred. ';
+    FMOD_ERR_HTTP_TIMEOUT:           Result := 'The HTTP request timed out. ';
+    FMOD_ERR_INITIALIZATION:         Result := 'FMOD was not initialized correctly to support this function. ';
+    FMOD_ERR_INITIALIZED:            Result := 'Cannot call this command after System::init. ';
+    FMOD_ERR_INTERNAL:               Result := 'An error occured that wasnt supposed to.  Contact support. ';
+    FMOD_ERR_INVALID_ADDRESS:        Result := 'On Xbox 360, this memory address passed to FMOD must be physical, (ie allocated with XPhysicalAlloc.) ';
+    FMOD_ERR_INVALID_FLOAT:          Result := 'Value passed in was a NaN, Inf or denormalized float. ';
+    FMOD_ERR_INVALID_HANDLE:         Result := 'An invalid object handle was used. ';
+    FMOD_ERR_INVALID_PARAM:          Result := 'An invalid parameter was passed to this function. ';
+    FMOD_ERR_INVALID_POSITION:       Result := 'An invalid seek position was passed to this function. ';
+    FMOD_ERR_INVALID_SPEAKER:        Result := 'An invalid speaker was passed to this function based on the current speaker mode. ';
+    FMOD_ERR_INVALID_SYNCPOINT:      Result := 'The syncpoint did not come from this sound handle. ';
+    FMOD_ERR_INVALID_VECTOR:         Result := 'The vectors passed in are not unit length, or perpendicular. ';
+    FMOD_ERR_IRX:                    Result := 'PS2 only.  fmodex.irx failed to initialize.  This is most likely because you forgot to load it. ';
+    FMOD_ERR_MAXAUDIBLE:             Result := 'Reached maximum audible playback count for this sounds soundgroup. ';
+    FMOD_ERR_MEMORY:                 Result := 'Not enough memory or resources. ';
+    FMOD_ERR_MEMORY_CANTPOINT:       Result := 'Cant use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used. ';
+    FMOD_ERR_MEMORY_IOP:             Result := 'PS2 only.  Not enough memory or resources on PlayStation 2 IOP ram. ';
+    FMOD_ERR_MEMORY_SRAM:            Result := 'Not enough memory or resources on console sound ram. ';
+    FMOD_ERR_MUSIC_UNINITIALIZED:    Result := 'Music system is not initialized probably because no music data is loaded. ';
+    FMOD_ERR_NEEDS2D:                Result := 'Tried to call a command on a 3d sound when the command was meant for 2d sound. ';
+    FMOD_ERR_NEEDS3D:                Result := 'Tried to call a command on a 2d sound when the command was meant for 3d sound. ';
+    FMOD_ERR_NEEDSHARDWARE:          Result := 'Tried to use a feature that requires hardware support.  (ie trying to play a VAG compressed sound in software on PS2). ';
+    FMOD_ERR_NEEDSSOFTWARE:          Result := 'Tried to use a feature that requires the software engine.  Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. ';
+    FMOD_ERR_NET_CONNECT:            Result := 'Couldnt connect to the specified host. ';
+    FMOD_ERR_NET_SOCKET_ERROR:       Result := 'A socket error occurred.  This is a catch-all for socket-related errors not listed elsewhere. ';
+    FMOD_ERR_NET_URL:                Result := 'The specified URL couldnt be resolved. ';
+    FMOD_ERR_NET_WOULD_BLOCK:        Result := 'Operation on a non-blocking socket could not complete immediately. ';
+    FMOD_ERR_NOTREADY:               Result := 'Operation could not be performed because specified sound/DSP connection is not ready. ';
+    FMOD_ERR_OUTPUT_ALLOCATED:       Result := 'Error initializing output device, but more specifically, the output device is already in use and cannot be reused. ';
+    FMOD_ERR_OUTPUT_CREATEBUFFER:    Result := 'Error creating hardware sound buffer. ';
+    FMOD_ERR_OUTPUT_DRIVERCALL:      Result := 'A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted. ';
+    FMOD_ERR_OUTPUT_ENUMERATION:     Result := 'Error enumerating the available driver list. List may be inconsistent due to a recent device addition or removal. ';
+    FMOD_ERR_OUTPUT_FORMAT:          Result := 'Soundcard does not support the minimum features needed for this soundsystem (16bit stereo output). ';
+    FMOD_ERR_OUTPUT_INIT:            Result := 'Error initializing output device. ';
+    FMOD_ERR_OUTPUT_NOHARDWARE:      Result := 'FMOD_HARDWARE was specified but the sound card does not have the resources necessary to play it. ';
+    FMOD_ERR_OUTPUT_NOSOFTWARE:      Result := 'Attempted to create a software sound but no software channels were specified in System::init. ';
+    FMOD_ERR_PAN:                    Result := 'Panning only works with mono or stereo sound sources. ';
+    FMOD_ERR_PLUGIN:                 Result := 'An unspecified error has been returned from a 3rd party plugin. ';
+    FMOD_ERR_PLUGIN_INSTANCES:       Result := 'The number of allowed instances of a plugin has been exceeded. ';
+    FMOD_ERR_PLUGIN_MISSING:         Result := 'A requested output, dsp unit type or codec was not available. ';
+    FMOD_ERR_PLUGIN_RESOURCE:        Result := 'A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback) ';
+    FMOD_ERR_PRELOADED:              Result := 'The specified sound is still in use by the event system, call EventSystem::unloadFSB before trying to release it. ';
+    FMOD_ERR_RECORD:                 Result := 'An error occured trying to initialize the recording device. ';
+    FMOD_ERR_REVERB_INSTANCE:        Result := 'Specified Instance in FMOD_REVERB_PROPERTIES couldnt be set. Most likely because it is an invalid instance number, or another application has locked the EAX4 FX slot. ';
+    FMOD_ERR_SUBSOUNDS:              Result := 'The error occured because the sound referenced contains subsounds.  The operation cannot be performed on a parent sound, or a parent sound was played without setting up a sentence first. ';
+    FMOD_ERR_SUBSOUND_ALLOCATED:     Result := 'This subsound is already being used by another sound, you cannot have more than one parent to a sound.  Null out the other parents entry first. ';
+    FMOD_ERR_SUBSOUND_CANTMOVE:      Result := 'Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file. ';
+    FMOD_ERR_SUBSOUND_MODE:          Result := 'The subsounds mode bits do not match with the parent sounds mode bits.  See documentation for function that it was called with. ';
+    FMOD_ERR_TAGNOTFOUND:            Result := 'The specified tag could not be found or there are no tags. ';
+    FMOD_ERR_TOOMANYCHANNELS:        Result := 'The sound created exceeds the allowable input channel count.  This can be increased using the maxinputchannels parameter in System::setSoftwareFormat. ';
+    FMOD_ERR_UNIMPLEMENTED:          Result := 'Something in FMOD hasnt been implemented when it should be! contact support! ';
+    FMOD_ERR_UNINITIALIZED:          Result := 'This command failed because System::init or System::setDriver was not called. ';
+    FMOD_ERR_UNSUPPORTED:            Result := 'A command issued was not supported by this object.  Possibly a plugin without certain callbacks specified. ';
+    FMOD_ERR_UPDATE:                 Result := 'An error caused by System::update occured. ';
+    FMOD_ERR_VERSION:                Result := 'The version number of this file format is not supported. ';
+    FMOD_OK:                         Result := 'No errors.';
+    else
+      Result := 'Unknown error.';
+  end;
+end;
+
+end.
diff --git a/src/lib/fmod/fmodpresets.pas b/src/lib/fmod/fmodpresets.pas
new file mode 100644 (file)
index 0000000..26905b2
--- /dev/null
@@ -0,0 +1,81 @@
+(* ========================================================================================== *)
+(* FMOD Ex - Presets header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2008.  *)
+(*                                                                                            *)
+(* A set of predefined environment PARAMETERS, created by Creative Labs.                      *)
+(* These are used to initialize an FMOD_REVERB_PROPERTIES structure statically.               *)
+(*                                                                                            *)
+(* ========================================================================================== *)
+
+unit fmodpresets;
+
+{$I fmod.inc}
+
+interface
+
+uses
+  fmodtypes;
+
+(*
+[DEFINE]
+[
+    [NAME]
+    FMOD_REVERB_PRESETS
+
+    [DESCRIPTION]
+    A set of predefined environment PARAMETERS, created by Creative Labs
+    These are used to initialize an FMOD_REVERB_PROPERTIES structure statically.
+    ie
+    FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC;
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable
+
+    [SEE_ALSO]
+    FMOD_System_SetReverbProperties
+]
+*)
+
+{$IFDEF COMPILER6_UP}{$J+}{$ENDIF}
+(*                                                           Instance     Env              Size            Diffuse               Room          RoomHF          RmLF        DecTm             DecHF               DecLF               Refl                RefDel                    RefPan                            Revb          RevDel              ReverbPan                   EchoTm            EchDp             ModTm                 ModDp                   AirAbs                  HFRef                 LFRef               RRlOff                  Diffus            Densty          FLAGS *)
+const
+  FSOUND_PRESET_OFF:              FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 0;  EnvSize: 7.5;   EnvDiffusion: 1.00;   Room: -10000; RoomHF: -10000; RoomLF: 0;  DecayTime: 1.00;  DecayHFRatio: 1.00; DecayLFRatio: 1.0;  Reflections: -2602; ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 200;  ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 0.0;   Density: 0.0;   Flags: $3f);
+  FSOUND_PRESET_GENERIC:          FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 0;  EnvSize: 7.5;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -100;   RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.83; DecayLFRatio: 1.0;  Reflections: -2602; ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 200;  ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_PADDEDCELL:       FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 1;  EnvSize: 1.4;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -6000;  RoomLF: 0;  DecayTime: 0.17;  DecayHFRatio: 0.10; DecayLFRatio: 1.0;  Reflections: -1204; ReflectionsDelay: 0.001;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 207;  ReverbDelay: 0.002; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_ROOM:             FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 2;  EnvSize: 1.9;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -454;   RoomLF: 0;  DecayTime: 0.40;  DecayHFRatio: 0.83; DecayLFRatio: 1.0;  Reflections: -1646; ReflectionsDelay: 0.002;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 53;   ReverbDelay: 0.003; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_BATHROOM:         FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 3;  EnvSize: 1.4;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -1200;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.54; DecayLFRatio: 1.0;  Reflections: -370;  ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 1030; ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 60.0;  Flags: $3f);
+  FSOUND_PRESET_LIVINGROOM:       FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 4;  EnvSize: 2.5;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -6000;  RoomLF: 0;  DecayTime: 0.50;  DecayHFRatio: 0.10; DecayLFRatio: 1.0;  Reflections: -1376; ReflectionsDelay: 0.003;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1104; ReverbDelay: 0.004; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_STONEROOM:        FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 5;  EnvSize: 11.6;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -300;   RoomLF: 0;  DecayTime: 2.31;  DecayHFRatio: 0.64; DecayLFRatio: 1.0;  Reflections: -711;  ReflectionsDelay: 0.012;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 83;   ReverbDelay: 0.017; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_AUDITORIUM:       FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 6;  EnvSize: 21.6;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -476;   RoomLF: 0;  DecayTime: 4.32;  DecayHFRatio: 0.59; DecayLFRatio: 1.0;  Reflections: -789;  ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-289;  ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_CONCERTHALL:      FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 7;  EnvSize: 19.6;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -500;   RoomLF: 0;  DecayTime: 3.92;  DecayHFRatio: 0.70; DecayLFRatio: 1.0;  Reflections: -1230; ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-2;    ReverbDelay: 0.029; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_CAVE:             FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 8;  EnvSize: 14.6;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: 0;      RoomLF: 0;  DecayTime: 2.91;  DecayHFRatio: 1.30; DecayLFRatio: 1.0;  Reflections: -602;  ReflectionsDelay: 0.015;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-302;  ReverbDelay: 0.022; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $1f);
+  FSOUND_PRESET_ARENA:            FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 9;  EnvSize: 36.2;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -698;   RoomLF: 0;  DecayTime: 7.24;  DecayHFRatio: 0.33; DecayLFRatio: 1.0;  Reflections: -1166; ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 16;   ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_HANGAR:           FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 10; EnvSize: 50.3;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -1000;  RoomLF: 0;  DecayTime: 10.05; DecayHFRatio: 0.23; DecayLFRatio: 1.0;  Reflections: -602;  ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 198;  ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_CARPETTEDHALLWAY: FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 11; EnvSize: 1.9;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -4000;  RoomLF: 0;  DecayTime: 0.30;  DecayHFRatio: 0.10; DecayLFRatio: 1.0;  Reflections: -1831; ReflectionsDelay: 0.002;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1630; ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_HALLWAY:          FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 12; EnvSize: 1.8;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -300;   RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.59; DecayLFRatio: 1.0;  Reflections: -1219; ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 441;  ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_STONECORRIDOR:    FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 13; EnvSize: 13.5;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -237;   RoomLF: 0;  DecayTime: 2.70;  DecayHFRatio: 0.79; DecayLFRatio: 1.0;  Reflections: -1214; ReflectionsDelay: 0.013;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 395;  ReverbDelay: 0.020; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_ALLEY:            FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 14; EnvSize: 7.5;   EnvDiffusion: 0.30;   Room: -1000;  RoomHF: -270;   RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.86; DecayLFRatio: 1.0;  Reflections: -1204; ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-4;    ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.125;  EchoDepth: 0.95;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_FOREST:           FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 15; EnvSize: 38.0;  EnvDiffusion: 0.30;   Room: -1000;  RoomHF: -3300;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.54; DecayLFRatio: 1.0;  Reflections: -2560; ReflectionsDelay: 0.162;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-229;  ReverbDelay: 0.088; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.125;  EchoDepth: 1.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 79.0;  Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_CITY:             FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 16; EnvSize: 7.5;   EnvDiffusion: 0.50;   Room: -1000;  RoomHF: -800;   RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.67; DecayLFRatio: 1.0;  Reflections: -2273; ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1691; ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 50.0;  Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_MOUNTAINS:        FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 17; EnvSize: 100.0; EnvDiffusion: 0.27;   Room: -1000;  RoomHF: -2500;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.21; DecayLFRatio: 1.0;  Reflections: -2780; ReflectionsDelay: 0.300;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1434; ReverbDelay: 0.100; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 1.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 27.0;  Density: 100.0; Flags: $1f);
+  FSOUND_PRESET_QUARRY:           FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 18; EnvSize: 17.5;  EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -1000;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.83; DecayLFRatio: 1.0;  Reflections: -10000;ReflectionsDelay: 0.061;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 500;  ReverbDelay: 0.025; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.125;  EchoDepth: 0.70;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_PLAIN:            FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 19; EnvSize: 42.5;  EnvDiffusion: 0.21;   Room: -1000;  RoomHF: -2000;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.50; DecayLFRatio: 1.0;  Reflections: -2466; ReflectionsDelay: 0.179;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1926; ReverbDelay: 0.100; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 1.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 21.0;  Density: 100.0; Flags: $3f);
+  FSOUND_PRESET_PARKINGLOT:       FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 20; EnvSize: 8.3;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: 0;      RoomLF: 0;  DecayTime: 1.65;  DecayHFRatio: 1.50; DecayLFRatio: 1.0;  Reflections: -1363; ReflectionsDelay: 0.008;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-1153; ReverbDelay: 0.012; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $1f);
+  FSOUND_PRESET_SEWERPIPE:        FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 21; EnvSize: 1.7;   EnvDiffusion: 0.80;   Room: -1000;  RoomHF: -1000;  RoomLF: 0;  DecayTime: 2.81;  DecayHFRatio: 0.14; DecayLFRatio: 1.0;  Reflections:  429;  ReflectionsDelay: 0.014;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 1023; ReverbDelay: 0.021; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 0.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 80.0;  Density: 60.0;  Flags: $3f);
+  FSOUND_PRESET_UNDERWATER:       FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 22; EnvSize: 1.8;   EnvDiffusion: 1.00;   Room: -1000;  RoomHF: -4000;  RoomLF: 0;  DecayTime: 1.49;  DecayHFRatio: 0.10; DecayLFRatio: 1.0;  Reflections: -449;  ReflectionsDelay: 0.007;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 1700; ReverbDelay: 0.011; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 1.18; ModulationDepth: 0.348; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $3f);
+
+(* Non I3DL2 presets *)
+
+  FSOUND_PRESET_DRUGGED:          FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 23; EnvSize: 1.9;   EnvDiffusion: 0.50;   Room: -1000;  RoomHF: 0;      RoomLF: 0;  DecayTime: 8.39;  DecayHFRatio: 1.39; DecayLFRatio: 1.0;  Reflections: -115;  ReflectionsDelay: 0.002;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 985;  ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 0.25; ModulationDepth: 1.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $1f);
+  FSOUND_PRESET_DIZZY:            FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 24; EnvSize: 1.8;   EnvDiffusion: 0.60;   Room: -1000;  RoomHF: -400;   RoomLF: 0;  DecayTime: 17.23; DecayHFRatio: 0.56; DecayLFRatio: 1.0;  Reflections: -1713; ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb:-613;  ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 1.00;  ModulationTime: 0.81; ModulationDepth: 0.310; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $1f);
+  FSOUND_PRESET_PSYCHOTIC:        FMOD_REVERB_PROPERTIES = (Instance: 0; Environment: 25; EnvSize: 1.0;   EnvDiffusion: 0.50;   Room: -1000;  RoomHF: -151;   RoomLF: 0;  DecayTime: 7.56;  DecayHFRatio: 0.91; DecayLFRatio: 1.0;  Reflections: -626;  ReflectionsDelay: 0.020;  ReflectionsPan: (0.0, 0.0, 0.0);  Reverb: 774;  ReverbDelay: 0.030; ReverbPan: (0.0, 0.0, 0.0); EchoTime: 0.250;  EchoDepth: 0.00;  ModulationTime: 4.00; ModulationDepth: 1.000; AirAbsorptionHF: -5.0;  HFReference: 5000.0;  LFReference: 250.0; RoomRolloffFactor: 0.0; Diffusion: 100.0; Density: 100.0; Flags: $1f);
+
+(* PlayStation 2 Only presets *)
+(* Delphi/Kylix cannot create PlayStation 2 executables, so there is no need to
+   convert the PlayStation 2 presets. *)
+{$IFDEF COMPILER6_UP}{$J-}{$ENDIF}
+
+(* [DEFINE_END] *)
+
+implementation
+
+end.
diff --git a/src/lib/fmod/fmodtypes.pas b/src/lib/fmod/fmodtypes.pas
new file mode 100644 (file)
index 0000000..bdd5942
--- /dev/null
@@ -0,0 +1,2181 @@
+(* ============================================================================================= *)
+(* FMOD Ex - Main C/C++ header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2008.  *)
+(*                                                                                               *)
+(* This header is the base header for all other FMOD headers.  If you are programming in C       *)
+(* use this exclusively, or if you are programming C++ use this in conjunction with FMOD.HPP     *)
+(*                                                                                               *)
+(* ============================================================================================= *)
+
+unit fmodtypes;
+
+{$I fmod.inc}
+
+interface
+
+(*
+    FMOD version number.  Check this against FMOD_System_GetVersion
+*)
+
+const
+  FMOD_VERSION = $00041500;
+
+(*
+    FMOD types.
+*)
+
+type
+  FMOD_SYSTEM       = Pointer;
+  FMOD_SOUND        = Pointer;
+  FMOD_CHANNEL      = Pointer;
+  FMOD_CHANNELGROUP = Pointer;
+  FMOD_DSP          = Pointer;
+  FMOD_BOOL         = LongBool;
+  FMOD_POLYGON    = Pointer;
+  FMOD_GEOMETRY     = Pointer;
+  FMOD_SYNCPOINT  = Pointer;
+  FMOD_TIMEUNIT     = Cardinal;
+            fmod_mode=cardinal;
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Structure describing a point in 3D space.
+
+    [REMARKS]
+    FMOD uses a left handed co-ordinate system by default.
+    To use a right handed co-ordinate system specify FMOD_INIT_3D_RIGHTHANDED from FMOD_INITFLAGS in FMOD_System_Init.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_Set3DListenerAttributes
+    FMOD_System_Get3DListenerAttributes
+    FMOD_Channel_Set3DAttributes
+    FMOD_Channel_Get3DAttributes
+    FMOD_Geometry_AddPolygon
+    FMOD_Geometry_SetPolygonVertex
+    FMOD_Geometry_GetPolygonVertex
+    FMOD_Geometry_SetRotation
+    FMOD_Geometry_GetRotation
+    FMOD_Geometry_SetPosition
+    FMOD_Geometry_GetPosition
+    FMOD_Geometry_SetScale
+    FMOD_Geometry_GetScale
+    FMOD_INITFLAGS
+]
+*)
+type PFMOD_VECTOR = ^FMOD_VECTOR;
+  FMOD_VECTOR = record
+    x, y, z: Single;
+  end;
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    error codes.  Returned from every function.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+]
+*)
+type
+  FMOD_RESULT =
+  (
+    FMOD_OK,                        {  No errors.  }
+    FMOD_ERR_ALREADYLOCKED,         {  Tried to call lock a second time before unlock was called.  }
+    FMOD_ERR_BADCOMMAND,            {  Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound).  }
+    FMOD_ERR_CDDA_DRIVERS,          {  Neither NTSCSI nor ASPI could be initialised.  }
+    FMOD_ERR_CDDA_INIT,             {  An error occurred while initialising the CDDA subsystem.  }
+    FMOD_ERR_CDDA_INVALID_DEVICE,   {  Couldn't find the specified device.  }
+    FMOD_ERR_CDDA_NOAUDIO,          {  No audio tracks on the specified disc.  }
+    FMOD_ERR_CDDA_NODEVICES,        {  No CD/DVD devices were found.  }
+    FMOD_ERR_CDDA_NODISC,           {  No disc present in the specified drive.  }
+    FMOD_ERR_CDDA_READ,             {  A CDDA read error occurred.  }
+    FMOD_ERR_CHANNEL_ALLOC,         {  Error trying to allocate a channel.  }
+    FMOD_ERR_CHANNEL_STOLEN,        {  The specified channel has been reused to play another sound.  }
+    FMOD_ERR_COM,                   {  A Win32 COM related error occured. COM failed to initialize or a QueryInterface failed meaning a Windows codec or driver was not installed properly.  }
+    FMOD_ERR_DMA,                   {  DMA Failure.  See debug output for more information.  }
+    FMOD_ERR_DSP_CONNECTION,        {  DSP connection error.  Connection possibly caused a cyclic dependancy.  Or tried to connect a tree too many units deep (more than 128).  }
+    FMOD_ERR_DSP_FORMAT,            {  DSP Format error.  A DSP unit may have attempted to connect to this network with the wrong format.  }
+    FMOD_ERR_DSP_NOTFOUND,          {  DSP connection error.  Couldn't find the DSP unit specified.  }
+    FMOD_ERR_DSP_RUNNING,           {  DSP error.  Cannot perform this operation while the network is in the middle of running.  This will most likely happen if a connection or disconnection is attempted in a DSP callback.  }
+    FMOD_ERR_DSP_TOOMANYCONNECTIONS,{  DSP connection error.  The unit being connected to or disconnected should only have 1 input or output.  }
+    FMOD_ERR_FILE_BAD,              {  Error loading file.  }
+    FMOD_ERR_FILE_COULDNOTSEEK,     {  Couldn't perform seek operation.  This is a limitation of the medium (ie netstreams) or the file format.  }
+    FMOD_ERR_FILE_DISKEJECTED,      {  Media was ejected while reading.  }
+    FMOD_ERR_FILE_EOF,              {  End of file unexpectedly reached while trying to read essential data (truncated data?).  }
+    FMOD_ERR_FILE_NOTFOUND,         {  File not found.  }
+    FMOD_ERR_FILE_UNWANTED,         {  Unwanted file access occured.  }
+    FMOD_ERR_FORMAT,                {  Unsupported file or audio format.  }
+    FMOD_ERR_HTTP,                  {  A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere.  }
+    FMOD_ERR_HTTP_ACCESS,           {  The specified resource requires authentication or is forbidden.  }
+    FMOD_ERR_HTTP_PROXY_AUTH,       {  Proxy authentication is required to access the specified resource.  }
+    FMOD_ERR_HTTP_SERVER_ERROR,     {  A HTTP server error occurred.  }
+    FMOD_ERR_HTTP_TIMEOUT,          {  The HTTP request timed out.  }
+    FMOD_ERR_INITIALIZATION,        {  FMOD was not initialized correctly to support this function.  }
+    FMOD_ERR_INITIALIZED,           {  Cannot call this command after System::init.  }
+    FMOD_ERR_INTERNAL,              {  An error occured that wasn't supposed to.  Contact support.  }
+    FMOD_ERR_INVALID_ADDRESS,       {  On Xbox 360, this memory address passed to FMOD must be physical, (ie allocated with XPhysicalAlloc.)  }
+    FMOD_ERR_INVALID_FLOAT,         {  Value passed in was a NaN, Inf or denormalized float.  }
+    FMOD_ERR_INVALID_HANDLE,        {  An invalid object handle was used.  }
+    FMOD_ERR_INVALID_PARAM,         {  An invalid parameter was passed to this function.  }
+    FMOD_ERR_INVALID_POSITION,      {  An invalid seek position was passed to this function.  }
+    FMOD_ERR_INVALID_SPEAKER,       {  An invalid speaker was passed to this function based on the current speaker mode.  }
+    FMOD_ERR_INVALID_SYNCPOINT,     {  The syncpoint did not come from this sound handle.  }
+    FMOD_ERR_INVALID_VECTOR,        {  The vectors passed in are not unit length, or perpendicular.  }
+    FMOD_ERR_IRX,                   {  PS2 only.  fmodex.irx failed to initialize.  This is most likely because you forgot to load it.  }
+    FMOD_ERR_MAXAUDIBLE,            {  Reached maximum audible playback count for this sound's soundgroup.  }
+    FMOD_ERR_MEMORY,                {  Not enough memory or resources.  }
+    FMOD_ERR_MEMORY_CANTPOINT,      {  Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used.  }
+    FMOD_ERR_MEMORY_IOP,            {  PS2 only.  Not enough memory or resources on PlayStation 2 IOP ram.  }
+    FMOD_ERR_MEMORY_SRAM,           {  Not enough memory or resources on console sound ram.  }
+    FMOD_ERR_NEEDS2D,               {  Tried to call a command on a 3d sound when the command was meant for 2d sound.  }
+    FMOD_ERR_NEEDS3D,               {  Tried to call a command on a 2d sound when the command was meant for 3d sound.  }
+    FMOD_ERR_NEEDSHARDWARE,         {  Tried to use a feature that requires hardware support.  (ie trying to play a VAG compressed sound in software on PS2).  }
+    FMOD_ERR_NEEDSSOFTWARE,         {  Tried to use a feature that requires the software engine.  Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature.  }
+    FMOD_ERR_NET_CONNECT,           {  Couldn't connect to the specified host.  }
+    FMOD_ERR_NET_SOCKET_ERROR,      {  A socket error occurred.  This is a catch-all for socket-related errors not listed elsewhere.  }
+    FMOD_ERR_NET_URL,               {  The specified URL couldn't be resolved.  }
+    FMOD_ERR_NET_WOULD_BLOCK,       {  Operation on a non-blocking socket could not complete immediately.  }
+    FMOD_ERR_NOTREADY,              {  Operation could not be performed because specified sound/DSP connection is not ready.  }
+    FMOD_ERR_OUTPUT_ALLOCATED,      {  Error initializing output device, but more specifically, the output device is already in use and cannot be reused.  }
+    FMOD_ERR_OUTPUT_CREATEBUFFER,   {  Error creating hardware sound buffer.  }
+    FMOD_ERR_OUTPUT_DRIVERCALL,     {  A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted.  }
+    FMOD_ERR_OUTPUT_ENUMERATION,    {  Error enumerating the available driver list. List may be inconsistent due to a recent device addition or removal.  }
+    FMOD_ERR_OUTPUT_FORMAT,         {  Soundcard does not support the minimum features needed for this soundsystem (16bit stereo output).  }
+    FMOD_ERR_OUTPUT_INIT,           {  Error initializing output device.  }
+    FMOD_ERR_OUTPUT_NOHARDWARE,     {  FMOD_HARDWARE was specified but the sound card does not have the resources necessary to play it.  }
+    FMOD_ERR_OUTPUT_NOSOFTWARE,     {  Attempted to create a software sound but no software channels were specified in System::init.  }
+    FMOD_ERR_PAN,                   {  Panning only works with mono or stereo sound sources.  }
+    FMOD_ERR_PLUGIN,                {  An unspecified error has been returned from a 3rd party plugin.  }
+    FMOD_ERR_PLUGIN_INSTANCES,      {  The number of allowed instances of a plugin has been exceeded.  }
+    FMOD_ERR_PLUGIN_MISSING,        {  A requested output, dsp unit type or codec was not available.  }
+    FMOD_ERR_PLUGIN_RESOURCE,       {  A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback)  }
+    FMOD_ERR_RECORD,                {  An error occured trying to initialize the recording device.  }
+    FMOD_ERR_REVERB_INSTANCE,       {  Specified Instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number, or another application has locked the EAX4 FX slot.  }
+    FMOD_ERR_SUBSOUND_ALLOCATED,    {  This subsound is already being used by another sound, you cannot have more than one parent to a sound.  Null out the other parent's entry first.  }
+    FMOD_ERR_SUBSOUND_CANTMOVE,     {  Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file.  }
+    FMOD_ERR_SUBSOUND_MODE,         {  The subsound's mode bits do not match with the parent sound's mode bits.  See documentation for function that it was called with.  }
+    FMOD_ERR_SUBSOUNDS,             {  The error occured because the sound referenced contains subsounds.  The operation cannot be performed on a parent sound, or a parent sound was played without setting up a sentence first.  }
+    FMOD_ERR_TAGNOTFOUND,           {  The specified tag could not be found or there are no tags.  }
+    FMOD_ERR_TOOMANYCHANNELS,       {  The sound created exceeds the allowable input channel count.  This can be increased using the maxinputchannels parameter in System::setSoftwareFormat.  }
+    FMOD_ERR_UNIMPLEMENTED,         {  Something in FMOD hasn't been implemented when it should be! contact support!  }
+    FMOD_ERR_UNINITIALIZED,         {  This command failed because System::init or System::setDriver was not called.  }
+    FMOD_ERR_UNSUPPORTED,           {  A command issued was not supported by this object.  Possibly a plugin without certain callbacks specified.  }
+    FMOD_ERR_UPDATE,                {  An error caused by System::update occured.  }
+    FMOD_ERR_VERSION,               {  The version number of this file format is not supported.  }
+    FMOD_ERR_PRELOADED,             {  The specified sound is still in use by the event system, call EventSystem::unloadFSB before trying to release it.  }
+
+    FMOD_ERR_EVENT_FAILED,          {  An Event failed to be retrieved, most likely due to 'just fail' being specified as the max playbacks behavior.  }
+    FMOD_ERR_EVENT_INFOONLY,        {  Can't execute this command on an EVENT_INFOONLY event.  }
+    FMOD_ERR_EVENT_INTERNAL,        {  An error occured that wasn't supposed to.  See debug log for reason.  }
+    FMOD_ERR_EVENT_MAXSTREAMS,      {  Event failed because 'Max streams' was hit when FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified.  }
+    FMOD_ERR_EVENT_MISMATCH,        {  FSB mismatches the FEV it was compiled with, the stream/sample mode it was meant to be created with was different, or the FEV was built for a different platform.  }
+    FMOD_ERR_EVENT_NAMECONFLICT,    {  A category with the same name already exists.  }
+    FMOD_ERR_EVENT_NOTFOUND,        {  The requested event, event group, event category or event property could not be found.  }
+    FMOD_ERR_EVENT_NEEDSSIMPLE,     {  Tried to call a function on a complex event that's only supported by simple events.  }
+    FMOD_ERR_EVENT_GUIDCONFLICT,    {  An event with the same GUID already exists.  }
+    FMOD_ERR_EVENT_ALREADY_LOADED,  {  The specified project has already been loaded. Having multiple copies of the same project loaded simultaneously is forbidden.  }
+
+    FMOD_ERR_MUSIC_UNINITIALIZED,   {  Music system is not initialized probably because no music data is loaded.  }
+
+    FMOD_RESULT_FORCEINT = 65536    {  Makes sure this enum is signed 32bit.  }
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These output types are used with FMOD_System_SetOutput/FMOD_System_GetOutput, to choose which output method to use.
+
+    [REMARKS]
+    To pass information to the driver when initializing fmod use the extradriverdata parameter in System::init for the following reasons.
+    - FMOD_OUTPUTTYPE_WAVWRITER - extradriverdata is a pointer to a char * filename that the wav writer will output to.
+    - FMOD_OUTPUTTYPE_WAVWRITER_NRT - extradriverdata is a pointer to a char * filename that the wav writer will output to.
+    - FMOD_OUTPUTTYPE_DSOUND - extradriverdata is a pointer to a HWND so that FMOD can set the focus on the audio for a particular window.
+    - FMOD_OUTPUTTYPE_GC - extradriverdata is a pointer to a FMOD_ARAMBLOCK_INFO struct. This can be found in fmodgc.h.
+    - FMOD_OUTPUTTYPE_ALSA - extradriverdata is a pointer to a char * argument if required by the chosen ALSA driver.
+    Currently these are the only FMOD drivers that take extra information.  Other unknown plugins may have different requirements.
+
+    Note! If FMOD_OUTPUTTYPE_NOSOUND_NRT or FMOD_OUTPUTTYPE_NOSOUND_NRT are used, and if the System::update function is being called
+    very quickly (ie for a non realtime decode) it may be being called too quickly for the FMOD streamer thread to respond to.
+    The result will be a skipping/stuttering output in the captured audio.
+    To remedy this, disable the FMOD Ex streamer thread, and use FMOD_INIT_STREAM_FROM_UPDATE can be used to avoid skipping in
+    the output stream, as it will lock the mixer and the streamer together in the same thread.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_SetOutput
+    FMOD_System_GetOutput
+    FMOD_System_SetSoftwareFormat
+    FMOD_System_GetSoftwareFormat
+    FMOD_System_Init
+    FMOD_System_Update
+    FMOD_INITFLAGS
+]
+*)
+type
+  FMOD_OUTPUTTYPE =
+  (
+    FMOD_OUTPUTTYPE_AUTODETECT,      (* Picks the best output mode for the platform.  This is the default. *)
+
+    FMOD_OUTPUTTYPE_UNKNOWN,         (* All         - 3rd party plugin, unknown.  This is for use with System::getOutput only. *)
+    FMOD_OUTPUTTYPE_NOSOUND,         (* All         - All calls in this mode succeed but make no sound. *)
+    FMOD_OUTPUTTYPE_WAVWRITER,       (* All         - Writes output to fmodoutput.wav by default.  Use the 'extradriverdata' parameter in System::init, by simply passing the filename as a string, to set the wav filename. *)
+    FMOD_OUTPUTTYPE_NOSOUND_NRT,     (* All         - Non-realtime version of FMOD_OUTPUTTYPE_NOSOUND.  User can drive mixer with System::update at whatever rate they want. *)
+    FMOD_OUTPUTTYPE_WAVWRITER_NRT,   (* All         - Non-realtime version of FMOD_OUTPUTTYPE_WAVWRITER.  User can drive mixer with System::update at whatever rate they want. *)
+
+    FMOD_OUTPUTTYPE_DSOUND,          (* Win32/Win64 - DirectSound output.  Use this to get hardware accelerated 3d audio and EAX Reverb support. (Default on Windows) *)
+    FMOD_OUTPUTTYPE_WINMM,           (* Win32/Win64 - Windows Multimedia output. *)
+    FMOD_OUTPUTTYPE_OPENAL,          (* Win32/Win64 - OpenAL 1.1 output. Use this for lower CPU overhead than FMOD_OUTPUTTYPE_DSOUND, and also Vista H/W support with Creative Labs cards. *)
+    FMOD_OUTPUTTYPE_WASAPI,          (* Win32       - Windows Audio Session API. (Default on Windows Vista) *)
+    FMOD_OUTPUTTYPE_ASIO,            (* Win32       - Low latency ASIO driver. *)
+    FMOD_OUTPUTTYPE_OSS,             (* Linux       - Open Sound System output. (Default on Linux) *)
+    FMOD_OUTPUTTYPE_ALSA,            (* Linux       - Advanced Linux Sound Architecture output. *)
+    FMOD_OUTPUTTYPE_ESD,             (* Linux       - Enlightment Sound Daemon output. *)
+    FMOD_OUTPUTTYPE_SOUNDMANAGER,    (* Mac         - Macintosh SoundManager output.  (Default on Mac carbon library)*)
+    FMOD_OUTPUTTYPE_COREAUDIO,       (* Mac         - Macintosh CoreAudio output.  (Default on Mac OSX library) *)
+    FMOD_OUTPUTTYPE_XBOX,            (* Xbox        - Native hardware output. (Default on Xbox) *)
+    FMOD_OUTPUTTYPE_PS2,             (* PS2         - Native hardware output. (Default on PS2) *)
+    FMOD_OUTPUTTYPE_PS3,             (* PS3         - Native hardware output. (Default on PS3) *)
+    FMOD_OUTPUTTYPE_GC,              (* GameCube    - Native hardware output. (Default on GameCube) *)
+    FMOD_OUTPUTTYPE_XBOX360,         (* Xbox 360    - Native hardware output. (Default on Xbox 360) *)
+    FMOD_OUTPUTTYPE_PSP,             (* PSP         - Native hardware output. (Default on PSP) *)
+    FMOD_OUTPUTTYPE_WII,       (* Wii     - Native hardware output. (Default on Wii) *)
+
+    FMOD_OUTPUTTYPE_MAX              (* Maximum number of output types supported. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Bit fields to use with FMOD_System_GetDriverCaps to determine the capabilities of a card / output device.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_GetDriverCaps
+]
+*)
+const
+    FMOD_CAPS_NONE                    = $00000000;    (* Device has no special capabilities *)
+    FMOD_CAPS_HARDWARE                = $00000001;    (* Device supports hardware mixing. *)
+    FMOD_CAPS_HARDWARE_EMULATED       = $00000002;    (* User has device set to 'Hardware acceleration = off' in control panel, and now extra 200ms latency is incurred.*)
+    FMOD_CAPS_OUTPUT_MULTICHANNEL     = $00000004;    (* Device can do multichannel output, ie greater than 2 channels *)
+    FMOD_CAPS_OUTPUT_FORMAT_PCM8      = $00000008;    (* Device can output to 8bit integer PCM *)
+    FMOD_CAPS_OUTPUT_FORMAT_PCM16     = $00000010;    (* Device can output to 16bit integer PCM *)
+    FMOD_CAPS_OUTPUT_FORMAT_PCM24     = $00000020;    (* Device can output to 24bit integer PCM *)
+    FMOD_CAPS_OUTPUT_FORMAT_PCM32     = $00000040;    (* Device can output to 32bit integer PCM *)
+    FMOD_CAPS_OUTPUT_FORMAT_PCMFLOAT  = $00000080;    (* Device can output to 32bit floating point PCM *)
+    FMOD_CAPS_REVERB_EAX2             = $00000100;    (* Device supports EAX2 reverb. *)
+    FMOD_CAPS_REVERB_EAX3             = $00000200;    (* Device supports EAX3 reverb. *)
+    FMOD_CAPS_REVERB_EAX4             = $00000400;    (* Device supports EAX4 reverb  *)
+    FMOD_CAPS_REVERB_EAX5       = $00000800;    (* Device supports EAX5 reverb  *)
+    FMOD_CAPS_REVERB_I3DL2            = $00001000;    (* Device supports I3DL2 reverb. *)
+    FMOD_CAPS_REVERB_LIMITED          = $00002000;    (* Device supports some form of limited hardware reverb, maybe parameterless and only selectable by environment. *)
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These are speaker types defined for use with the FMOD_System_SetSpeakerMode or FMOD_System_GetSpeakerMode command.
+
+    [REMARKS]
+    These are important notes on speaker modes in regards to sounds created with FMOD_SOFTWARE.
+    Note below the phrase 'sound channels' is used.  These are the subchannels inside a sound, they are not related and
+    have nothing to do with the FMOD class "FMOD_CHANNEL".
+    For example a mono sound has 1 sound channel, a stereo sound has 2 sound channels, and an AC3 or 6 channel wav file have 6 "sound channels".
+
+    FMOD_SPEAKERMODE_NONE
+    ---------------------
+    This mode is for output devices that are not specifically mono/stereo/quad/surround/5.1 or 7.1, but are multichannel.
+    Sound channels map to speakers sequentially, so a mono sound maps to output speaker 0, stereo sound maps to output speaker 0 & 1.
+    The user assumes knowledge of the speaker order.  FMOD_SPEAKER enumerations may not apply, so raw channel indicies should be used.
+    Multichannel sounds map input channels to output channels 1:1.
+    Channel::setPan and Channel::setSpeakerMix do not work.
+    Speaker levels must be manually set with Channel::setSpeakerLevels.
+
+    FMOD_SPEAKERMODE_MONO
+    ---------------------
+    This mode is for a 1 speaker arrangement.
+    Panning does not work in this speaker mode.
+    Mono, stereo and multichannel sounds have each sound channel played on the one speaker unity.
+    Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    Channel::setSpeakerMix does not work.
+
+    FMOD_SPEAKERMODE_STEREO
+    -----------------------
+    This mode is for 2 speaker arrangements that have a left and right speaker.
+    - Mono sounds default to an even distribution between left and right.  They can be panned with Channel::setPan.
+    - Stereo sounds default to the middle, or full left in the left speaker and full right in the right speaker.
+    - They can be cross faded with Channel::setPan.
+    - Multichannel sounds have each sound channel played on each speaker at unity.
+    - Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    - Channel::setSpeakerMix works but only front left and right parameters are used, the rest are ignored.
+
+    FMOD_SPEAKERMODE_QUAD
+    ------------------------
+    This mode is for 4 speaker arrangements that have a front left, front right, rear left and a rear right speaker.
+    - Mono sounds default to an even distribution between front left and front right.  They can be panned with Channel::setPan.
+    - Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right.
+    - They can be cross faded with Channel::setPan.
+    - Multichannel sounds default to all of their sound channels being played on each speaker in order of input.
+    - Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    - Channel::setSpeakerMix works but side left, side right, center and lfe are ignored.
+
+    FMOD_SPEAKERMODE_SURROUND
+    ------------------------
+    This mode is for 4 speaker arrangements that have a front left, front right, front center and a rear center.
+    - Mono sounds default to the center speaker.  They can be panned with Channel::setPan.
+    - Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right.
+    - They can be cross faded with Channel::setPan.
+    - Multichannel sounds default to all of their sound channels being played on each speaker in order of input.
+    - Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    - Channel::setSpeakerMix works but side left, side right and lfe are ignored, and rear left / rear right are averaged into the rear speaker.
+
+    FMOD_SPEAKERMODE_5POINT1
+    ------------------------
+    This mode is for 5.1 speaker arrangements that have a left/right/center/rear left/rear right and a subwoofer speaker.
+    - Mono sounds default to the center speaker.  They can be panned with Channel::setPan.
+    - Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right.
+    - They can be cross faded with Channel::setPan.
+    - Multichannel sounds default to all of their sound channels being played on each speaker in order of input.
+    - Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    - Channel::setSpeakerMix works but side left / side right are ignored.
+
+    FMOD_SPEAKERMODE_7POINT1
+    ------------------------
+    This mode is for 7.1 speaker arrangements that have a left/right/center/rear left/rear right/side left/side right
+    and a subwoofer speaker.
+    - Mono sounds default to the center speaker.  They can be panned with Channel::setPan.
+    - Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right.
+    - They can be cross faded with Channel::setPan.
+    - Multichannel sounds default to all of their sound channels being played on each speaker in order of input.
+    - Mix behaviour for multichannel sounds can be set with Channel::setSpeakerLevels.
+    - Channel::setSpeakerMix works and every parameter is used to set the balance of a sound in any speaker.
+
+    FMOD_SPEAKERMODE_PROLOGIC
+    ------------------------------------------------------
+    This mode is for mono, stereo, 5.1 and 7.1 speaker arrangements, as it is backwards and forwards compatible with stereo,
+    but to get a surround effect a Dolby Prologic or Prologic 2 hardware decoder / amplifier is needed.
+    Pan behaviour is the same as FMOD_SPEAKERMODE_5POINT1.
+
+    If this function is called the numoutputchannels setting in System::setSoftwareFormat is overwritten.
+
+    For 3D sounds, panning is determined at runtime by the 3D subsystem based on the speaker mode to determine which speaker the
+    sound should be placed in.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_SetSpeakerMode
+    FMOD_System_GetSpeakerMode
+    FMOD_System_GetDriverCaps
+    FMOD_Channel_SetSpeakerLevels
+]
+*)
+type
+  FMOD_SPEAKERMODE =
+  (
+    FMOD_SPEAKERMODE_RAW,              (* There is no specific speakermode.  Sound channels are mapped in order of input to output.  See remarks for more information. *)
+    FMOD_SPEAKERMODE_MONO,             (* The speakers are monaural. *)
+    FMOD_SPEAKERMODE_STEREO,           (* The speakers are stereo (DEFAULT). *)
+    FMOD_SPEAKERMODE_QUAD,             (* 4 speaker setup.  This includes front left, front right, rear left, rear right.  *)
+    FMOD_SPEAKERMODE_SURROUND,         (* 4 speaker setup.  This includes front left, front right, center, rear center (rear left/rear right are averaged). *)
+    FMOD_SPEAKERMODE_5POINT1,          (* 5.1 speaker setup.  This includes front left, front right, center, rear left, rear right and a subwoofer. *)
+    FMOD_SPEAKERMODE_7POINT1,          (* 7.1 speaker setup.  This includes front left, front right, center, rear left, rear right, side left, side right and a subwoofer. *)
+    FMOD_SPEAKERMODE_PROLOGIC          (* Stereo output, but data is encoded in a way that is picked up by a Prologic/Prologic2 decoder and split into a 5.1 speaker setup. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These are speaker types defined for use with the FMOD_Channel_SetSpeakerLevels command.
+    It can also be used for speaker placement in the FMOD_System_Set3DSpeakerPosition command.
+
+    [REMARKS]
+    If you are using FMOD_SPEAKERMODE_NONE and speaker assignments are meaningless, just cast a raw integer value to this type.
+    For example (FMOD_SPEAKER)7 would use the 7th speaker (also the same as FMOD_SPEAKER_SIDE_RIGHT).
+    Values higher than this can be used if an output system has more than 8 speaker types / output channels.  15 is the current maximum.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_SPEAKERMODE
+    FMOD_Channel_SetSpeakerLevels
+    FMOD_Channel_GetSpeakerLevels
+    FMOD_System_Set3DSpeakerPosition
+    FMOD_System_Get3DSpeakerPosition
+]
+*)
+type
+  FMOD_SPEAKER =
+  (
+    FMOD_SPEAKER_FRONT_LEFT,
+    FMOD_SPEAKER_FRONT_RIGHT,
+    FMOD_SPEAKER_FRONT_CENTER,
+    FMOD_SPEAKER_LOW_FREQUENCY,
+    FMOD_SPEAKER_BACK_LEFT,
+    FMOD_SPEAKER_BACK_RIGHT,
+    FMOD_SPEAKER_SIDE_LEFT,
+    FMOD_SPEAKER_SIDE_RIGHT,
+    FMOD_SPEAKER_MAX
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These are plugin types defined for use with the FMOD_System_GetNumPlugins,
+    FMOD_System_GetPluginInfo and FMOD_System_UnloadPlugin functions.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_GetNumPlugins
+    FMOD_System_GetPluginInfo
+    FMOD_System_UnloadPlugin
+]
+*)
+type
+  FMOD_PLUGINTYPE =
+  (
+    FMOD_PLUGINTYPE_OUTPUT,          (* The plugin type is an output module.  FMOD mixed audio will play through one of these devices *)
+    FMOD_PLUGINTYPE_CODEC,           (* The plugin type is a file format codec.  FMOD will use these codecs to load file formats for playback. *)
+    FMOD_PLUGINTYPE_DSP              (* The plugin type is a DSP unit.  FMOD will use these plugins as part of its DSP network to apply effects to output or generate sound in realtime. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Initialization flags.  Use them with FMOD_System_Init in the flags parameter to change various behaviour.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_Init
+]
+*)
+const
+    FMOD_INIT_NORMAL                   = $00000000;   (* All platforms - Initialize normally *)
+    FMOD_INIT_STREAM_FROM_UPDATE       = $00000001;   (* All platforms - No stream thread is created internally.  Streams are driven from System::update.  Mainly used with non-realtime outputs. *)
+    FMOD_INIT_3D_RIGHTHANDED           = $00000002;   (* All platforms - FMOD will treat +X as left, +Y as up and +Z as forwards. *)
+    FMOD_INIT_SOFTWARE_DISABLE         = $00000004;   (* All platforms - Disable software mixer to save memory.  Anything created with FMOD_SOFTWARE will fail and DSP will not work. *)
+    FMOD_INIT_SOFTWARE_OCCLUSION       = $00000008;   (* All platforms - All FMOD_SOFTWARE with FMOD_3D based voices will add a software lowpass filter effect into the DSP chain which is automatically used when Channel::set3DOcclusion is used or the geometry API. *)
+    FMOD_INIT_SOFTWARE_HRTF            = $00000010;   (* All platforms - All FMOD_SOFTWARE with FMOD_3D based voices will add a software lowpass filter effect into the DSP chain which causes sounds to sound duller when the sound goes behind the listener. *)
+    FMOD_INIT_VOL0_BECOMES_VIRTUAL     = $00000080;   (* All platforms - Any sounds that are 0 volume will go virtual and not be processed except for having their positions updated virtually.  Use System::setAdvancedSettings to adjust what volume besides zero to switch to virtual at. *)
+    FMOD_INIT_WASAPI_EXCLUSIVE         = $00000100;   (* Win32 Vista only - for WASAPI output - Enable exclusive access to hardware, lower latency at the expense of excluding other applications from accessing the audio hardware. *)
+    FMOD_INIT_DSOUND_HRTFNONE          = $00000200;   (* Win32 only - for DirectSound output - FMOD_HARDWARE | FMOD_3D buffers use simple stereo panning/doppler/attenuation when 3D hardware acceleration is not present. *)
+    FMOD_INIT_DSOUND_HRTFLIGHT         = $00000400;   (* Win32 only - for DirectSound output - FMOD_HARDWARE | FMOD_3D buffers use a slightly higher quality algorithm when 3D hardware acceleration is not present. *)
+    FMOD_INIT_DSOUND_HRTFFULL          = $00000800;   (* Win32 only - for DirectSound output - FMOD_HARDWARE | FMOD_3D buffers use full quality 3D playback when 3d hardware acceleration is not present. *)
+    FMOD_INIT_PS2_DISABLECORE0REVERB   = $00010000;   (* PS2 only - Disable reverb on CORE 0 to regain SRAM. *)
+    FMOD_INIT_PS2_DISABLECORE1REVERB   = $00020000;   (* PS2 only - Disable reverb on CORE 1 to regain SRAM. *)
+    FMOD_INIT_PS2_DONTUSESCRATCHPAD    = $00040000;   (* PS2 only - FMOD's usage of the scratchpad between System::update and System::updateFinished. *)
+    FMOD_INIT_PS2_SWAPDMACHANNELS      = $00080000;   (* PS2 only - Changes FMOD from using SPU DMA channel 0 for software mixing, and 1 for sound data upload/file streaming, to 1 and 0 respectively. *)
+    FMOD_INIT_XBOX_REMOVEHEADROOM      = $00100000;   (* Xbox only - By default DirectSound attenuates all sound by 6db to avoid clipping/distortion.  CAUTION.  If you use this flag you are responsible for the final mix to make sure clipping / distortion doesn't happen. *)
+    FMOD_INIT_360_MUSICMUTENOTPAUSE    = $00200000;   (* Xbox 360 only - The "music" channelgroup which by default pauses when custom 360 dashboard music is played, can be changed to mute (therefore continues playing) instead of pausing, by using this flag. *)
+
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These definitions describe the type of song being played.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetFormat
+]
+*)
+type
+  FMOD_SOUND_TYPE =
+  (
+    FMOD_SOUND_TYPE_UNKNOWN,         {  3rd party / unknown plugin format. }
+    FMOD_SOUND_TYPE_AAC,             {  AAC.  Currently unsupported. }
+    FMOD_SOUND_TYPE_AIFF,            {  AIFF. }
+    FMOD_SOUND_TYPE_ASF,             {  Microsoft Advanced Systems Format (ie WMA/ASF/WMV). }
+    FMOD_SOUND_TYPE_AT3,             {  Sony ATRAC 3 format }
+    FMOD_SOUND_TYPE_CDDA,            {  Digital CD audio. }
+    FMOD_SOUND_TYPE_DLS,             {  Sound font / downloadable sound bank. }
+    FMOD_SOUND_TYPE_FLAC,            {  FLAC lossless codec. }
+    FMOD_SOUND_TYPE_FSB,             {  FMOD Sample Bank. }
+    FMOD_SOUND_TYPE_GCADPCM,         {  GameCube ADPCM }
+    FMOD_SOUND_TYPE_IT,              {  Impulse Tracker. }
+    FMOD_SOUND_TYPE_MIDI,            {  MIDI. }
+    FMOD_SOUND_TYPE_MOD,             {  Protracker / Fasttracker MOD. }
+    FMOD_SOUND_TYPE_MPEG,            {  MP2/MP3 MPEG. }
+    FMOD_SOUND_TYPE_OGGVORBIS,       {  Ogg vorbis. }
+    FMOD_SOUND_TYPE_PLAYLIST,        {  Information only from ASX/PLS/M3U/WAX playlists }
+    FMOD_SOUND_TYPE_RAW,             {  Raw PCM data. }
+    FMOD_SOUND_TYPE_S3M,             {  ScreamTracker 3. }
+    FMOD_SOUND_TYPE_SF2,             {  Sound font 2 format. }
+    FMOD_SOUND_TYPE_USER,            {  User created sound. }
+    FMOD_SOUND_TYPE_WAV,             {  Microsoft WAV. }
+    FMOD_SOUND_TYPE_XM,              {  FastTracker 2 XM. }
+    FMOD_SOUND_TYPE_XMA,             {  Xbox360 XMA }
+    FMOD_SOUND_TYPE_VAG,             {  PlayStation 2 / PlayStation Portable adpcm VAG format. }
+
+    FMOD_SOUND_TYPE_MAX,             {  Maximum number of sound types supported. }
+    FMOD_SOUND_TYPE_FORCEINT = 65536 {  Makes sure this enum is signed 32bit. }
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These definitions describe the native format of the hardware or software buffer that will be used.
+
+    [REMARKS]
+    This is the format the native hardware or software buffer will be or is created in.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateSound
+    FMOD_Sound_GetFormat
+]
+*)
+type
+  FMOD_SOUND_FORMAT =
+  (
+    FMOD_SOUND_FORMAT_NONE,             {  Unitialized / unknown.  }
+    FMOD_SOUND_FORMAT_PCM8,             {  8bit integer PCM data.  }
+    FMOD_SOUND_FORMAT_PCM16,            {  16bit integer PCM data.   }
+    FMOD_SOUND_FORMAT_PCM24,            {  24bit integer PCM data.   }
+    FMOD_SOUND_FORMAT_PCM32,            {  32bit integer PCM data.   }
+    FMOD_SOUND_FORMAT_PCMFLOAT,         {  32bit floating point PCM data.   }
+    FMOD_SOUND_FORMAT_GCADPCM,          {  Compressed GameCube DSP data.  }
+    FMOD_SOUND_FORMAT_IMAADPCM,         {  Compressed IMA ADPCM / Xbox ADPCM data.  }
+    FMOD_SOUND_FORMAT_VAG,              {  Compressed PlayStation 2 / PlayStation Portable ADPCM data.  }
+    FMOD_SOUND_FORMAT_XMA,              {  Compressed Xbox360 data.  }
+    FMOD_SOUND_FORMAT_MPEG,             {  Compressed MPEG layer 2 or 3 data.  }
+
+    FMOD_SOUND_FORMAT_MAX,              {  Maximum number of sound formats supported.  }
+    FMOD_SOUND_FORMAT_FORCEINT = 65536  {  Makes sure this enum is signed 32bit.  }
+  );
+  PFMOD_SOUND_FORMAT = ^FMOD_SOUND_FORMAT;
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Sound description bitfields, bitwise OR them together for loading and describing sounds.
+
+    [REMARKS]
+    By default a sound will open as a static sound that is decompressed fully into memory.  To have a sound stream instead, use FMOD_CREATESTREAM.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateSound
+    FMOD_System_CreateStream
+    FMOD_Sound_GetMode
+    FMOD_Sound_GetMode
+    FMOD_Channel_SetMode
+    FMOD_Channel_GetMode
+]
+*)
+const
+  FMOD_DEFAULT                 = $00000000;  {  FMOD_DEFAULT is a default sound type.  Equivalent to all the defaults listed below.  FMOD_LOOP_OFF, FMOD_2D, FMOD_HARDWARE.  (Note - only Windows with a high spec soundcard, PS2, PSP, and Wii support FMOD_HARDWARE)  }
+  FMOD_LOOP_OFF                = $00000001;  {  For non looping sounds. (DEFAULT).  Overrides FMOD_LOOP_NORMAL / FMOD_LOOP_BIDI.  }
+  FMOD_LOOP_NORMAL             = $00000002;  {  For forward looping sounds.  }
+  FMOD_LOOP_BIDI               = $00000004;  {  For bidirectional looping sounds. (only works on software mixed static sounds).  }
+  FMOD_2D                      = $00000008;  {  Ignores any 3d processing. (DEFAULT).  }
+  FMOD_3D                      = $00000010;  {  Makes the sound positionable in 3D.  Overrides FMOD_2D.  }
+  FMOD_HARDWARE                = $00000020;  {  Attempts to make sounds use hardware acceleration. (DEFAULT).  Note on platforms that don't support FMOD_HARDWARE (only Windows with a high spec soundcard, PS2, PSP, and Wii support FMOD_HARDWARE), this will be internally treated as FMOD_SOFTWARE.  }
+  FMOD_SOFTWARE                = $00000040;  {  Makes the sound be mixed by the FMOD CPU based software mixer.  Overrides FMOD_HARDWARE.  Use this for FFT, DSP, compressed sample support, 2D multi-speaker support and other software related features.  }
+  FMOD_CREATESTREAM            = $00000080;  {  Decompress at runtime, streaming from the source provided (ie from disk).  Overrides FMOD_CREATESAMPLE and FMOD_CREATECOMPRESSEDSAMPLE.  Note a stream can only be played once at a time due to a stream only having 1 stream buffer and file handle.  Open multiple streams to have them play concurrently.  }
+  FMOD_CREATESAMPLE            = $00000100;  {  Decompress at loadtime, decompressing or decoding whole file into memory as the target sample format (ie PCM).  Fastest for FMOD_SOFTWARE based playback and most flexible.   }
+  FMOD_CREATECOMPRESSEDSAMPLE  = $00000200;  {  Load MP2, MP3, IMAADPCM or XMA into memory and leave it compressed.  During playback the FMOD software mixer will decode it in realtime as a 'compressed sample'.  Can only be used in combination with FMOD_SOFTWARE.  Overrides FMOD_CREATESAMPLE.  If the sound data is not ADPCM, MPEG or XMA it will behave as if it was created with FMOD_CREATESAMPLE and decode the sound into PCM.  }
+  FMOD_OPENUSER                = $00000400;  {  Opens a user created static sample or stream. Use FMOD_CREATESOUNDEXINFO to specify format and/or read callbacks.  If a user created 'sample' is created with no read callback, the sample will be empty.  Use Sound::lock and Sound::unlock to place sound data into the sound if this is the case.  }
+  FMOD_OPENMEMORY              = $00000800;  {  "name_or_data" will be interpreted as a pointer to memory instead of filename for creating sounds.  Use FMOD_CREATESOUNDEXINFO to specify length.  If used with FMOD_CREATESAMPLE or FMOD_CREATECOMPRESSEDSAMPLE, FMOD duplicates the memory into its own buffers.  Your own buffer can be freed after open.  If used with FMOD_CREATESTREAM, FMOD will stream out of the buffer whose pointer you passed in.  In this case, your own buffer should not be freed until you have finished with and released the stream. }
+  FMOD_OPENMEMORY_POINT        = $10000000;  {  "name_or_data" will be interpreted as a pointer to memory instead of filename for creating sounds.  Use FMOD_CREATESOUNDEXINFO to specify length.  This differs to FMOD_OPENMEMORY in that it uses the memory as is, without duplicating the memory into its own buffers.  For Wii/PSP FMOD_HARDWARE supports this flag for the GCADPCM/VAG formats.  On other platforms FMOD_SOFTWARE must be used, as sound hardware on the other platforms (ie PC) cannot access main ram.  Cannot be freed after open, only after Sound::release.   Will not work if the data is compressed and FMOD_CREATECOMPRESSEDSAMPLE is not used.  }
+  FMOD_OPENRAW                 = $00001000;  {  Will ignore file format and treat as raw pcm.  Use FMOD_CREATESOUNDEXINFO to specify format.  Requires at least defaultfrequency, numchannels and format to be specified before it will open.  Must be little endian data.  }
+  FMOD_OPENONLY                = $00002000;  {  Just open the file, dont prebuffer or read.  Good for fast opens for info, or when sound::readData is to be used.  }
+  FMOD_ACCURATETIME            = $00004000;  {  For System::createSound - for accurate Sound::getLength/Channel::setPosition on VBR MP3, and MOD/S3M/XM/IT/MIDI files.  Scans file first, so takes longer to open. FMOD_OPENONLY does not affect this.  }
+  FMOD_MPEGSEARCH              = $00008000;  {  For corrupted / bad MP3 files.  This will search all the way through the file until it hits a valid MPEG header.  Normally only searches for 4k.  }
+  FMOD_NONBLOCKING             = $00010000;  {  For opening sounds and getting streamed subsounds (seeking) asyncronously.  Use Sound::getOpenState to poll the state of the sound as it opens or retrieves the subsound in the background.  }
+  FMOD_UNIQUE                  = $00020000;  {  Unique sound, can only be played one at a time  }
+  FMOD_3D_HEADRELATIVE         = $00040000;  {  Make the sound's position, velocity and orientation relative to the listener.  }
+  FMOD_3D_WORLDRELATIVE        = $00080000;  {  Make the sound's position, velocity and orientation absolute (relative to the world). (DEFAULT)  }
+  FMOD_3D_LOGROLLOFF           = $00100000;  {  This sound will follow the standard logarithmic rolloff model where mindistance = full volume, maxdistance = where sound stops attenuating, and rolloff is fixed according to the global rolloff factor.  (DEFAULT)  }
+  FMOD_3D_LINEARROLLOFF        = $00200000;  {  This sound will follow a linear rolloff model where mindistance = full volume, maxdistance = silence.  Rolloffscale is ignored.  }
+  FMOD_3D_CUSTOMROLLOFF        = $04000000;  {  This sound will follow a rolloff model defined by Sound::set3DCustomRolloff / Channel::set3DCustomRolloff.   }
+  FMOD_3D_IGNOREGEOMETRY       = $40000000;  {  Is not affect by geometry occlusion.  If not specified in Sound::setMode, or Channel::setMode, the flag is cleared and it is affected by geometry again.  }
+  FMOD_CDDA_FORCEASPI          = $00400000;  {  For CDDA sounds only - use ASPI instead of NTSCSI to access the specified CD/DVD device.  }
+  FMOD_CDDA_JITTERCORRECT      = $00800000;  {  For CDDA sounds only - perform jitter correction. Jitter correction helps produce a more accurate CDDA stream at the cost of more CPU time.  }
+  FMOD_UNICODE                 = $01000000;  {  Filename is double-byte unicode.  }
+  FMOD_IGNORETAGS              = $02000000;  {  Skips id3v2/asf/etc tag checks when opening a sound, to reduce seek/read overhead when opening files (helps with CD performance).  }
+  FMOD_LOWMEM                  = $08000000;  {  Removes some features from samples to give a lower memory overhead, like Sound::getName.  See remarks.  }
+  FMOD_LOADSECONDARYRAM        = $20000000;  {  Load sound into the secondary RAM of supported platform. On PS3, sounds will be loaded into RSX/VRAM.  }
+  FMOD_VIRTUAL_PLAYFROMSTART   = $80000000;  {  For sounds that start virtual (due to being quiet or low importance), instead of swapping back to audible, and playing at the correct offset according to time, this flag makes the sound play from the start.  }
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These values describe what state a sound is in after FMOD_NONBLOCKING has been used to open it.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetOpenState
+    FMOD_MODE
+]
+*)
+type
+  FMOD_OPENSTATE =
+  (
+    FMOD_OPENSTATE_READY = 0,       {  Opened and ready to play.  }
+    FMOD_OPENSTATE_LOADING,         {  Initial load in progress.  }
+    FMOD_OPENSTATE_ERROR,           {  Failed to open - file not found, out of memory etc.  See return value of Sound::getOpenState for what happened.  }
+    FMOD_OPENSTATE_CONNECTING,      {  Connecting to remote host (internet sounds only).  }
+    FMOD_OPENSTATE_BUFFERING,       {  Buffering data.  }
+    FMOD_OPENSTATE_SEEKING,         {  Seeking to subsound and re-flushing stream buffer.  }
+    FMOD_OPENSTATE_STREAMING,       {  Ready and playing, but not possible to release at this time without stalling the main thread.  }
+    FMOD_OPENSTATE_SETPOSITION,     {  Seeking within a stream to a different position.  }
+
+    FMOD_OPENSTATE_MAX,             {  Maximum number of open state types.  }
+    FMOD_OPENSTATE_FORCEINT = 65536 {  Makes sure this enum is signed 32bit.  }
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These callback types are used with FMOD_Channel_SetCallback.
+
+    [REMARKS]
+    Each callback has commanddata parameters passed int unique to the type of callback.
+    See reference to FMOD_CHANNEL_CALLBACK to determine what they might mean for each type of callback.
+
+    Note!  Currently the user must call System::update for these callbacks to trigger!
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Channel_SetCallback
+    FMOD_CHANNEL_CALLBACK
+    FMOD_System_Update
+]
+*)
+type
+  FMOD_CHANNEL_CALLBACKTYPE =
+  (
+    FMOD_CHANNEL_CALLBACKTYPE_END,            (* Called when a sound ends. *)
+    FMOD_CHANNEL_CALLBACKTYPE_VIRTUALVOICE,   (* Called when a voice is swapped out or swapped in. *)
+    FMOD_CHANNEL_CALLBACKTYPE_SYNCPOINT,      (* Called when a syncpoint is encountered.  Can be from wav file markers. *)
+    FMOD_CHANNEL_CALLBACKTYPE_OCCLUSION,      (* Called when the channel has its geometry occlusion value calculated.  Can be used to clamp or change the value. *)
+
+    FMOD_CHANNEL_CALLBACKTYPE_MAX ,           (* Maximum number of callback types supported. *)
+    FMOD_CHANNEL_CALLBACKTYPE_FORCEINT = 65536
+  );
+
+
+(*
+    FMOD Callbacks
+*)
+type
+  FMOD_CHANNEL_CALLBACK       = function (channel: FMOD_CHANNEL; callbacktype: FMOD_CHANNEL_CALLBACKTYPE; commanddata1: Pointer; commanddata2: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+  FMOD_SOUND_NONBLOCKCALLBACK = function (sound: FMOD_SOUND; result: FMOD_RESULT): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_SOUND_PCMREADCALLBACK  = function (sound: FMOD_SOUND; data: Pointer; datalen: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_SOUND_PCMSEEKCALLBACK  = function (sound: FMOD_SOUND; subsound: Integer; pcmoffset: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+  FMOD_FILE_OPENCALLBACK      = function (const name: PChar; unicode: Integer; filesize: Cardinal; handle: Pointer; var userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_FILE_CLOSECALLBACK     = function (handle: Pointer; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_FILE_READCALLBACK      = function (handle, buffer: Pointer; sizebytes: Cardinal; var bytesread: Cardinal; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_FILE_SEEKCALLBACK      = function (handle: Pointer; pos, type_: Integer; userdata: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+  FMOD_MEMORY_ALLOCCALLBACK   = function (size: Cardinal): Pointer; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_MEMORY_REALLOCCALLBACK = function (ptr: Pointer; size: Cardinal): Pointer; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_MEMORY_FREECALLBACK    = procedure (ptr: Pointer); {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    List of windowing methods used in spectrum analysis to reduce leakage / transient signals intefering with the analysis.
+    This is a problem with analysis of continuous signals that only have a small portion of the signal sample (the fft window size).
+    Windowing the signal with a curve or triangle tapers the sides of the fft window to help alleviate this problem.
+
+    [REMARKS]
+    Cyclic signals such as a sine wave that repeat their cycle in a multiple of the window size do not need windowing.
+    I.e. If the sine wave repeats every 1024, 512, 256 etc samples and the FMOD fft window is 1024, then the signal would not need windowing.
+    Not windowing is the same as FMOD_DSP_FFT_WINDOW_RECT, which is the default.
+    If the cycle of the signal (ie the sine wave) is not a multiple of the window size, it will cause frequency abnormalities, so a different windowing method is needed.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_GetSpectrum
+    FMOD_Channel_GetSpectrum
+]
+*)
+type
+  FMOD_DSP_FFT_WINDOW =
+  (
+    FMOD_DSP_FFT_WINDOW_RECT,           (* w[n] = 1.0                                                                                            *)
+    FMOD_DSP_FFT_WINDOW_TRIANGLE,       (* w[n] = TRI(2n/N)                                                                                      *)
+    FMOD_DSP_FFT_WINDOW_HAMMING,        (* w[n] = 0.54 - (0.46 * COS(n/N) )                                                                      *)
+    FMOD_DSP_FFT_WINDOW_HANNING,        (* w[n] = 0.5 *  (1.0  - COS(n/N) )                                                                      *)
+    FMOD_DSP_FFT_WINDOW_BLACKMAN,       (* w[n] = 0.42 - (0.5  * COS(n/N) ) + (0.08 * COS(2.0 * n/N) )                                           *)
+    FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS, (* w[n] = 0.35875 - (0.48829 * COS(1.0 * n/N)) + (0.14128 * COS(2.0 * n/N)) - (0.01168 * COS(3.0 * n/N)) *)
+    FMOD_DSP_FFT_WINDOW_MAX
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    List of interpolation types that the FMOD Ex software mixer supports.
+
+    [REMARKS]
+    The default resampler type is FMOD_DSP_RESAMPLER_LINEAR.
+    Use System::setSoftwareFormat to tell FMOD the resampling quality you require for FMOD_SOFTWARE based sounds.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    System::setSoftwareFormat
+    System::getSoftwareFormat
+]
+*)
+type
+  FMOD_DSP_RESAMPLER =
+  (
+    FMOD_DSP_RESAMPLER_NOINTERP,        (* No interpolation.  High frequency aliasing hiss will be audible depending on the sample rate of the sound. *)
+    FMOD_DSP_RESAMPLER_LINEAR,          (* Linear interpolation (default method).  Fast and good quality, causes very slight lowpass effect on low frequency sounds. *)
+    FMOD_DSP_RESAMPLER_CUBIC,           (* Cubic interoplation.  Slower than linear interpolation but better quality. *)
+    FMOD_DSP_RESAMPLER_SPLINE,          (* 5 point spline interoplation.  Slowest resampling method but best quality. *)
+    FMOD_DSP_RESAMPLER_MAX
+  );
+
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    List of tag types that could be stored within a sound.  These include id3 tags, metadata from netstreams and vorbis/asf data.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetTag
+]
+*)
+type
+  FMOD_TAGTYPE =
+  (
+    FMOD_TAGTYPE_UNKNOWN,
+    FMOD_TAGTYPE_ID3V1,
+    FMOD_TAGTYPE_ID3V2,
+    FMOD_TAGTYPE_VORBISCOMMENT,
+    FMOD_TAGTYPE_SHOUTCAST,
+    FMOD_TAGTYPE_ICECAST,
+    FMOD_TAGTYPE_ASF,
+    FMOD_TAGTYPE_MIDI,
+    FMOD_TAGTYPE_PLAYLIST,
+    FMOD_TAGTYPE_FMOD,
+    FMOD_TAGTYPE_USER,
+    FMOD_TAGTYPE_MAX
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    List of data types that can be returned by FMOD_Sound_GetTag
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetTag
+]
+*)
+type
+  FMOD_TAGDATATYPE =
+  (
+    FMOD_TAGDATATYPE_BINARY,
+    FMOD_TAGDATATYPE_INT,
+    FMOD_TAGDATATYPE_FLOAT,
+    FMOD_TAGDATATYPE_STRING,
+    FMOD_TAGDATATYPE_STRING_UTF16,
+    FMOD_TAGDATATYPE_STRING_UTF16BE,
+    FMOD_TAGDATATYPE_STRING_UTF8,
+    FMOD_TAGDATATYPE_CDTOC
+  );
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Structure describing a piece of tag data.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetTag
+    FMOD_TAGTYPE
+    FMOD_TAGDATATYPE
+]
+*)
+type
+  FMOD_TAG = record
+    tagtype: FMOD_TAGTYPE;      (* [out] The type of this tag. *)
+    datatype: FMOD_TAGDATATYPE; (* [out] The type of data that this tag contains *)
+    name: PChar;                (* [out] The name of this tag i.e. "TITLE", "ARTIST" etc. *)
+    data: Pointer;              (* [out] Pointer to the tag data - its format is determined by the datatype member *)
+    datalen: Cardinal;          (* [out] Length of the data contained in this tag *)
+    updated: FMOD_BOOL;         (* [out] True if this tag has been updated since last being accessed with FMOD_Sound_GetTag *)
+  end;
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Structure describing a CD/DVD table of contents
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetTag
+]
+*)
+type
+  FMOD_CDTOC = record
+    numtracks: Integer;                 (* [out] The number of tracks on the CD *)
+    min: array [0..99] of Integer;      (* [out] The start offset of each track in minutes *)
+    sec: array [0..99] of Integer;      (* [out] The start offset of each track in seconds *)
+    frame: array [0..99] of Integer;    (* [out] The start offset of each track in frames *)
+  end;
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    List of time types that can be returned by FMOD_Sound_GetLength and used with FMOD_Channel_SetPosition or FMOD_Channel_GetPosition.
+
+    [REMARKS]
+    FMOD_TIMEUNIT_SUBSOUND_MS, FMOD_TIMEUNIT_SUBSOUND_PCM, FMOD_TIMEUNIT_SUBSOUND_PCMBYTES, FMOD_TIMEUNIT_SUBSOUND and FMOD_TIMEUNIT_SUBSOUND_BUFFERED are only supported by Channel::getPosition.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Sound_GetLength
+    FMOD_Channel_SetPosition
+    FMOD_Channel_GetPosition
+]
+*)
+const
+    FMOD_TIMEUNIT_MS                 = $00000001;  (* Milliseconds. *)
+    FMOD_TIMEUNIT_PCM                = $00000002;  (* PCM Samples, related to milliseconds * samplerate / 1000. *)
+    FMOD_TIMEUNIT_PCMBYTES           = $00000004;  (* Bytes, related to PCM samples * channels * datawidth (ie 16bit = 2 bytes). *)
+    FMOD_TIMEUNIT_RAWBYTES           = $00000008;  (* Raw file bytes of (compressed) sound data (does not include headers).  Only used by FMOD_Sound_GetLength and FMOD_Channel_GetPosition. *)
+    FMOD_TIMEUNIT_MODORDER           = $00000100;  (* MOD/S3M/XM/IT.  Order in a sequenced module format.  Use FMOD_Sound_GetFormat to determine the format. *)
+    FMOD_TIMEUNIT_MODROW             = $00000200;  (* MOD/S3M/XM/IT.  Current row in a sequenced module format.  FMOD_Sound_GetLength will return the number if rows in the currently playing or seeked to pattern. *)
+    FMOD_TIMEUNIT_MODPATTERN         = $00000400;  (* MOD/S3M/XM/IT.  Current pattern in a sequenced module format.  Sound::getLength will return the number of patterns in the song and Channel::getPosition will return the currently playing pattern. *)
+    FMOD_TIMEUNIT_SENTENCE_MS        = $00010000;  (* Currently playing subsound in a sentence time in milliseconds. *)
+    FMOD_TIMEUNIT_SENTENCE_PCM       = $00020000;  (* Currently playing subsound in a sentence time in PCM Samples, related to milliseconds * samplerate / 1000. *)
+    FMOD_TIMEUNIT_SENTENCE_PCMBYTES  = $00040000;  (* Currently playing subsound in a sentence time in bytes, related to PCM samples * channels * datawidth (ie 16bit = 2 bytes). *)
+    FMOD_TIMEUNIT_SENTENCE           = $00080000;  (* Currently playing subsound in a sentence according to the channel. For display.  *)
+    FMOD_TIMEUNIT_SENTENCE_SUBSOUND  = $00100000;  (* Currently playing subsound in a sentence according to the buffered ahead of time sound.  For sentence processing ahead of time. *)
+    FMOD_TIMEUNIT_BUFFERED           = $10000000;  (* Time value as seen by buffered stream.  This is always ahead of audible time, and is only used for processing. *)
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    When creating a multichannel sound, FMOD will pan them to their default speaker locations, for example a 6 channel sound will default to one channel per 5.1 output speaker.
+    Another example is a stereo sound.  It will default to left = front left, right = front right.
+
+    This is for sounds that are not 'default'.  For example you might have a sound that is 6 channels but actually made up of 3 stereo pairs, that should all be located in front left, front right only.
+
+    [REMARKS]
+    For full flexibility of speaker assignments, use Channel::setSpeakerLevels.  This functionality is cheaper, uses less memory and easier to use.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3, Wii
+
+    [SEE_ALSO]
+    FMOD_CREATESOUNDEXINFO
+    FMOD_Channel_SetSpeakerLevels
+]
+*)
+type
+  FMOD_SPEAKERMAPTYPE =
+  (
+    FMOD_SPEAKERMAPTYPE_DEFAULT,     (* This is the default, and just means FMOD decides which speakers it puts the source channels. *)
+    FMOD_SPEAKERMAPTYPE_ALLMONO,     (* This means the sound is made up of all mono sounds.  All voices will be panned to the front center by default in this case.  *)
+    FMOD_SPEAKERMAPTYPE_ALLSTEREO    (* This means the sound is made up of all stereo sounds.  All voices will be panned to front left and front right alternating every second channel.  *)
+  );
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Use this structure with FMOD_System_CreateSound when more control is needed over loading.
+    The possible reasons to use this with FMOD_System_CreateSound are:
+    - Loading a file from memory.
+    - Loading a file from within another file, giving an offset and length.
+    - To create a user created / non file based sound.
+    - To specify a starting subsound to seek to within a multi-sample sounds (ie FSB/DLS/SF2) when created as a stream.
+    - To specify which subsounds to load for multi-sample sounds (ie FSB/DLS/SF2) so that memory is saved and only a subset is actually loaded/read from disk.
+    - To specify 'piggyback' read and seek callbacks for capture of sound data as fmod reads and decodes it.  Useful for ripping decoded PCM data from sounds as they are loaded / played.
+    - To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI file.
+    See below on what members to fill for each of the above types of sound you want to create.
+
+    [REMARKS]
+    This structure is optional!  Specify 0 or NULL in FMOD_System_CreateSound if you don't need it!
+
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    Loading a file from memory.
+    ---------------------------
+    - Create the sound using the FMOD_OPENMEMORY flag.
+    - Mandatory.  Specify 'length' for the size of the memory block in bytes.
+    - Other flags are optional.
+
+    Loading a file from within another larger (possibly wad/pak) file, by giving the loader an offset and length.
+    -------------------------------------------------------------------------------------------------------------
+    - Mandatory.  Specify 'fileoffset' and 'length'.
+    - Other flags are optional.
+
+    To create a user created / non file based sound.
+    ------------------------------------------------
+    - Create the sound using the FMOD_OPENUSER flag.
+    - Mandatory.  Specify 'defaultfrequency, 'numchannels' and 'format'.
+    - Other flags are optional.
+
+    To specify a starting subsound to seek to and flush with, within a multi-sample stream (ie FSB/DLS/SF2).
+    --------------------------------------------------------------------------------------------------------
+    - Mandatory.  Specify 'initialsubsound'.
+
+    To specify which subsounds to load for multi-sample sounds (ie FSB/DLS/SF2) so that memory is saved and only a subset is actually loaded/read from disk.
+    --------------------------------------------------------------------------------------------------------------------------------------------------------
+    - Mandatory.  Specify 'inclusionlist' and 'inclusionlistnum'.
+
+    To specify 'piggyback' read and seek callbacks for capture of sound data as fmod reads and decodes it.  Useful for ripping decoded PCM data from sounds as they are loaded / played.
+    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+    - Mandatory.  Specify 'pcmreadcallback' and 'pcmseekcallback'.
+
+    To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI file.
+    ---------------------------------------------------------------------------
+    - Mandatory.  Specify 'dlsname'.
+
+    Setting the 'decodebuffersize' is for cpu intensive codecs that may be causing stuttering, not file intensive codecs (ie those from CD or netstreams) which are normally altered with System::setStreamBufferSize.  As an example of cpu intensive codecs, an mp3 file will take more cpu to decode than a PCM wav file.
+    If you have a stuttering effect, then it is using more cpu than the decode buffer playback rate can keep up with.  Increasing the decode buffersize will most likely solve this problem.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateSound
+]
+*)
+type
+  FMOD_CREATESOUNDEXINFO = record
+    cbsize: Integer;                                   (* [in] Size of this structure.  This is used so the structure can be expanded in the future and still work on older versions of FMOD Ex. *)
+    length: Cardinal;                                  (* [in] Optional. Specify 0 to ignore. Size in bytes of file to load, or sound to create (in this case only if FMOD_OPENUSER is used).  Required if loading from memory.  If 0 is specified, then it will use the size of the file (unless loading from memory then an error will be returned). *)
+    fileoffset: Cardinal;                              (* [in] Optional. Specify 0 to ignore. Offset from start of the file to start loading from.  This is useful for loading files from inside big data files. *)
+    numchannels: Integer;                              (* [in] Optional. Specify 0 to ignore. Number of channels in a sound specified only if FMOD_OPENUSER is used. *)
+    defaultfrequency: Integer;                         (* [in] Optional. Specify 0 to ignore. Default frequency of sound in a sound specified only if FMOD_OPENUSER is used.  Other formats use the frequency determined by the file format. *)
+    format: FMOD_SOUND_FORMAT;                         (* [in] Optional. Specify 0 or FMOD_SOUND_FORMAT_NONE to ignore. Format of the sound specified only if FMOD_OPENUSER is used.  Other formats use the format determined by the file format.   *)
+    decodebuffersize: Integer;                         (* [in] Optional. Specify 0 to ignore. For streams.  This determines the size of the double buffer (in PCM samples) that a stream uses.  Use this for user created streams if you want to determine the size of the callback buffer passed to you.  Specify 0 to use FMOD's default size which is currently equivalent to 400ms of the sound format created/loaded. *)
+    initialsubsound: Integer;                          (* [in] Optional. Specify 0 to ignore. In a multi-sample file format such as .FSB/.DLS/.SF2, specify the initial subsound to seek to, only if FMOD_CREATESTREAM is used. *)
+    numsubsounds: Integer;                             (* [in] Optional. Specify 0 to ignore or have no subsounds.  In a user created multi-sample sound, specify the number of subsounds within the sound that are accessable with FMOD_SoundGetSubSound. *)
+    inclusionlist: ^Integer;                           (* [in] Optional. Specify 0 to ignore. In a multi-sample format such as .FSB/.DLS/.SF2 it may be desirable to specify only a subset of sounds to be loaded out of the whole file.  This is an array of subsound indicies to load into memory when created. *)
+    inclusionlistnum: Integer;                         (* [in] Optional. Specify 0 to ignore. This is the number of integers contained within the *)
+    pcmreadcallback: FMOD_SOUND_PCMREADCALLBACK;       (* [in] Optional. Specify 0 to ignore. Callback to 'piggyback' on FMOD's read functions and accept or even write PCM data while FMOD is opening the sound.  Used for user sounds created with FMOD_OPENUSER or for capturing decoded data as FMOD reads it. *)
+    pcmseekcallback: FMOD_SOUND_PCMSEEKCALLBACK;       (* [in] Optional. Specify 0 to ignore. Callback for when the user calls a seeking function such as FMOD_Channel_SetPosition within a multi-sample sound, and for when it is opened.*)
+    nonblockcallback: FMOD_SOUND_NONBLOCKCALLBACK;     (* [in] Optional. Specify 0 to ignore. Callback for successful completion, or error while loading a sound that used the FMOD_NONBLOCKING flag.*)
+    dlsname: PChar;                                    (* [in] Optional. Specify 0 to ignore. Filename for a DLS or SF2 sample set when loading a MIDI file.   If not specified, on windows it will attempt to open /windows/system32/drivers/gm.dls, otherwise the MIDI will fail to open.  *)
+    encryptionkey: PChar;                              (* [in] Optional. Specify 0 to ignore. Key for encrypted FSB file.  Without this key an encrypted FSB file will not load. *)
+    maxpolyphony: Integer;                             (* [in] Optional. Specify 0 to ignore. For sequenced formats with dynamic channel allocation such as .MID and .IT, this specifies the maximum voice count allowed while playing.  .IT defaults to 64.  .MID defaults to 32. *)
+    userdata: Pointer;                                 (* [in] Optional. Specify 0 to ignore. This is user data to be attached to the sound during creation.  Access via Sound::getUserData. *)
+    suggestedsoundtype: FMOD_SOUND_TYPE;               (* [in] Optional. Specify 0 or FMOD_SOUND_TYPE_UNKNOWN to ignore.  Instead of scanning all codec types, use this to speed up loading by making it jump straight to this codec. *)
+    useropen:  FMOD_FILE_OPENCALLBACK;                 (* [in] Optional. Specify 0 to ignore. Callback for opening this file. *)
+    userclose: FMOD_FILE_CLOSECALLBACK;                (* [in] Optional. Specify 0 to ignore. Callback for closing this file. *)
+    userread: FMOD_FILE_READCALLBACK;                  (* [in] Optional. Specify 0 to ignore. Callback for reading from this file. *)
+    userseek: FMOD_FILE_SEEKCALLBACK;                  (* [in] Optional. Specify 0 to ignore. Callback for seeking within this file. *)
+    speakermap: FMOD_SPEAKERMAPTYPE;                   (* [in] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers.  See FMOD_SPEAKERMAPTYPE for more. *)
+    initialsoundgroup: Integer;                        (* [in] Optional. Specify 0 to ignore. Specify a sound group if required, to put sound in as it is created. *)
+    initialseekposition: Integer;                      (* [in] Optional. Specify 0 to ignore. For streams. Specify an initial position to seek the stream to. *)
+    initialseekpostype: FMOD_TIMEUNIT;                 (* [in] Optional. Specify 0 to ignore. For streams. Specify the time unit for the position set in initialseekposition. *)
+    ignoresetfilesystem: Integer;                      (* [in] Optional. Specify 0 to ignore. Set to 1 to use fmod's built in file system. Ignores setFileSystem callbacks and also FMOD_CREATESOUNEXINFO file callbacks.  Useful for specific cases where you don't want to use your own file system but want to use fmod's file system (ie net streaming). *)
+    // myVersion2013: Array [0..27] of Byte;
+  end;
+  PFMOD_CREATESOUNDEXINFO = ^FMOD_CREATESOUNDEXINFO;
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Structure defining a reverb environment.
+
+    For more indepth descriptions of the reverb properties under win32, please see the EAX2 and EAX3
+    documentation at http://developer.creative.com/ under the 'downloads' section.
+    If they do not have the EAX3 documentation, then most information can be attained from
+    the EAX2 documentation, as EAX3 only adds some more parameters and functionality on top of
+    EAX2.
+
+    [REMARKS]
+    Note the default reverb properties are the same as the FMOD_PRESET_GENERIC preset.
+    Note that integer values that typically range from -10,000 to 1000 are represented in
+    decibels, and are of a logarithmic scale, not linear, wheras float values are always linear.
+    PORTABILITY: Each member has the platform it supports in braces ie (win32/xbox).
+    Some reverb parameters are only supported in win32 and some only on xbox. If all parameters are set then
+    the reverb should product a similar effect on either platform.
+    Win32/Win64 - This is only supported with FMOD_OUTPUTTYPE_DSOUND and EAX compatible sound cards.
+    Macintosh - Currently unsupported.
+    Linux - Currently unsupported.
+    Xbox - Only a subset of parameters are supported.
+    PlayStation 2 - Only the Environment and Flags paramenters are supported.
+    GameCube - Only a subset of parameters are supported.
+
+    The numerical values listed below are the maximum, minimum and default values for each variable respectively.
+
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    [PLATFORMS]
+    Win32, Win64, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable
+
+    [SEE_ALSO]
+    FMOD_System_SetReverbProperties
+    FMOD_System_GetReverbProperties
+    FMOD_REVERB_PRESETS
+    FMOD_REVERB_FLAGS
+]
+*)
+type
+  FMOD_REVERB_PROPERTIES = record           (*          MIN     MAX     DEFAULT  DESCRIPTION *)
+    Instance: Integer;                      (* [in/out] 0     , 2     , 0      , EAX4 only. Environment Instance. 3 seperate reverbs simultaneously are possible. This specifies which one to set. (win32 only) *)
+    Environment: Cardinal;                  (* [in/out] 0     , 25    , 0      , sets all listener properties (win32/ps2) *)
+    EnvSize: Single;                        (* [in/out] 1.0   , 100.0 , 7.5    , environment size in meters (win32 only) *)
+    EnvDiffusion: Single;                   (* [in/out] 0.0   , 1.0   , 1.0    , environment diffusion (win32/xbox) *)
+    Room: Integer;                          (* [in/out] -10000, 0     , -1000  , room effect level (at mid frequencies) (win32/xbox) *)
+    RoomHF: Integer;                        (* [in/out] -10000, 0     , -100   , relative room effect level at high frequencies (win32/xbox) *)
+    RoomLF: Integer;                        (* [in/out] -10000, 0     , 0      , relative room effect level at low frequencies (win32 only) *)
+    DecayTime: Single;                      (* [in/out] 0.1   , 20.0  , 1.49   , reverberation decay time at mid frequencies (win32/xbox) *)
+    DecayHFRatio: Single;                   (* [in/out] 0.1   , 2.0   , 0.83   , high-frequency to mid-frequency decay time ratio (win32/xbox) *)
+    DecayLFRatio: Single;                   (* [in/out] 0.1   , 2.0   , 1.0    , low-frequency to mid-frequency decay time ratio (win32 only) *)
+    Reflections: Integer;                   (* [in/out] -10000, 1000  , -2602  , early reflections level relative to room effect (win32/xbox) *)
+    ReflectionsDelay: Single;               (* [in/out] 0.0   , 0.3   , 0.007  , initial reflection delay time (win32/xbox) *)
+    ReflectionsPan: array [0..2] of Single; (* [in/out]       ,       , [0,0,0], early reflections panning vector (win32 only) *)
+    Reverb: Integer;                        (* [in/out] -10000, 2000  , 200    , late reverberation level relative to room effect (win32/xbox) *)
+    ReverbDelay: Single;                    (* [in/out] 0.0   , 0.1   , 0.011  , late reverberation delay time relative to initial reflection (win32/xbox) *)
+    ReverbPan: array [0..2] of Single;      (* [in/out]       ,       , [0,0,0], late reverberation panning vector (win32 only) *)
+    EchoTime: Single;                       (* [in/out] .075  , 0.25  , 0.25   , echo time (win32 only) *)
+    EchoDepth: Single;                      (* [in/out] 0.0   , 1.0   , 0.0    , echo depth (win32 only) *)
+    ModulationTime: Single;                 (* [in/out] 0.04  , 4.0   , 0.25   , modulation time (win32 only) *)
+    ModulationDepth: Single;                (* [in/out] 0.0   , 1.0   , 0.0    , modulation depth (win32 only) *)
+    AirAbsorptionHF: Single;                (* [in/out] -100  , 0.0   , -5.0   , change in level per meter at high frequencies (win32 only) *)
+    HFReference: Single;                    (* [in/out] 1000.0, 20000 , 5000.0 , reference high frequency (hz) (win32/xbox) *)
+    LFReference: Single;                    (* [in/out] 20.0  , 1000.0, 250.0  , reference low frequency (hz) (win32 only) *)
+    RoomRolloffFactor: Single;              (* [in/out] 0.0   , 10.0  , 0.0    , like FMOD_3D_Listener_SetRolloffFactor but for room effect (win32/xbox) *)
+    Diffusion: Single;                      (* [in/out] 0.0   , 100.0 , 100.0  , Value that controls the echo density in the late reverberation decay. (xbox only) *)
+    Density: Single;                        (* [in/out] 0.0   , 100.0 , 100.0  , Value that controls the modal density in the late reverberation decay (xbox only) *)
+    Flags: Cardinal;                        (* [in/out] FMOD_REVERB_FLAGS - modifies the behavior of above properties (win32/ps2) *)
+  end;
+
+
+(*
+[DEFINE]
+[
+    [NAME]
+    FMOD_REVERB_FLAGS
+
+    [DESCRIPTION]
+    Values for the Flags member of the FMOD_REVERB_PROPERTIES structure.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_REVERB_PROPERTIES
+]
+*)
+const
+  FMOD_REVERB_FLAGS_DECAYTIMESCALE        = $00000001; (* 'EnvSize' affects reverberation decay time *)
+  FMOD_REVERB_FLAGS_REFLECTIONSSCALE      = $00000002; (* 'EnvSize' affects reflection level *)
+  FMOD_REVERB_FLAGS_REFLECTIONSDELAYSCALE = $00000004; (* 'EnvSize' affects initial reflection delay time *)
+  FMOD_REVERB_FLAGS_REVERBSCALE           = $00000008; (* 'EnvSize' affects reflections level *)
+  FMOD_REVERB_FLAGS_REVERBDELAYSCALE      = $00000010; (* 'EnvSize' affects late reverberation delay time *)
+  FMOD_REVERB_FLAGS_DECAYHFLIMIT          = $00000020; (* AirAbsorptionHF affects DecayHFRatio *)
+  FMOD_REVERB_FLAGS_ECHOTIMESCALE         = $00000040; (* 'EnvSize' affects echo time *)
+  FMOD_REVERB_FLAGS_MODULATIONTIMESCALE   = $00000080; (* 'EnvSize' affects modulation time *)
+  FMOD_REVERB_FLAGS_DEFAULT               = (FMOD_REVERB_FLAGS_DECAYTIMESCALE or
+                                                FMOD_REVERB_FLAGS_REFLECTIONSSCALE or
+                                                FMOD_REVERB_FLAGS_REFLECTIONSDELAYSCALE or
+                                                FMOD_REVERB_FLAGS_REVERBSCALE or
+                                                FMOD_REVERB_FLAGS_REVERBDELAYSCALE or
+                                                FMOD_REVERB_FLAGS_DECAYHFLIMIT);
+(* [DEFINE_END] *)
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Structure defining the properties for a reverb source, related to a FMOD channel.
+
+    For more indepth descriptions of the reverb properties under win32, please see the EAX3
+    documentation at http://developer.creative.com/ under the 'downloads' section.
+    If they do not have the EAX3 documentation, then most information can be attained from
+    the EAX2 documentation, as EAX3 only adds some more parameters and functionality on top of
+    EAX2.
+
+    Note the default reverb properties are the same as the FMOD_PRESET_GENERIC preset.
+    Note that integer values that typically range from -10,000 to 1000 are represented in
+    decibels, and are of a logarithmic scale, not linear, wheras float values are typically linear.
+    PORTABILITY: Each member has the platform it supports in braces ie (win32/xbox).
+    Some reverb parameters are only supported in win32 and some only on xbox. If all parameters are set then
+    the reverb should product a similar effect on either platform.
+    Linux and FMODCE do not support the reverb api.
+
+    The numerical values listed below are the maximum, minimum and default values for each variable respectively.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_Channel_SetReverbProperties
+    FMOD_Channel_GetReverbProperties
+    FMOD_REVERB_CHANNELFLAGS
+]
+*)
+type
+  FMOD_REVERB_CHANNELPROPERTIES = record  (* MIN     MAX    DEFAULT *)
+    Direct: Integer;                      (* -10000, 1000,  0,    direct path level (at low and mid frequencies) (win32/xbox) *)
+    DirectHF: Integer;                    (* -10000, 0,     0,    relative direct path level at high frequencies (win32/xbox) *)
+    Room: Integer;                        (* -10000, 1000,  0,    room effect level (at low and mid frequencies) (win32/xbox) *)
+    RoomHF: Integer;                      (* -10000, 0,     0,    relative room effect level at high frequencies (win32/xbox) *)
+    Obstruction: Integer;                 (* -10000, 0,     0,    main obstruction control (attenuation at high frequencies)  (win32/xbox) *)
+    ObstructionLFRatio: Single;           (* 0.0,    1.0,   0.0,  obstruction low-frequency level re. main control (win32/xbox) *)
+    Occlusion: Integer;                   (* -10000, 0,     0,    main occlusion control (attenuation at high frequencies) (win32/xbox) *)
+    OcclusionLFRatio: Single;             (* 0.0,    1.0,   0.25, occlusion low-frequency level re. main control (win32/xbox) *)
+    OcclusionRoomRatio: Single;           (* 0.0,    10.0,  1.5,  relative occlusion control for room effect (win32) *)
+    OcclusionDirectRatio: Single;         (* 0.0,    10.0,  1.0,  relative occlusion control for direct path (win32) *)
+    Exclusion: Integer;                   (* -10000, 0,     0,    main exlusion control (attenuation at high frequencies) (win32) *)
+    ExclusionLFRatio: Single;             (* 0.0,    1.0,   1.0,  exclusion low-frequency level re. main control (win32) *)
+    OutsideVolumeHF: Integer;             (* -10000, 0,     0,    outside sound cone level at high frequencies (win32) *)
+    DopplerFactor: Single;                (* 0.0,    10.0,  0.0,  like DS3D flDopplerFactor but per source (win32) *)
+    RolloffFactor: Single;                (* 0.0,    10.0,  0.0,  like DS3D flRolloffFactor but per source (win32) *)
+    RoomRolloffFactor: Single;            (* 0.0,    10.0,  0.0,  like DS3D flRolloffFactor but for room effect (win32/xbox) *)
+    AirAbsorptionFactor: Single;          (* 0.0,    10.0,  1.0,  multiplies AirAbsorptionHF member of FMOD_REVERB_PROPERTIES (win32) *)
+    Flags: Integer;                       (* FMOD_REVERB_CHANNELFLAGS - modifies the behavior of properties (win32) *)
+  end;
+
+
+(*
+[DEFINE]
+[
+    [NAME]
+    FMOD_REVERB_CHANNELFLAGS
+
+    [DESCRIPTION]
+    Values for the Flags member of the FMOD_REVERB_CHANNELPROPERTIES structure.
+
+    [REMARKS]
+    For EAX4 support with multiple reverb environments, set FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT0,
+    FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT1 or/and FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT2 in the flags member
+    of FMOD_REVERB_CHANNELPROPERTIES to specify which environment instance(s) to target.
+    Only up to 2 environments to target can be specified at once. Specifying three will result in an error.
+    If the sound card does not support EAX4, the environment flag is ignored.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_REVERB_CHANNELPROPERTIES
+]
+*)
+const
+  FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO  = $00000001; (* Automatic setting of 'Direct'  due to distance from listener *)
+  FMOD_REVERB_CHANNELFLAGS_ROOMAUTO      = $00000002; (* Automatic setting of 'Room'  due to distance from listener *)
+  FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO    = $00000004; (* Automatic setting of 'RoomHF' due to distance from listener *)
+  FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT0  = $00000008; (* EAX4 only. Specify channel to target reverb instance 0. *)
+  FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT1  = $00000010; (* EAX4 only. Specify channel to target reverb instance 1. *)
+  FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT2  = $00000020; (* EAX4 only. Specify channel to target reverb instance 2. *)
+  FMOD_REVERB_CHANNELFLAGS_DEFAULT       = (FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO or
+                                                FMOD_REVERB_CHANNELFLAGS_ROOMAUTO or
+                                                FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO or
+                                                FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT0);
+(* [DEFINE_END] *)
+
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Settings for advanced features like configuring memory and cpu usage for the FMOD_CREATECOMPRESSEDSAMPLE feature.
+
+    [REMARKS]
+    maxMPEGcodecs / maxADPCMcodecs / maxXMAcodecs will determine the maximum cpu usage of playing realtime samples.  Use this to lower potential excess cpu usage and also control memory usage.<br>
+
+    Memory will be allocated for codecs 'up front' (during System::init) if these values are specified as non zero.  If any are zero, it allocates memory for the codec whenever a file of the type in question is loaded.  So if maxMPEGcodecs is 0 for example, it will allocate memory for the mpeg codecs the first time an mp3 is loaded or an mp3 based .FSB file is loaded.
+
+    Due to inefficient encoding techniques on certain .wav based ADPCM files, FMOD can can need an extra 29720 bytes per codec.  This means for lowest memory consumption.  Use FSB as it uses an optimal/small ADPCM block size.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_SetAdvancedSettings
+    FMOD_System_GetAdvancedSettings
+    FMOD_System_Init
+    FMOD_MODE
+]
+*)
+type
+  FMOD_ADVANCEDSETTINGS = record
+    cbsize: Integer;                (* Size of structure.  Use sizeof(FMOD_ADVANCEDSETTINGS) *)
+    maxMPEGcodecs: Integer;         (* For use with FMOD_CREATECOMPRESSEDSAMPLE only.  Mpeg  codecs consume 29.076 bytes per instance and this number will determine how many mpeg channels can be played simultaneously.  Default = 16. *)
+    maxADPCMcodecs: Integer;        (* For use with FMOD_CREATECOMPRESSEDSAMPLE only.  ADPCM codecs consume ?? bytes per instance and this number will determine how many ADPCM channels can be played simultaneously.  Default = 32. *)
+    maxXMAcodecs: Integer;          (* For use with FMOD_CREATECOMPRESSEDSAMPLE only.  XMA   codecs consume ?? bytes per instance and this number will determine how many XMA channels can be played simultaneously.  Default = 32.  *)
+    ASIONumChannels: Integer;       (* [in/out] *)
+    ASIOChannelList: Pointer;       (* [in/out] *)
+    max3DReverbDSPs: Integer;       (* [in/out] The max number of 3d reverb DSP's in the system. *)
+    HRTFMinAngle: Single;           (* [in/out] For use with FMOD_INIT_SOFTWARE_HRTF.  The angle (0-360) of a 3D sound from the listener's forward vector at which the HRTF function begins to have an effect.  Default = 180.0. *)
+    HRTFMaxAngle: Single;           (* [in/out] For use with FMOD_INIT_SOFTWARE_HRTF.  The angle (0-360) of a 3D sound from the listener's forward vector at which the HRTF function begins to have maximum effect.  Default = 360.0.  *)
+    HRTFFreq: Single;               (* [in/out] For use with FMOD_INIT_SOFTWARE_HRTF.  The cutoff frequency of the HRTF's lowpass filter function when at maximum effect. (i.e. at HRTFMaxAngle).  Default = 4000.0. *)
+  end;
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Special channel index values for FMOD functions.
+
+    [REMARKS]
+    To get 'all' of the channels, use System::getChannelGroup.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    System::playSound
+    System::playDSP
+    System::getChannel
+]
+*)
+const
+  FMOD_CHANNEL_FREE           = -1;      (* Value to play on any free channel. *)
+  FMOD_CHANNEL_REUSE          = -2;      (* For a channel index, re-use the channel handle that was passed in. *)
+
+
+(* =============================================================================================== *)
+(* FMOD Ex - codec development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004.  *)
+(*                                                                                                 *)
+(* Use this header if you are wanting to develop your own file format plugin to use with           *)
+(* FMOD's codec system.  With this header you can make your own fileformat plugin that FMOD        *)
+(* can register and use.  See the documentation and examples on how to make a working plugin.      *)
+(*                                                                                                 *)
+(* =============================================================================================== *)
+
+type
+  FMOD_CODEC_STATE = ^tagFMOD_CODEC_STATE;
+
+
+(*
+    Codec callbacks
+*)
+(* type- Cannot use the type keyword here because the declaration of FMOD_CODEC_STATE requires tagFMOD_CODEC_STATE in the same type block *)
+  FMOD_CODEC_OPENCALLBACK        = function (codec: FMOD_CODEC_STATE; usermode: Cardinal; userfrequency: Integer; userformat: FMOD_SOUND_FORMAT): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF} {$ENDIF}
+  FMOD_CODEC_CLOSECALLBACK       = function (codec: FMOD_CODEC_STATE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_READCALLBACK        = function (codec: FMOD_CODEC_STATE; buffer: Pointer; sizebytes: Cardinal; var bytesread: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_GETLENGTHCALLBACK   = function (codec: FMOD_CODEC_STATE; length: Cardinal; lengthtype: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_SETPOSITIONCALLBACK = function (codec: FMOD_CODEC_STATE; subsound: Integer; pcm: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_GETPOSITIONCALLBACK = function (codec: FMOD_CODEC_STATE; var subsound: Integer; var position: Cardinal; postype: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_SOUNDCREATECALLBACK = function (codec: FMOD_CODEC_STATE; subsound: Integer; sound: FMOD_SOUND): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_CODEC_METADATACALLBACK    = function (codec: FMOD_CODEC_STATE; tagtype: FMOD_TAGTYPE; name: PChar; data: Pointer; datalen: Cardinal; datatype: FMOD_TAGDATATYPE; unique: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    When creating a codec, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+]
+*)
+(* type- Cannot use the type keyword here because the declaration of FMOD_CODEC_STATE requires tagFMOD_CODEC_STATE in the same type block *)
+  FMOD_CODEC_DESCRIPTION = record
+    name: PChar;                                    (* [in] Name of the codec. *)
+    version: Cardinal;                              (* [in] Plugin writer's version number. *)
+    timeunits: Integer;                             (* [in] When setposition codec is called, only these time formats will be passed to the codec. Use bitwise OR to accumulate different types. *)
+    open: FMOD_CODEC_OPENCALLBACK;                  (* [in] Open callback for the codec for when FMOD tries to open a sound using this codec. *)
+    close: FMOD_CODEC_CLOSECALLBACK;                (* [in] Close callback for the codec for when FMOD tries to close a sound using this codec.  *)
+    read: FMOD_CODEC_READCALLBACK;                  (* [in] Read callback for the codec for when FMOD tries to read some data from the file to the destination format (specified in the open callback). *)
+    getlength: FMOD_CODEC_GETLENGTHCALLBACK;        (* [in] Callback to return the length of the song in whatever format required when Sound::getLength is called. *)
+    setposition: FMOD_CODEC_SETPOSITIONCALLBACK;    (* [in] Seek callback for the codec for when FMOD tries to seek within the file with Sound::setTime or Sound::setPosition. *)
+    getposition: FMOD_CODEC_GETPOSITIONCALLBACK;    (* [in] Tell callback for the codec for when FMOD tries to get the current position within the with Sound::getTime or Sound::getPosition. *)
+    soundcreate: FMOD_CODEC_SOUNDCREATECALLBACK;    (* [in] Sound creation callback for the codec when FMOD finishes creating the sound.  (So the codec can set more parameters for the related created sound, ie loop points/mode or 3D attributes etc). *)
+  end;
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Set these values marked 'in' to tell fmod what sort of sound to create.
+    The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code.  So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
+    Members marked as 'out' are set by fmod.  Do not modify these.  Simply specify 0 for these values when declaring the structure, FMOD will fill in the values for you after creation with the correct function pointers.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    An FMOD file might be from disk, memory or network, however the file may be opened by the user.
+
+    'numsubsounds' should be 0 if the file is a normal single sound stream or sound.  Examples of this would be .WAV, .WMA, .MP3, .AIFF.
+    'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself.  Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), MIDI/MOD/S3M/XM/IT (contain instruments).
+    The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format.  If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1.  If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
+    When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with FMOD_Sound_GetSubSound.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_SOUND_FORMAT
+    FMOD_FILE_READCALLBACK
+    FMOD_FILE_SEEKCALLBACK
+    FMOD_CODEC_METADATACALLBACK
+    FMOD_Sound_GetSubSound
+    FMOD_Sound_GetNumSubSounds
+]
+*)
+(* type- Cannot use the type keyword here because the declaration of FMOD_CODEC_STATE requires tagFMOD_CODEC_STATE in the same type block *)
+  FMOD_CODEC_WAVEFORMAT = record
+    name:  array [0..255] of Char;    (* [in] Name of sound. *)
+    format: FMOD_SOUND_FORMAT;        (* [in] format for codec output, ie FMOD_SOUND_FORMAT_PCM8, FMOD_SOUND_FORMAT_PCM16.*)
+    channels: Integer;                (* [in] number of channels used by codec, ie mono = 1, stereo = 2. *)
+    frequency: Integer;               (* [in] default frequency in hz of the codec, ie 44100. *)
+    lengthpcm: Cardinal;              (* [in] length in decompressed, PCM samples of the file, ie length in seconds * frequency. *)
+    blockalign: Integer;              (* [in] blockalign in decompressed, PCM samples of the optimal decode chunk size for this format.  The codec read callback will be called in multiples of this value. *)
+    loopstart: Integer;               (* [in] loopstart in decompressed, PCM samples of file. *)
+    loopend: Integer;                 (* [in] loopend in decompressed, PCM samples of file. *)
+    mode: Cardinal;                   (* [in] mode to determine whether the sound should by default load as looping, non looping, 2d or 3d. *)
+    channelmask: Cardinal;            (* [in] Microsoft speaker channel mask, as defined for WAVEFORMATEXTENSIBLE and is found in ksmedia.h.  Leave at 0 to play in natural speaker order. *)
+  end;
+  PFMOD_CODEC_WAVEFORMAT = ^FMOD_CODEC_WAVEFORMAT;
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Codec plugin structure that is passed into each callback.
+
+    Set these numsubsounds and waveformat members when called in FMOD_CODEC_OPENCALLBACK to tell fmod what sort of sound to create.
+
+    The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code.  So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+
+    An FMOD file might be from disk, memory or network, however the file may be opened by the user.
+
+    'numsubsounds' should be 0 if the file is a normal single sound stream or sound.  Examples of this would be .WAV, .WMA, .MP3, .AIFF.
+    'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself.  Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), MIDI/MOD/S3M/XM/IT (contain instruments).
+    The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format.  If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1.  If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
+    When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with FMOD_Sound_GetSubSound.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_SOUND_FORMAT
+    FMOD_FILE_READCALLBACK
+    FMOD_FILE_SEEKCALLBACK
+    FMOD_CODEC_METADATACALLBACK
+    FMOD_Sound_GetSubSound
+    FMOD_Sound_GetNumSubSounds
+]
+*)
+(* type- Cannot use the type keyword here because the declaration of FMOD_CODEC_STATE requires tagFMOD_CODEC_STATE in the same type block *)
+  tagFMOD_CODEC_STATE = record
+    numsubsounds: Integer;                  (* [in] Number of 'subsounds' in this sound.  Anything other than 0 makes it a 'container' format (ie CDDA/FSB/MIDI/MOD/etc which contain 1 or more subsounds).  For most normal, single sound codec such as WAV/AIFF/MP3, this should be 0 as they are not a container for subsounds, they are the sound itself. *)
+    waveformat: PFMOD_CODEC_WAVEFORMAT;     (* [in] Pointer to an array of format structures containing information about each sample.  The number of entries here must equal the number of subsounds defined in the subsound parameter. If numsubsounds = 0 then there should be 1 instance of this structure. *)
+    plugindata: Pointer;                    (* [in/out] User created data the codec plugin writer wants to attach to this object. *)
+
+    filehandle: Pointer;                    (* [out] - Do not modify.  This will return an internal FMOD file handle to use with the callbacks provided.  *)
+    filesize: Cardinal;                     (* [out] - Do not modify.  This will return an internal FMOD file handle to use with the callbacks provided.  *)
+    fileread: FMOD_FILE_READCALLBACK;       (* [out] - Do not modify.  This will return a callable FMOD file function to use from codec. *)
+    fileseek: FMOD_FILE_SEEKCALLBACK;       (* [out] - Do not modify.  This will return a callable FMOD file function to use from codec.  *)
+    metadata: FMOD_CODEC_METADATACALLBACK;  (* [out] - Do not modify.  This will return a callable FMOD metadata function to use from codec.  *)
+  end;
+
+
+(* ========================================================================================== *)
+(* FMOD Ex - DSP header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2005.      *)
+(*                                                                                            *)
+(* Use this header if you are interested in delving deeper into the FMOD software mixing /    *)
+(* DSP engine.  In this header you can find parameter structures for FMOD system reigstered   *)
+(* DSP effects and generators.                                                                *)
+(* Also use this header if you are wanting to develop your own DSP plugin to use with FMOD's  *)
+(* dsp system.  With this header you can make your own DSP plugin that FMOD can               *)
+(* register and use.  See the documentation and examples on how to make a working plugin.     *)
+(*                                                                                            *)
+(* ========================================================================================== *)
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    DSP plugin structure that is passed into each callback.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable
+
+    [SEE_ALSO]
+    FMOD_DSP_DESCRIPTION
+]
+*)
+  tagFMOD_DSP_STATE = record
+    instance: FMOD_DSP;     (* [out] Handle to the DSP hand the user created.  Not to be modified.  C++ users cast to FMOD::DSP to use.  *)
+    plugindata: Pointer;    (* [in] Plugin writer created data the output author wants to attach to this object. *)
+  end;
+
+type
+  FMOD_DSP_STATE = ^tagFMOD_DSP_STATE;
+
+(*
+    DSP callbacks
+*)
+(* type- Cannot use the type keyword here because the declaration of FMOD_CODEC_STATE requires tagFMOD_CODEC_STATE in the same type block *)
+  FMOD_DSP_CREATECALLBACK       = function (dsp: FMOD_DSP_STATE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_RELEASECALLBACK      = function (dsp: FMOD_DSP_STATE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_RESETCALLBACK        = function (dsp: FMOD_DSP_STATE): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_READCALLBACK         = function (dsp: FMOD_DSP_STATE; var inbuffer: Single; var outbuffer: Single; length: Cardinal; inchannels: Integer; outchannels: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_SETPOSITIONCALLBACK  = function (dsp: FMOD_DSP_STATE; position: Cardinal): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_SETPARAMCALLBACK     = function (dsp: FMOD_DSP_STATE; index: Integer; value: Single): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_GETPARAMCALLBACK     = function (dsp: FMOD_DSP_STATE; index: Integer; var value: Single; valuestr: PString): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+  FMOD_DSP_DIALOGCALLBACK       = function (dsp: FMOD_DSP_STATE; hwnd: Pointer; show: Integer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    These definitions can be used for creating FMOD defined special effects or DSP units.
+
+    [REMARKS]
+    To get them to be active, first create the unit, then add it somewhere into the DSP network, either at the front of the network near the soundcard unit to affect the global output (by using FMOD_System_GetDSPHead, or on a single channel (using FMOD_Channel_GetDSPHead).
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateDSPByType
+]
+*)
+type
+  FMOD_DSP_TYPE =
+  (
+    FMOD_DSP_TYPE_UNKNOWN,            (* This unit was created via a non FMOD plugin so has an unknown purpose. *)
+    FMOD_DSP_TYPE_MIXER,              (* This unit does nothing but take inputs and mix them together then feed the result to the soundcard unit *)
+    FMOD_DSP_TYPE_OSCILLATOR,         (* This unit generates sine/square/saw/triangle or noise tones. *)
+    FMOD_DSP_TYPE_LOWPASS,            (* This unit filters sound using a high quality, resonant lowpass filter algorithm but consumes more CPU time. *)
+    FMOD_DSP_TYPE_ITLOWPASS,          (* This unit filters sound using a resonant lowpass filter algorithm that is used in Impulse Tracker. *)
+    FMOD_DSP_TYPE_HIGHPASS,           (* This unit filters sound using a resonant highpass filter algorithm. *)
+    FMOD_DSP_TYPE_ECHO,               (* This unit produces an echo on the sound and fades out at the desired rate. *)
+    FMOD_DSP_TYPE_FLANGE,             (* This unit produces a flange effect on the sound. *)
+    FMOD_DSP_TYPE_DISTORTION,         (* This unit distorts the sound. *)
+    FMOD_DSP_TYPE_NORMALIZE,          (* This unit normalizes or amplifies the sound to a certain level. *)
+    FMOD_DSP_TYPE_PARAMEQ,            (* This unit attenuates or amplifies a selected frequency range. *)
+    FMOD_DSP_TYPE_PITCHSHIFT,         (* This unit bends the pitch of a sound without changing the speed of playback. *)
+    FMOD_DSP_TYPE_CHORUS,             (* This unit produces a chorus effect on the sound. *)
+    FMOD_DSP_TYPE_REVERB,             (* This unit produces a reverb effect on the sound. *)
+    FMOD_DSP_TYPE_VSTPLUGIN,          (* This unit allows the use of Steinberg VST plugins *)
+    FMOD_DSP_TYPE_WINAMPPLUGIN,       (* This unit allows the use of Nullsoft Winamp plugins *)
+    FMOD_DSP_TYPE_ITECHO,             (* This unit produces an echo on the sound and fades out at the desired rate as is used in Impulse Tracker. *)
+    FMOD_DSP_TYPE_COMPRESSOR,         (* This unit implements dynamic compression (linked multichannel, wideband) *)
+    FMOD_DSP_TYPE_SFXREVERB,          (* This unit implements SFX reverb *)
+    FMOD_DSP_TYPE_LOWPASS_SIMPLE      (* This unit filters sound using a simple lowpass with no resonance, but has flexible cutoff and is fast. *)
+  );
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    The step parameter tells the gui or application that the parameter has a certain granularity.
+    For example in the example of cutoff frequency with a range from 100.0 to 22050.0 you might only want the selection to be in 10hz increments.  For this you would simply use 10.0 as the step value.
+    For a boolean, you can use min = 0.0, max = 1.0, step = 1.0.  This way the only possible values are 0.0 and 1.0.
+    Some applications may detect min = 0.0, max = 1.0, step = 1.0 and replace a graphical slider bar with a checkbox instead.
+    A step value of 1.0 would simulate integer values only.
+    A step value of 0.0 would mean the full floating point range is accessable.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateDSP
+    FMOD_DSP_SetParameter
+]
+*)
+type
+  FMOD_DSP_PARAMETERDESC = record
+    min: Single;                     (* [in] Minimum value of the parameter (ie 100.0). *)
+    max: Single;                     (* [in] Maximum value of the parameter (ie 22050.0). *)
+    defaultval: Single;              (* [in] Default value of parameter. *)
+    name:  array [0..15] of Char;    (* [in] Name of the parameter to be displayed (ie "Cutoff frequency"). *)
+    plabel:  array [0..15] of Char;   (* [in] Short string to be put next to value to denote the unit type (ie "hz"). *)
+    description: PChar;              (* [in] Description of the parameter to be displayed as a help item / tooltip for this parameter. *)
+  end;
+  PFMOD_DSP_PARAMETERDESC = ^FMOD_DSP_PARAMETERDESC;
+
+
+(*
+[STRUCTURE]
+[
+    [DESCRIPTION]
+    Strcture to define the parameters for a DSP unit.
+
+    [REMARKS]
+    Members marked with [in] mean the variable can be written to.  The user can set the value.
+    Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.
+
+    There are 2 different ways to change a parameter in this architecture.
+    One is to use FMOD_DSP_SetParameter / FMOD_DSP_GetParameter.  This is platform independant and is dynamic, so new unknown plugins can have their parameters enumerated and used.
+    The other is to use FMOD_DSP_ShowConfigDialog.  This is platform specific and requires a GUI, and will display a dialog box to configure the plugin.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_System_CreateDSP
+    FMOD_System_GetDSP
+]
+*)
+type
+  FMOD_DSP_DESCRIPTION = record
+    name: array [0..31] of Char;                    (* [in] Name of the unit to be displayed in the network. *)
+    version: Cardinal;                              (* [in] Plugin writer's version number. *)
+    channels: Integer;                              (* [in] Number of channels.  Use 0 to process whatever number of channels is currently in the network.  >0 would be mostly used if the unit is a fixed format generator and not a filter. *)
+    create: FMOD_DSP_CREATECALLBACK;                (* [in] Create callback.  This is called when DSP unit is created.  Can be null. *)
+    release: FMOD_DSP_RELEASECALLBACK;              (* [in] Release callback.  This is called just before the unit is freed so the user can do any cleanup needed for the unit.  Can be null. *)
+    reset: FMOD_DSP_RESETCALLBACK;                  (* [in] Reset callback.  This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state.  Use to avoid clicks or artifacts. *)
+    read: FMOD_DSP_READCALLBACK;                    (* [in] Read callback.  Processing is done here.  Can be null. *)
+    setposition: FMOD_DSP_SETPOSITIONCALLBACK;      (* [in] Set position callback.  This is called if the unit wants to update its position info but not process data, or reset a cursor position internally if it is reading data from a certain source.  Can be null. *)
+    numparameters: Integer;                         (* [in] Number of parameters used in this filter.  The user finds this with FMOD_DSP_GetNumParameters *)
+    paramdesc: PFMOD_DSP_PARAMETERDESC;             (* [in] Variable number of parameter structures. *)
+    setparameter: FMOD_DSP_SETPARAMCALLBACK;        (* [in] This is called when the user calls FMOD_DSP_SetParameter.  Can be null. *)
+    getparameter: FMOD_DSP_GETPARAMCALLBACK;        (* [in] This is called when the user calls FMOD_DSP_GetParameter.  Can be null. *)
+    config: FMOD_DSP_DIALOGCALLBACK;                (* [in] This is called when the user calls FMOD_DSP_ShowConfigDialog.  Can be used to display a dialog to configure the filter.  Can be null. *)
+    configwidth: Integer;                           (* [in] Width of config dialog graphic if there is one.  0 otherwise. *)
+    configheight: Integer;                          (* [in] Height of config dialog graphic if there is one.  0 otherwise. *)
+  end;
+
+
+(*
+    ==============================================================================================================
+
+    FMOD built in effect parameters.
+    Use FMOD_DSP_SetParameter with these enums for the 'index' parameter.
+
+    ==============================================================================================================
+*)
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_OSCILLATOR filter.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_OSCILLATOR =
+  (
+    FMOD_DSP_OSCILLATOR_TYPE,   (* Waveform type.  0 = sine.  1 = square. 2 = sawup. 3 = sawdown. 4 = triangle. 5 = noise.  *)
+    FMOD_DSP_OSCILLATOR_RATE    (* Frequency of the sinewave in hz.  1.0 to 22000.0.  Default = 220.0. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_LOWPASS filter.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_LOWPASS =
+  (
+    FMOD_DSP_LOWPASS_CUTOFF,    (* Lowpass cutoff frequency in hz.   1.0 to 22000.0.  Default = 5000.0. *)
+    FMOD_DSP_LOWPASS_RESONANCE  (* Lowpass resonance Q value. 1.0 to 10.0.  Default = 1.0. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_LOWPASS2 filter.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_LOWPASS2 =
+  (
+    FMOD_DSP_LOWPASS2_CUTOFF,    (* Lowpass cutoff frequency in hz.  1.0 to 22000.0.  Default = 5000.0/ *)
+    FMOD_DSP_LOWPASS2_RESONANCE  (* Lowpass resonance Q value.  0.0 to 127.0.  Default = 1.0. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_HIGHPASS filter.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_HIGHPASS =
+  (
+    FMOD_DSP_HIGHPASS_CUTOFF,    (* Highpass cutoff frequency in hz.  10.0 to output 22000.0.  Default = 5000.0. *)
+    FMOD_DSP_HIGHPASS_RESONANCE  (* Highpass resonance Q value.  1.0 to 10.0.  Default = 1.0. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_ECHO filter.
+
+    [REMARKS]
+    Note.  Every time the delay is changed, the plugin re-allocates the echo buffer.  This means the echo will dissapear at that time while it refills its new buffer.
+    Larger echo delays result in larger amounts of memory allocated.
+
+    '<i>maxchannels</i>' also dictates the amount of memory allocated.  By default, the maxchannels value is 0.  If FMOD is set to stereo, the echo unit will allocate enough memory for 2 channels.  If it is 5.1, it will allocate enough memory for a 6 channel echo, etc.
+    If the echo effect is only ever applied to the global mix (ie it was added with FMOD_System_AddDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
+    When the echo is added to a channel (ie FMOD_Channel_AddDSP) then the channel count that comes in could be anything from 1 to 8 possibly.  It is only in this case where you might want to increase the channel count above the output's channel count.
+    If a channel echo is set to a lower number than the sound's channel count that is coming in, it will not echo the sound.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_ECHO =
+  (
+    FMOD_DSP_ECHO_DELAY,       (* Echo delay in ms.  10  to 5000.  Default = 500. *)
+    FMOD_DSP_ECHO_DECAYRATIO,  (* Echo decay per delay.  0 to 1.  1.0 = No decay, 0.0 = total decay.  Default = 0.5. *)
+    FMOD_DSP_ECHO_FEEDBACK,    (* 0 = Unit is a simple 1 line delay.  1 = Unit echos what has already been processed by echo. Default = 1. *)
+    FMOD_DSP_ECHO_MAXCHANNELS  (* Maximum channels supported.  0 to 16.  0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc.  See remarks for more.  Default = 0.  It is suggested to leave at 0! *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_FLANGE filter.
+
+    [REMARKS]
+    Flange is an effect where the signal is played twice at the same time, and one copy slides back and forth creating a whooshing or flanging effect.
+    As there are 2 copies of the same signal, by default each signal is given 50% mix, so that the total is not louder than the original unaffected signal.
+
+    Flange depth is a percentage of a 10ms shift from the original signal.  Anything above 10ms is not considered flange because to the ear it begins to 'echo' so 10ms is the highest value possible.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_FLANGE =
+  (
+    FMOD_DSP_FLANGE_DRYMIX,      (* Volume of original signal to pass to output.  0.0 to 1.0. Default = 0.45. *)
+    FMOD_DSP_FLANGE_WETMIX,      (* Volume of flange signal to pass to output.  0.0 to 1.0. Default = 0.55. *)
+    FMOD_DSP_FLANGE_DEPTH,       (* Flange depth.  0.01 to 1.0.  Default = 1.0. *)
+    FMOD_DSP_FLANGE_RATE         (* Flange speed in hz.  0.0 to 20.0.  Default = 0.1. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_DISTORTION filter.
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_DISTORTION =
+  (
+    FMOD_DSP_DISTORTION_LEVEL    (* Distortion value.  0.0 to 1.0.  Default = 0.5. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_NORMALIZE filter.
+
+    [REMARKS]
+    Normalize amplifies the sound based on the maximum peaks within the signal.
+    For example if the maximum peaks in the signal were 50% of the bandwidth, it would scale the whole sound by 2.
+    The lower threshold value makes the normalizer ignores peaks below a certain point, to avoid over-amplification if a loud signal suddenly came in, and also to avoid amplifying to maximum things like background hiss.
+
+    Because FMOD is a realtime audio processor, it doesn't have the luxury of knowing the peak for the whole sound (ie it can't see into the future), so it has to process data as it comes in.
+    To avoid very sudden changes in volume level based on small samples of new data, fmod fades towards the desired amplification which makes for smooth gain control.  The fadetime parameter can control this.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_NORMALIZE =
+  (
+    FMOD_DSP_NORMALIZE_FADETIME,    (* Time to ramp the silence to full in ms.  0.0 to 20000.0. Default = 5000.0. *)
+    FMOD_DSP_NORMALIZE_THRESHHOLD,  (* Lower volume range threshold to ignore.  0.0 to 1.0.  Default = 0.1.  Raise higher to stop amplification of very quiet signals. *)
+    FMOD_DSP_NORMALIZE_MAXAMP       (* Maximum amplification allowed.  1.0 to 100000.0.  Default = 20.0.  1.0 = no amplifaction, higher values allow more boost. *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_PARAMEQ filter.
+
+    [REMARKS]
+    Parametric EQ is a bandpass filter that attenuates or amplifies a selected frequency and its neighbouring frequencies.
+
+    To create a multi-band EQ create multiple FMOD_DSP_TYPE_PARAMEQ units and set each unit to different frequencies, for example 1000hz, 2000hz, 4000hz, 8000hz, 16000hz with a range of 1 octave each.
+
+    When a frequency has its gain set to 1.0, the sound will be unaffected and represents the original signal exactly.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_PARAMEQ =
+  (
+    FMOD_DSP_PARAMEQ_CENTER,     (* Frequency center.  20.0 to 22000.0.  Default = 8000.0. *)
+    FMOD_DSP_PARAMEQ_BANDWIDTH,  (* Octave range around the center frequency to filter.  0.2 to 5.0.  Default = 1.0. *)
+    FMOD_DSP_PARAMEQ_GAIN        (* Frequency Gain.  0.05 to 3.0.  Default = 1.0.  *)
+  );
+
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_PITCHSHIFT filter.
+
+    [REMARKS]
+    This pitch shifting unit can be used to change the pitch of a sound without speeding it up or slowing it down.
+    It can also be used for time stretching or scaling, for example if the pitch was doubled, and the frequency of the sound was halved, the pitch of the sound would sound correct but it would be twice as slow.
+
+    <b>Warning!</b> This filter is very computationally expensive!  Similar to a vocoder, it requires several overlapping FFT and IFFT's to produce smooth output, and can require around 440mhz for 1 stereo 48khz signal using the default settings.
+    Reducing the signal to mono will half the cpu usage, as will the overlap count.
+    Reducing this will lower audio quality, but what settings to use are largely dependant on the sound being played.  A noisy polyphonic signal will need higher overlap and fft size compared to a speaking voice for example.
+
+    This pitch shifter is based on the pitch shifter code at http://www.dspdimension.com, written by Stephan M. Bernsee.
+    The original code is COPYRIGHT 1999-2003 Stephan M. Bernsee <smb@dspdimension.com>.
+
+    '<i>maxchannels</i>' dictates the amount of memory allocated.  By default, the maxchannels value is 0.  If FMOD is set to stereo, the pitch shift unit will allocate enough memory for 2 channels.  If it is 5.1, it will allocate enough memory for a 6 channel pitch shift, etc.
+    If the pitch shift effect is only ever applied to the global mix (ie it was added with FMOD_System_AddDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
+    When the pitch shift is added to a channel (ie FMOD_Channel_AddDSP) then the channel count that comes in could be anything from 1 to 8 possibly.  It is only in this case where you might want to increase the channel count above the output's channel count.
+    If a channel pitch shift is set to a lower number than the sound's channel count that is coming in, it will not pitch shift the sound.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_PITCHSHIFT =
+  (
+    FMOD_DSP_PITCHSHIFT_PITCH,       (* Pitch value.  0.5 to 2.0.  Default = 1.0. 0.5 = one octave down, 2.0 = one octave up.  1.0 does not change the pitch. *)
+    FMOD_DSP_PITCHSHIFT_FFTSIZE,     (* FFT window size.  256, 512, 1024, 2048, 4096.  Default = 1024.  Increase this to reduce 'smearing'.  This effect is a warbling sound similar to when an mp3 is encoded at very low bitrates. *)
+    FMOD_DSP_PITCHSHIFT_OVERLAP,     (* Window overlap.  1 to 32.  Default = 4.  Increase this to reduce 'tremolo' effect.  Increasing it by a factor of 2 doubles the CPU usage. *)
+    FMOD_DSP_PITCHSHIFT_MAXCHANNELS  (* Maximum channels supported.  0 to 16.  0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc.  See remarks for more.  Default = 0.  It is suggested to leave at 0! *)
+  );
+
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_CHORUS filter.
+
+    [REMARKS]
+    Chrous is an effect where the sound is more 'spacious' due to 1 to 3 versions of the sound being played along side the original signal but with the pitch of each copy modulating on a sine wave.
+    This is a highly configurable chorus unit.  It supports 3 taps, small and large delay times and also feedback.
+    This unit also could be used to do a simple echo, or a flange effect.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_CHORUS =
+  (
+    FMOD_DSP_CHORUS_DRYMIX,   (* Volume of original signal to pass to output.  0.0 to 1.0. Default = 0.5. *)
+    FMOD_DSP_CHORUS_WETMIX1,  (* Volume of 1st chorus tap.  0.0 to 1.0.  Default = 0.5. *)
+    FMOD_DSP_CHORUS_WETMIX2,  (* Volume of 2nd chorus tap. This tap is 90 degrees out of phase of the first tap.  0.0 to 1.0.  Default = 0.5. *)
+    FMOD_DSP_CHORUS_WETMIX3,  (* Volume of 3rd chorus tap. This tap is 90 degrees out of phase of the second tap.  0.0 to 1.0.  Default = 0.5. *)
+    FMOD_DSP_CHORUS_DELAY,    (* Chorus delay in ms.  0.1 to 100.0.  Default = 40.0 ms. *)
+    FMOD_DSP_CHORUS_RATE,     (* Chorus modulation rate in hz.  0.0 to 20.0.  Default = 0.8 hz. *)
+    FMOD_DSP_CHORUS_DEPTH,    (* Chorus modulation depth.  0.0 to 1.0.  Default = 0.03. *)
+    FMOD_DSP_CHORUS_FEEDBACK  (* Chorus feedback.  Controls how much of the wet signal gets fed back into the chorus buffer.  0.0 to 1.0.  Default = 0.0. *)
+  );
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_REVERB filter.
+
+    [REMARKS]
+    Based on freeverb by Jezar at Dreampoint - http://www.dreampoint.co.uk.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_REVERB =
+  (
+    FMOD_DSP_REVERB_ROOMSIZE, (* Roomsize. 0.0 to 1.0.  Default = 0.5 *)
+    FMOD_DSP_REVERB_DAMP,     (* Damp.     0.0 to 1.0.  Default = 0.5 *)
+    FMOD_DSP_REVERB_WETMIX,   (* Wet mix.  0.0 to 1.0.  Default = 0.33 *)
+    FMOD_DSP_REVERB_DRYMIX,   (* Dry mix.  0.0 to 1.0.  Default = 0.66 *)
+    FMOD_DSP_REVERB_WIDTH,    (* Width.    0.0 to 1.0.  Default = 1.0 *)
+    FMOD_DSP_REVERB_MODE      (* Mode.     0 (normal), 1 (freeze).  Default = 0 *)
+  );
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_ITECHO filter.
+    This is effectively a software based echo filter that emulates the DirectX DMO echo effect.  Impulse tracker files can support this, and FMOD will produce the effect on ANY platform, not just those that support DirectX effects!
+
+    [REMARKS]
+    Note.  Every time the delay is changed, the plugin re-allocates the echo buffer.  This means the echo will dissapear at that time while it refills its new buffer.
+    Larger echo delays result in larger amounts of memory allocated.
+
+    As this is a stereo filter made mainly for IT playback, it is targeted for stereo signals.
+    With mono signals only the FMOD_DSP_ITECHO_LEFTDELAY is used.
+    For multichannel signals (>2) there will be no echo on those channels.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3
+
+    [SEE_ALSO]
+    FMOD_DSP_SetParameter
+    FMOD_DSP_GetParameter
+    FMOD_DSP_TYPE
+    FMOD_System_AddDSP
+]
+*)
+type
+  FMOD_DSP_ITECHO =
+  (
+    FMOD_DSP_ITECHO_WETDRYMIX,      (* Ratio of wet (processed) signal to dry (unprocessed) signal. Must be in the range from 0.0 through 100.0 (all wet). The default value is 50. *)
+    FMOD_DSP_ITECHO_FEEDBACK,       (* Percentage of output fed back into input, in the range from 0.0 through 100.0. The default value is 50. *)
+    FMOD_DSP_ITECHO_LEFTDELAY,      (* Delay for left channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. *)
+    FMOD_DSP_ITECHO_RIGHTDELAY,     (* Delay for right channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. *)
+    FMOD_DSP_ITECHO_PANDELAY        (* Value that specifies whether to swap left and right delays with each successive echo. The default value is zero, meaning no swap. Possible values are defined as 0.0 (equivalent to FALSE) and 1.0 (equivalent to TRUE).  CURRENTLY NOT SUPPORTED. *)
+  );
+
+
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_COMPRESSOR unit.
+    This is a simple linked multichannel software limiter that is uniform across the whole spectrum.<br>
+
+    [REMARKS]
+    The limiter is not guaranteed to catch every peak above the threshold level,
+    because it cannot apply gain reduction instantaneously - the time delay is
+    determined by the attack time. However setting the attack time too short will
+    distort the sound, so it is a compromise. High level peaks can be avoided by
+    using a short attack time - but not too short, and setting the threshold a few
+    decibels below the critical level.
+    <br>
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3, Wii
+
+    [SEE_ALSO]
+    DSP::SetParameter
+    DSP::GetParameter
+    FMOD_DSP_TYPE
+    System::addDSP
+]
+*)
+type
+  FMOD_DSP_COMPRESSOR =
+  (
+    FMOD_DSP_COMPRESSOR_THRESHOLD,  (* Threshold level (dB) in the range from -60 through 0. The default value is 0. *)
+    FMOD_DSP_COMPRESSOR_ATTACK,     (* Gain reduction attack time (milliseconds), in the range from 10 through 200. The default value is 50. *)
+    FMOD_DSP_COMPRESSOR_RELEASE,    (* Gain reduction release time (milliseconds), in the range from 20 through 1000. The default value is 50. *)
+    FMOD_DSP_COMPRESSOR_GAINMAKEUP  (* Make-up gain (dB) applied after limiting, in the range from 0 through 30. The default value is 0. *)
+  );
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_SFXREVERB unit.<br>
+
+    [REMARKS]
+    This is a high quality I3DL2 based reverb which improves greatly on FMOD_DSP_REVERB.<br>
+    On top of the I3DL2 property set, "Dry Level" is also included to allow the dry mix to be changed.<br>
+    <br>
+    Currently FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL, FMOD_DSP_SFXREVERB_REFLECTIONSDELAY and FMOD_DSP_SFXREVERB_REVERBDELAY are not enabled but will come in future versions.<br>
+    <br>
+    These properties can be set with presets in FMOD_REVERB_PRESETS.
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3, Wii
+
+    [SEE_ALSO]
+    DSP::SetParameter
+    DSP::GetParameter
+    FMOD_DSP_TYPE
+    System::addDSP
+    FMOD_REVERB_PRESETS
+]
+*)
+type
+  FMOD_DSP_SFXREVERB =
+  (
+    FMOD_DSP_SFXREVERB_DRYLEVEL,            (* Dry Level      : Mix level of dry signal in output in mB.  Ranges from -10000.0 to 0.0.  Default is 0. *)
+    FMOD_DSP_SFXREVERB_ROOM,                (* Room           : Room effect level at low frequencies in mB.  Ranges from -10000.0 to 0.0.  Default is 0.0. *)
+    FMOD_DSP_SFXREVERB_ROOMHF,              (* Room HF        : Room effect high-frequency level re. low frequency level in mB.  Ranges from -10000.0 to 0.0.  Default is 0.0. *)
+    FMOD_DSP_SFXREVERB_ROOMROLLOFFFACTOR,   (* Room Rolloff   : Like DS3D flRolloffFactor but for room effect.  Ranges from 0.0 to 10.0. Default is 10.0 *)
+    FMOD_DSP_SFXREVERB_DECAYTIME,           (* Decay Time     : Reverberation decay time at low-frequencies in seconds.  Ranges from 0.1 to 20.0. Default is 1.0. *)
+    FMOD_DSP_SFXREVERB_DECAYHFRATIO,        (* Decay HF Ratio : High-frequency to low-frequency decay time ratio.  Ranges from 0.1 to 2.0. Default is 0.5. *)
+    FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL,    (* Reflections    : Early reflections level relative to room effect in mB.  Ranges from -10000.0 to 1000.0.  Default is -10000.0. *)
+    FMOD_DSP_SFXREVERB_REFLECTIONSDELAY,    (* Reflect Delay  : Delay time of first reflection in seconds.  Ranges from 0.0 to 0.3.  Default is 0.02. *)
+    FMOD_DSP_SFXREVERB_REVERBLEVEL,         (* Reverb         : Late reverberation level relative to room effect in mB.  Ranges from -10000.0 to 2000.0.  Default is 0.0. *)
+    FMOD_DSP_SFXREVERB_REVERBDELAY,         (* Reverb Delay   : Late reverberation delay time relative to first reflection in seconds.  Ranges from 0.0 to 0.1.  Default is 0.04. *)
+    FMOD_DSP_SFXREVERB_DIFFUSION,           (* Diffusion      : Reverberation diffusion (echo density) in percent.  Ranges from 0.0 to 100.0.  Default is 100.0. *)
+    FMOD_DSP_SFXREVERB_DENSITY,             (* Density        : Reverberation density (modal density) in percent.  Ranges from 0.0 to 100.0.  Default is 100.0. *)
+    FMOD_DSP_SFXREVERB_HFREFERENCE          (* HF Reference   : Reference high frequency in Hz.  Ranges from 20.0 to 20000.0. Default is 5000.0. *)
+  );
+
+(*
+[ENUM]
+[
+    [DESCRIPTION]
+    Parameter types for the FMOD_DSP_TYPE_LOWPASS_SIMPLE filter.<br>
+    This is a very simple low pass filter, based on two single-pole RC time-constant modules.
+    The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.<br>
+
+    [REMARKS]
+
+    [PLATFORMS]
+    Win32, Win64, Linux, Linux64, Macintosh, Xbox, Xbox360, PlayStation 2, GameCube, PlayStation Portable, PlayStation 3, Wii
+
+    [SEE_ALSO]
+    DSP::setParameter
+    DSP::getParameter
+    FMOD_DSP_TYPE
+]
+*)
+type
+  FMOD_DSP_LOWPASS_SIMPLE =
+  (
+    FMOD_DSP_LOWPASS_SIMPLE_CUTOFF     (* Lowpass cutoff frequency in hz.  10.0 to 22000.0.  Default = 5000.0 *)
+  );
+
+
+
+
+implementation
+
+end.