index b5b838d4ba224da50e1301ec8db02cfedea0a6e2..340aa920725f1cd69dca7054f4f70acd3c152eb2 100644 (file)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
end;
TWAVLoaderFactory = class (TSoundLoaderFactory)
+ public
function MatchHeader(Data: Pointer; Len: LongWord): Boolean; override;
function MatchExtension(FName: string): Boolean; override;
function GetLoader(): TSoundLoader; override;
implementation
-uses sdl2, utils, e_log;
+uses
+ {$IFDEF USE_SDL}
+ SDL,
+ {$ELSE}
+ SDL2,
+ {$ENDIF}
+ utils, ctypes, e_log;
(* TWAVLoaderFactory *)
end;
(* TWAVLoader *)
+function FixSoundEndian (Buf: PUInt8; Len: UInt32; format: UInt16; rate: cint; chan: UInt8): Boolean;
+ const
+ {$IFDEF FPC_LITTLE_ENDIAN}
+ TARGET_AUDIO_S16 = AUDIO_S16LSB;
+ TARGET_AUDIO_U16 = AUDIO_U16LSB;
+ {$ELSE}
+ TARGET_AUDIO_S16 = AUDIO_S16MSB;
+ TARGET_AUDIO_U16 = AUDIO_U16MSB;
+ {$ENDIF}
+ var cvt: TSDL_AudioCVT; tformat: UInt16;
+begin
+ case format of
+ AUDIO_U16LSB, AUDIO_U16MSB: tformat := TARGET_AUDIO_U16;
+ AUDIO_S16LSB, AUDIO_S16MSB: tformat := TARGET_AUDIO_S16;
+ else tformat := format
+ end;
+ Result := True;
+ if format <> tformat then
+ begin
+ Result := False;
+ if SDL_BuildAudioCVT(@cvt, format, chan, rate, tformat, chan, rate) <> -1 then
+ begin
+ cvt.buf := Buf;
+ cvt.len := Len;
+ assert(cvt.len_mult = 1);
+ Result := SDL_ConvertAudio(@cvt) = 0;
+ assert(cvt.len_ratio = 1);
+ assert(cvt.len = Len)
+ end
+ end
+end;
-function TWAVLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
-var
- Spec: TSDL_AudioSpec;
- RW: PSDL_RWops;
- TmpLen: UInt32;
- TmpBuf: PUInt8;
+function LoadWavRW (Loader: TWAVLoader; RW: PSDL_RWops): Boolean;
+ var
+ Spec: TSDL_AudioSpec;
+ Len: UInt32;
+ Buf: PUInt8;
begin
Result := False;
-
- RW := SDL_RWFromConstMem(Data, Len);
-
- if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
+{$IFDEF USE_SDL2}
+ if SDL_LoadWAV_RW(RW, 0, @Spec, @Buf, @Len) <> nil then
+{$ELSE}
+ if SDL_LoadWAV_RW(RW, 0, @Spec, PUInt8(@Buf), @Len) <> nil then
+{$ENDIF}
begin
- e_LogWriteln('Could not load WAV: ' + SDL_GetError());
+ Result := FixSoundEndian(Buf, Len, Spec.format, Spec.freq, Spec.channels);
+ if Result = True then
+ begin
+ with Loader do
+ begin
+ FFormat.SampleRate := Spec.freq;
+ {$IFDEF USE_SDL2}
+ FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
+ {$ELSE}
+ FFormat.SampleBits := Spec.format and $FF;
+ {$ENDIF}
+ FFormat.Channels := Spec.channels;
+ FStreaming := False; // never stream wavs
+ FDataLen := Len;
+ FData := Buf;
+ end
+ end
+ else
+ begin
+ SDL_FreeWav(Buf)
+ end
end
- else
- begin
- FFormat.SampleRate := Spec.freq;
- FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
- FFormat.Channels := Spec.channels;
- FStreaming := False; // never stream wavs
- FDataLen := TmpLen;
- FData := TmpBuf;
- Result := True;
- end;
+end;
+function TWAVLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
+ var
+ RW: PSDL_RWops;
+begin
+ RW := SDL_RWFromConstMem(Data, Len);
+ Result := LoadWavRW(Self, RW);
+ if Result = False then
+ e_LogWriteln('Could not load WAV: ' + SDL_GetError());
SDL_RWclose(RW);
end;
function TWAVLoader.Load(FName: string; SStreaming: Boolean): Boolean;
-var
- Spec: TSDL_AudioSpec;
- RW: PSDL_RWops;
- TmpLen: UInt32;
- TmpBuf: PUInt8;
+ var
+ RW: PSDL_RWops;
begin
- Result := False;
-
RW := SDL_RWFromFile(PChar(FName), 'rb');
-
- if RW = nil then
- begin
- e_LogWritefln('Could not open WAV file `%s`: %s', [FName, SDL_GetError()]);
- exit;
- end;
-
- if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
+ if RW <> nil then
begin
- e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
+ Result := LoadWavRW(Self, RW);
+ if Result = False then
+ e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
end
else
begin
- FFormat.SampleRate := Spec.freq;
- FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
- FFormat.Channels := Spec.channels;
- FStreaming := False; // never stream wavs
- FDataLen := TmpLen;
- FData := TmpBuf;
- Result := True;
+ e_LogWritefln('Could not open WAV file `%s`: %s', [FName, SDL_GetError()]);
+ Result := False
end;
-
SDL_RWclose(RW);
end;