DEADSOFTWARE

changed some backslashes to forward slashes
[d2df-editor.git] / src / engine / e_sound.pas
1 unit e_sound;
3 interface
5 uses
6 fmod,
7 fmodtypes,
8 fmoderrors,
9 e_log,
10 SysUtils,
11 Windows;
13 type
14 TSoundRec = record
15 Data: Pointer;
16 Sound: FMOD_SOUND;
17 Loop: Boolean;
18 nRefs: Integer;
19 end;
21 TBasicSound = class (TObject)
22 private
23 FChannel: FMOD_CHANNEL;
25 protected
26 FID: DWORD;
27 FLoop: Boolean;
28 FPosition: DWORD;
29 FPriority: Integer;
31 function RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
33 public
34 constructor Create();
35 destructor Destroy(); override;
36 procedure SetID(ID: DWORD);
37 procedure FreeSound();
38 function IsPlaying(): Boolean;
39 procedure Stop();
40 function IsPaused(): Boolean;
41 procedure Pause(Enable: Boolean);
42 function GetVolume(): Single;
43 procedure SetVolume(Volume: Single);
44 function GetPan(): Single;
45 procedure SetPan(Pan: Single);
46 function IsMuted(): Boolean;
47 procedure Mute(Enable: Boolean);
48 function GetPosition(): DWORD;
49 procedure SetPosition(aPos: DWORD);
50 procedure SetPriority(priority: Integer);
51 end;
53 const
54 NO_SOUND_ID = DWORD(-1);
56 function e_InitSoundSystem(Freq: Integer): Boolean;
58 function e_LoadSound(FileName: string; var ID: DWORD; bLoop: Boolean): Boolean;
59 function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
61 function e_PlaySound(ID: DWORD): Boolean;
62 function e_PlaySoundPan(ID: DWORD; Pan: Single): Boolean;
63 function e_PlaySoundVolume(ID: DWORD; Volume: Single): Boolean;
64 function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Boolean;
66 procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
67 procedure e_MuteChannels(Enable: Boolean);
68 procedure e_StopChannels();
70 procedure e_DeleteSound(ID: DWORD);
71 procedure e_RemoveAllSounds();
72 procedure e_ReleaseSoundSystem();
73 procedure e_SoundUpdate();
75 var
76 e_SoundsArray: array of TSoundRec = nil;
78 implementation
80 uses
81 g_window, g_options;
83 const
84 N_CHANNELS = 512;
86 var
87 F_System: FMOD_SYSTEM = nil;
88 SoundMuted: Boolean = False;
91 function Channel_Callback(channel: FMOD_CHANNEL; callbacktype: FMOD_CHANNEL_CALLBACKTYPE;
92 commanddata1: Pointer; commanddata2: Pointer): FMOD_RESULT; stdcall;
93 var
94 res: FMOD_RESULT;
95 sound: FMOD_SOUND;
96 ud: Pointer;
97 id: DWORD;
99 begin
100 res := FMOD_OK;
102 if callbacktype = FMOD_CHANNEL_CALLBACKTYPE_END then
103 begin
104 res := FMOD_Channel_GetCurrentSound(channel, sound);
105 if res = FMOD_OK then
106 begin
107 res := FMOD_Sound_GetUserData(sound, ud);
108 if res = FMOD_OK then
109 begin
110 id := DWORD(ud^);
111 if id < DWORD(Length(e_SoundsArray)) then
112 if e_SoundsArray[id].nRefs > 0 then
113 Dec(e_SoundsArray[id].nRefs);
114 end;
115 end;
116 end;
118 Result := res;
119 end;
121 function e_InitSoundSystem(Freq: Integer): Boolean;
122 var
123 res: FMOD_RESULT;
124 ver: Cardinal;
125 output: FMOD_OUTPUTTYPE;
126 drv: Integer;
128 begin
129 Result := False;
131 res := FMOD_System_Create(F_System);
132 if res <> FMOD_OK then
133 begin
134 e_WriteLog('Error creating FMOD system:', MSG_FATALERROR);
135 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
136 Exit;
137 end;
139 res := FMOD_System_GetVersion(F_System, ver);
140 if res <> FMOD_OK then
141 begin
142 e_WriteLog('Error getting FMOD version:', MSG_FATALERROR);
143 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
144 Exit;
145 end;
147 if ver < FMOD_VERSION then
148 begin
149 e_WriteLog('FMOD DLL version is too old! Need '+IntToStr(FMOD_VERSION), MSG_FATALERROR);
150 Exit;
151 end;
153 res := FMOD_System_SetSoftwareFormat(F_System, Freq,
154 FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
155 if res <> FMOD_OK then
156 begin
157 e_WriteLog('Error setting FMOD software format!', MSG_FATALERROR);
158 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
159 Exit;
160 end;
162 res := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
163 if res <> FMOD_OK then
164 begin
165 e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
166 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
167 e_WriteLog('Trying with OUTPUTTYPE_NOSOUND...', MSG_WARNING);
168 res := FMOD_System_SetOutput(F_System, FMOD_OUTPUTTYPE_NOSOUND);
169 if res <> FMOD_OK then
170 begin
171 e_WriteLog('Error setting FMOD output to NOSOUND!', MSG_FATALERROR);
172 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
173 Exit;
174 end;
175 res := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
176 if res <> FMOD_OK then
177 begin
178 e_WriteLog('Error initializing FMOD system!', MSG_FATALERROR);
179 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
180 Exit;
181 end;
182 end;
184 res := FMOD_System_GetOutput(F_System, output);
185 if res <> FMOD_OK then
186 e_WriteLog('Error getting FMOD output!', MSG_WARNING)
187 else
188 case output of
189 FMOD_OUTPUTTYPE_NOSOUND: e_WriteLog('FMOD Output Method: NOSOUND', MSG_NOTIFY);
190 FMOD_OUTPUTTYPE_NOSOUND_NRT: e_WriteLog('FMOD Output Method: NOSOUND_NRT', MSG_NOTIFY);
191 FMOD_OUTPUTTYPE_DSOUND: e_WriteLog('FMOD Output Method: DSOUND', MSG_NOTIFY);
192 FMOD_OUTPUTTYPE_WINMM: e_WriteLog('FMOD Output Method: WINMM', MSG_NOTIFY);
193 FMOD_OUTPUTTYPE_OPENAL: e_WriteLog('FMOD Output Method: OPENAL', MSG_NOTIFY);
194 FMOD_OUTPUTTYPE_WASAPI: e_WriteLog('FMOD Output Method: WASAPI', MSG_NOTIFY);
195 FMOD_OUTPUTTYPE_ASIO: e_WriteLog('FMOD Output Method: ASIO', MSG_NOTIFY);
196 else e_WriteLog('FMOD Output Method: Unknown', MSG_NOTIFY);
197 end;
199 res := FMOD_System_GetDriver(F_System, drv);
200 if res <> FMOD_OK then
201 e_WriteLog('Error getting FMOD driver!', MSG_WARNING)
202 else
203 begin
204 {res := FMOD_System_GetDriverName(F_System, drv, str, 64);
205 if res <> FMOD_OK then
206 e_WriteLog('Error getting FMOD driver name!', MSG_WARNING)
207 else }
208 e_WriteLog('FMOD driver id: '+IntToStr(drv), MSG_NOTIFY);
209 end;
211 Result := True;
212 end;
214 function FindESound(): DWORD;
215 var
216 i: Integer;
218 begin
219 if e_SoundsArray <> nil then
220 for i := 0 to High(e_SoundsArray) do
221 if e_SoundsArray[i].Sound = nil then
222 begin
223 Result := i;
224 Exit;
225 end;
227 if e_SoundsArray = nil then
228 begin
229 SetLength(e_SoundsArray, 16);
230 Result := 0;
231 end
232 else
233 begin
234 Result := High(e_SoundsArray) + 1;
235 SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
236 end;
237 end;
239 function e_LoadSound(FileName: String; var ID: DWORD; bLoop: Boolean): Boolean;
240 var
241 find_id: DWORD;
242 res: FMOD_RESULT;
243 bt: Cardinal;
244 ud: Pointer;
246 begin
247 Result := False;
249 e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
251 find_id := FindESound();
253 if bLoop then
254 bt := FMOD_LOOP_NORMAL
255 else
256 bt := FMOD_LOOP_OFF;
258 if not bLoop then
259 res := FMOD_System_CreateSound(F_System, PAnsiChar(FileName),
260 bt + FMOD_2D + FMOD_HARDWARE,
261 nil, e_SoundsArray[find_id].Sound)
262 else
263 res := FMOD_System_CreateStream(F_System, PAnsiChar(FileName),
264 bt + FMOD_2D + FMOD_HARDWARE,
265 nil, e_SoundsArray[find_id].Sound);
266 if res <> FMOD_OK then
267 begin
268 e_SoundsArray[find_id].Sound := nil;
269 Exit;
270 end;
272 GetMem(ud, SizeOf(DWORD));
273 DWORD(ud^) := find_id;
274 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
275 if res <> FMOD_OK then
276 begin
277 e_SoundsArray[find_id].Sound := nil;
278 Exit;
279 end;
281 e_SoundsArray[find_id].Data := nil;
282 e_SoundsArray[find_id].Loop := bLoop;
283 e_SoundsArray[find_id].nRefs := 0;
285 ID := find_id;
287 Result := True;
288 end;
290 function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
291 var
292 find_id: DWORD;
293 res: FMOD_RESULT;
294 sz: Integer;
295 bt: Cardinal;
296 soundExInfo: FMOD_CREATESOUNDEXINFO;
297 ud: Pointer;
299 begin
300 Result := False;
302 find_id := FindESound();
304 sz := SizeOf(FMOD_CREATESOUNDEXINFO);
305 FillMemory(@soundExInfo, sz, 0);
306 soundExInfo.cbsize := sz;
307 soundExInfo.length := Length;
309 if bLoop then
310 bt := FMOD_LOOP_NORMAL
311 else
312 bt := FMOD_LOOP_OFF;
314 if not bLoop then
315 res := FMOD_System_CreateSound(F_System, pData,
316 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
317 @soundExInfo, e_SoundsArray[find_id].Sound)
318 else
319 res := FMOD_System_CreateStream(F_System, pData,
320 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
321 @soundExInfo, e_SoundsArray[find_id].Sound);
322 if res <> FMOD_OK then
323 begin
324 e_SoundsArray[find_id].Sound := nil;
325 Exit;
326 end;
328 GetMem(ud, SizeOf(DWORD));
329 DWORD(ud^) := find_id;
330 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
331 if res <> FMOD_OK then
332 begin
333 e_SoundsArray[find_id].Sound := nil;
334 Exit;
335 end;
337 e_SoundsArray[find_id].Data := pData;
338 e_SoundsArray[find_id].Loop := bLoop;
339 e_SoundsArray[find_id].nRefs := 0;
341 ID := find_id;
343 Result := True;
344 end;
346 function e_PlaySound(ID: DWORD): Boolean;
347 var
348 res: FMOD_RESULT;
349 Chan: FMOD_CHANNEL;
351 begin
352 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
353 begin
354 Result := True;
355 Exit;
356 end;
358 Result := False;
360 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
361 e_SoundsArray[ID].Sound, False, Chan);
362 if res <> FMOD_OK then
363 begin
364 Exit;
365 end;
367 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
368 if res <> FMOD_OK then
369 begin
370 end;
372 if SoundMuted then
373 begin
374 res := FMOD_Channel_SetMute(Chan, True);
375 if res <> FMOD_OK then
376 begin
377 end;
378 end;
380 Inc(e_SoundsArray[ID].nRefs);
381 Result := True;
382 end;
384 function e_PlaySoundPan(ID: DWORD; Pan: Single): Boolean;
385 var
386 res: FMOD_RESULT;
387 Chan: FMOD_CHANNEL;
389 begin
390 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
391 begin
392 Result := True;
393 Exit;
394 end;
396 Result := False;
398 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
399 e_SoundsArray[ID].Sound, False, Chan);
400 if res <> FMOD_OK then
401 begin
402 Exit;
403 end;
405 res := FMOD_Channel_SetPan(Chan, Pan);
406 if res <> FMOD_OK then
407 begin
408 end;
410 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
411 if res <> FMOD_OK then
412 begin
413 end;
415 if SoundMuted then
416 begin
417 res := FMOD_Channel_SetMute(Chan, True);
418 if res <> FMOD_OK then
419 begin
420 end;
421 end;
423 Inc(e_SoundsArray[ID].nRefs);
424 Result := True;
425 end;
427 function e_PlaySoundVolume(ID: DWORD; Volume: Single): Boolean;
428 var
429 res: FMOD_RESULT;
430 Chan: FMOD_CHANNEL;
432 begin
433 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
434 begin
435 Result := True;
436 Exit;
437 end;
439 Result := False;
441 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
442 e_SoundsArray[ID].Sound, False, Chan);
443 if res <> FMOD_OK then
444 begin
445 Exit;
446 end;
448 res := FMOD_Channel_SetVolume(Chan, Volume);
449 if res <> FMOD_OK then
450 begin
451 end;
453 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
454 if res <> FMOD_OK then
455 begin
456 end;
458 if SoundMuted then
459 begin
460 res := FMOD_Channel_SetMute(Chan, True);
461 if res <> FMOD_OK then
462 begin
463 end;
464 end;
466 Inc(e_SoundsArray[ID].nRefs);
467 Result := True;
468 end;
470 function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Boolean;
471 var
472 res: FMOD_RESULT;
473 Chan: FMOD_CHANNEL;
475 begin
476 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
477 begin
478 Result := True;
479 Exit;
480 end;
482 Result := False;
484 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
485 e_SoundsArray[ID].Sound, False, Chan);
486 if res <> FMOD_OK then
487 begin
488 Exit;
489 end;
491 res := FMOD_Channel_SetPan(Chan, Pan);
492 if res <> FMOD_OK then
493 begin
494 end;
496 res := FMOD_Channel_SetVolume(Chan, Volume);
497 if res <> FMOD_OK then
498 begin
499 end;
501 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
502 if res <> FMOD_OK then
503 begin
504 end;
506 if SoundMuted then
507 begin
508 res := FMOD_Channel_SetMute(Chan, True);
509 if res <> FMOD_OK then
510 begin
511 end;
512 end;
514 Inc(e_SoundsArray[ID].nRefs);
515 Result := True;
516 end;
518 procedure e_DeleteSound(ID: DWORD);
519 var
520 res: FMOD_RESULT;
521 ud: Pointer;
523 begin
524 if e_SoundsArray[ID].Sound = nil then
525 Exit;
527 if e_SoundsArray[ID].Data <> nil then
528 FreeMem(e_SoundsArray[ID].Data);
530 res := FMOD_Sound_GetUserData(e_SoundsArray[ID].Sound, ud);
531 if res = FMOD_OK then
532 begin
533 FreeMem(ud);
534 end;
536 res := FMOD_Sound_Release(e_SoundsArray[ID].Sound);
537 if res <> FMOD_OK then
538 begin
539 e_WriteLog('Error releasing sound:', MSG_WARNING);
540 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
541 end;
543 e_SoundsArray[ID].Sound := nil;
544 e_SoundsArray[ID].Data := nil;
545 end;
547 procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
548 var
549 res: FMOD_RESULT;
550 i: Integer;
551 Chan: FMOD_CHANNEL;
552 vol: Single;
554 begin
555 for i := 0 to N_CHANNELS-1 do
556 begin
557 Chan := nil;
558 res := FMOD_System_GetChannel(F_System, i, Chan);
560 if (res = FMOD_OK) and (Chan <> nil) then
561 begin
562 res := FMOD_Channel_GetVolume(Chan, vol);
564 if res = FMOD_OK then
565 begin
566 if setMode then
567 vol := SoundMod
568 else
569 vol := vol * SoundMod;
571 res := FMOD_Channel_SetVolume(Chan, vol);
573 if res <> FMOD_OK then
574 begin
575 end;
576 end;
577 end;
578 end;
579 end;
581 procedure e_MuteChannels(Enable: Boolean);
582 var
583 res: FMOD_RESULT;
584 i: Integer;
585 Chan: FMOD_CHANNEL;
587 begin
588 if Enable = SoundMuted then
589 Exit;
591 SoundMuted := Enable;
593 for i := 0 to N_CHANNELS-1 do
594 begin
595 Chan := nil;
596 res := FMOD_System_GetChannel(F_System, i, Chan);
598 if (res = FMOD_OK) and (Chan <> nil) then
599 begin
600 res := FMOD_Channel_SetMute(Chan, Enable);
602 if res <> FMOD_OK then
603 begin
604 end;
605 end;
606 end;
607 end;
609 procedure e_StopChannels();
610 var
611 res: FMOD_RESULT;
612 i: Integer;
613 Chan: FMOD_CHANNEL;
615 begin
616 for i := 0 to N_CHANNELS-1 do
617 begin
618 Chan := nil;
619 res := FMOD_System_GetChannel(F_System, i, Chan);
621 if (res = FMOD_OK) and (Chan <> nil) then
622 begin
623 res := FMOD_Channel_Stop(Chan);
625 if res <> FMOD_OK then
626 begin
627 end;
628 end;
629 end;
630 end;
632 procedure e_RemoveAllSounds();
633 var
634 i: Integer;
636 begin
637 for i := 0 to High(e_SoundsArray) do
638 if e_SoundsArray[i].Sound <> nil then
639 e_DeleteSound(i);
641 SetLength(e_SoundsArray, 0);
642 e_SoundsArray := nil;
643 end;
645 procedure e_ReleaseSoundSystem();
646 var
647 res: FMOD_RESULT;
649 begin
650 e_RemoveAllSounds();
652 res := FMOD_System_Close(F_System);
653 if res <> FMOD_OK then
654 begin
655 e_WriteLog('Error closing FMOD system!', MSG_FATALERROR);
656 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
657 Exit;
658 end;
660 res := FMOD_System_Release(F_System);
661 if res <> FMOD_OK then
662 begin
663 e_WriteLog('Error releasing FMOD system!', MSG_FATALERROR);
664 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
665 end;
666 end;
668 procedure e_SoundUpdate();
669 begin
670 FMOD_System_Update(F_System);
671 end;
673 { TBasicSound: }
675 constructor TBasicSound.Create();
676 begin
677 FID := NO_SOUND_ID;
678 FLoop := False;
679 FChannel := nil;
680 FPosition := 0;
681 FPriority := 128;
682 end;
684 destructor TBasicSound.Destroy();
685 begin
686 FreeSound();
687 inherited;
688 end;
690 procedure TBasicSound.FreeSound();
691 begin
692 if FID = NO_SOUND_ID then
693 Exit;
695 Stop();
696 FID := NO_SOUND_ID;
697 FLoop := False;
698 FPosition := 0;
699 end;
701 function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
702 var
703 res: FMOD_RESULT;
705 begin
706 if e_SoundsArray[FID].nRefs >= gMaxSimSounds then
707 begin
708 Result := True;
709 Exit;
710 end;
712 Result := False;
714 if FID = NO_SOUND_ID then
715 Exit;
717 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
718 e_SoundsArray[FID].Sound, False, FChannel);
719 if res <> FMOD_OK then
720 begin
721 FChannel := nil;
722 Exit;
723 end;
725 res := FMOD_Channel_SetPosition(FChannel, aPos, FMOD_TIMEUNIT_MS);
726 if res <> FMOD_OK then
727 begin
728 FPosition := 0;
729 end
730 else
731 FPosition := aPos;
733 res := FMOD_Channel_SetPan(FChannel, Pan);
734 if res <> FMOD_OK then
735 begin
736 end;
738 res := FMOD_Channel_SetVolume(FChannel, Volume);
739 if res <> FMOD_OK then
740 begin
741 end;
743 res := FMOD_Channel_SetCallback(FChannel, Channel_Callback);
744 if res <> FMOD_OK then
745 begin
746 end;
748 if SoundMuted then
749 begin
750 res := FMOD_Channel_SetMute(FChannel, True);
751 if res <> FMOD_OK then
752 begin
753 end;
754 end;
756 Inc(e_SoundsArray[FID].nRefs);
757 Result := True;
758 end;
760 procedure TBasicSound.SetID(ID: DWORD);
761 begin
762 FreeSound();
763 FID := ID;
764 FLoop := e_SoundsArray[ID].Loop;
765 end;
767 function TBasicSound.IsPlaying(): Boolean;
768 var
769 res: FMOD_RESULT;
770 b: LongBool;
772 begin
773 Result := False;
775 if FChannel = nil then
776 Exit;
778 res := FMOD_Channel_IsPlaying(FChannel, b);
779 if res <> FMOD_OK then
780 begin
781 Exit;
782 end;
784 Result := b;
785 end;
787 procedure TBasicSound.Stop();
788 var
789 res: FMOD_RESULT;
791 begin
792 if FChannel = nil then
793 Exit;
795 GetPosition();
797 res := FMOD_Channel_Stop(FChannel);
798 if res <> FMOD_OK then
799 begin
800 end;
802 FChannel := nil;
803 end;
805 function TBasicSound.IsPaused(): Boolean;
806 var
807 res: FMOD_RESULT;
808 b: LongBool;
810 begin
811 Result := False;
813 if FChannel = nil then
814 Exit;
816 res := FMOD_Channel_GetPaused(FChannel, b);
817 if res <> FMOD_OK then
818 begin
819 Exit;
820 end;
822 Result := b;
823 end;
825 procedure TBasicSound.Pause(Enable: Boolean);
826 var
827 res: FMOD_RESULT;
829 begin
830 if FChannel = nil then
831 Exit;
833 res := FMOD_Channel_SetPaused(FChannel, Enable);
834 if res <> FMOD_OK then
835 begin
836 end;
838 if Enable then
839 begin
840 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
841 if res <> FMOD_OK then
842 begin
843 end;
844 end;
845 end;
847 function TBasicSound.GetVolume(): Single;
848 var
849 res: FMOD_RESULT;
850 vol: Single;
852 begin
853 Result := 0.0;
855 if FChannel = nil then
856 Exit;
858 res := FMOD_Channel_GetVolume(FChannel, vol);
859 if res <> FMOD_OK then
860 begin
861 Exit;
862 end;
864 Result := vol;
865 end;
867 procedure TBasicSound.SetVolume(Volume: Single);
868 var
869 res: FMOD_RESULT;
871 begin
872 if FChannel = nil then
873 Exit;
875 res := FMOD_Channel_SetVolume(FChannel, Volume);
876 if res <> FMOD_OK then
877 begin
878 end;
879 end;
881 function TBasicSound.GetPan(): Single;
882 var
883 res: FMOD_RESULT;
884 pan: Single;
886 begin
887 Result := 0.0;
889 if FChannel = nil then
890 Exit;
892 res := FMOD_Channel_GetPan(FChannel, pan);
893 if res <> FMOD_OK then
894 begin
895 Exit;
896 end;
898 Result := pan;
899 end;
901 procedure TBasicSound.SetPan(Pan: Single);
902 var
903 res: FMOD_RESULT;
905 begin
906 if FChannel = nil then
907 Exit;
909 res := FMOD_Channel_SetPan(FChannel, Pan);
910 if res <> FMOD_OK then
911 begin
912 end;
913 end;
915 function TBasicSound.IsMuted(): Boolean;
916 var
917 res: FMOD_RESULT;
918 b: LongBool;
920 begin
921 Result := False;
923 if FChannel = nil then
924 Exit;
926 res := FMOD_Channel_GetMute(FChannel, b);
927 if res <> FMOD_OK then
928 begin
929 Exit;
930 end;
932 Result := b;
933 end;
935 procedure TBasicSound.Mute(Enable: Boolean);
936 var
937 res: FMOD_RESULT;
939 begin
940 if FChannel = nil then
941 Exit;
943 res := FMOD_Channel_SetMute(FChannel, Enable);
944 if res <> FMOD_OK then
945 begin
946 end;
947 end;
949 function TBasicSound.GetPosition(): DWORD;
950 var
951 res: FMOD_RESULT;
953 begin
954 Result := 0;
956 if FChannel = nil then
957 Exit;
959 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
960 if res <> FMOD_OK then
961 begin
962 Exit;
963 end;
965 Result := FPosition;
966 end;
968 procedure TBasicSound.SetPosition(aPos: DWORD);
969 var
970 res: FMOD_RESULT;
972 begin
973 FPosition := aPos;
975 if FChannel = nil then
976 Exit;
978 res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
979 if res <> FMOD_OK then
980 begin
981 end;
982 end;
984 procedure TBasicSound.SetPriority(priority: Integer);
985 var
986 res: FMOD_RESULT;
988 begin
989 if (FChannel <> nil) and (FPriority <> priority) and
990 (priority >= 0) and (priority <= 256) then
991 begin
992 FPriority := priority;
993 res := FMOD_Channel_SetPriority(FChannel, priority);
994 if res <> FMOD_OK then
995 begin
996 end;
997 end;
998 end;
1000 end.