1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../shared/a_modes.inc}
23 // a WAV loader that just uses SDL_LoadWAV
25 TWAVLoader
= class (TSoundLoader
)
27 function Load(Data
: Pointer; Len
: LongWord; SStreaming
: Boolean): Boolean; override; overload
;
28 function Load(FName
: string; SStreaming
: Boolean): Boolean; override; overload
;
29 function SetPosition(Pos
: LongWord): Boolean; override;
30 function FillBuffer(Buf
: Pointer; Len
: LongWord): LongWord; override;
31 function GetAll(var OutPtr
: Pointer): LongWord; override;
32 procedure Free(); override;
38 TWAVLoaderFactory
= class (TSoundLoaderFactory
)
40 function MatchHeader(Data
: Pointer; Len
: LongWord): Boolean; override;
41 function MatchExtension(FName
: string): Boolean; override;
42 function GetLoader(): TSoundLoader
; override;
55 (* TWAVLoaderFactory *)
57 function TWAVLoaderFactory
.MatchHeader(Data
: Pointer; Len
: LongWord): Boolean;
67 Result
:= ((P
+0)^ = Ord('R')) and ((P
+1)^ = Ord('I')) and ((P
+2)^ = Ord('F')) and ((P
+3)^ = Ord('F'));
70 function TWAVLoaderFactory
.MatchExtension(FName
: string): Boolean;
73 Result
:= GetFilenameExt(FName
) = '.wav';
76 function TWAVLoaderFactory
.GetLoader(): TSoundLoader
;
78 Result
:= TWAVLoader
.Create();
82 function FixSoundEndian (Buf
: PUInt8
; Len
: UInt32
; format
: UInt16
; rate
: cint
; chan
: UInt8
): Boolean;
84 {$IFDEF FPC_LITTLE_ENDIAN}
85 TARGET_AUDIO_S16
= AUDIO_S16LSB
;
86 TARGET_AUDIO_U16
= AUDIO_U16LSB
;
88 TARGET_AUDIO_S16
= AUDIO_S16MSB
;
89 TARGET_AUDIO_U16
= AUDIO_U16MSB
;
91 var cvt
: TSDL_AudioCVT
; tformat
: UInt16
;
94 AUDIO_U16LSB
, AUDIO_U16MSB
: tformat
:= TARGET_AUDIO_U16
;
95 AUDIO_S16LSB
, AUDIO_S16MSB
: tformat
:= TARGET_AUDIO_S16
;
96 else tformat
:= format
99 if format
<> tformat
then
102 if SDL_BuildAudioCVT(@cvt
, format
, chan
, rate
, tformat
, chan
, rate
) <> -1 then
106 assert(cvt
.len_mult
= 1);
107 Result
:= SDL_ConvertAudio(@cvt
) = 0;
108 assert(cvt
.len_ratio
= 1);
109 assert(cvt
.len
= Len
)
114 function LoadWavRW (Loader
: TWAVLoader
; RW
: PSDL_RWops
): Boolean;
116 Spec
: TSDL_AudioSpec
;
122 if SDL_LoadWAV_RW(RW
, 0, @Spec
, @Buf
, @Len
) <> nil then
124 if SDL_LoadWAV_RW(RW
, 0, @Spec
, PUInt8(@Buf
), @Len
) <> nil then
127 Result
:= FixSoundEndian(Buf
, Len
, Spec
.format
, Spec
.freq
, Spec
.channels
);
128 if Result
= True then
132 FFormat
.SampleRate
:= Spec
.freq
;
134 FFormat
.SampleBits
:= SDL_AUDIO_BITSIZE(Spec
.format
);
136 FFormat
.SampleBits
:= Spec
.format
and $FF;
138 FFormat
.Channels
:= Spec
.channels
;
139 FStreaming
:= False; // never stream wavs
151 function TWAVLoader
.Load(Data
: Pointer; Len
: LongWord; SStreaming
: Boolean): Boolean;
155 RW
:= SDL_RWFromConstMem(Data
, Len
);
156 Result
:= LoadWavRW(Self
, RW
);
157 if Result
= False then
158 e_LogWriteln('Could not load WAV: ' + SDL_GetError());
162 function TWAVLoader
.Load(FName
: string; SStreaming
: Boolean): Boolean;
166 RW
:= SDL_RWFromFile(PChar(FName
), 'rb');
169 Result
:= LoadWavRW(Self
, RW
);
170 if Result
= False then
171 e_LogWritefln('Could not load WAV file `%s`: %s', [FName
, SDL_GetError()]);
175 e_LogWritefln('Could not open WAV file `%s`: %s', [FName
, SDL_GetError()]);
181 function TWAVLoader
.SetPosition(Pos
: LongWord): Boolean;
183 Result
:= False; // makes no sense when not streaming
186 function TWAVLoader
.FillBuffer(Buf
: Pointer; Len
: LongWord): LongWord;
188 if FDataLen
< Len
then
192 Move(FData
^, Buf
^, Len
);
199 function TWAVLoader
.GetAll(var OutPtr
: Pointer): LongWord;
205 procedure TWAVLoader
.Free();
208 SDL_FreeWAV(FData
); // SDL allocates inside the DLL, so we need this
212 e_AddSoundLoader(TWAVLoaderFactory
.Create());