DEADSOFTWARE

acfd069c2ed1c7100042e3946c4458fe1486c3d7
[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(NoOutput: Boolean = False): 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: Integer): 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 if forceNoSound = 2 then
179 begin
180 res := TryInitWithOutput(FMOD_OUTPUTTYPE_NOSOUND, 'OUTPUTTYPE_NOSOUND');
181 if res <> FMOD_OK then
182 begin
183 e_WriteLog('FMOD: Giving up, can''t init with NOSOUND.', MSG_FATALERROR);
184 Exit;
185 end;
186 end
187 else
188 begin
189 res := FMOD_System_Init(F_System, N_CHANNELS, FMOD_INIT_NORMAL, nil);
190 if res <> FMOD_OK then
191 begin
192 e_WriteLog('Error initializing FMOD system!', MSG_WARNING);
193 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
195 {$IFDEF LINUX}
196 res := TryInitWithOutput(FMOD_OUTPUTTYPE_ALSA, 'OUTPUTTYPE_ALSA');
197 if res <> FMOD_OK then
198 res := TryInitWithOutput(FMOD_OUTPUTTYPE_OSS, 'OUTPUTTYPE_OSS');
199 {$ENDIF}
200 if (res <> FMOD_OK) and (forceNoSound <> 1) then Exit;
201 if res <> FMOD_OK then
202 res := TryInitWithOutput(FMOD_OUTPUTTYPE_NOSOUND, 'OUTPUTTYPE_NOSOUND');
203 if res <> FMOD_OK then
204 begin
205 e_WriteLog('FMOD: Giving up, can''t init any output.', MSG_FATALERROR);
206 Exit;
207 end;
208 end;
209 end;
211 res := FMOD_System_GetOutput(F_System, output);
212 if res <> FMOD_OK then
213 e_WriteLog('Error getting FMOD output!', MSG_WARNING)
214 else
215 case output of
216 FMOD_OUTPUTTYPE_NOSOUND: e_WriteLog('FMOD Output Method: NOSOUND', MSG_NOTIFY);
217 FMOD_OUTPUTTYPE_NOSOUND_NRT: e_WriteLog('FMOD Output Method: NOSOUND_NRT', MSG_NOTIFY);
218 FMOD_OUTPUTTYPE_DSOUND: e_WriteLog('FMOD Output Method: DSOUND', MSG_NOTIFY);
219 FMOD_OUTPUTTYPE_WINMM: e_WriteLog('FMOD Output Method: WINMM', MSG_NOTIFY);
220 FMOD_OUTPUTTYPE_OPENAL: e_WriteLog('FMOD Output Method: OPENAL', MSG_NOTIFY);
221 FMOD_OUTPUTTYPE_WASAPI: e_WriteLog('FMOD Output Method: WASAPI', MSG_NOTIFY);
222 FMOD_OUTPUTTYPE_ASIO: e_WriteLog('FMOD Output Method: ASIO', MSG_NOTIFY);
223 FMOD_OUTPUTTYPE_OSS: e_WriteLog('FMOD Output Method: OSS', MSG_NOTIFY);
224 FMOD_OUTPUTTYPE_ALSA: e_Writelog('FMOD Output Method: ALSA', MSG_NOTIFY);
225 else e_WriteLog('FMOD Output Method: Unknown', MSG_NOTIFY);
226 end;
228 res := FMOD_System_GetDriver(F_System, drv);
229 if res <> FMOD_OK then
230 e_WriteLog('Error getting FMOD driver!', MSG_WARNING)
231 else
232 e_WriteLog('FMOD driver id: '+IntToStr(drv), MSG_NOTIFY);
234 Result := True;
235 end;
237 function e_InitSoundSystem(NoOutput: Boolean = False): Boolean;
238 begin
239 if NoOutput then
240 begin
241 Result := e_TrySS(48000, 2);
242 Exit;
243 end;
244 Result := e_TrySS(48000, 0);
245 if not Result then Result := e_TrySS(44100, 1);
246 end;
248 function FindESound(): DWORD;
249 var
250 i: Integer;
252 begin
253 if e_SoundsArray <> nil then
254 for i := 0 to High(e_SoundsArray) do
255 if e_SoundsArray[i].Sound = nil then
256 begin
257 Result := i;
258 Exit;
259 end;
261 if e_SoundsArray = nil then
262 begin
263 SetLength(e_SoundsArray, 16);
264 Result := 0;
265 end
266 else
267 begin
268 Result := High(e_SoundsArray) + 1;
269 SetLength(e_SoundsArray, Length(e_SoundsArray) + 16);
270 end;
271 end;
273 function e_LoadSound(FileName: String; var ID: DWORD; bLoop: Boolean): Boolean;
274 var
275 find_id: DWORD;
276 res: FMOD_RESULT;
277 bt: Cardinal;
278 ud: Pointer;
280 begin
281 Result := False;
283 e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY);
285 find_id := FindESound();
287 if bLoop then
288 bt := FMOD_LOOP_NORMAL
289 else
290 bt := FMOD_LOOP_OFF;
292 if not bLoop then
293 res := FMOD_System_CreateSound(F_System, PAnsiChar(FileName),
294 bt + FMOD_2D + FMOD_HARDWARE,
295 nil, e_SoundsArray[find_id].Sound)
296 else
297 res := FMOD_System_CreateStream(F_System, PAnsiChar(FileName),
298 bt + FMOD_2D + FMOD_HARDWARE,
299 nil, e_SoundsArray[find_id].Sound);
300 if res <> FMOD_OK then
301 begin
302 e_SoundsArray[find_id].Sound := nil;
303 Exit;
304 end;
306 GetMem(ud, SizeOf(DWORD));
307 DWORD(ud^) := find_id;
308 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
309 if res <> FMOD_OK then
310 begin
311 e_SoundsArray[find_id].Sound := nil;
312 Exit;
313 end;
315 e_SoundsArray[find_id].Data := nil;
316 e_SoundsArray[find_id].isMusic := bLoop;
317 e_SoundsArray[find_id].nRefs := 0;
319 ID := find_id;
321 Result := True;
322 end;
324 function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; bLoop: Boolean): Boolean;
325 var
326 find_id: DWORD;
327 res: FMOD_RESULT;
328 sz: Integer;
329 bt: Cardinal;
330 soundExInfo: FMOD_CREATESOUNDEXINFO;
331 ud: Pointer;
333 begin
334 Result := False;
336 find_id := FindESound();
338 sz := SizeOf(FMOD_CREATESOUNDEXINFO);
339 FillMemory(@soundExInfo, sz, 0);
340 soundExInfo.cbsize := sz;
341 soundExInfo.length := Length;
343 if bLoop then
344 bt := FMOD_LOOP_NORMAL
345 else
346 bt := FMOD_LOOP_OFF;
348 if not bLoop then
349 res := FMOD_System_CreateSound(F_System, pData,
350 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
351 @soundExInfo, e_SoundsArray[find_id].Sound)
352 else
353 res := FMOD_System_CreateStream(F_System, pData,
354 bt + FMOD_2D + FMOD_HARDWARE + FMOD_OPENMEMORY,
355 @soundExInfo, e_SoundsArray[find_id].Sound);
356 if res <> FMOD_OK then
357 begin
358 e_SoundsArray[find_id].Sound := nil;
359 Exit;
360 end;
362 GetMem(ud, SizeOf(DWORD));
363 DWORD(ud^) := find_id;
364 res := FMOD_Sound_SetUserData(e_SoundsArray[find_id].Sound, ud);
365 if res <> FMOD_OK then
366 begin
367 e_SoundsArray[find_id].Sound := nil;
368 Exit;
369 end;
371 e_SoundsArray[find_id].Data := pData;
372 e_SoundsArray[find_id].isMusic := bLoop;
373 e_SoundsArray[find_id].nRefs := 0;
375 ID := find_id;
377 Result := True;
378 end;
380 function e_PlaySound(ID: DWORD): Integer;
381 var
382 res: FMOD_RESULT;
383 Chan: FMOD_CHANNEL;
385 begin
386 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
387 begin
388 Result := 0;
389 Exit;
390 end;
392 Result := -1;
394 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
395 e_SoundsArray[ID].Sound, False, Chan);
396 if res <> FMOD_OK then
397 begin
398 Exit;
399 end;
401 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
402 if res <> FMOD_OK then
403 begin
404 end;
406 if SoundMuted then
407 begin
408 res := FMOD_Channel_SetMute(Chan, True);
409 if res <> FMOD_OK then
410 begin
411 end;
412 end;
414 Inc(e_SoundsArray[ID].nRefs);
415 Result := 0;
416 end;
418 function e_PlaySoundPan(ID: DWORD; Pan: Single): Integer;
419 var
420 res: FMOD_RESULT;
421 Chan: FMOD_CHANNEL;
423 begin
424 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
425 begin
426 Result := 0;
427 Exit;
428 end;
430 Result := -1;
432 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
433 e_SoundsArray[ID].Sound, False, Chan);
434 if res <> FMOD_OK then
435 begin
436 Exit;
437 end;
439 res := FMOD_Channel_SetPan(Chan, Pan);
440 if res <> FMOD_OK then
441 begin
442 end;
444 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
445 if res <> FMOD_OK then
446 begin
447 end;
449 if SoundMuted then
450 begin
451 res := FMOD_Channel_SetMute(Chan, True);
452 if res <> FMOD_OK then
453 begin
454 end;
455 end;
457 Inc(e_SoundsArray[ID].nRefs);
458 Result := 0;
459 end;
461 function e_PlaySoundVolume(ID: DWORD; Volume: Single): Integer;
462 var
463 res: FMOD_RESULT;
464 Chan: FMOD_CHANNEL;
466 begin
467 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
468 begin
469 Result := 0;
470 Exit;
471 end;
473 Result := -1;
475 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
476 e_SoundsArray[ID].Sound, False, Chan);
477 if res <> FMOD_OK then
478 begin
479 Exit;
480 end;
482 res := FMOD_Channel_SetVolume(Chan, Volume);
483 if res <> FMOD_OK then
484 begin
485 end;
487 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
488 if res <> FMOD_OK then
489 begin
490 end;
492 if SoundMuted then
493 begin
494 res := FMOD_Channel_SetMute(Chan, True);
495 if res <> FMOD_OK then
496 begin
497 end;
498 end;
500 Inc(e_SoundsArray[ID].nRefs);
501 Result := 0;
502 end;
504 function e_PlaySoundPanVolume(ID: DWORD; Pan, Volume: Single): Integer;
505 var
506 res: FMOD_RESULT;
507 Chan: FMOD_CHANNEL;
509 begin
510 if e_SoundsArray[ID].nRefs >= gMaxSimSounds then
511 begin
512 Result := 0;
513 Exit;
514 end;
516 Result := -1;
518 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
519 e_SoundsArray[ID].Sound, False, Chan);
520 if res <> FMOD_OK then
521 begin
522 Exit;
523 end;
525 res := FMOD_Channel_SetPan(Chan, Pan);
526 if res <> FMOD_OK then
527 begin
528 end;
530 res := FMOD_Channel_SetVolume(Chan, Volume);
531 if res <> FMOD_OK then
532 begin
533 end;
535 res := FMOD_Channel_SetCallback(Chan, Channel_Callback);
536 if res <> FMOD_OK then
537 begin
538 end;
540 if SoundMuted then
541 begin
542 res := FMOD_Channel_SetMute(Chan, True);
543 if res <> FMOD_OK then
544 begin
545 end;
546 end;
548 Inc(e_SoundsArray[ID].nRefs);
549 Result := 0;
550 end;
552 procedure e_DeleteSound(ID: DWORD);
553 var
554 res: FMOD_RESULT;
555 ud: Pointer;
557 begin
558 if e_SoundsArray[ID].Sound = nil then
559 Exit;
561 if e_SoundsArray[ID].Data <> nil then
562 FreeMem(e_SoundsArray[ID].Data);
564 res := FMOD_Sound_GetUserData(e_SoundsArray[ID].Sound, ud);
565 if res = FMOD_OK then
566 begin
567 FreeMem(ud);
568 end;
570 res := FMOD_Sound_Release(e_SoundsArray[ID].Sound);
571 if res <> FMOD_OK then
572 begin
573 e_WriteLog('Error releasing sound:', MSG_WARNING);
574 e_WriteLog(FMOD_ErrorString(res), MSG_WARNING);
575 end;
577 e_SoundsArray[ID].Sound := nil;
578 e_SoundsArray[ID].Data := nil;
579 end;
581 procedure e_ModifyChannelsVolumes(SoundMod: Single; setMode: Boolean);
582 var
583 res: FMOD_RESULT;
584 i: Integer;
585 Chan: FMOD_CHANNEL;
586 vol: Single;
588 begin
589 for i := 0 to N_CHANNELS-1 do
590 begin
591 Chan := nil;
592 res := FMOD_System_GetChannel(F_System, i, Chan);
594 if (res = FMOD_OK) and (Chan <> nil) then
595 begin
596 res := FMOD_Channel_GetVolume(Chan, vol);
598 if res = FMOD_OK then
599 begin
600 if setMode then
601 vol := SoundMod
602 else
603 vol := vol * SoundMod;
605 res := FMOD_Channel_SetVolume(Chan, vol);
607 if res <> FMOD_OK then
608 begin
609 end;
610 end;
611 end;
612 end;
613 end;
615 procedure e_MuteChannels(Enable: Boolean);
616 var
617 res: FMOD_RESULT;
618 i: Integer;
619 Chan: FMOD_CHANNEL;
621 begin
622 if Enable = SoundMuted then
623 Exit;
625 SoundMuted := Enable;
627 for i := 0 to N_CHANNELS-1 do
628 begin
629 Chan := nil;
630 res := FMOD_System_GetChannel(F_System, i, Chan);
632 if (res = FMOD_OK) and (Chan <> nil) then
633 begin
634 res := FMOD_Channel_SetMute(Chan, Enable);
636 if res <> FMOD_OK then
637 begin
638 end;
639 end;
640 end;
641 end;
643 procedure e_StopChannels();
644 var
645 res: FMOD_RESULT;
646 i: Integer;
647 Chan: FMOD_CHANNEL;
649 begin
650 for i := 0 to N_CHANNELS-1 do
651 begin
652 Chan := nil;
653 res := FMOD_System_GetChannel(F_System, i, Chan);
655 if (res = FMOD_OK) and (Chan <> nil) then
656 begin
657 res := FMOD_Channel_Stop(Chan);
659 if res <> FMOD_OK then
660 begin
661 end;
662 end;
663 end;
664 end;
666 procedure e_RemoveAllSounds();
667 var
668 i: Integer;
670 begin
671 for i := 0 to High(e_SoundsArray) do
672 if e_SoundsArray[i].Sound <> nil then
673 e_DeleteSound(i);
675 SetLength(e_SoundsArray, 0);
676 e_SoundsArray := nil;
677 end;
679 procedure e_ReleaseSoundSystem();
680 var
681 res: FMOD_RESULT;
683 begin
684 e_RemoveAllSounds();
686 res := FMOD_System_Close(F_System);
687 if res <> FMOD_OK then
688 begin
689 e_WriteLog('Error closing FMOD system!', MSG_FATALERROR);
690 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
691 Exit;
692 end;
694 res := FMOD_System_Release(F_System);
695 if res <> FMOD_OK then
696 begin
697 e_WriteLog('Error releasing FMOD system!', MSG_FATALERROR);
698 e_WriteLog(FMOD_ErrorString(res), MSG_FATALERROR);
699 end;
700 end;
702 procedure e_SoundUpdate();
703 begin
704 FMOD_System_Update(F_System);
705 end;
707 { TBasicSound: }
709 constructor TBasicSound.Create();
710 begin
711 FID := NO_SOUND_ID;
712 FMusic := False;
713 FChannel := nil;
714 FPosition := 0;
715 FPriority := 128;
716 end;
718 destructor TBasicSound.Destroy();
719 begin
720 FreeSound();
721 inherited;
722 end;
724 procedure TBasicSound.FreeSound();
725 begin
726 if FID = NO_SOUND_ID then
727 Exit;
729 Stop();
730 FID := NO_SOUND_ID;
731 FMusic := False;
732 FPosition := 0;
733 end;
735 function TBasicSound.RawPlay(Pan: Single; Volume: Single; aPos: DWORD): Boolean;
736 var
737 res: FMOD_RESULT;
739 begin
740 Result := False;
741 if FID = NO_SOUND_ID then Exit;
743 if e_SoundsArray[FID].nRefs >= gMaxSimSounds then
744 begin
745 Result := True;
746 Exit;
747 end;
749 res := FMOD_System_PlaySound(F_System, FMOD_CHANNEL_FREE,
750 e_SoundsArray[FID].Sound, False, FChannel);
751 if res <> FMOD_OK then
752 begin
753 FChannel := nil;
754 Exit;
755 end;
757 res := FMOD_Channel_SetPosition(FChannel, aPos, FMOD_TIMEUNIT_MS);
758 if res <> FMOD_OK then
759 begin
760 FPosition := 0;
761 end
762 else
763 FPosition := aPos;
765 res := FMOD_Channel_SetPan(FChannel, Pan);
766 if res <> FMOD_OK then
767 begin
768 end;
770 res := FMOD_Channel_SetVolume(FChannel, Volume);
771 if res <> FMOD_OK then
772 begin
773 end;
775 res := FMOD_Channel_SetCallback(FChannel, Channel_Callback);
776 if res <> FMOD_OK then
777 begin
778 end;
780 if SoundMuted then
781 begin
782 res := FMOD_Channel_SetMute(FChannel, True);
783 if res <> FMOD_OK then
784 begin
785 end;
786 end;
788 Inc(e_SoundsArray[FID].nRefs);
789 Result := True;
790 end;
792 procedure TBasicSound.SetID(ID: DWORD);
793 begin
794 FreeSound();
795 FID := ID;
796 FMusic := e_SoundsArray[ID].isMusic;
797 end;
799 function TBasicSound.IsPlaying(): Boolean;
800 var
801 res: FMOD_RESULT;
802 b: LongBool;
804 begin
805 Result := False;
807 if FChannel = nil then
808 Exit;
810 res := FMOD_Channel_IsPlaying(FChannel, b);
811 if res <> FMOD_OK then
812 begin
813 Exit;
814 end;
816 Result := b;
817 end;
819 procedure TBasicSound.Stop();
820 var
821 res: FMOD_RESULT;
823 begin
824 if FChannel = nil then
825 Exit;
827 GetPosition();
829 res := FMOD_Channel_Stop(FChannel);
830 if res <> FMOD_OK then
831 begin
832 end;
834 FChannel := nil;
835 end;
837 function TBasicSound.IsPaused(): Boolean;
838 var
839 res: FMOD_RESULT;
840 b: LongBool;
842 begin
843 Result := False;
845 if FChannel = nil then
846 Exit;
848 res := FMOD_Channel_GetPaused(FChannel, b);
849 if res <> FMOD_OK then
850 begin
851 Exit;
852 end;
854 Result := b;
855 end;
857 procedure TBasicSound.Pause(Enable: Boolean);
858 var
859 res: FMOD_RESULT;
861 begin
862 if FChannel = nil then
863 Exit;
865 res := FMOD_Channel_SetPaused(FChannel, Enable);
866 if res <> FMOD_OK then
867 begin
868 end;
870 if Enable then
871 begin
872 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
873 if res <> FMOD_OK then
874 begin
875 end;
876 end;
877 end;
879 function TBasicSound.GetVolume(): Single;
880 var
881 res: FMOD_RESULT;
882 vol: Single;
884 begin
885 Result := 0.0;
887 if FChannel = nil then
888 Exit;
890 res := FMOD_Channel_GetVolume(FChannel, vol);
891 if res <> FMOD_OK then
892 begin
893 Exit;
894 end;
896 Result := vol;
897 end;
899 procedure TBasicSound.SetVolume(Volume: Single);
900 var
901 res: FMOD_RESULT;
903 begin
904 if FChannel = nil then
905 Exit;
907 res := FMOD_Channel_SetVolume(FChannel, Volume);
908 if res <> FMOD_OK then
909 begin
910 end;
911 end;
913 function TBasicSound.GetPan(): Single;
914 var
915 res: FMOD_RESULT;
916 pan: Single;
918 begin
919 Result := 0.0;
921 if FChannel = nil then
922 Exit;
924 res := FMOD_Channel_GetPan(FChannel, pan);
925 if res <> FMOD_OK then
926 begin
927 Exit;
928 end;
930 Result := pan;
931 end;
933 procedure TBasicSound.SetPan(Pan: Single);
934 var
935 res: FMOD_RESULT;
937 begin
938 if FChannel = nil then
939 Exit;
941 res := FMOD_Channel_SetPan(FChannel, Pan);
942 if res <> FMOD_OK then
943 begin
944 end;
945 end;
947 function TBasicSound.IsMuted(): Boolean;
948 var
949 res: FMOD_RESULT;
950 b: LongBool;
952 begin
953 Result := False;
955 if FChannel = nil then
956 Exit;
958 res := FMOD_Channel_GetMute(FChannel, b);
959 if res <> FMOD_OK then
960 begin
961 Exit;
962 end;
964 Result := b;
965 end;
967 procedure TBasicSound.Mute(Enable: Boolean);
968 var
969 res: FMOD_RESULT;
971 begin
972 if FChannel = nil then
973 Exit;
975 res := FMOD_Channel_SetMute(FChannel, Enable);
976 if res <> FMOD_OK then
977 begin
978 end;
979 end;
981 function TBasicSound.GetPosition(): DWORD;
982 var
983 res: FMOD_RESULT;
985 begin
986 Result := 0;
988 if FChannel = nil then
989 Exit;
991 res := FMOD_Channel_GetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
992 if res <> FMOD_OK then
993 begin
994 Exit;
995 end;
997 Result := FPosition;
998 end;
1000 procedure TBasicSound.SetPosition(aPos: DWORD);
1001 var
1002 res: FMOD_RESULT;
1004 begin
1005 FPosition := aPos;
1007 if FChannel = nil then
1008 Exit;
1010 res := FMOD_Channel_SetPosition(FChannel, FPosition, FMOD_TIMEUNIT_MS);
1011 if res <> FMOD_OK then
1012 begin
1013 end;
1014 end;
1016 procedure TBasicSound.SetPriority(priority: Integer);
1017 var
1018 res: FMOD_RESULT;
1020 begin
1021 if (FChannel <> nil) and (FPriority <> priority) and
1022 (priority >= 0) and (priority <= 256) then
1023 begin
1024 FPriority := priority;
1025 res := FMOD_Channel_SetPriority(FChannel, priority);
1026 if res <> FMOD_OK then
1027 begin
1028 end;
1029 end;
1030 end;
1032 end.