20 TBasicSound
= class (TObject
)
22 FChanNum
: Integer; // <0: no channel allocated
30 function RawPlay(Pan
: Single; Volume
: Single; aPos
: DWORD
): Boolean;
31 function GetChan (): Integer;
33 property Channel
: Integer read GetChan
;
37 destructor Destroy(); override;
38 procedure SetID(ID
: DWORD
);
39 procedure FreeSound();
40 function IsPlaying(): Boolean;
42 function IsPaused(): Boolean;
43 procedure Pause(Enable
: Boolean);
44 function GetVolume(): Single;
45 procedure SetVolume(Volume
: Single);
46 function GetPan(): Single;
47 procedure SetPan(Pan
: Single);
48 function IsMuted(): Boolean;
49 procedure Mute(Enable
: Boolean);
50 function GetPosition(): DWORD
;
51 procedure SetPosition(aPos
: DWORD
);
52 procedure SetPriority(priority
: Integer);
56 NO_SOUND_ID
= DWORD(-1);
58 function e_InitSoundSystem(): Boolean;
60 function e_LoadSound(FileName
: string; var ID
: DWORD
; isMusic
: Boolean): Boolean;
61 function e_LoadSoundMem(pData
: Pointer; Length
: Integer; var ID
: DWORD
; isMusic
: Boolean): Boolean;
63 // returns channel number or -1
64 function e_PlaySound(ID
: DWORD
): Integer;
65 function e_PlaySoundPan(ID
: DWORD
; Pan
: Single): Integer;
66 function e_PlaySoundVolume(ID
: DWORD
; Volume
: Single): Integer;
67 function e_PlaySoundPanVolume(ID
: DWORD
; Pan
, Volume
: Single): Integer;
69 procedure e_ModifyChannelsVolumes(SoundMod
: Single; setMode
: Boolean);
70 procedure e_MuteChannels(Enable
: Boolean);
71 procedure e_StopChannels();
73 procedure e_DeleteSound(ID
: DWORD
);
74 procedure e_RemoveAllSounds();
75 procedure e_ReleaseSoundSystem();
76 procedure e_SoundUpdate();
79 e_SoundsArray
: array of TSoundRec
= nil;
84 g_window
, g_options
, BinEditor
;
88 N_MUSCHAN
= N_CHANNELS
+42;
92 id
: DWORD
; // sound id
94 oldvol
: Integer; // for muted
99 SoundMuted
: Boolean = False;
100 SoundInitialized
: Boolean = False;
101 ChanSIds
: array[0..N_CHANNELS
] of TChanInfo
;
102 MusVolume
: Integer = MIX_MAX_VOLUME
;
105 procedure chanFinished (chan
: Integer); cdecl;
107 //e_WriteLog(Format('chanFinished: %d', [chan]), MSG_NOTIFY);
108 if (chan
>= 0) and (chan
< N_CHANNELS
) then
110 if ChanSIds
[chan
].id
<> NO_SOUND_ID
then
112 if (ChanSIds
[chan
].id
<= High(e_SoundsArray
)) and (e_SoundsArray
[ChanSIds
[chan
].id
].nRefs
> 0) then
114 Dec(e_SoundsArray
[ChanSIds
[chan
].id
].nRefs
);
116 ChanSIds
[chan
].id
:= NO_SOUND_ID
;
122 procedure dumpMusicType (ms
: PMix_Music
);
126 e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY
);
130 case Mix_GetMusicType(ms
^) of
131 TMix_MusicType
.MUS_NONE
:
132 e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY
);
133 TMix_MusicType
.MUS_CMD
:
134 e_WriteLog('MUSIC FORMAT: CMD', MSG_NOTIFY
);
135 TMix_MusicType
.MUS_WAV
:
136 e_WriteLog('MUSIC FORMAT: WAV', MSG_NOTIFY
);
137 TMix_MusicType
.MUS_MOD
:
138 e_WriteLog('MUSIC FORMAT: MOD', MSG_NOTIFY
);
139 TMix_MusicType
.MUS_MID
:
140 e_WriteLog('MUSIC FORMAT: MID', MSG_NOTIFY
);
141 TMix_MusicType
.MUS_OGG
:
142 e_WriteLog('MUSIC FORMAT: OGG', MSG_NOTIFY
);
143 TMix_MusicType
.MUS_MP3
:
144 e_WriteLog('MUSIC FORMAT: MP3', MSG_NOTIFY
);
145 TMix_MusicType
.MUS_MP3_MAD
:
146 e_WriteLog('MUSIC FORMAT: MP3_MAD', MSG_NOTIFY
);
147 TMix_MusicType
.MUS_FLAC
:
148 e_WriteLog('MUSIC FORMAT: FLAC', MSG_NOTIFY
);
149 TMix_MusicType
.MUS_MODPLUG
:
150 e_WriteLog('MUSIC FORMAT: MODPLUG', MSG_NOTIFY
);
152 e_WriteLog('MUSIC FORMAT: UNKNOWN', MSG_NOTIFY
);
157 function e_InitSoundSystem(): Boolean;
161 if SoundInitialized
then begin Result
:= true; Exit
end;
164 SoundInitialized
:= False;
166 // wow, this is actually MIDI player!
167 // we need module player
168 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
);
169 e_WriteLog(Format('SDL: res=0x%x', [res
]), MSG_NOTIFY
);
170 if (res
and MIX_INIT_FLAC
) <> 0 then e_WriteLog('SDL: FLAC playback is active', MSG_NOTIFY
);
171 if (res
and MIX_INIT_MOD
) <> 0 then e_WriteLog('SDL: MOD playback is active', MSG_NOTIFY
);
172 if (res
and MIX_INIT_MODPLUG
) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', MSG_NOTIFY
);
173 if (res
and MIX_INIT_MP3
) <> 0 then e_WriteLog('SDL: MP3 playback is active', MSG_NOTIFY
);
174 if (res
and MIX_INIT_OGG
) <> 0 then e_WriteLog('SDL: OGG playback is active', MSG_NOTIFY
);
175 if (res
and MIX_INIT_FLUIDSYNTH
) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', MSG_NOTIFY
);
177 res
:= Mix_OpenAudio(48000, AUDIO_S16LSB
, 2, 2048);
178 if res
= -1 then res
:= Mix_OpenAudio(44100, AUDIO_S16LSB
, 2, 2048);
181 e_WriteLog('Error initializing SDL mixer:', MSG_FATALERROR
);
182 e_WriteLog(Mix_GetError(), MSG_FATALERROR
);
186 Mix_AllocateChannels(N_CHANNELS
);
187 Mix_ChannelFinished(chanFinished
);
189 for i
:= 0 to N_CHANNELS
-1 do
191 ChanSIds
[i
].id
:= NO_SOUND_ID
;
192 ChanSIds
[i
].muted
:= SoundMuted
;
193 ChanSIds
[i
].oldvol
:= MIX_MAX_VOLUME
;
194 ChanSIds
[i
].pan
:= 1.0;
196 MusVolume
:= MIX_MAX_VOLUME
;
198 SoundInitialized
:= True;
202 function e_isMusic (id
: DWORD
): Boolean;
205 if (e_SoundsArray
<> nil) and (id
<= High(e_SoundsArray
)) then
207 Result
:= (e_SoundsArray
[id
].Music
<> nil);
211 function e_isSound (id
: DWORD
): Boolean;
214 if (e_SoundsArray
<> nil) and (id
<= High(e_SoundsArray
)) then
216 Result
:= (e_SoundsArray
[id
].Sound
<> nil);
220 function FindESound(): DWORD
;
224 if e_SoundsArray
<> nil then
226 for i
:= 0 to High(e_SoundsArray
) do
227 if (e_SoundsArray
[i
].Sound
= nil) and (e_SoundsArray
[i
].Music
= nil) then
233 if e_SoundsArray
= nil then
235 SetLength(e_SoundsArray
, 16);
240 Result
:= High(e_SoundsArray
) + 1;
241 SetLength(e_SoundsArray
, Length(e_SoundsArray
) + 16);
243 for i
:= Result
to High(e_SoundsArray
) do
245 e_SoundsArray
[i
].Sound
:= nil;
246 e_SoundsArray
[i
].Music
:= nil;
247 e_SoundsArray
[i
].Data
:= nil;
248 e_SoundsArray
[i
].isMusic
:= False;
249 e_SoundsArray
[i
].nRefs
:= 0;
253 function e_LoadSound(FileName
: String; var ID
: DWORD
; isMusic
: Boolean): Boolean;
259 if not SoundInitialized
then Exit
;
261 if isMusic
then e_WriteLog('Loading music '+FileName
+'...', MSG_NOTIFY
)
262 else e_WriteLog('Loading sound '+FileName
+'...', MSG_NOTIFY
);
267 e_WriteLog('IGNORING MUSIC FROM FILE', MSG_WARNING);
272 find_id
:= FindESound();
274 e_SoundsArray
[find_id
].Data
:= nil;
275 e_SoundsArray
[find_id
].isMusic
:= isMusic
;
276 e_SoundsArray
[find_id
].nRefs
:= 0;
280 e_WriteLog(Format(' MUSIC SLOT: %u', [find_id
]), MSG_NOTIFY
);
281 e_SoundsArray
[find_id
].Music
:= Mix_LoadMUS(PAnsiChar(FileName
));
282 if e_SoundsArray
[find_id
].Music
= nil then
284 e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id
]), MSG_WARNING
);
285 e_WriteLog(Mix_GetError(), MSG_WARNING
);
288 dumpMusicType(e_SoundsArray
[find_id
].Music
);
292 e_SoundsArray
[find_id
].Sound
:= Mix_LoadWAV(PAnsiChar(FileName
));
293 if e_SoundsArray
[find_id
].Sound
= nil then Exit
;
301 function e_LoadSoundMem(pData
: Pointer; Length
: Integer; var ID
: DWORD
; isMusic
: Boolean): Boolean;
310 if not SoundInitialized
then Exit
;
316 e_WriteLog('IGNORING MUSIC FROM MEMORY', MSG_WARNING);
321 //FIXME: correctly skip ID3
324 if (Length > $400) and (pc[0] = 'I') and (pc[1] = 'D') and (pc[2] = '3') then
328 pData := Pointer(pc);
330 e_WriteLog('MUSIC: MP3 ID3 WORKAROUND APPLIED!', MSG_WARNING);
334 rw
:= SDL_RWFromConstMem(pData
, Length
);
335 if rw
= nil then Exit
;
337 find_id
:= FindESound();
339 e_SoundsArray
[find_id
].Data
:= pData
;
340 if isid3
then e_SoundsArray
[find_id
].Data
:= nil;
341 e_SoundsArray
[find_id
].isMusic
:= isMusic
;
342 e_SoundsArray
[find_id
].nRefs
:= 0;
346 e_WriteLog(Format(' MUSIC SLOT: %u', [find_id
]), MSG_NOTIFY
);
347 e_SoundsArray
[find_id
].Music
:= Mix_LoadMUS_RW(rw
, 0);
348 if e_SoundsArray
[find_id
].Music
= nil then
350 e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id
]), MSG_WARNING
);
351 e_WriteLog(Mix_GetError(), MSG_WARNING
);
355 dumpMusicType(e_SoundsArray
[find_id
].Music
);
359 if e_SoundsArray[find_id].Music <> nil then
361 Mix_FreeMusic(e_SoundsArray[find_id].Music);
363 e_SoundsArray[find_id].Music := nil;
369 e_SoundsArray
[find_id
].Sound
:= Mix_LoadWAV_RW(rw
, 0);
371 //SDL_FreeRW(rw); // somehow it segfaults...
372 if (e_SoundsArray
[find_id
].Sound
= nil) and (e_SoundsArray
[find_id
].Music
= nil) then
374 e_SoundsArray
[find_id
].Data
:= nil;
383 function e_PlaySound (ID
: DWORD
): Integer;
388 if not SoundInitialized
then Exit
;
390 if e_isSound(ID
) then
392 if e_SoundsArray
[ID
].nRefs
>= gMaxSimSounds
then Exit
;
393 Inc(e_SoundsArray
[ID
].nRefs
);
394 res
:= Mix_PlayChannel(-1, e_SoundsArray
[ID
].Sound
, 0);
397 ChanSIds
[res
].id
:= ID
;
398 ChanSIds
[res
].muted
:= SoundMuted
;
399 if SoundMuted
then Mix_Volume(res
, 0) else Mix_Volume(res
, ChanSIds
[res
].oldvol
);
401 if e_SoundsArray[ID].isMusic then
402 res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, -1)
404 res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
410 if not e_isMusic(ID
) then Exit
;
412 res
:= Mix_PlayMusic(e_SoundsArray
[ID
].Music
, -1);
413 if res
>= 0 then res
:= N_MUSCHAN
;
414 if SoundMuted
then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume
);
421 function e_chanSetPan (chan
: Integer; Pan
: Single): Boolean;
426 if chan
= N_MUSCHAN
then
428 // no panning for music
430 else if chan
>= 0 then
432 if Pan
< -1.0 then Pan
:= -1.0 else if Pan
> 1.0 then Pan
:= 1.0;
433 Pan
:= Pan
+1.0; // 0..2
434 l
:= trunc(127.0*(2.0-Pan
));
435 r
:= trunc(127.0*Pan
);
436 Mix_SetPanning(chan
, l
, r
);
437 ChanSIds
[chan
].pan
:= Pan
;
445 function e_chanSetVol (chan
: Integer; Volume
: Single): Boolean;
450 if Volume
< 0 then Volume
:= 0 else if Volume
> 1 then Volume
:= 1;
451 vol
:= trunc(Volume
*MIX_MAX_VOLUME
);
452 if chan
= N_MUSCHAN
then
455 if SoundMuted
then Mix_VolumeMusic(0) else Mix_VolumeMusic(vol
);
457 else if chan
>= 0 then
459 ChanSIds
[chan
].oldvol
:= vol
;
460 if ChanSIds
[chan
].muted
then Mix_Volume(chan
, 0) else Mix_Volume(chan
, vol
);
468 function e_PlaySoundPan(ID
: DWORD
; Pan
: Single): Integer;
473 chan
:= e_PlaySound(ID
);
474 e_chanSetPan(chan
, Pan
);
478 function e_PlaySoundVolume(ID
: DWORD
; Volume
: Single): Integer;
483 chan
:= e_PlaySound(ID
);
484 e_chanSetVol(chan
, Volume
);
488 function e_PlaySoundPanVolume(ID
: DWORD
; Pan
, Volume
: Single): Integer;
493 chan
:= e_PlaySound(ID
);
494 e_chanSetPan(chan
, Pan
);
495 e_chanSetVol(chan
, Volume
);
499 procedure e_DeleteSound(ID
: DWORD
);
503 if ID
> High(e_SoundsArray
) then Exit
;
504 if (e_SoundsArray
[ID
].Sound
= nil) and (e_SoundsArray
[ID
].Music
= nil) then Exit
;
506 for i
:= 0 to N_CHANNELS
-1 do
508 if ChanSIds
[i
].id
= ID
then
510 ChanSIds
[i
].id
:= NO_SOUND_ID
;
515 if e_SoundsArray
[ID
].Sound
<> nil then Mix_FreeChunk(e_SoundsArray
[ID
].Sound
);
516 if e_SoundsArray
[ID
].Music
<> nil then Mix_FreeMusic(e_SoundsArray
[ID
].Music
);
517 if e_SoundsArray
[ID
].Data
<> nil then FreeMem(e_SoundsArray
[ID
].Data
);
519 e_SoundsArray
[ID
].Sound
:= nil;
520 e_SoundsArray
[ID
].Music
:= nil;
521 e_SoundsArray
[ID
].Data
:= nil;
522 e_SoundsArray
[ID
].nRefs
:= 0;
525 procedure e_ModifyChannelsVolumes(SoundMod
: Single; setMode
: Boolean);
531 for i
:= 0 to N_CHANNELS
-1 do
533 ovol
:= ChanSIds
[i
].oldvol
;
540 vol
:= (MIX_MAX_VOLUME
+0.0)/ovol
;
543 if vol
< 0 then vol
:= 0 else if vol
> 1 then vol
:= 1;
544 ChanSIds
[i
].oldvol
:= trunc(vol
*MIX_MAX_VOLUME
);
545 //if i = 0 then e_WriteLog(Format('modifying volumes: vol=%f; newvol=%d', [vol, ChanSIds[i].oldvol]), MSG_WARNING);
546 if ChanSIds
[i
].muted
then Mix_Volume(i
, 0) else Mix_Volume(i
, ChanSIds
[i
].oldvol
);
548 ovol
:= Mix_VolumeMusic(-1);
557 vol
:= (MIX_MAX_VOLUME
+0.0)/ovol
;
558 vol
:= vol
* SoundMod
;
560 if vol
< 0 then vol
:= 0 else if vol
> 1 then vol
:= 1;
561 MusVolume
:= trunc(vol
*MIX_MAX_VOLUME
);
562 if SoundMuted
then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume
);
566 procedure e_MuteChannels(Enable
: Boolean);
570 //if Enable = SoundMuted then Exit;
571 SoundMuted
:= Enable
;
572 for i
:= 0 to N_CHANNELS
-1 do
574 if ChanSIds
[i
].muted
<> SoundMuted
then
576 ChanSIds
[i
].muted
:= SoundMuted
;
577 //e_WriteLog(Format('gmuting sound for channel %d', [i]), MSG_WARNING);
578 if ChanSIds
[i
].muted
then Mix_Volume(i
, 0) else Mix_Volume(i
, ChanSIds
[i
].oldvol
);
581 //if SoundMuted then e_WriteLog('muting music', MSG_NOTIFY) else e_WriteLog(Format('unmuting music (%d)', [MusVolume]), MSG_NOTIFY);
582 if SoundMuted
then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume
);
585 procedure e_StopChannels();
591 for i
:= 0 to High(e_SoundsArray
) do e_SoundsArray
[i
].nRefs
:= 0;
592 for i
:= 0 to N_CHANNELS
-1 do ChanSIds
[i
].id
:= NO_SOUND_ID
;
595 procedure e_RemoveAllSounds();
599 if SoundInitialized
then e_StopChannels();
600 for i
:= 0 to High(e_SoundsArray
) do e_DeleteSound(i
);
601 SetLength(e_SoundsArray
, 0);
602 e_SoundsArray
:= nil;
605 procedure e_ReleaseSoundSystem();
608 if SoundInitialized
then
611 SoundInitialized
:= False;
615 procedure e_SoundUpdate();
617 //FMOD_System_Update(F_System);
623 constructor TBasicSound
.Create();
632 destructor TBasicSound
.Destroy();
638 function TBasicSound
.GetChan (): Integer;
640 if (FID
<> NO_SOUND_ID
) and (FChanNum
>= 0) and (FChanNum
< N_CHANNELS
) then
642 if ChanSIds
[FChanNum
].id
<> FID
then FChanNum
:= -1;
644 else if e_isMusic(FID
) then
646 FChanNum
:= N_MUSCHAN
;
651 procedure TBasicSound
.FreeSound();
653 if FID
= NO_SOUND_ID
then Exit
;
662 function TBasicSound
.RawPlay(Pan
: Single; Volume
: Single; aPos
: DWORD
): Boolean;
665 if (FID
= NO_SOUND_ID
) or not SoundInitialized
then Exit
;
666 FChanNum
:= e_PlaySoundPanVolume(FID
, Pan
, Volume
);
667 Result
:= (FChanNum
>= 0);
668 //if e_isMusic(FID) then e_WriteLog(Format('playing music (%u)', [FID]), MSG_NOTIFY);
672 procedure TBasicSound
.SetID(ID
: DWORD
);
676 if ID
<> NO_SOUND_ID
then
678 FMusic
:= e_SoundsArray
[ID
].isMusic
;
683 function TBasicSound
.IsPlaying(): Boolean;
688 if e_isSound(FID
) then
690 //e_WriteLog(Format('IsPlaying: FID=%u; FChanNum=%d', [FID, FChanNum]), MSG_WARNING);
694 //e_WriteLog(Format('IsPlaying: FID=%u; ONA', [FID]), MSG_WARNING);
697 //Result := (Mix_Playing(chan) > 0)
698 //e_WriteLog(Format('IsPlaying: FID=%u; TAN', [FID]), MSG_WARNING);
701 else if e_isMusic(FID
) then
703 Result
:= (Mix_PlayingMusic() > 0);
707 procedure TBasicSound
.Stop();
711 if e_isSound(FID
) then
717 Mix_HaltChannel(chan
);
720 else if e_isMusic(FID
) then
727 function TBasicSound
.IsPaused(): Boolean;
732 if e_isSound(FID
) then
735 if chan
< 0 then Exit
;
736 Result
:= (Mix_Paused(chan
) > 0);
738 else if e_isMusic(FID
) then
740 Result
:= (Mix_PausedMusic() > 0);
744 procedure TBasicSound
.Pause(Enable
: Boolean);
749 Enable
:= not Enable
; // fuckin' double negation
750 if e_isSound(FID
) then
753 if chan
< 0 then Exit
;
754 pl
:= not (Mix_Paused(chan
) > 0);
757 if Enable
then Mix_Resume(chan
) else Mix_Pause(chan
);
760 else if e_isMusic(FID
) then
762 pl
:= not (Mix_PausedMusic() > 0);
765 if Enable
then Mix_ResumeMusic() else Mix_PauseMusic();
771 res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
772 if res <> FMOD_OK then
779 function TBasicSound
.GetVolume(): Single;
784 if e_isSound(FID
) then
787 if chan
< 0 then Exit
;
788 Result
:= (ChanSIds
[chan
].oldvol
+0.0)/(MIX_MAX_VOLUME
+0.0);
790 else if e_isMusic(FID
) then
792 Result
:= (MusVolume
+0.0)/(MIX_MAX_VOLUME
+0.0);
796 procedure TBasicSound
.SetVolume(Volume
: Single);
800 if e_isSound(FID
) then
803 if chan
< 0 then Exit
;
804 //e_WriteLog(Format('SetVolume: chan=%d; Volume=%f', [chan, Volume]), MSG_WARNING);
805 e_chanSetVol(chan
, Volume
);
807 else if e_isMusic(FID
) then
809 //e_WriteLog(Format('SetVolume: chan=MUSIC; Volume=%f', [Volume]), MSG_WARNING);
810 e_chanSetVol(N_MUSCHAN
, Volume
);
814 function TBasicSound
.GetPan(): Single;
819 if e_isSound(FID
) then
822 if chan
< 0 then Exit
;
823 Result
:= ChanSIds
[chan
].pan
;
827 procedure TBasicSound
.SetPan(Pan
: Single);
831 if e_isSound(FID
) then
834 if chan
< 0 then Exit
;
835 e_chanSetPan(chan
, Pan
);
839 function TBasicSound
.IsMuted(): Boolean;
844 if e_isSound(FID
) then
847 if chan
< 0 then Exit
;
848 Result
:= ChanSIds
[chan
].muted
;
850 else if e_isMusic(FID
) then
852 Result
:= SoundMuted
;
856 procedure TBasicSound
.Mute(Enable
: Boolean);
860 if e_isSound(FID
) then
863 if chan
< 0 then Exit
;
864 if ChanSIds
[chan
].muted
<> Enable
then
866 //e_WriteLog(Format('muting sound for channel %d', [cnan]), MSG_WARNING);
867 ChanSIds
[chan
].muted
:= Enable
;
868 if ChanSIds
[chan
].muted
then Mix_Volume(chan
, 0) else Mix_Volume(chan
, ChanSIds
[chan
].oldvol
);
871 else if e_isMusic(FID
) then
873 if Enable
then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume
);
878 function TBasicSound
.GetPosition(): DWORD
;
882 if FChanNum < 0 then Exit;
883 res := FMOD_Channel_GetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
884 if res <> FMOD_OK then
893 procedure TBasicSound
.SetPosition(aPos
: DWORD
);
897 if FChanNum < 0 then Exit;
898 res := FMOD_Channel_SetPosition(FChanNum, FPosition, FMOD_TIMEUNIT_MS);
899 if res <> FMOD_OK then
906 procedure TBasicSound
.SetPriority(priority
: Integer);
909 if (FChanNum <> nil) and (FPriority <> priority) and
910 (priority >= 0) and (priority <= 256) then
912 FPriority := priority;
913 res := FMOD_Channel_SetPriority(FChanNum, priority);
914 if res <> FMOD_OK then