DEADSOFTWARE

24effff9709233d5ea9fe5feb7fee47dfb7b5f8d
[d2df-sdl.git] / src / engine / e_soundfile_wav.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
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, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 unit e_soundfile_wav;
19 interface
21 uses e_soundfile;
23 type
24 // a WAV loader that just uses SDL_LoadWAV
26 TWAVLoader = class (TSoundLoader)
27 public
28 function Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean; override; overload;
29 function Load(FName: string; SStreaming: Boolean): Boolean; override; overload;
30 function SetPosition(Pos: LongWord): Boolean; override;
31 function FillBuffer(Buf: Pointer; Len: LongWord): LongWord; override;
32 function GetAll(var OutPtr: Pointer): LongWord; override;
33 procedure Free(); override;
34 private
35 FData: Pointer;
36 FDataLen: LongWord;
37 end;
39 TWAVLoaderFactory = class (TSoundLoaderFactory)
40 public
41 function MatchHeader(Data: Pointer; Len: LongWord): Boolean; override;
42 function MatchExtension(FName: string): Boolean; override;
43 function GetLoader(): TSoundLoader; override;
44 end;
46 implementation
48 uses sdl2, utils, e_log;
50 (* TWAVLoaderFactory *)
52 function TWAVLoaderFactory.MatchHeader(Data: Pointer; Len: LongWord): Boolean;
53 var
54 P: PByte;
55 begin
56 if Len < 5 then
57 begin
58 Result := False;
59 exit;
60 end;
61 P := PByte(Data);
62 Result := ((P+0)^ = Ord('R')) and ((P+1)^ = Ord('I')) and ((P+2)^ = Ord('F')) and ((P+3)^ = Ord('F'));
63 end;
65 function TWAVLoaderFactory.MatchExtension(FName: string): Boolean;
66 begin
67 // TODO: ehhh
68 Result := GetFilenameExt(FName) = '.wav';
69 end;
71 function TWAVLoaderFactory.GetLoader(): TSoundLoader;
72 begin
73 Result := TWAVLoader.Create();
74 end;
76 (* TWAVLoader *)
78 function TWAVLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
79 var
80 Spec: TSDL_AudioSpec;
81 RW: PSDL_RWops;
82 TmpLen: UInt32;
83 TmpBuf: PUInt8;
84 begin
85 Result := False;
87 RW := SDL_RWFromConstMem(Data, Len);
89 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
90 begin
91 e_LogWriteln('Could not load WAV: ' + SDL_GetError());
92 end
93 else
94 begin
95 FFormat.SampleRate := Spec.freq;
96 FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
97 FFormat.Channels := Spec.channels;
98 FStreaming := False; // never stream wavs
99 FDataLen := TmpLen;
100 FData := TmpBuf;
101 Result := True;
102 end;
104 SDL_RWclose(RW);
105 end;
107 function TWAVLoader.Load(FName: string; SStreaming: Boolean): Boolean;
108 var
109 Spec: TSDL_AudioSpec;
110 RW: PSDL_RWops;
111 TmpLen: UInt32;
112 TmpBuf: PUInt8;
113 begin
114 Result := False;
116 RW := SDL_RWFromFile(PChar(FName), 'rb');
118 if RW = nil then
119 begin
120 e_LogWritefln('Could not open WAV file `%s`: %s', [FName, SDL_GetError()]);
121 exit;
122 end;
124 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
125 begin
126 e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
127 end
128 else
129 begin
130 FFormat.SampleRate := Spec.freq;
131 FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
132 FFormat.Channels := Spec.channels;
133 FStreaming := False; // never stream wavs
134 FDataLen := TmpLen;
135 FData := TmpBuf;
136 Result := True;
137 end;
139 SDL_RWclose(RW);
140 end;
142 function TWAVLoader.SetPosition(Pos: LongWord): Boolean;
143 begin
144 Result := False; // makes no sense when not streaming
145 end;
147 function TWAVLoader.FillBuffer(Buf: Pointer; Len: LongWord): LongWord;
148 begin
149 if FDataLen < Len then
150 Len := FDataLen;
151 if FData <> nil then
152 begin
153 Move(FData^, Buf^, Len);
154 Result := Len;
155 end
156 else
157 Result := 0;
158 end;
160 function TWAVLoader.GetAll(var OutPtr: Pointer): LongWord;
161 begin
162 OutPtr := FData;
163 Result := FDataLen;
164 end;
166 procedure TWAVLoader.Free();
167 begin
168 if FData <> nil then
169 SDL_FreeWAV(FData); // SDL allocates inside the DLL, so we need this
170 end;
172 initialization
173 e_AddSoundLoader(TWAVLoaderFactory.Create());
174 end.