DEADSOFTWARE

Sound: Initial OpenAL driver impl
[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
25 TWAVLoader = class (TSoundLoader)
26 public
27 function CanLoad(Data: Pointer; Len: Integer): Boolean; override; overload;
28 function CanLoad(FName: string): Boolean; override; overload;
29 function Load(Data: Pointer; Len: Integer; var OutLen: Integer; var OutFmt: TSoundFormat): Pointer; override; overload;
30 function Load(FName: string; var OutLen: Integer; var OutFmt: TSoundFormat): Pointer; override; overload;
31 procedure Free(Data: Pointer); override;
32 end;
34 implementation
36 uses sdl2, utils, e_log;
38 function TWAVLoader.CanLoad(Data: Pointer; Len: Integer): Boolean;
39 var
40 P: PByte;
41 begin
42 if Len < 5 then
43 begin
44 Result := False;
45 exit;
46 end;
47 P := PByte(Data);
48 Result := ((P+0)^ = Ord('R')) and ((P+1)^ = Ord('I')) and ((P+2)^ = Ord('F')) and ((P+3)^ = Ord('F'));
49 end;
51 function TWAVLoader.CanLoad(FName: string): Boolean;
52 begin
53 // TODO: actually check for RIFF header
54 Result := GetFilenameExt(FName) = '.wav';
55 end;
57 function TWAVLoader.Load(Data: Pointer; Len: Integer; var OutLen: Integer; var OutFmt: TSoundFormat): Pointer;
58 var
59 Spec: TSDL_AudioSpec;
60 RW: PSDL_RWops;
61 TmpLen: UInt32;
62 TmpBuf: PUInt8;
63 begin
64 Result := nil;
66 RW := SDL_RWFromConstMem(Data, Len);
68 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
69 begin
70 e_LogWriteln('Could not load WAV: ' + SDL_GetError());
71 end
72 else
73 begin
74 OutFmt.Loader := self;
75 OutFmt.SampleRate := Spec.freq;
76 OutFmt.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
77 OutFmt.Channels := Spec.channels;
78 OutLen := TmpLen;
79 Result := TmpBuf;
80 end;
82 SDL_RWclose(RW);
83 end;
85 function TWAVLoader.Load(FName: string; var OutLen: Integer; var OutFmt: TSoundFormat): Pointer;
86 var
87 Spec: TSDL_AudioSpec;
88 RW: PSDL_RWops;
89 TmpLen: UInt32;
90 TmpBuf: PUInt8;
91 begin
92 Result := nil;
94 RW := SDL_RWFromFile(PChar(FName), 'rb');
96 if RW = nil then
97 begin
98 e_LogWritefln('Could not open WAV file `%s`: %s', [FName, SDL_GetError()]);
99 exit;
100 end;
102 if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
103 begin
104 e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
105 Result := nil;
106 end
107 else
108 begin
109 OutFmt.Loader := self;
110 OutFmt.SampleRate := Spec.freq;
111 OutFmt.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
112 OutFmt.Channels := Spec.channels;
113 OutLen := TmpLen;
114 Result := TmpBuf;
115 end;
117 SDL_RWclose(RW);
118 end;
120 procedure TWAVLoader.Free(Data: Pointer);
121 begin
122 SDL_FreeWAV(Data); // SDL allocates inside the DLL, so we need this
123 end;
125 initialization
126 e_AddSoundLoader(TWAVLoader.Create());
127 end.