DEADSOFTWARE

123db2c84975599d4e71bd124b1cee77371b1fb4
[d2df-sdl.git] / src / engine / e_sound_fmod.inc
1 interface
3 uses
4 fmod,
5 fmodtypes,
6 fmoderrors,
7 e_log,
8 SysUtils;
10 type
11 TSoundRec = record
12 Data: Pointer;
13 Sound: FMOD_SOUND;
14 isMusic: Boolean;
15 nRefs: Integer;
16 end;
18 TBasicSound = class (TObject)
19 private
20 FChannel: FMOD_CHANNEL;
22 protected
23 FID: DWORD;
24 FMusic: Boolean;
25 FPosition: DWORD;
26 FPriority: Integer;
28 function RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
30 public
31 constructor Create();
32 destructor Destroy(); override;
33 procedure SetID(ID: DWORD);
34 procedure FreeSound();
35 function IsPlaying(): Boolean;
36 procedure Stop();
37 function IsPaused(): Boolean;
38 procedure Pause(Enable: Boolean);
39 function GetVolume(): Single;
40 procedure SetVolume(Volume: Single);
41 function GetPan(): Single;
42 procedure SetPan(Pan: Single);
43 function IsMuted(): Boolean;
44 procedure Mute(Enable: Boolean);
45 function GetPosition(): DWORD;
46 procedure SetPosition(aPos: DWORD);
47 procedure SetPriority(priority: Integer);
48 end;
50 const
51 NO_SOUND_ID = DWORD(-1);
53 function e_InitSoundSystem(): Boolean;
55 function e_LoadSound(FileName: string; var ID: DWORD; bLoop: Boolean): Boolean;
56 function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
58 function e_PlaySound(ID: DWORD): Integer;
59 function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
60 function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
61 function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
63 procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
64 procedure e_MuteChannels(Enable: Boolean);
65 procedure e_StopChannels();
67 procedure e_DeleteSound(ID: DWORD);
68 procedure e_RemoveAllSounds();
69 procedure e_ReleaseSoundSystem();
70 procedure e_SoundUpdate();
72 var
73 e_SoundsArray: array of TSoundRec = nil;
75 implementation
77 uses
78 g_window, g_options, BinEditor;
80 const
81 N_CHANNELS = 512;
83 var
84 F_System: FMOD_SYSTEM = nil;
85 SoundMuted: Boolean = False;
88 function Channel_Callback(channel: FMOD_CHANNEL; callbacktype: FMOD_CHANNEL_CALLBACKTYPE;
89 commanddata1: Pointer; commanddata2: Pointer): FMOD_RESULT; {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF}
90 var
91 res: FMOD_RESULT;
92 sound: FMOD_SOUND;
93 ud: Pointer;
94 id: DWORD;
96 begin
97 res := FMOD_OK;
99 if callbacktype = FMOD_CHANNEL_CALLBACKTYPE_END then
100 begin
101 res := FMOD_Channel_GetCurrentSound(channel, sound);
102 if res = FMOD_OK then
103 begin
104 res := FMOD_Sound_GetUserData(sound, ud);
105 if res = FMOD_OK then
106 begin
107 id := DWORD(ud^);
108 if id < DWORD(Length(e_SoundsArray)) then
109 if e_SoundsArray[id].nRefs > 0 then
110 Dec(e_SoundsArray[id].nRefs);
111 end;
112 end;
113 end;
115 Result := res;
116 end;
118 function TryInitWithOutput(Output: FMOD_OUTPUTTYPE; OutputName: String): FMOD_RESULT;
119 begin
120 e_WriteLog('Trying with ' + OutputName + '...', MSG_WARNING);
121 Result := FMOD_System_SetOutput(F_System, Output);
122 if Result <> FMOD_OK then
123 begin
124 e_WriteLog('Error setting FMOD output to ' + OutputName + '!', MSG_WARNING);
125 e_WriteLog(FMOD_ErrorString(Result), MSG_WARNING);
126 Exit;
127 end;
128 Result := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
129 if Result <> FMOD_OK then
130 begin
131 e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
132 e_WriteLog(FMOD_ErrorString(Result), MSG_WARNING);
133 Exit;
134 end;
135 end;
137 function e_TrySS (Freq: Integer; forceNoSound: Boolean): Boolean;
138 var
139 res: FMOD_RESULT;
140 ver: Cardinal;
141 output: FMOD_OUTPUTTYPE;
142 drv: Integer;
144 begin
145 Result := False;
146 e_WriteLog(Format('Trying to initialize FMOD with %d', [Freq]), MSG_NOTIFY);
148 res := FMOD_System_Create(F_System);
149 if res <> FMOD_OK then
150 begin
151 e_WriteLog('Error creating FMOD system:', MSG_FATALERROR);
152 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
153 Exit;
154 end;
156 res := FMOD_System_GetVersion(F_System, ver);
157 if res <> FMOD_OK then
158 begin
159 e_WriteLog('Error getting FMOD version:', MSG_FATALERROR);
160 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
161 Exit;
162 end;
164 if ver < FMOD_VERSION then
165 begin
166 e_WriteLog('FMOD library version is too old! Need '+IntToStr(FMOD_VERSION), MSG_FATALERROR);
167 Exit;
168 end;
170 res := FMOD_System_SetSoftwareFormat(F_System, Freq, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
171 if res <> FMOD_OK then
172 begin
173 e_WriteLog('Error setting FMOD software format!', MSG_FATALERROR);
174 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
175 Exit;
176 end;
178 res := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
179 if res <> FMOD_OK then
180 begin
181 e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
182 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
184 {$IFDEF LINUX}
185 res := TryInitWithOutput(FMOD_OUTPUTTYPE_ALSA, 'OUTPUTTYPE_ALSA');
186 if res <> FMOD_OK then
187 res := TryInitWithOutput(FMOD_OUTPUTTYPE_OSS, 'OUTPUTTYPE_OSS');
188 {$ENDIF}
189 if (res <> FMOD_OK) and not forceNoSound then Exit;
190 if res <> FMOD_OK then
191 res := TryInitWithOutput(FMOD_OUTPUTTYPE_NOSOUND, 'OUTPUTTYPE_NOSOUND');
192 if res <> FMOD_OK then
193 begin
194 e_WriteLog('FMOD: Giving up, can''t init any output.', MSG_FATALERROR);
195 Exit;
196 end;
197 end;
199 res := FMOD_System_GetOutput(F_System, output);
200 if res <> FMOD_OK then
201 e_WriteLog('Error getting FMOD output!', MSG_WARNING)
202 else
203 case output of
204 FMOD_OUTPUTTYPE_NOSOUND: e_WriteLog('FMOD Output Method: NOSOUND', MSG_NOTIFY);
205 FMOD_OUTPUTTYPE_NOSOUND_NRT: e_WriteLog('FMOD Output Method: NOSOUND_NRT', MSG_NOTIFY);
206 FMOD_OUTPUTTYPE_DSOUND: e_WriteLog('FMOD Output Method: DSOUND', MSG_NOTIFY);
207 FMOD_OUTPUTTYPE_WINMM: e_WriteLog('FMOD Output Method: WINMM', MSG_NOTIFY);
208 FMOD_OUTPUTTYPE_OPENAL: e_WriteLog('FMOD Output Method: OPENAL', MSG_NOTIFY);
209 FMOD_OUTPUTTYPE_WASAPI: e_WriteLog('FMOD Output Method: WASAPI', MSG_NOTIFY);
210 FMOD_OUTPUTTYPE_ASIO: e_WriteLog('FMOD Output Method: ASIO', MSG_NOTIFY);
211 FMOD_OUTPUTTYPE_OSS: e_WriteLog('FMOD Output Method: OSS', MSG_NOTIFY);
212 FMOD_OUTPUTTYPE_ALSA: e_Writelog('FMOD Output Method: ALSA', MSG_NOTIFY);
213 else e_WriteLog('FMOD Output Method: Unknown', MSG_NOTIFY);
214 end;
216 res := FMOD_System_GetDriver(F_System, drv);
217 if res <> FMOD_OK then
218 e_WriteLog('Error getting FMOD driver!', MSG_WARNING)
219 else
220 e_WriteLog('FMOD driver id: '+IntToStr(drv), MSG_NOTIFY);
222 Result := True;
223 end;
225 function e_InitSoundSystem(): Boolean;
226 begin
227 Result := e_TrySS(48000, False);
228 if not Result then Result := e_TrySS(44100, True);
229 end;
231 function FindESound(): DWORD;
232 var
233 i: Integer;
235 begin
236 if e_SoundsArray <> nil then
237 for i := 0 to High(e_SoundsArray) do
238 if e_SoundsArray[i].Sound = nil then
239 begin
240 Result := i;
241 Exit;
242 end;
244 if e_SoundsArray = nil then
245 begin
246 SetLength(e_SoundsArray, 16);
247 Result := 0;
248 end
249 else
250 begin
251 Result := High(e_SoundsArray) + 1;
252 SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
253 end;
254 end;
256 function e_LoadSound(FileName: String; var ID: DWORD; bLoop: Boolean): Boolean;
257 var
258 find_id: DWORD;
259 res: FMOD_RESULT;
260 bt: Cardinal;
261 ud: Pointer;
263 begin
264 Result := False;
266 e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
268 find_id := FindESound();
270 if bLoop then
271 bt := FMOD_LOOP_NORMAL
272 else
273 bt := FMOD_LOOP_OFF;
275 if not bLoop then
276 res := FMOD_System_CreateSound(F_System, PAnsiChar(FileName),
277 bt + FMOD_2D + FMOD_HARDWARE,
278 nil, e_SoundsArray[find_id].Sound)
279 else
280 res := FMOD_System_CreateStream(F_System, PAnsiChar(FileName),
281 bt + FMOD_2D + FMOD_HARDWARE,
282 nil, e_SoundsArray[find_id].Sound);
283 if res <> FMOD_OK then
284 begin
285 e_SoundsArray[find_id].Sound := nil;
286 Exit;
287 end;
289 GetMem(ud, SizeOf(DWORD));
290 DWORD(ud^) := find_id;
291 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
292 if res <> FMOD_OK then
293 begin
294 e_SoundsArray[find_id].Sound := nil;
295 Exit;
296 end;
298 e_SoundsArray[find_id].Data := nil;
299 e_SoundsArray[find_id].isMusic := bLoop;
300 e_SoundsArray[find_id].nRefs := 0;
302 ID := find_id;
304 Result := True;
305 end;
307 function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
308 var
309 find_id: DWORD;
310 res: FMOD_RESULT;
311 sz: Integer;
312 bt: Cardinal;
313 soundExInfo: FMOD_CREATESOUNDEXINFO;
314 ud: Pointer;
316 begin
317 Result := False;
319 find_id := FindESound();
321 sz := SizeOf(FMOD_CREATESOUNDEXINFO);
322 FillMemory(@soundExInfo, sz, 0);
323 soundExInfo.cbsize := sz;
324 soundExInfo.length := Length;
326 if bLoop then
327 bt := FMOD_LOOP_NORMAL
328 else
329 bt := FMOD_LOOP_OFF;
331 if not bLoop then
332 res := FMOD_System_CreateSound(F_System, pData,
333 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
334 @soundExInfo, e_SoundsArray[find_id].Sound)
335 else
336 res := FMOD_System_CreateStream(F_System, pData,
337 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
338 @soundExInfo, e_SoundsArray[find_id].Sound);
339 if res <> FMOD_OK then
340 begin
341 e_SoundsArray[find_id].Sound := nil;
342 Exit;
343 end;
345 GetMem(ud, SizeOf(DWORD));
346 DWORD(ud^) := find_id;
347 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
348 if res <> FMOD_OK then
349 begin
350 e_SoundsArray[find_id].Sound := nil;
351 Exit;
352 end;
354 e_SoundsArray[find_id].Data := pData;
355 e_SoundsArray[find_id].isMusic := bLoop;
356 e_SoundsArray[find_id].nRefs := 0;
358 ID := find_id;
360 Result := True;
361 end;
363 function e_PlaySound(ID: DWORD): Integer;
364 var
365 res: FMOD_RESULT;
366 Chan: FMOD_CHANNEL;
368 begin
369 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
370 begin
371 Result := 0;
372 Exit;
373 end;
375 Result := -1;
377 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
378 e_SoundsArray[ID].Sound, False, Chan);
379 if res <> FMOD_OK then
380 begin
381 Exit;
382 end;
384 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
385 if res <> FMOD_OK then
386 begin
387 end;
389 if SoundMuted then
390 begin
391 res := FMOD_Channel_SetMute(Chan, True);
392 if res <> FMOD_OK then
393 begin
394 end;
395 end;
397 Inc(e_SoundsArray[ID].nRefs);
398 Result := 0;
399 end;
401 function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
402 var
403 res: FMOD_RESULT;
404 Chan: FMOD_CHANNEL;
406 begin
407 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
408 begin
409 Result := 0;
410 Exit;
411 end;
413 Result := -1;
415 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
416 e_SoundsArray[ID].Sound, False, Chan);
417 if res <> FMOD_OK then
418 begin
419 Exit;
420 end;
422 res := FMOD_Channel_SetPan(Chan, Pan);
423 if res <> FMOD_OK then
424 begin
425 end;
427 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
428 if res <> FMOD_OK then
429 begin
430 end;
432 if SoundMuted then
433 begin
434 res := FMOD_Channel_SetMute(Chan, True);
435 if res <> FMOD_OK then
436 begin
437 end;
438 end;
440 Inc(e_SoundsArray[ID].nRefs);
441 Result := 0;
442 end;
444 function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
445 var
446 res: FMOD_RESULT;
447 Chan: FMOD_CHANNEL;
449 begin
450 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
451 begin
452 Result := 0;
453 Exit;
454 end;
456 Result := -1;
458 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
459 e_SoundsArray[ID].Sound, False, Chan);
460 if res <> FMOD_OK then
461 begin
462 Exit;
463 end;
465 res := FMOD_Channel_SetVolume(Chan, Volume);
466 if res <> FMOD_OK then
467 begin
468 end;
470 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
471 if res <> FMOD_OK then
472 begin
473 end;
475 if SoundMuted then
476 begin
477 res := FMOD_Channel_SetMute(Chan, True);
478 if res <> FMOD_OK then
479 begin
480 end;
481 end;
483 Inc(e_SoundsArray[ID].nRefs);
484 Result := 0;
485 end;
487 function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
488 var
489 res: FMOD_RESULT;
490 Chan: FMOD_CHANNEL;
492 begin
493 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
494 begin
495 Result := 0;
496 Exit;
497 end;
499 Result := -1;
501 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
502 e_SoundsArray[ID].Sound, False, Chan);
503 if res <> FMOD_OK then
504 begin
505 Exit;
506 end;
508 res := FMOD_Channel_SetPan(Chan, Pan);
509 if res <> FMOD_OK then
510 begin
511 end;
513 res := FMOD_Channel_SetVolume(Chan, Volume);
514 if res <> FMOD_OK then
515 begin
516 end;
518 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
519 if res <> FMOD_OK then
520 begin
521 end;
523 if SoundMuted then
524 begin
525 res := FMOD_Channel_SetMute(Chan, True);
526 if res <> FMOD_OK then
527 begin
528 end;
529 end;
531 Inc(e_SoundsArray[ID].nRefs);
532 Result := 0;
533 end;
535 procedure e_DeleteSound(ID: DWORD);
536 var
537 res: FMOD_RESULT;
538 ud: Pointer;
540 begin
541 if e_SoundsArray[ID].Sound = nil then
542 Exit;
544 if e_SoundsArray[ID].Data <> nil then
545 FreeMem(e_SoundsArray[ID].Data);
547 res := FMOD_Sound_GetUserData(e_SoundsArray[ID].Sound, ud);
548 if res = FMOD_OK then
549 begin
550 FreeMem(ud);
551 end;
553 res := FMOD_Sound_Release(e_SoundsArray[ID].Sound);
554 if res <> FMOD_OK then
555 begin
556 e_WriteLog('Error releasing sound:', MSG_WARNING);
557 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
558 end;
560 e_SoundsArray[ID].Sound := nil;
561 e_SoundsArray[ID].Data := nil;
562 end;
564 procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
565 var
566 res: FMOD_RESULT;
567 i: Integer;
568 Chan: FMOD_CHANNEL;
569 vol: Single;
571 begin
572 for i := 0 to N_CHANNELS-1 do
573 begin
574 Chan := nil;
575 res := FMOD_System_GetChannel(F_System, i, Chan);
577 if (res = FMOD_OK) and (Chan <> nil) then
578 begin
579 res := FMOD_Channel_GetVolume(Chan, vol);
581 if res = FMOD_OK then
582 begin
583 if setMode then
584 vol := SoundMod
585 else
586 vol := vol * SoundMod;
588 res := FMOD_Channel_SetVolume(Chan, vol);
590 if res <> FMOD_OK then
591 begin
592 end;
593 end;
594 end;
595 end;
596 end;
598 procedure e_MuteChannels(Enable: Boolean);
599 var
600 res: FMOD_RESULT;
601 i: Integer;
602 Chan: FMOD_CHANNEL;
604 begin
605 if Enable = SoundMuted then
606 Exit;
608 SoundMuted := Enable;
610 for i := 0 to N_CHANNELS-1 do
611 begin
612 Chan := nil;
613 res := FMOD_System_GetChannel(F_System, i, Chan);
615 if (res = FMOD_OK) and (Chan <> nil) then
616 begin
617 res := FMOD_Channel_SetMute(Chan, Enable);
619 if res <> FMOD_OK then
620 begin
621 end;
622 end;
623 end;
624 end;
626 procedure e_StopChannels();
627 var
628 res: FMOD_RESULT;
629 i: Integer;
630 Chan: FMOD_CHANNEL;
632 begin
633 for i := 0 to N_CHANNELS-1 do
634 begin
635 Chan := nil;
636 res := FMOD_System_GetChannel(F_System, i, Chan);
638 if (res = FMOD_OK) and (Chan <> nil) then
639 begin
640 res := FMOD_Channel_Stop(Chan);
642 if res <> FMOD_OK then
643 begin
644 end;
645 end;
646 end;
647 end;
649 procedure e_RemoveAllSounds();
650 var
651 i: Integer;
653 begin
654 for i := 0 to High(e_SoundsArray) do
655 if e_SoundsArray[i].Sound <> nil then
656 e_DeleteSound(i);
658 SetLength(e_SoundsArray, 0);
659 e_SoundsArray := nil;
660 end;
662 procedure e_ReleaseSoundSystem();
663 var
664 res: FMOD_RESULT;
666 begin
667 e_RemoveAllSounds();
669 res := FMOD_System_Close(F_System);
670 if res <> FMOD_OK then
671 begin
672 e_WriteLog('Error closing FMOD system!', MSG_FATALERROR);
673 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
674 Exit;
675 end;
677 res := FMOD_System_Release(F_System);
678 if res <> FMOD_OK then
679 begin
680 e_WriteLog('Error releasing FMOD system!', MSG_FATALERROR);
681 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
682 end;
683 end;
685 procedure e_SoundUpdate();
686 begin
687 FMOD_System_Update(F_System);
688 end;
690 { TBasicSound: }
692 constructor TBasicSound.Create();
693 begin
694 FID := NO_SOUND_ID;
695 FMusic := False;
696 FChannel := nil;
697 FPosition := 0;
698 FPriority := 128;
699 end;
701 destructor TBasicSound.Destroy();
702 begin
703 FreeSound();
704 inherited;
705 end;
707 procedure TBasicSound.FreeSound();
708 begin
709 if FID = NO_SOUND_ID then
710 Exit;
712 Stop();
713 FID := NO_SOUND_ID;
714 FMusic := False;
715 FPosition := 0;
716 end;
718 function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
719 var
720 res: FMOD_RESULT;
722 begin
723 Result := False;
724 if FID = NO_SOUND_ID then Exit;
726 if e_SoundsArray[FID].nRefs >= gMaxSimSounds then
727 begin
728 Result := True;
729 Exit;
730 end;
732 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
733 e_SoundsArray[FID].Sound, False, FChannel);
734 if res <> FMOD_OK then
735 begin
736 FChannel := nil;
737 Exit;
738 end;
740 res := FMOD_Channel_SetPosition(FChannel, aPos, FMOD_TIMEUNIT_MS);
741 if res <> FMOD_OK then
742 begin
743 FPosition := 0;
744 end
745 else
746 FPosition := aPos;
748 res := FMOD_Channel_SetPan(FChannel, Pan);
749 if res <> FMOD_OK then
750 begin
751 end;
753 res := FMOD_Channel_SetVolume(FChannel, Volume);
754 if res <> FMOD_OK then
755 begin
756 end;
758 res := FMOD_Channel_SetCallback(FChannel, Channel_Callback);
759 if res <> FMOD_OK then
760 begin
761 end;
763 if SoundMuted then
764 begin
765 res := FMOD_Channel_SetMute(FChannel, True);
766 if res <> FMOD_OK then
767 begin
768 end;
769 end;
771 Inc(e_SoundsArray[FID].nRefs);
772 Result := True;
773 end;
775 procedure TBasicSound.SetID(ID: DWORD);
776 begin
777 FreeSound();
778 FID := ID;
779 FMusic := e_SoundsArray[ID].isMusic;
780 end;
782 function TBasicSound.IsPlaying(): Boolean;
783 var
784 res: FMOD_RESULT;
785 b: LongBool;
787 begin
788 Result := False;
790 if FChannel = nil then
791 Exit;
793 res := FMOD_Channel_IsPlaying(FChannel, b);
794 if res <> FMOD_OK then
795 begin
796 Exit;
797 end;
799 Result := b;
800 end;
802 procedure TBasicSound.Stop();
803 var
804 res: FMOD_RESULT;
806 begin
807 if FChannel = nil then
808 Exit;
810 GetPosition();
812 res := FMOD_Channel_Stop(FChannel);
813 if res <> FMOD_OK then
814 begin
815 end;
817 FChannel := nil;
818 end;
820 function TBasicSound.IsPaused(): Boolean;
821 var
822 res: FMOD_RESULT;
823 b: LongBool;
825 begin
826 Result := False;
828 if FChannel = nil then
829 Exit;
831 res := FMOD_Channel_GetPaused(FChannel, b);
832 if res <> FMOD_OK then
833 begin
834 Exit;
835 end;
837 Result := b;
838 end;
840 procedure TBasicSound.Pause(Enable: Boolean);
841 var
842 res: FMOD_RESULT;
844 begin
845 if FChannel = nil then
846 Exit;
848 res := FMOD_Channel_SetPaused(FChannel, Enable);
849 if res <> FMOD_OK then
850 begin
851 end;
853 if Enable then
854 begin
855 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
856 if res <> FMOD_OK then
857 begin
858 end;
859 end;
860 end;
862 function TBasicSound.GetVolume(): Single;
863 var
864 res: FMOD_RESULT;
865 vol: Single;
867 begin
868 Result := 0.0;
870 if FChannel = nil then
871 Exit;
873 res := FMOD_Channel_GetVolume(FChannel, vol);
874 if res <> FMOD_OK then
875 begin
876 Exit;
877 end;
879 Result := vol;
880 end;
882 procedure TBasicSound.SetVolume(Volume: Single);
883 var
884 res: FMOD_RESULT;
886 begin
887 if FChannel = nil then
888 Exit;
890 res := FMOD_Channel_SetVolume(FChannel, Volume);
891 if res <> FMOD_OK then
892 begin
893 end;
894 end;
896 function TBasicSound.GetPan(): Single;
897 var
898 res: FMOD_RESULT;
899 pan: Single;
901 begin
902 Result := 0.0;
904 if FChannel = nil then
905 Exit;
907 res := FMOD_Channel_GetPan(FChannel, pan);
908 if res <> FMOD_OK then
909 begin
910 Exit;
911 end;
913 Result := pan;
914 end;
916 procedure TBasicSound.SetPan(Pan: Single);
917 var
918 res: FMOD_RESULT;
920 begin
921 if FChannel = nil then
922 Exit;
924 res := FMOD_Channel_SetPan(FChannel, Pan);
925 if res <> FMOD_OK then
926 begin
927 end;
928 end;
930 function TBasicSound.IsMuted(): Boolean;
931 var
932 res: FMOD_RESULT;
933 b: LongBool;
935 begin
936 Result := False;
938 if FChannel = nil then
939 Exit;
941 res := FMOD_Channel_GetMute(FChannel, b);
942 if res <> FMOD_OK then
943 begin
944 Exit;
945 end;
947 Result := b;
948 end;
950 procedure TBasicSound.Mute(Enable: Boolean);
951 var
952 res: FMOD_RESULT;
954 begin
955 if FChannel = nil then
956 Exit;
958 res := FMOD_Channel_SetMute(FChannel, Enable);
959 if res <> FMOD_OK then
960 begin
961 end;
962 end;
964 function TBasicSound.GetPosition(): DWORD;
965 var
966 res: FMOD_RESULT;
968 begin
969 Result := 0;
971 if FChannel = nil then
972 Exit;
974 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
975 if res <> FMOD_OK then
976 begin
977 Exit;
978 end;
980 Result := FPosition;
981 end;
983 procedure TBasicSound.SetPosition(aPos: DWORD);
984 var
985 res: FMOD_RESULT;
987 begin
988 FPosition := aPos;
990 if FChannel = nil then
991 Exit;
993 res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
994 if res <> FMOD_OK then
995 begin
996 end;
997 end;
999 procedure TBasicSound.SetPriority(priority: Integer);
1000 var
1001 res: FMOD_RESULT;
1003 begin
1004 if (FChannel <> nil) and (FPriority <> priority) and
1005 (priority >= 0) and (priority <= 256) then
1006 begin
1007 FPriority := priority;
1008 res := FMOD_Channel_SetPriority(FChannel, priority);
1009 if res <> FMOD_OK then
1010 begin
1011 end;
1012 end;
1013 end;
1015 end.