DEADSOFTWARE

0ebe256b9d9d818245067079d9fe22c99a5e252c
[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, version 3 of the License ONLY.
6 *
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.
11 *
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/>.
14 *)
15 {$INCLUDE ../shared/a_modes.inc}
16 unit e_soundfile_wav;
18 interface
20 uses e_soundfile;
22 type
23 // a WAV loader that just uses SDL_LoadWAV
25 TWAVLoader = class (TSoundLoader)
26 public
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;
33 private
34 FData: Pointer;
35 FDataLen: LongWord;
36 end;
38 TWAVLoaderFactory = class (TSoundLoaderFactory)
39 public
40 function MatchHeader(Data: Pointer; Len: LongWord): Boolean; override;
41 function MatchExtension(FName: string): Boolean; override;
42 function GetLoader(): TSoundLoader; override;
43 end;
45 implementation
47 uses sdl2, utils, e_log;
49 (* TWAVLoaderFactory *)
51 function TWAVLoaderFactory.MatchHeader(Data: Pointer; Len: LongWord): Boolean;
52 var
53 P: PByte;
54 begin
55 if Len < 5 then
56 begin
57 Result := False;
58 exit;
59 end;
60 P := PByte(Data);
61 Result := ((P+0)^ = Ord('R')) and ((P+1)^ = Ord('I')) and ((P+2)^ = Ord('F')) and ((P+3)^ = Ord('F'));
62 end;
64 function TWAVLoaderFactory.MatchExtension(FName: string): Boolean;
65 begin
66 // TODO: ehhh
67 Result := GetFilenameExt(FName) = '.wav';
68 end;
70 function TWAVLoaderFactory.GetLoader(): TSoundLoader;
71 begin
72 Result := TWAVLoader.Create();
73 end;
75 (* TWAVLoader *)
77 function TWAVLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
78 var
79 Spec: TSDL_AudioSpec;
80 RW: PSDL_RWops;
81 TmpLen: UInt32;
82 TmpBuf: PUInt8;
83 begin
84 Result := False;
86 RW := SDL_RWFromConstMem(Data, Len);
88 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
89 begin
90 e_LogWriteln('Could not load WAV: ' + SDL_GetError());
91 end
92 else
93 begin
94 FFormat.SampleRate := Spec.freq;
95 FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
96 FFormat.Channels := Spec.channels;
97 FStreaming := False; // never stream wavs
98 FDataLen := TmpLen;
99 FData := TmpBuf;
100 Result := True;
101 end;
103 SDL_RWclose(RW);
104 end;
106 function TWAVLoader.Load(FName: string; SStreaming: Boolean): Boolean;
107 var
108 Spec: TSDL_AudioSpec;
109 RW: PSDL_RWops;
110 TmpLen: UInt32;
111 TmpBuf: PUInt8;
112 begin
113 Result := False;
115 RW := SDL_RWFromFile(PChar(FName), 'rb');
117 if RW = nil then
118 begin
119 e_LogWritefln('Could not open WAV file `%s`: %s', [FName, SDL_GetError()]);
120 exit;
121 end;
123 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
124 begin
125 e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
126 end
127 else
128 begin
129 FFormat.SampleRate := Spec.freq;
130 FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
131 FFormat.Channels := Spec.channels;
132 FStreaming := False; // never stream wavs
133 FDataLen := TmpLen;
134 FData := TmpBuf;
135 Result := True;
136 end;
138 SDL_RWclose(RW);
139 end;
141 function TWAVLoader.SetPosition(Pos: LongWord): Boolean;
142 begin
143 Result := False; // makes no sense when not streaming
144 end;
146 function TWAVLoader.FillBuffer(Buf: Pointer; Len: LongWord): LongWord;
147 begin
148 if FDataLen < Len then
149 Len := FDataLen;
150 if FData <> nil then
151 begin
152 Move(FData^, Buf^, Len);
153 Result := Len;
154 end
155 else
156 Result := 0;
157 end;
159 function TWAVLoader.GetAll(var OutPtr: Pointer): LongWord;
160 begin
161 OutPtr := FData;
162 Result := FDataLen;
163 end;
165 procedure TWAVLoader.Free();
166 begin
167 if FData <> nil then
168 SDL_FreeWAV(FData); // SDL allocates inside the DLL, so we need this
169 end;
171 initialization
172 e_AddSoundLoader(TWAVLoaderFactory.Create());
173 end.