unit IDX_sound;
///////////////////////////////////////
//   Unit : IDX_Sound
//   Date : 02/04/2005
// Author : Amosow 'Gambit_OZ' Evgeniy
// e-Mail : greenrat@mail333.com
///////////////////////////////////////

interface
  uses Fmod,
       Fmodtypes,
       Fmoderrors,
       SysUtils,
       Log;

type
 TGraphEQ=array [0..5] of double;

var
 playingmusic:boolean=True;
 playingsound:boolean=false;
 Music, Effect: PFMusicModule;
 EffectStream,MusicStream : PFSoundStream;
 SoundBox:array[0..7] of PFSoundSample;
 p_channel:integer;

 MyMusic: PFSoundStream;

//GlobalPath:string;
procedure PlayEffect(FileName : string);
procedure PlayMusic(FileName : string);
function InitSoundEngine:Boolean;
procedure StopMusic;
procedure StopEffect;
procedure FreeSoundEngine;

procedure PlaySoundFromMEM(Id:integer);
function PlaySound(f:string;var S:PFSoundStream):integer;

implementation
      uses
      windows;

function SoundVolUp(c:integer):integer;
begin
  FSOUND_SetVolumeAbsolute(c,FSOUND_GetVolume(c)+1);
  result:=FSOUND_GetVolume(c);
end;

function SoundVolDown(c:integer):integer;
begin
  FSOUND_SetVolumeAbsolute(c,FSOUND_GetVolume(c)-1);
  result:=FSOUND_GetVolume(c);
end;

function SoundGoForward(s:PFSoundStream):integer;
begin
  result:=FSOUND_Stream_GetPosition(s)+1;
  FSOUND_Stream_SetPosition(s,result);
end;

function SoundGoBackward(s:PFSoundStream):integer;
begin
  result:=FSOUND_Stream_GetPosition(s)-1;
  FSOUND_Stream_SetPosition(s,result);
end;

procedure PlaySoundFromMEM(Id:integer);
begin
  if playingsound then
  FSOUND_PlaySound(FSOUND_free,SoundBox[id]);
end;


function InitSoundEngine:Boolean;
begin
  result:=false;
  try
  FMOD_Load(nil);
  if not FSOUND_Init(44100, 32, 0) then
  begin
    AddToLog('ERROR: Unable to Init Sound Engine!',true,true);
    AddToLog(FMOD_ErrorString(FSOUND_GetError()),true,true);
    FSOUND_Close();

    playingmusic:=false;
    playingsound:=false;
    exit;
  end;

   FSOUND_SetSFXMasterVolume(200);
    SoundBox[0]:= FSound_Sample_Load(FSOUND_Free,'data\sound\sound63.mp3',0,0,0);
    SoundBox[1]:= FSound_Sample_Load(FSOUND_Free,'data\sound\sound881.mp3',0,0,0);

    SoundBox[2]:= FSound_Sample_Load(FSOUND_Free,'data\sound\sound70.mp3',0,0,0);
    SoundBox[3]:= FSound_Sample_Load(FSOUND_Free,'data\sound\sound71.mp3',0,0,0);
    SoundBox[4]:= FSound_Sample_Load(FSOUND_Free,'data\sound\sound72.mp3',0,0,0);

    result:=true;
  except
   exit;
  end;

end;

procedure LoopMusic;
begin
if playingmusic then
begin
try
if (FMUSIC_IsFinished(Music)) and (not FMUSIC_IsPlaying(Music)) and (music<>nil) then FMUSIC_PlaySong(Music);

except
AddToLog('ERROR: Sound Engine[LoopMusic]!',true,true);
end;
end;
end;

procedure PauseMusic;
begin
if (FMUSIC_IsPlaying(Music)) and (playingmusic) then
FMUSIC_SetPaused(Music, true) else
FMUSIC_SetPaused(Music, false);
end;

