DEADSOFTWARE

restored fmod sound driver
[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 if e_SoundsArray[FID].nRefs >= gMaxSimSounds then
724 begin
725 Result := True;
726 Exit;
727 end;
729 Result := False;
731 if FID = NO_SOUND_ID then
732 Exit;
734 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
735 e_SoundsArray[FID].Sound, False, FChannel);
736 if res <> FMOD_OK then
737 begin
738 FChannel := nil;
739 Exit;
740 end;
742 res := FMOD_Channel_SetPosition(FChannel, aPos, FMOD_TIMEUNIT_MS);
743 if res <> FMOD_OK then
744 begin
745 FPosition := 0;
746 end
747 else
748 FPosition := aPos;
750 res := FMOD_Channel_SetPan(FChannel, Pan);
751 if res <> FMOD_OK then
752 begin
753 end;
755 res := FMOD_Channel_SetVolume(FChannel, Volume);
756 if res <> FMOD_OK then
757 begin
758 end;
760 res := FMOD_Channel_SetCallback(FChannel, Channel_Callback);
761 if res <> FMOD_OK then
762 begin
763 end;
765 if SoundMuted then
766 begin
767 res := FMOD_Channel_SetMute(FChannel, True);
768 if res <> FMOD_OK then
769 begin
770 end;
771 end;
773 Inc(e_SoundsArray[FID].nRefs);
774 Result := True;
775 end;
777 procedure TBasicSound.SetID(ID: DWORD);
778 begin
779 FreeSound();
780 FID := ID;
781 FMusic := e_SoundsArray[ID].isMusic;
782 end;
784 function TBasicSound.IsPlaying(): Boolean;
785 var
786 res: FMOD_RESULT;
787 b: LongBool;
789 begin
790 Result := False;
792 if FChannel = nil then
793 Exit;
795 res := FMOD_Channel_IsPlaying(FChannel, b);
796 if res <> FMOD_OK then
797 begin
798 Exit;
799 end;
801 Result := b;
802 end;
804 procedure TBasicSound.Stop();
805 var
806 res: FMOD_RESULT;
808 begin
809 if FChannel = nil then
810 Exit;
812 GetPosition();
814 res := FMOD_Channel_Stop(FChannel);
815 if res <> FMOD_OK then
816 begin
817 end;
819 FChannel := nil;
820 end;
822 function TBasicSound.IsPaused(): Boolean;
823 var
824 res: FMOD_RESULT;
825 b: LongBool;
827 begin
828 Result := False;
830 if FChannel = nil then
831 Exit;
833 res := FMOD_Channel_GetPaused(FChannel, b);
834 if res <> FMOD_OK then
835 begin
836 Exit;
837 end;
839 Result := b;
840 end;
842 procedure TBasicSound.Pause(Enable: Boolean);
843 var
844 res: FMOD_RESULT;
846 begin
847 if FChannel = nil then
848 Exit;
850 res := FMOD_Channel_SetPaused(FChannel, Enable);
851 if res <> FMOD_OK then
852 begin
853 end;
855 if Enable then
856 begin
857 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
858 if res <> FMOD_OK then
859 begin
860 end;
861 end;
862 end;
864 function TBasicSound.GetVolume(): Single;
865 var
866 res: FMOD_RESULT;
867 vol: Single;
869 begin
870 Result := 0.0;
872 if FChannel = nil then
873 Exit;
875 res := FMOD_Channel_GetVolume(FChannel, vol);
876 if res <> FMOD_OK then
877 begin
878 Exit;
879 end;
881 Result := vol;
882 end;
884 procedure TBasicSound.SetVolume(Volume: Single);
885 var
886 res: FMOD_RESULT;
888 begin
889 if FChannel = nil then
890 Exit;
892 res := FMOD_Channel_SetVolume(FChannel, Volume);
893 if res <> FMOD_OK then
894 begin
895 end;
896 end;
898 function TBasicSound.GetPan(): Single;
899 var
900 res: FMOD_RESULT;
901 pan: Single;
903 begin
904 Result := 0.0;
906 if FChannel = nil then
907 Exit;
909 res := FMOD_Channel_GetPan(FChannel, pan);
910 if res <> FMOD_OK then
911 begin
912 Exit;
913 end;
915 Result := pan;
916 end;
918 procedure TBasicSound.SetPan(Pan: Single);
919 var
920 res: FMOD_RESULT;
922 begin
923 if FChannel = nil then
924 Exit;
926 res := FMOD_Channel_SetPan(FChannel, Pan);
927 if res <> FMOD_OK then
928 begin
929 end;
930 end;
932 function TBasicSound.IsMuted(): Boolean;
933 var
934 res: FMOD_RESULT;
935 b: LongBool;
937 begin
938 Result := False;
940 if FChannel = nil then
941 Exit;
943 res := FMOD_Channel_GetMute(FChannel, b);
944 if res <> FMOD_OK then
945 begin
946 Exit;
947 end;
949 Result := b;
950 end;
952 procedure TBasicSound.Mute(Enable: Boolean);
953 var
954 res: FMOD_RESULT;
956 begin
957 if FChannel = nil then
958 Exit;
960 res := FMOD_Channel_SetMute(FChannel, Enable);
961 if res <> FMOD_OK then
962 begin
963 end;
964 end;
966 function TBasicSound.GetPosition(): DWORD;
967 var
968 res: FMOD_RESULT;
970 begin
971 Result := 0;
973 if FChannel = nil then
974 Exit;
976 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
977 if res <> FMOD_OK then
978 begin
979 Exit;
980 end;
982 Result := FPosition;
983 end;
985 procedure TBasicSound.SetPosition(aPos: DWORD);
986 var
987 res: FMOD_RESULT;
989 begin
990 FPosition := aPos;
992 if FChannel = nil then
993 Exit;
995 res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
996 if res <> FMOD_OK then
997 begin
998 end;
999 end;
1001 procedure TBasicSound.SetPriority(priority: Integer);
1002 var
1003 res: FMOD_RESULT;
1005 begin
1006 if (FChannel <> nil) and (FPriority <> priority) and
1007 (priority >= 0) and (priority <= 256) then
1008 begin
1009 FPriority := priority;
1010 res := FMOD_Channel_SetPriority(FChannel, priority);
1011 if res <> FMOD_OK then
1012 begin
1013 end;
1014 end;
1015 end;
1017 end.