DEADSOFTWARE

fix 16/32 bit and float wav formats for openal
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 9 Dec 2019 19:31:28 +0000 (22:31 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 9 Dec 2019 19:31:28 +0000 (22:31 +0300)
src/engine/e_soundfile_wav.pas
src/lib/sdl2/sdl2.pas
src/lib/sdl2/sdlstdinc.inc [new file with mode: 0644]

index 340aa920725f1cd69dca7054f4f70acd3c152eb2..fe9a8a26f9c10ded420e82f183cee4c6167f3c77 100644 (file)
@@ -79,34 +79,29 @@ begin
 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}
+function ConvertSound (var buf: PUInt8; var len: UInt32; var format: UInt16; rate: cint; chan: UInt8): Boolean;
   var cvt: TSDL_AudioCVT; tformat: UInt16;
 begin
+  result := true;
   case format of
-    AUDIO_U16LSB, AUDIO_U16MSB: tformat := TARGET_AUDIO_U16;
-    AUDIO_S16LSB, AUDIO_S16MSB: tformat := TARGET_AUDIO_S16;
-  else tformat := format
+    AUDIO_U8,     AUDIO_S8    : tformat := AUDIO_U8; (* yes, unsigned *)
+    AUDIO_U16LSB, AUDIO_U16MSB: tformat := AUDIO_S16SYS; (* and yes, signed *)
+    AUDIO_S16LSB, AUDIO_S16MSB: tformat := AUDIO_S16SYS;
+    AUDIO_S32LSB, AUDIO_S32MSB: tformat := AUDIO_S16SYS; (* 32bit not supported in al core *)
+    AUDIO_F32LSB, AUDIO_F32MSB: tformat := AUDIO_S16SYS; (* float not supported in al core *)
+  else result := false (* unsupported format *)
   end;
-  Result := True;
-  if format <> tformat then
+  if (result = true) and (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)
+      buf := SDL_realloc(buf, len * cvt.len_mult);
+      cvt.len := len;
+      cvt.buf := buf;
+      result := SDL_ConvertAudio(@cvt) = 0;
+      len := cvt.len_cvt;
+      format := tformat
     end
   end
 end;
@@ -124,7 +119,7 @@ begin
   if SDL_LoadWAV_RW(RW, 0, @Spec, PUInt8(@Buf), @Len) <> nil then
 {$ENDIF}
   begin
-    Result := FixSoundEndian(Buf, Len, Spec.format, Spec.freq, Spec.channels);
+    Result := ConvertSound(Buf, Len, Spec.format, Spec.freq, Spec.channels);
     if Result = True then
     begin
       with Loader do
index 2e1c51e54ba079805c642cdf0ce25e1f7573ab13..d5bb58e2529905e3afaf1307b3bf0a57689d3dc3 100644 (file)
@@ -212,6 +212,7 @@ const
 {$I sdlfilesystem.inc}
 {$I sdllog.inc}
 {$I sdlsystem.inc}
+{$I sdlstdinc.inc}
 {$I sdl.inc}
 
 implementation
diff --git a/src/lib/sdl2/sdlstdinc.inc b/src/lib/sdl2/sdlstdinc.inc
new file mode 100644 (file)
index 0000000..0ed77eb
--- /dev/null
@@ -0,0 +1,9 @@
+//from "sdl_stdinc.h"
+
+  function SDL_malloc (size: size_t): Pointer; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_malloc' {$ENDIF} {$ENDIF};
+
+  function SDL_calloc (nmemb, size: size_t): Pointer; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_calloc' {$ENDIF} {$ENDIF};
+
+  function SDL_realloc (mem: Pointer; size: size_t): Pointer; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_realloc' {$ENDIF} {$ENDIF};
+
+  procedure SDL_free (mem: Pointer); cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_free' {$ENDIF} {$ENDIF};