procedure FreeSoundEngine;
var
i:integer;
begin
  if Effect<>nil then
  begin
    FMUSIC_StopSong(Effect);
    FMUSIC_FreeSong(Effect);
  end;
  Effect:= nil;

  if Music<>nil then
  begin
    FMUSIC_StopSong(Music);
    FMUSIC_FreeSong(Music);
  end;
  Music:= nil;

  for i:=0 to high(SoundBox) do
 if SoundBox[i]<>nil then
  begin
//  FMUSIC_StopSong(SoundBox[i]);
 // FMUSIC_FreeSong(SoundBox[i]);
  SoundBox[i]:= nil;
  end;

  FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit, FALSE);
  FSOUND_Close;
end;

procedure StopMusic;
begin
try
FMUSIC_StopSong(Music);

FMUSIC_FreeSong(Music);
FSOUND_Stream_Stop(MusicStream);
musicstream:=nil;
music:=nil;
except
AddToLog('ERROR: Sound Engine[StopMusic]!',true,true);
end;
end;

procedure StopEffect;
begin
if (playingsound) then
begin
try
  if FMUSIC_IsPlaying(Effect) then
  begin
  FMUSIC_StopSong(Effect);
  FMUSIC_FreeSong(Effect);
  end else
  FSOUND_Stream_Stop(EffectStream);
except
AddToLog('ERROR: Sound Engine[StopEffect]!',true,true);
end;
end;
end;

procedure PlayMusic(FileName : string);
var
FilePath : string;
Chanel:integer;
begin
 try
  FilePath := 'data\music\'+FileName;

 if fileexists(FilePath)  then
  begin
       if playingmusic then
       begin

        Music := FMUSIC_LoadSong(pchar(FilePath));

        if  Music <> nil then
          begin
            FMUSIC_PlaySong(Music);
            FMUSIC_SetMasterVolume(Music,100);
          end
        else
        begin
         // MusicStream :=
          PlaySound(FilePath,MyMusic);
          //FSOUND_Stream_Open(PChar(FilePath), FSOUND_LOOP_NORMAL , 0,0);
          //Chanel:=FSOUND_Stream_Play(FSOUND_FREE, MusicStream);
        end;
       end;
  end
  else
  begin
   AddToLog('ERROR: Sound Engine[File "data\music\'+FilePath+'"] not found!',true,true);
  end;
 except
  AddToLog('ERROR: Sound Engine[PlayMusic]!',true,true);
 end;

end;

function PlaySound(f:string;var S:PFSoundStream):integer;
begin
 if s <> nil then FSOUND_Stream_Close(s);

  s := FSOUND_Stream_Open(PChar(f), FSOUND_LOOP_NORMAL or FSOUND_NORMAL, 0, 0);

  if s = nil then
  begin
    AddToLog(FMOD_ErrorString(FSOUND_GetError()),true,true);
    exit;
  end;

  result := FSOUND_Stream_Play(FSOUND_FREE, s);
  p_channel:=result;

  if result < 0 then
  begin
    AddToLog(FMOD_ErrorString(FSOUND_GetError()),true,true);
    exit;
  end;

end;


procedure PlayEffect(FileName : string);
var
FilePath : string;
begin
try
if Effect<>nil then
begin
  FMUSIC_StopSong(Effect);
  FMUSIC_FreeSong(Effect);
  Effect:= nil;
end;

FilePath := 'data\sound\' + FileName;
if fileexists(FilePath)  then
begin
if playingsound then
begin
Effect := FMUSIC_LoadSong(pchar(FilePath));
if Effect = nil then
begin
   //EffectStream := FSOUND_Stream_OpenFile(PChar(FilePath), FSOUND_NORMAL , 0);
   FSOUND_Stream_Play(FSOUND_FREE, EffectStream);
end
else
FMUSIC_PlaySong(Effect);
end;
end else
begin
AddToLog('ERROR: Sound Engine[File "'+FilePath+'"] not found!',true,true);
end;
except
AddToLog('ERROR: Sound Engine[PlayEffect]!',true,true);
end;

end;


end.
