mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Play sounds using SDL2 under Linux/FreeBSD
This commit is contained in:
parent
9c26a1cd5e
commit
ef94d8327b
2 changed files with 184 additions and 1 deletions
162
src/platform/unix/sdl2.pas
Normal file
162
src/platform/unix/sdl2.pas
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
unit sdl2;
|
||||
|
||||
{$mode delphi}
|
||||
{$packrecords c}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, CTypes;
|
||||
|
||||
const
|
||||
SDL_INIT_AUDIO = $00000010;
|
||||
|
||||
SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = $00000001;
|
||||
SDL_AUDIO_ALLOW_FORMAT_CHANGE = $00000002;
|
||||
SDL_AUDIO_ALLOW_CHANNELS_CHANGE = $00000004;
|
||||
SDL_AUDIO_ALLOW_SAMPLES_CHANGE = $00000008;
|
||||
SDL_AUDIO_ALLOW_ANY_CHANGE = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE or SDL_AUDIO_ALLOW_FORMAT_CHANGE or
|
||||
SDL_AUDIO_ALLOW_CHANNELS_CHANGE or SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
||||
|
||||
type
|
||||
SDL_AudioFormat = type UInt16;
|
||||
SDL_AudioDeviceID = type UInt32;
|
||||
|
||||
TSDL_RWops = record end;
|
||||
PSDL_RWops = ^TSDL_RWops;
|
||||
|
||||
SDL_AudioCallback = procedure(userdata: Pointer; stream: PByte; len: cint); cdecl;
|
||||
|
||||
SDL_AudioSpec = record
|
||||
freq: cint;
|
||||
format: SDL_AudioFormat;
|
||||
channels: UInt8;
|
||||
silence: UInt8;
|
||||
samples: UInt16;
|
||||
padding: UInt16;
|
||||
size: UInt32;
|
||||
callback: SDL_AudioCallback;
|
||||
userdata: Pointer;
|
||||
end;
|
||||
PSDL_AudioSpec = ^SDL_AudioSpec;
|
||||
|
||||
TAudioData = record
|
||||
wavStart: PByte;
|
||||
wavLength: UInt32;
|
||||
wavSpec: SDL_AudioSpec;
|
||||
end;
|
||||
PAudioData = ^TAudioData;
|
||||
|
||||
var
|
||||
SDL_InitSubSystem: function(flags: UInt32): cint; cdecl;
|
||||
SDL_Delay: procedure(ms: UInt32); cdecl;
|
||||
SDL_GetError: function(): PAnsiChar; cdecl;
|
||||
SDL_RWFromFile: function(const file_name: PAnsiChar; const mode: PAnsiChar): PSDL_RWops; cdecl;
|
||||
SDL_LoadWAV_RW: function(src: PSDL_RWops; freesrc: cint; spec: PSDL_AudioSpec;
|
||||
audio_buf: PPByte; audio_len: PUInt32): PSDL_AudioSpec; cdecl;
|
||||
SDL_FreeWAV: procedure(audio_buf: PByte); cdecl;
|
||||
SDL_QueueAudio: function(dev: SDL_AudioDeviceID; const data: Pointer; len: UInt32): cint; cdecl;
|
||||
SDL_GetQueuedAudioSize: function(dev: SDL_AudioDeviceID): UInt32; cdecl;
|
||||
SDL_OpenAudioDevice: function(const device: PAnsiChar; iscapture: cint;
|
||||
const desired: PSDL_AudioSpec; obtained: PSDL_AudioSpec;
|
||||
allowed_changes: cint): SDL_AudioDeviceID; cdecl;
|
||||
SDL_PauseAudioDevice: procedure(dev: SDL_AudioDeviceID; pause_on: cint); cdecl;
|
||||
SDL_CloseAudioDevice: procedure(dev: SDL_AudioDeviceID); cdecl;
|
||||
|
||||
function SDL_Initialize: Boolean;
|
||||
function SDL_Play(const FileName: String): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
DCOSUtils, LazLogger;
|
||||
|
||||
function Play(Parameter: Pointer): PtrInt;
|
||||
var
|
||||
audioDevice: SDL_AudioDeviceID;
|
||||
AudioData: PAudioData absolute parameter;
|
||||
begin
|
||||
Result:= 0;
|
||||
try
|
||||
audioDevice:= SDL_OpenAudioDevice(nil, 0, @AudioData^.wavSpec, nil, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
|
||||
if audioDevice = 0 then
|
||||
begin
|
||||
DebugLn('SDL_OpenAudioDevice: ', SDL_GetError());
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
SDL_QueueAudio(audioDevice, AudioData^.wavStart, AudioData^.wavLength);
|
||||
SDL_PauseAudioDevice(audioDevice, 0);
|
||||
|
||||
while SDL_GetQueuedAudioSize(audioDevice) > 0 do
|
||||
begin
|
||||
SDL_Delay(100);
|
||||
end;
|
||||
|
||||
SDL_CloseAudioDevice(audioDevice);
|
||||
finally
|
||||
SDL_FreeWAV(AudioData^.wavStart);
|
||||
Dispose(AudioData);
|
||||
end;
|
||||
end;
|
||||
|
||||
function SDL_Play(const FileName: String): Boolean;
|
||||
var
|
||||
RWops: PSDL_RWops;
|
||||
AudioData: PAudioData;
|
||||
begin
|
||||
RWops:= SDL_RWFromFile(PAnsiChar(FileName), 'rb');
|
||||
if (RWops = nil) then
|
||||
begin
|
||||
DebugLn('SDL_RWFromFile: ', SDL_GetError());
|
||||
Exit(False);
|
||||
end;
|
||||
New(AudioData);
|
||||
with AudioData^ do
|
||||
begin
|
||||
if (SDL_LoadWAV_RW(RWops, 1, @wavSpec, @wavStart, @wavLength) = nil) then
|
||||
begin
|
||||
DebugLn('SDL_LoadWAV_RW: ', SDL_GetError());
|
||||
Dispose(AudioData);
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
Result:= BeginThread(@Play, AudioData) > 0;
|
||||
end;
|
||||
|
||||
const
|
||||
sdllib= 'libSDL2-2.0.so.0';
|
||||
|
||||
var
|
||||
libsdl: TLibHandle;
|
||||
|
||||
function SDL_Initialize: Boolean;
|
||||
begin
|
||||
libsdl:= SafeLoadLibrary(sdllib);
|
||||
Result:= (libsdl <> NilHandle);
|
||||
if Result then
|
||||
try
|
||||
SDL_InitSubSystem:= SafeGetProcAddress(libsdl, 'SDL_InitSubSystem');
|
||||
SDL_Delay:= SafeGetProcAddress(libsdl, 'SDL_Delay');
|
||||
SDL_GetError:= SafeGetProcAddress(libsdl, 'SDL_GetError');
|
||||
SDL_RWFromFile:= SafeGetProcAddress(libsdl, 'SDL_RWFromFile');
|
||||
SDL_LoadWAV_RW:= SafeGetProcAddress(libsdl, 'SDL_LoadWAV_RW');
|
||||
SDL_FreeWAV:= SafeGetProcAddress(libsdl, 'SDL_FreeWAV');
|
||||
SDL_QueueAudio:= SafeGetProcAddress(libsdl, 'SDL_QueueAudio');
|
||||
SDL_GetQueuedAudioSize:= SafeGetProcAddress(libsdl, 'SDL_GetQueuedAudioSize');
|
||||
SDL_OpenAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_OpenAudioDevice');
|
||||
SDL_PauseAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_PauseAudioDevice');
|
||||
SDL_CloseAudioDevice:= SafeGetProcAddress(libsdl, 'SDL_CloseAudioDevice');
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
Result:= False;
|
||||
DebugLn(E.Message);
|
||||
FreeLibrary(libsdl);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -13,6 +13,8 @@ uses
|
|||
, MMSystem, LazUTF8
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
, CocoaAll, uMyDarwin
|
||||
{$ELSE}
|
||||
, LazLogger, sdl2
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
|
|
@ -66,8 +68,27 @@ begin
|
|||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
const
|
||||
Res: Integer = -1;
|
||||
First: Boolean = True;
|
||||
begin
|
||||
Result:= False;
|
||||
if First then
|
||||
begin
|
||||
if SDL_Initialize then
|
||||
begin
|
||||
Res:= SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
if (Res < 0) then
|
||||
begin
|
||||
DebugLn('SDL_InitSubSystem: ', SDL_GetError());
|
||||
end;
|
||||
end;
|
||||
First:= False;
|
||||
end;
|
||||
if (Res < 0) then
|
||||
Result:= False
|
||||
else begin
|
||||
Result:= SDL_Play(FileName);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue