diff --git a/src/engine/e_sound.pas b/src/engine/e_sound.pas
index 05bcb10611fe9ac5977d030d894a4e83e96a62ac..a173c883b65908ac1daeec908deca545b0a645af 100644 (file)
--- a/src/engine/e_sound.pas
+++ b/src/engine/e_sound.pas
interface
uses
- fmod,
- fmodtypes,
- fmoderrors,
+ sdl2 in '../lib/sdl2/sdl2.pas',
+ SDL2_mixer in '../lib/sdl2/SDL2_mixer.pas',
e_log,
SysUtils;
type
TSoundRec = record
Data: Pointer;
- Sound: FMOD_SOUND;
+ Sound: PMix_Chunk;
Loop: Boolean;
- nRefs: Integer;
end;
TBasicSound = class (TObject)
private
- FChannel: FMOD_CHANNEL;
+ FChannel: Integer; // <0: no channel allocated
protected
FID: DWORD;
const
NO_SOUND_ID = DWORD(-1);
-function e_InitSoundSystem(Freq: Integer; forceNoSound: Boolean): Boolean;
+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): Boolean;
-function e_PlaySoundPan(ID: DWORD; Pan: Single): Boolean;
-function e_PlaySoundVolume(ID: DWORD; Volume: Single): Boolean;
-function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): 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);
N_CHANNELS = 512;
var
- F_System: FMOD_SYSTEM = nil;
SoundMuted: Boolean = False;
+ SoundInitialized: Boolean = False;
-function Channel_Callback(channel: FMOD_CHANNEL; callbacktype: FMOD_CHANNEL_CALLBACKTYPE;
- commanddata1: Pointer; commanddata2: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
+function e_InitSoundSystem(): Boolean;
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;
+ res: Integer;
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;
+ if SoundInitialized then begin Result := true; Exit end;
-function e_InitSoundSystem(Freq: Integer; forceNoSound: Boolean): Boolean;
-var
- res: FMOD_RESULT;
- ver: Cardinal;
- output: FMOD_OUTPUTTYPE;
- drv: Integer;
-
-begin
Result := False;
+ SoundInitialized := False;
- 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
+ // we need module player
+ if (Mix_Init(MIX_INIT_MOD) and MIX_INIT_MOD) <> MIX_INIT_MOD then
begin
- e_WriteLog('Error getting FMOD version:', MSG_FATALERROR);
- e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
- Exit;
+ e_WriteLog('Error initializing SDL module player:', MSG_FATALERROR);
+ e_WriteLog(Mix_GetError(), MSG_FATALERROR);
+ //Exit;
end;
- if ver < FMOD_VERSION then
+ res := Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 512);
+ if res = -1 then
begin
- e_WriteLog('FMOD library version is too old! Need '+IntToStr(FMOD_VERSION), MSG_FATALERROR);
+ e_WriteLog('Error initializing SDL mixer:', MSG_FATALERROR);
+ e_WriteLog(Mix_GetError(), 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 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);
+ Mix_AllocateChannels(N_CHANNELS);
+ SoundInitialized := True;
Result := True;
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;
+ if not SoundInitialized then Exit;
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].Sound := Mix_LoadWAV(PAnsiChar(FileName));
+ if e_SoundsArray[find_id].Sound = nil then Exit;
e_SoundsArray[find_id].Data := nil;
e_SoundsArray[find_id].Loop := bLoop;
- e_SoundsArray[find_id].nRefs := 0;
ID := find_id;
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;
-
+ rw: PSDL_RWops;
begin
Result := False;
+ if not SoundInitialized then Exit;
- find_id := FindESound();
-
- sz := SizeOf(FMOD_CREATESOUNDEXINFO);
- FillMemory(@soundExInfo, sz, 0);
- soundExInfo.cbsize := sz;
- soundExInfo.length := Length;
+ rw := SDL_RWFromConstMem(pData, Length);
+ if rw = nil then Exit;
- if bLoop then
- bt := FMOD_LOOP_NORMAL
- else
- bt := FMOD_LOOP_OFF;
+ find_id := FindESound();
- 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].Sound := Mix_LoadWAV_RW(rw, 0);
+ SDL_FreeRW(rw);
+ if e_SoundsArray[find_id].Sound = nil then Exit;
e_SoundsArray[find_id].Data := pData;
e_SoundsArray[find_id].Loop := bLoop;
- e_SoundsArray[find_id].nRefs := 0;
ID := find_id;
Result := True;
end;
-function e_PlaySound(ID: DWORD): Boolean;
+function e_PlaySound (ID: DWORD): Integer;
var
- res: FMOD_RESULT;
- Chan: FMOD_CHANNEL;
-
+ res: Integer;
begin
- if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
- begin
- Result := True;
- Exit;
- end;
+ Result := -1;
+ if not SoundInitialized then Exit;
- Result := False;
-
- res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
- e_SoundsArray[ID].Sound, False, Chan);
- if res <> FMOD_OK then
- begin
- Exit;
- end;
+ if {(e_SoundsArray[ID].nRefs >= gMaxSimSounds) or} (e_SoundsArray[ID].Sound = nil) then Exit;
- res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
- if res <> FMOD_OK then
- begin
- end;
+ if e_SoundsArray[ID].Loop then
+ res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, -1)
+ else
+ res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
- if SoundMuted then
- begin
- res := FMOD_Channel_SetMute(Chan, True);
- if res <> FMOD_OK then
- begin
- end;
- end;
+ if SoundMuted and (res >= 0) then Mix_Volume(res, 0);
- Inc(e_SoundsArray[ID].nRefs);
- Result := True;
+ Result := res;
end;
-function e_PlaySoundPan(ID: DWORD; Pan: Single): Boolean;
+function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
var
- res: FMOD_RESULT;
- Chan: FMOD_CHANNEL;
-
+ chan: Integer;
+ l, r: UInt8;
begin
- if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
- begin
- Result := True;
- Exit;
- end;
+ Result := -1;
+ chan := e_PlaySound(ID);
+ if chan < 0 then Exit;
- Result := False;
+ if not SoundMuted then
+ 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);
- 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 := True;
+ Result := chan;
end;
-function e_PlaySoundVolume(ID: DWORD; Volume: Single): Boolean;
+function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
var
- res: FMOD_RESULT;
- Chan: FMOD_CHANNEL;
-
+ chan: Integer;
begin
- if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
- begin
- Result := True;
- Exit;
- end;
+ Result := -1;
+ chan := e_PlaySound(ID);
+ if chan < 0 then Exit;
- Result := False;
-
- res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
- e_SoundsArray[ID].Sound, False, Chan);
- if res <> FMOD_OK then
- begin
- Exit;
- end;
+ if Volume < 0 then Volume := 0 else if Volume > 1 then Volume := 1;
+ if not SoundMuted then Mix_Volume(chan, trunc(Volume*MIX_MAX_VOLUME));
- 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 := True;
+ Result := chan;
end;
-function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Boolean;
+function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
var
- res: FMOD_RESULT;
- Chan: FMOD_CHANNEL;
-
+ chan: Integer;
+ l, r: UInt8;
begin
- if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
- begin
- Result := True;
- Exit;
- end;
-
- Result := False;
+ Result := -1;
+ chan := e_PlaySound(ID);
+ if chan < 0 then Exit;
- res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
- e_SoundsArray[ID].Sound, False, Chan);
- if res <> FMOD_OK then
- begin
- Exit;
- end;
+ 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);
- 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;
+ if Volume < 0 then Volume := 0 else if Volume > 1 then Volume := 1;
+ if not SoundMuted then Mix_Volume(chan, trunc(Volume*MIX_MAX_VOLUME));
- Inc(e_SoundsArray[ID].nRefs);
- Result := True;
+ Result := chan;
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;
+ if e_SoundsArray[ID].Sound = nil then Exit;
+ if e_SoundsArray[ID].Data <> nil then FreeMem(e_SoundsArray[ID].Data);
- 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;
+ Mix_FreeChunk(e_SoundsArray[ID].Sound);
e_SoundsArray[ID].Sound := nil;
e_SoundsArray[ID].Data := nil;
end;
+//TODO
procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
+{
var
- res: FMOD_RESULT;
i: Integer;
Chan: FMOD_CHANNEL;
vol: Single;
-
+}
begin
+ // Mix_Volume(-1, volm);
+{
for i := 0 to N_CHANNELS-1 do
begin
Chan := nil;
end;
end;
end;
+}
end;
+//TODO
procedure e_MuteChannels(Enable: Boolean);
+{
var
res: FMOD_RESULT;
i: Integer;
Chan: FMOD_CHANNEL;
-
+}
begin
+{
if Enable = SoundMuted then
Exit;
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;
+ Mix_HaltChannel(-1);
end;
procedure e_RemoveAllSounds();
var
i: Integer;
-
begin
+ if SoundInitialized then e_StopChannels();
+
for i := 0 to High(e_SoundsArray) do
if e_SoundsArray[i].Sound <> nil then
e_DeleteSound(i);
end;
procedure e_ReleaseSoundSystem();
-var
- res: FMOD_RESULT;
-
begin
e_RemoveAllSounds();
- res := FMOD_System_Close(F_System);
- if res <> FMOD_OK then
+ if SoundInitialized 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);
+ Mix_CloseAudio();
+ SoundInitialized := False;
end;
end;
procedure e_SoundUpdate();
begin
- FMOD_System_Update(F_System);
+ //FMOD_System_Update(F_System);
end;
{ TBasicSound: }
begin
FID := NO_SOUND_ID;
FLoop := False;
- FChannel := nil;
+ FChannel := -1;
FPosition := 0;
FPriority := 128;
end;
procedure TBasicSound.FreeSound();
begin
- if FID = NO_SOUND_ID then
- Exit;
-
+ if FID = NO_SOUND_ID then Exit;
Stop();
FID := NO_SOUND_ID;
FLoop := False;
FPosition := 0;
end;
+// aPos: msecs
function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
var
- res: FMOD_RESULT;
-
+ oldloop: Boolean;
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;
+ if (FID = NO_SOUND_ID) or not SoundInitialized then Exit;
+ oldloop := e_SoundsArray[FID].Loop;
+ e_SoundsArray[FID].Loop := FLoop;
+ Result := (e_PlaySoundPanVolume(FID, Pan, Volume) >= 0);
+ e_SoundsArray[FID].Loop := oldloop;
+ //TODO: aPos
end;
procedure TBasicSound.SetID(ID: DWORD);
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;
+ if FChannel < 0 then Exit;
+ Result := (Mix_Playing(FChannel) > 0);
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;
+ if FChannel < 0 then Exit;
+ //GetPosition();
+ Mix_HaltChannel(FChannel);
+ FChannel := -1;
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;
+ if FChannel < 0 then Exit;
+ Result := (Mix_Paused(FChannel) > 0);
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
+ if FChannel < 0 then Exit;
+ if Mix_Paused(FChannel) > 0 then
+ begin
+ if Enable then Mix_Resume(FChannel);
+ end
+ else
begin
+ if not Enable then Mix_Pause(FChannel);
end;
-
+ {
if Enable then
begin
res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
begin
end;
end;
+ }
end;
+//TODO
function TBasicSound.GetVolume(): Single;
-var
- res: FMOD_RESULT;
- vol: Single;
-
begin
Result := 0.0;
-
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 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;
+ if FChannel < 0 then Exit;
- res := FMOD_Channel_SetVolume(FChannel, Volume);
- if res <> FMOD_OK then
- begin
- end;
+ if Volume < 0 then Volume := 0 else if Volume > 1 then Volume := 1;
+ Mix_Volume(FChannel, trunc(Volume*MIX_MAX_VOLUME));
end;
+//TODO
function TBasicSound.GetPan(): Single;
-var
- res: FMOD_RESULT;
- pan: Single;
-
begin
Result := 0.0;
-
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 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;
-
+ l, r: UInt8;
begin
- if FChannel = nil then
- Exit;
+ if FChannel < 0 then Exit;
- res := FMOD_Channel_SetPan(FChannel, Pan);
- if res <> FMOD_OK then
- begin
- end;
+ 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(FChannel, l, r);
end;
+//TODO
function TBasicSound.IsMuted(): Boolean;
-var
- res: FMOD_RESULT;
- b: LongBool;
-
begin
Result := False;
-
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 then Exit;
+{
res := FMOD_Channel_GetMute(FChannel, b);
if res <> FMOD_OK then
begin
Exit;
end;
-
Result := b;
+}
end;
+//TODO
procedure TBasicSound.Mute(Enable: Boolean);
-var
- res: FMOD_RESULT;
-
begin
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 then Exit;
+{
res := FMOD_Channel_SetMute(FChannel, Enable);
if res <> FMOD_OK then
begin
end;
+}
end;
+//TODO
function TBasicSound.GetPosition(): DWORD;
-var
- res: FMOD_RESULT;
-
begin
Result := 0;
-
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 then Exit;
+{
res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
if res <> FMOD_OK then
begin
Exit;
end;
-
Result := FPosition;
+}
end;
+//TODO
procedure TBasicSound.SetPosition(aPos: DWORD);
-var
- res: FMOD_RESULT;
-
begin
FPosition := aPos;
-
- if FChannel = nil then
- Exit;
-
+ if FChannel < 0 then Exit;
+{
res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
if res <> FMOD_OK then
begin
end;
+}
end;
+//TODO
procedure TBasicSound.SetPriority(priority: Integer);
-var
- res: FMOD_RESULT;
-
begin
+{
if (FChannel <> nil) and (FPriority <> priority) and
(priority >= 0) and (priority <= 256) then
begin
begin
end;
end;
+}
end;
end.