Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
518f628f
Commit
518f628f
authored
Dec 29, 2016
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Exploratory work on the OpenAL backend.
parent
f8daea07
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
614 additions
and
2 deletions
+614
-2
mini_al.h
mini_al.h
+614
-2
No files found.
mini_al.h
View file @
518f628f
...
@@ -183,6 +183,9 @@ extern "C" {
...
@@ -183,6 +183,9 @@ extern "C" {
#if !defined(MAL_NO_OPENSLES) && defined(MAL_ANDROID)
#if !defined(MAL_NO_OPENSLES) && defined(MAL_ANDROID)
#define MAL_ENABLE_OPENSLES
#define MAL_ENABLE_OPENSLES
#endif
#endif
#if !defined(MAL_NO_OPENAL)
#define MAL_ENABLE_OPENAL
#endif
#if !defined(MAL_NO_NULL)
#if !defined(MAL_NO_NULL)
#define MAL_ENABLE_NULL
#define MAL_ENABLE_NULL
#endif
#endif
...
@@ -215,6 +218,7 @@ typedef mal_int32 mal_bool32;
...
@@ -215,6 +218,7 @@ typedef mal_int32 mal_bool32;
typedef
void
*
mal_handle
;
typedef
void
*
mal_handle
;
typedef
void
*
mal_ptr
;
typedef
void
*
mal_ptr
;
typedef
void
(
*
mal_proc
)();
#ifdef MAL_WIN32
#ifdef MAL_WIN32
typedef
mal_handle
mal_thread
;
typedef
mal_handle
mal_thread
;
...
@@ -234,6 +238,9 @@ typedef void* mal_ptr;
...
@@ -234,6 +238,9 @@ typedef void* mal_ptr;
#ifdef MAL_ENABLE_DSOUND
#ifdef MAL_ENABLE_DSOUND
#define MAL_MAX_PERIODS_DSOUND 4
#define MAL_MAX_PERIODS_DSOUND 4
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
#define MAL_MAX_PERIODS_OPENAL 4
#endif
typedef
int
mal_result
;
typedef
int
mal_result
;
#define MAL_SUCCESS 0
#define MAL_SUCCESS 0
...
@@ -284,7 +291,8 @@ typedef enum
...
@@ -284,7 +291,8 @@ typedef enum
mal_backend_wasapi
,
mal_backend_wasapi
,
mal_backend_dsound
,
mal_backend_dsound
,
mal_backend_alsa
,
mal_backend_alsa
,
mal_backend_sles
mal_backend_sles
,
mal_backend_openal
}
mal_backend
;
}
mal_backend
;
typedef
enum
typedef
enum
...
@@ -307,10 +315,22 @@ typedef enum
...
@@ -307,10 +315,22 @@ typedef enum
typedef
union
typedef
union
{
{
// Just look at this shit...
// Just look at this shit...
#if defined(MAL_ENABLE_OPENSLES)
mal_uint32
id32
;
// OpenSL|ES uses a 32-bit unsigned integer for identification.
mal_uint32
id32
;
// OpenSL|ES uses a 32-bit unsigned integer for identification.
#endif
#if defined(MAL_ENABLE_ALSA)
char
str
[
32
];
// ALSA uses a name string for identification.
char
str
[
32
];
// ALSA uses a name string for identification.
wchar_t
wstr
[
64
];
// WASAPI uses a wchar_t string for identification which is also annoyingly long...
#endif
#if defined(MAL_ENABLE_DSOUND)
mal_uint8
guid
[
16
];
// DirectSound uses a GUID for identification.
mal_uint8
guid
[
16
];
// DirectSound uses a GUID for identification.
#endif
#if defined(MAL_ENABLE_WASAPI)
wchar_t
wstr
[
64
];
// WASAPI uses a wchar_t string for identification which is also annoyingly long...
#endif
#if defined(MAL_ENABLE_OPENAL)
char
openal
[
256
];
// OpenAL uses human-readable device names as the ID which is so flippin' stupid...
#endif
int
null
;
// <-- Just to ensure compilation works when no backends are enabled.
}
mal_device_id
;
}
mal_device_id
;
typedef
struct
typedef
struct
...
@@ -372,6 +392,105 @@ typedef struct
...
@@ -372,6 +392,105 @@ typedef struct
}
sles
;
}
sles
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
struct
{
/*HMODULE*/
mal_handle
hOpenAL
;
// OpenAL32.dll, etc.
mal_proc
alcCreateContext
;
mal_proc
alcMakeContextCurrent
;
mal_proc
alcProcessContext
;
mal_proc
alcSuspendContext
;
mal_proc
alcDestroyContext
;
mal_proc
alcGetCurrentContext
;
mal_proc
alcGetContextsDevice
;
mal_proc
alcOpenDevice
;
mal_proc
alcCloseDevice
;
mal_proc
alcGetError
;
mal_proc
alcIsExtensionPresent
;
mal_proc
alcGetProcAddress
;
mal_proc
alcGetEnumValue
;
mal_proc
alcGetString
;
mal_proc
alcGetIntegerv
;
mal_proc
alcCaptureOpenDevice
;
mal_proc
alcCaptureCloseDevice
;
mal_proc
alcCaptureStart
;
mal_proc
alcCaptureStop
;
mal_proc
alcCaptureSamples
;
mal_proc
alEnable
;
mal_proc
alDisable
;
mal_proc
alIsEnabled
;
mal_proc
alGetString
;
mal_proc
alGetBooleanv
;
mal_proc
alGetIntegerv
;
mal_proc
alGetFloatv
;
mal_proc
alGetDoublev
;
mal_proc
alGetBoolean
;
mal_proc
alGetInteger
;
mal_proc
alGetFloat
;
mal_proc
alGetDouble
;
mal_proc
alGetError
;
mal_proc
alIsExtensionPresent
;
mal_proc
alGetProcAddress
;
mal_proc
alGetEnumValue
;
mal_proc
alListenerf
;
mal_proc
alListener3f
;
mal_proc
alListenerfv
;
mal_proc
alListeneri
;
mal_proc
alListener3i
;
mal_proc
alListeneriv
;
mal_proc
alGetListenerf
;
mal_proc
alGetListener3f
;
mal_proc
alGetListenerfv
;
mal_proc
alGetListeneri
;
mal_proc
alGetListener3i
;
mal_proc
alGetListeneriv
;
mal_proc
alGenSources
;
mal_proc
alDeleteSources
;
mal_proc
alIsSource
;
mal_proc
alSourcef
;
mal_proc
alSource3f
;
mal_proc
alSourcefv
;
mal_proc
alSourcei
;
mal_proc
alSource3i
;
mal_proc
alSourceiv
;
mal_proc
alGetSourcef
;
mal_proc
alGetSource3f
;
mal_proc
alGetSourcefv
;
mal_proc
alGetSourcei
;
mal_proc
alGetSource3i
;
mal_proc
alGetSourceiv
;
mal_proc
alSourcePlayv
;
mal_proc
alSourceStopv
;
mal_proc
alSourceRewindv
;
mal_proc
alSourcePausev
;
mal_proc
alSourcePlay
;
mal_proc
alSourceStop
;
mal_proc
alSourceRewind
;
mal_proc
alSourcePause
;
mal_proc
alSourceQueueBuffers
;
mal_proc
alSourceUnqueueBuffers
;
mal_proc
alGenBuffers
;
mal_proc
alDeleteBuffers
;
mal_proc
alIsBuffer
;
mal_proc
alBufferData
;
mal_proc
alBufferf
;
mal_proc
alBuffer3f
;
mal_proc
alBufferfv
;
mal_proc
alBufferi
;
mal_proc
alBuffer3i
;
mal_proc
alBufferiv
;
mal_proc
alGetBufferf
;
mal_proc
alGetBuffer3f
;
mal_proc
alGetBufferfv
;
mal_proc
alGetBufferi
;
mal_proc
alGetBuffer3i
;
mal_proc
alGetBufferiv
;
mal_uint32
isFloat32Supported
;
}
openal
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
struct
struct
{
{
...
@@ -464,6 +583,16 @@ struct mal_device
...
@@ -464,6 +583,16 @@ struct mal_device
}
sles
;
}
sles
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
struct
{
/*ALCcontext**/
mal_ptr
pContextALC
;
/*ALCdevice**/
mal_ptr
pDeviceALC
;
/*ALuint*/
mal_uint32
sourceAL
;
/*ALuint*/
mal_uint32
buffersAL
[
MAL_MAX_PERIODS_OPENAL
];
}
openal
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
struct
struct
{
{
...
@@ -492,6 +621,7 @@ struct mal_device
...
@@ -492,6 +621,7 @@ struct mal_device
// - WASAPI
// - WASAPI
// - ALSA
// - ALSA
// - OpenSL|ES
// - OpenSL|ES
// - OpenAL
// - Null
// - Null
//
//
// Return Value:
// Return Value:
...
@@ -756,6 +886,7 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format);
...
@@ -756,6 +886,7 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format);
#ifdef MAL_POSIX
#ifdef MAL_POSIX
#include <unistd.h>
#include <unistd.h>
#include <dlfcn.h>
#endif
#endif
#ifdef MAL_ENABLE_ALSA
#ifdef MAL_ENABLE_ALSA
...
@@ -1031,6 +1162,39 @@ double mal_timer_get_time_in_seconds(mal_timer* pTimer)
...
@@ -1031,6 +1162,39 @@ double mal_timer_get_time_in_seconds(mal_timer* pTimer)
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Dynamic Linking
//
///////////////////////////////////////////////////////////////////////////////
mal_handle
mal_dlopen
(
const
char
*
filename
)
{
#ifdef _WIN32
return
(
mal_handle
)
LoadLibraryA
(
filename
);
#else
return
(
mal_handle
)
dlopen
(
filename
,
RTLD_NOW
);
#endif
}
void
mal_dlclose
(
mal_handle
handle
)
{
#ifdef _WIN32
CloseHandle
((
HANDLE
)
handle
);
#else
dlclose
((
void
*
)
handle
);
#endif
}
mal_proc
mal_dlsym
(
mal_handle
handle
,
const
char
*
symbol
)
{
#ifdef _WIN32
return
(
mal_proc
)
GetProcAddress
((
HMODULE
)
handle
,
symbol
);
#else
return
(
mal_proc
)
dlsym
((
void
*
)
handle
,
symbol
);
#endif
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
// Threading
// Threading
...
@@ -3899,8 +4063,426 @@ static mal_result mal_device__stop_backend__sles(mal_device* pDevice)
...
@@ -3899,8 +4063,426 @@ static mal_result mal_device__stop_backend__sles(mal_device* pDevice)
return
MAL_SUCCESS
;
return
MAL_SUCCESS
;
}
}
#endif // OpenSL|ES
///////////////////////////////////////////////////////////////////////////////
//
// OpenAL Backend
//
///////////////////////////////////////////////////////////////////////////////
#ifdef MAL_ENABLE_OPENAL
#ifdef MAL_APPLE
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#endif
#ifdef MAL_WIN32
#define MAL_AL_APIENTRY __cdecl
#else
#define MAL_AL_APIENTRY
#endif
#define MAL_AL_FORMAT_MONO_FLOAT32 0x10010
#define MAL_AL_FORMAT_STEREO_FLOAT32 0x10011
// TODO: Remove unused APIs.
typedef
ALCcontext
*
(
MAL_AL_APIENTRY
*
MAL_LPALCCREATECONTEXT
)
(
ALCdevice
*
device
,
const
ALCint
*
attrlist
);
typedef
ALCboolean
(
MAL_AL_APIENTRY
*
MAL_LPALCMAKECONTEXTCURRENT
)(
ALCcontext
*
context
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCPROCESSCONTEXT
)
(
ALCcontext
*
context
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCSUSPENDCONTEXT
)
(
ALCcontext
*
context
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCDESTROYCONTEXT
)
(
ALCcontext
*
context
);
typedef
ALCcontext
*
(
MAL_AL_APIENTRY
*
MAL_LPALCGETCURRENTCONTEXT
)
(
void
);
typedef
ALCdevice
*
(
MAL_AL_APIENTRY
*
MAL_LPALCGETCONTEXTSDEVICE
)
(
ALCcontext
*
context
);
typedef
ALCdevice
*
(
MAL_AL_APIENTRY
*
MAL_LPALCOPENDEVICE
)
(
const
ALCchar
*
devicename
);
typedef
ALCboolean
(
MAL_AL_APIENTRY
*
MAL_LPALCCLOSEDEVICE
)
(
ALCdevice
*
device
);
typedef
ALCenum
(
MAL_AL_APIENTRY
*
MAL_LPALCGETERROR
)
(
ALCdevice
*
device
);
typedef
ALCboolean
(
MAL_AL_APIENTRY
*
MAL_LPALCISEXTENSIONPRESENT
)(
ALCdevice
*
device
,
const
ALCchar
*
extname
);
typedef
void
*
(
MAL_AL_APIENTRY
*
MAL_LPALCGETPROCADDRESS
)
(
ALCdevice
*
device
,
const
ALCchar
*
funcname
);
typedef
ALCenum
(
MAL_AL_APIENTRY
*
MAL_LPALCGETENUMVALUE
)
(
ALCdevice
*
device
,
const
ALCchar
*
enumname
);
typedef
const
ALCchar
*
(
MAL_AL_APIENTRY
*
MAL_LPALCGETSTRING
)
(
ALCdevice
*
device
,
ALCenum
param
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCGETINTEGERV
)
(
ALCdevice
*
device
,
ALCenum
param
,
ALCsizei
size
,
ALCint
*
values
);
typedef
ALCdevice
*
(
MAL_AL_APIENTRY
*
MAL_LPALCCAPTUREOPENDEVICE
)
(
const
ALCchar
*
devicename
,
ALCuint
frequency
,
ALCenum
format
,
ALCsizei
buffersize
);
typedef
ALCboolean
(
MAL_AL_APIENTRY
*
MAL_LPALCCAPTURECLOSEDEVICE
)(
ALCdevice
*
device
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCCAPTURESTART
)
(
ALCdevice
*
device
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCCAPTURESTOP
)
(
ALCdevice
*
device
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALCCAPTURESAMPLES
)
(
ALCdevice
*
device
,
ALCvoid
*
buffer
,
ALCsizei
samples
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALENABLE
)
(
ALenum
capability
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDISABLE
)
(
ALenum
capability
);
typedef
ALboolean
(
MAL_AL_APIENTRY
*
MAL_LPALISENABLED
)
(
ALenum
capability
);
typedef
const
ALchar
*
(
MAL_AL_APIENTRY
*
MAL_LPALGETSTRING
)
(
ALenum
param
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBOOLEANV
)
(
ALenum
param
,
ALboolean
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETINTEGERV
)
(
ALenum
param
,
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETFLOATV
)
(
ALenum
param
,
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETDOUBLEV
)
(
ALenum
param
,
ALdouble
*
values
);
typedef
ALboolean
(
MAL_AL_APIENTRY
*
MAL_LPALGETBOOLEAN
)
(
ALenum
param
);
typedef
ALint
(
MAL_AL_APIENTRY
*
MAL_LPALGETINTEGER
)
(
ALenum
param
);
typedef
ALfloat
(
MAL_AL_APIENTRY
*
MAL_LPALGETFLOAT
)
(
ALenum
param
);
typedef
ALdouble
(
MAL_AL_APIENTRY
*
MAL_LPALGETDOUBLE
)
(
ALenum
param
);
typedef
ALenum
(
MAL_AL_APIENTRY
*
MAL_LPALGETERROR
)
(
void
);
typedef
ALboolean
(
MAL_AL_APIENTRY
*
MAL_LPALISEXTENSIONPRESENT
)
(
const
ALchar
*
extname
);
typedef
void
*
(
MAL_AL_APIENTRY
*
MAL_LPALGETPROCADDRESS
)
(
const
ALchar
*
fname
);
typedef
ALenum
(
MAL_AL_APIENTRY
*
MAL_LPALGETENUMVALUE
)
(
const
ALchar
*
ename
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENERF
)
(
ALenum
param
,
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENER3F
)
(
ALenum
param
,
ALfloat
value1
,
ALfloat
value2
,
ALfloat
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENERFV
)
(
ALenum
param
,
const
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENERI
)
(
ALenum
param
,
ALint
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENER3I
)
(
ALenum
param
,
ALint
value1
,
ALint
value2
,
ALint
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALLISTENERIV
)
(
ALenum
param
,
const
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENERF
)
(
ALenum
param
,
ALfloat
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENER3F
)
(
ALenum
param
,
ALfloat
*
value1
,
ALfloat
*
value2
,
ALfloat
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENERFV
)
(
ALenum
param
,
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENERI
)
(
ALenum
param
,
ALint
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENER3I
)
(
ALenum
param
,
ALint
*
value1
,
ALint
*
value2
,
ALint
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETLISTENERIV
)
(
ALenum
param
,
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGENSOURCES
)
(
ALsizei
n
,
ALuint
*
sources
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDELETESOURCES
)
(
ALsizei
n
,
const
ALuint
*
sources
);
typedef
ALboolean
(
MAL_AL_APIENTRY
*
MAL_LPALISSOURCE
)
(
ALuint
source
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEF
)
(
ALuint
source
,
ALenum
param
,
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCE3F
)
(
ALuint
source
,
ALenum
param
,
ALfloat
value1
,
ALfloat
value2
,
ALfloat
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEFV
)
(
ALuint
source
,
ALenum
param
,
const
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEI
)
(
ALuint
source
,
ALenum
param
,
ALint
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCE3I
)
(
ALuint
source
,
ALenum
param
,
ALint
value1
,
ALint
value2
,
ALint
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEIV
)
(
ALuint
source
,
ALenum
param
,
const
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCEF
)
(
ALuint
source
,
ALenum
param
,
ALfloat
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCE3F
)
(
ALuint
source
,
ALenum
param
,
ALfloat
*
value1
,
ALfloat
*
value2
,
ALfloat
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCEFV
)
(
ALuint
source
,
ALenum
param
,
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCEI
)
(
ALuint
source
,
ALenum
param
,
ALint
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCE3I
)
(
ALuint
source
,
ALenum
param
,
ALint
*
value1
,
ALint
*
value2
,
ALint
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETSOURCEIV
)
(
ALuint
source
,
ALenum
param
,
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEPLAYV
)
(
ALsizei
n
,
const
ALuint
*
sources
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCESTOPV
)
(
ALsizei
n
,
const
ALuint
*
sources
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEREWINDV
)
(
ALsizei
n
,
const
ALuint
*
sources
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEPAUSEV
)
(
ALsizei
n
,
const
ALuint
*
sources
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEPLAY
)
(
ALuint
source
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCESTOP
)
(
ALuint
source
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEREWIND
)
(
ALuint
source
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEPAUSE
)
(
ALuint
source
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEQUEUEBUFFERS
)
(
ALuint
source
,
ALsizei
nb
,
const
ALuint
*
buffers
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSOURCEUNQUEUEBUFFERS
)(
ALuint
source
,
ALsizei
nb
,
ALuint
*
buffers
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGENBUFFERS
)
(
ALsizei
n
,
ALuint
*
buffers
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDELETEBUFFERS
)
(
ALsizei
n
,
const
ALuint
*
buffers
);
typedef
ALboolean
(
MAL_AL_APIENTRY
*
MAL_LPALISBUFFER
)
(
ALuint
buffer
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFERDATA
)
(
ALuint
buffer
,
ALenum
format
,
const
ALvoid
*
data
,
ALsizei
size
,
ALsizei
freq
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFERF
)
(
ALuint
buffer
,
ALenum
param
,
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFER3F
)
(
ALuint
buffer
,
ALenum
param
,
ALfloat
value1
,
ALfloat
value2
,
ALfloat
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFERFV
)
(
ALuint
buffer
,
ALenum
param
,
const
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFERI
)
(
ALuint
buffer
,
ALenum
param
,
ALint
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFER3I
)
(
ALuint
buffer
,
ALenum
param
,
ALint
value1
,
ALint
value2
,
ALint
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALBUFFERIV
)
(
ALuint
buffer
,
ALenum
param
,
const
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFERF
)
(
ALuint
buffer
,
ALenum
param
,
ALfloat
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFER3F
)
(
ALuint
buffer
,
ALenum
param
,
ALfloat
*
value1
,
ALfloat
*
value2
,
ALfloat
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFERFV
)
(
ALuint
buffer
,
ALenum
param
,
ALfloat
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFERI
)
(
ALuint
buffer
,
ALenum
param
,
ALint
*
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFER3I
)
(
ALuint
buffer
,
ALenum
param
,
ALint
*
value1
,
ALint
*
value2
,
ALint
*
value3
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALGETBUFFERIV
)
(
ALuint
buffer
,
ALenum
param
,
ALint
*
values
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDOPPLERFACTOR
)
(
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDOPPLERVELOCITY
)
(
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALSPEEDOFSOUND
)
(
ALfloat
value
);
typedef
void
(
MAL_AL_APIENTRY
*
MAL_LPALDISTANCEMODEL
)
(
ALenum
distanceModel
);
mal_result
mal_context_init__openal
(
mal_context
*
pContext
)
{
mal_assert
(
pContext
!=
NULL
);
const
char
*
libName
=
#ifdef MAL_WIN32
"OpenAL32.dll"
;
#endif
#ifdef MAL_LINUX
"libopenal.so"
;
#endif
#ifdef MAL_APPLE
// I don't own a Mac so a contribution here would be much appreciated!
#endif
pContext
->
openal
.
hOpenAL
=
mal_dlopen
(
libName
);
#ifdef MAL_WIN32
// Special case for Win32 - try "soft_oal.dll" for OpenAL Soft drop-ins.
if
(
pContext
->
openal
.
hOpenAL
==
NULL
)
{
pContext
->
openal
.
hOpenAL
=
mal_dlopen
(
"soft_oal.dll"
);
}
#endif
if
(
pContext
->
openal
.
hOpenAL
==
NULL
)
{
return
MAL_FAILED_TO_INIT_BACKEND
;
}
pContext
->
openal
.
alcCreateContext
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCreateContext"
);
pContext
->
openal
.
alcMakeContextCurrent
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcMakeContextCurrent"
);
pContext
->
openal
.
alcProcessContext
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcProcessContext"
);
pContext
->
openal
.
alcSuspendContext
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcSuspendContext"
);
pContext
->
openal
.
alcDestroyContext
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcDestroyContext"
);
pContext
->
openal
.
alcGetCurrentContext
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetCurrentContext"
);
pContext
->
openal
.
alcGetContextsDevice
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetContextsDevice"
);
pContext
->
openal
.
alcOpenDevice
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcOpenDevice"
);
pContext
->
openal
.
alcCloseDevice
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCloseDevice"
);
pContext
->
openal
.
alcGetError
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetError"
);
pContext
->
openal
.
alcIsExtensionPresent
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcIsExtensionPresent"
);
pContext
->
openal
.
alcGetProcAddress
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetProcAddress"
);
pContext
->
openal
.
alcGetEnumValue
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetEnumValue"
);
pContext
->
openal
.
alcGetString
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetString"
);
pContext
->
openal
.
alcGetIntegerv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcGetIntegerv"
);
pContext
->
openal
.
alcCaptureOpenDevice
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCaptureOpenDevice"
);
pContext
->
openal
.
alcCaptureCloseDevice
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCaptureCloseDevice"
);
pContext
->
openal
.
alcCaptureStart
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCaptureStart"
);
pContext
->
openal
.
alcCaptureStop
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCaptureStop"
);
pContext
->
openal
.
alcCaptureSamples
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alcCaptureSamples"
);
pContext
->
openal
.
alEnable
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alEnable"
);
pContext
->
openal
.
alDisable
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alDisable"
);
pContext
->
openal
.
alIsEnabled
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alIsEnabled"
);
pContext
->
openal
.
alGetString
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetString"
);
pContext
->
openal
.
alGetBooleanv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBooleanv"
);
pContext
->
openal
.
alGetIntegerv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetIntegerv"
);
pContext
->
openal
.
alGetFloatv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetFloatv"
);
pContext
->
openal
.
alGetDoublev
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetDoublev"
);
pContext
->
openal
.
alGetBoolean
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBoolean"
);
pContext
->
openal
.
alGetInteger
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetInteger"
);
pContext
->
openal
.
alGetFloat
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetFloat"
);
pContext
->
openal
.
alGetDouble
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetDouble"
);
pContext
->
openal
.
alGetError
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetError"
);
pContext
->
openal
.
alIsExtensionPresent
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alIsExtensionPresent"
);
pContext
->
openal
.
alGetProcAddress
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetProcAddress"
);
pContext
->
openal
.
alGetEnumValue
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetEnumValue"
);
pContext
->
openal
.
alListenerf
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListenerf"
);
pContext
->
openal
.
alListener3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListener3f"
);
pContext
->
openal
.
alListenerfv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListenerfv"
);
pContext
->
openal
.
alListeneri
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListeneri"
);
pContext
->
openal
.
alListener3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListener3i"
);
pContext
->
openal
.
alListeneriv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alListeneriv"
);
pContext
->
openal
.
alGetListenerf
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListenerf"
);
pContext
->
openal
.
alGetListener3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListener3f"
);
pContext
->
openal
.
alGetListenerfv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListenerfv"
);
pContext
->
openal
.
alGetListeneri
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListeneri"
);
pContext
->
openal
.
alGetListener3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListener3i"
);
pContext
->
openal
.
alGetListeneriv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetListeneriv"
);
pContext
->
openal
.
alGenSources
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGenSources"
);
pContext
->
openal
.
alDeleteSources
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alDeleteSources"
);
pContext
->
openal
.
alIsSource
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alIsSource"
);
pContext
->
openal
.
alSourcef
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcef"
);
pContext
->
openal
.
alSource3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSource3f"
);
pContext
->
openal
.
alSourcefv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcefv"
);
pContext
->
openal
.
alSourcei
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcei"
);
pContext
->
openal
.
alSource3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSource3i"
);
pContext
->
openal
.
alSourceiv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceiv"
);
pContext
->
openal
.
alGetSourcef
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSourcef"
);
pContext
->
openal
.
alGetSource3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSource3f"
);
pContext
->
openal
.
alGetSourcefv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSourcefv"
);
pContext
->
openal
.
alGetSourcei
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSourcei"
);
pContext
->
openal
.
alGetSource3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSource3i"
);
pContext
->
openal
.
alGetSourceiv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetSourceiv"
);
pContext
->
openal
.
alSourcePlayv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcePlayv"
);
pContext
->
openal
.
alSourceStopv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceStopv"
);
pContext
->
openal
.
alSourceRewindv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceRewindv"
);
pContext
->
openal
.
alSourcePausev
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcePausev"
);
pContext
->
openal
.
alSourcePlay
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcePlay"
);
pContext
->
openal
.
alSourceStop
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceStop"
);
pContext
->
openal
.
alSourceRewind
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceRewind"
);
pContext
->
openal
.
alSourcePause
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourcePause"
);
pContext
->
openal
.
alSourceQueueBuffers
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceQueueBuffers"
);
pContext
->
openal
.
alSourceUnqueueBuffers
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alSourceUnqueueBuffers"
);
pContext
->
openal
.
alGenBuffers
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGenBuffers"
);
pContext
->
openal
.
alDeleteBuffers
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alDeleteBuffers"
);
pContext
->
openal
.
alIsBuffer
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alIsBuffer"
);
pContext
->
openal
.
alBufferData
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBufferData"
);
pContext
->
openal
.
alBufferf
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBufferf"
);
pContext
->
openal
.
alBuffer3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBuffer3f"
);
pContext
->
openal
.
alBufferfv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBufferfv"
);
pContext
->
openal
.
alBufferi
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBufferi"
);
pContext
->
openal
.
alBuffer3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBuffer3i"
);
pContext
->
openal
.
alBufferiv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alBufferiv"
);
pContext
->
openal
.
alGetBufferf
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBufferf"
);
pContext
->
openal
.
alGetBuffer3f
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBuffer3f"
);
pContext
->
openal
.
alGetBufferfv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBufferfv"
);
pContext
->
openal
.
alGetBufferi
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBufferi"
);
pContext
->
openal
.
alGetBuffer3i
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBuffer3i"
);
pContext
->
openal
.
alGetBufferiv
=
(
mal_proc
)
mal_dlsym
(
pContext
->
openal
.
hOpenAL
,
"alGetBufferiv"
);
// We depend on the ALC_ENUMERATION_EXT extension.
if
(
!
((
MAL_LPALCISEXTENSIONPRESENT
)
pContext
->
openal
.
alcIsExtensionPresent
)(
NULL
,
"ALC_ENUMERATION_EXT"
))
{
mal_dlclose
(
pContext
->
openal
.
hOpenAL
);
return
MAL_FAILED_TO_INIT_BACKEND
;
}
pContext
->
openal
.
isFloat32Supported
=
((
MAL_LPALISEXTENSIONPRESENT
)
pContext
->
openal
.
alIsExtensionPresent
)(
"AL_EXT_float32"
);
return
MAL_SUCCESS
;
}
mal_result
mal_context_uninit__openal
(
mal_context
*
pContext
)
{
mal_assert
(
pContext
!=
NULL
);
mal_assert
(
pContext
->
backend
==
mal_backend_openal
);
mal_dlclose
(
pContext
->
openal
.
hOpenAL
);
return
MAL_SUCCESS
;
}
mal_result
mal_enumerate_devices__openal
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_uint32
*
pCount
,
mal_device_info
*
pInfo
)
{
mal_uint32
infoCapacity
=
*
pCount
;
*
pCount
=
0
;
const
ALCchar
*
pDeviceNames
=
((
MAL_LPALCGETSTRING
)
pContext
->
openal
.
alcGetString
)(
NULL
,
(
type
==
mal_device_type_playback
)
?
ALC_DEVICE_SPECIFIER
:
ALC_CAPTURE_DEVICE_SPECIFIER
);
if
(
pDeviceNames
==
NULL
)
{
return
MAL_NO_DEVICE
;
}
// Each device is stored in pDeviceNames, separated by a null-terminator. The string itself is double-null-terminated.
const
ALCchar
*
pNextDeviceName
=
pDeviceNames
;
for
(;;)
{
*
pCount
+=
1
;
if
(
pInfo
!=
NULL
&&
infoCapacity
>
0
)
{
mal_strncpy_s
(
pInfo
->
id
.
openal
,
sizeof
(
pInfo
->
id
.
openal
),
(
const
char
*
)
pNextDeviceName
,
(
size_t
)
-
1
);
mal_strncpy_s
(
pInfo
->
name
,
sizeof
(
pInfo
->
name
),
(
const
char
*
)
pNextDeviceName
,
(
size_t
)
-
1
);
pInfo
+=
1
;
infoCapacity
-=
1
;
}
// Move to the next device name.
while
(
*
pNextDeviceName
!=
'\0'
)
{
pNextDeviceName
+=
1
;
}
// If we've reached the double-null-terminator, we're done.
pNextDeviceName
+=
1
;
if
(
*
pNextDeviceName
==
'\0'
)
{
break
;
}
};
return
MAL_SUCCESS
;
}
static
void
mal_device_uninit__openal
(
mal_device
*
pDevice
)
{
mal_assert
(
pDevice
!=
NULL
);
((
MAL_LPALCDESTROYCONTEXT
)
pDevice
->
pContext
->
openal
.
alcDestroyContext
)(
pDevice
->
openal
.
pContextALC
);
if
(
pDevice
->
type
==
mal_device_type_playback
)
{
((
MAL_LPALCCLOSEDEVICE
)
pDevice
->
pContext
->
openal
.
alcCloseDevice
)(
pDevice
->
openal
.
pDeviceALC
);
}
else
{
((
MAL_LPALCCAPTURECLOSEDEVICE
)
pDevice
->
pContext
->
openal
.
alcCaptureCloseDevice
)(
pDevice
->
openal
.
pDeviceALC
);
}
}
static
mal_result
mal_device_init__openal
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
{
if
(
pDevice
->
periods
>
MAL_MAX_PERIODS_OPENAL
)
{
pDevice
->
periods
=
MAL_MAX_PERIODS_OPENAL
;
}
ALCsizei
bufferSizeInSamplesAL
=
pConfig
->
bufferSizeInFrames
;
ALCuint
frequencyAL
=
pConfig
->
sampleRate
;
// OpenAL supports only mono and stereo.
ALCenum
formatAL
=
0
;
if
(
pConfig
->
channels
==
1
)
{
// Mono.
if
(
pConfig
->
format
==
mal_format_f32
)
{
if
(
pContext
->
openal
.
isFloat32Supported
)
{
formatAL
=
MAL_AL_FORMAT_MONO_FLOAT32
;
}
else
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
}
else
if
(
pConfig
->
format
==
mal_format_s32
)
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
else
if
(
pConfig
->
format
==
mal_format_s24
)
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
else
if
(
pConfig
->
format
==
mal_format_s16
)
{
formatAL
=
AL_FORMAT_MONO16
;
}
else
if
(
pConfig
->
format
==
mal_format_u8
)
{
formatAL
=
AL_FORMAT_MONO8
;
}
}
else
{
// Stereo.
bufferSizeInSamplesAL
*=
2
;
if
(
pConfig
->
format
==
mal_format_f32
)
{
if
(
pContext
->
openal
.
isFloat32Supported
)
{
formatAL
=
MAL_AL_FORMAT_STEREO_FLOAT32
;
}
else
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
}
else
if
(
pConfig
->
format
==
mal_format_s32
)
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
else
if
(
pConfig
->
format
==
mal_format_s24
)
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
else
if
(
pConfig
->
format
==
mal_format_s16
)
{
formatAL
=
AL_FORMAT_STEREO16
;
}
else
if
(
pConfig
->
format
==
mal_format_u8
)
{
formatAL
=
AL_FORMAT_STEREO8
;
}
}
if
(
formatAL
==
0
)
{
return
MAL_FORMAT_NOT_SUPPORTED
;
}
// OpenAL feels a bit unintuitive to me... The global object is a device, and it would appear that each device can have
// many context's...
ALCdevice
*
pDeviceALC
=
NULL
;
if
(
type
==
mal_device_type_playback
)
{
pDeviceALC
=
((
MAL_LPALCOPENDEVICE
)
pContext
->
openal
.
alcOpenDevice
)((
pDeviceID
==
NULL
)
?
NULL
:
pDeviceID
->
openal
);
}
else
{
pDeviceALC
=
((
MAL_LPALCCAPTUREOPENDEVICE
)
pContext
->
openal
.
alcCaptureOpenDevice
)((
pDeviceID
==
NULL
)
?
NULL
:
pDeviceID
->
openal
,
frequencyAL
,
formatAL
,
bufferSizeInSamplesAL
);
}
if
(
pDeviceALC
==
NULL
)
{
return
MAL_FAILED_TO_INIT_BACKEND
;
}
ALCcontext
*
pContextALC
=
((
MAL_LPALCCREATECONTEXT
)
pContext
->
openal
.
alcCreateContext
)(
pDeviceALC
,
NULL
);
if
(
pContextALC
==
NULL
)
{
if
(
pDevice
->
type
==
mal_device_type_playback
)
{
((
MAL_LPALCCLOSEDEVICE
)
pDevice
->
pContext
->
openal
.
alcCloseDevice
)(
pDeviceALC
);
}
else
{
((
MAL_LPALCCAPTURECLOSEDEVICE
)
pDevice
->
pContext
->
openal
.
alcCaptureCloseDevice
)(
pDeviceALC
);
}
return
MAL_FAILED_TO_INIT_BACKEND
;
}
((
MAL_LPALCMAKECONTEXTCURRENT
)
pDevice
->
pContext
->
openal
.
alcMakeContextCurrent
)(
pContextALC
);
ALuint
sourceAL
;
((
MAL_LPALGENSOURCES
)
pDevice
->
pContext
->
openal
.
alGenSources
)(
1
,
&
sourceAL
);
pDevice
->
openal
.
sourceAL
=
sourceAL
;
// We create the buffers, but only fill and queue them when the device is started.
ALuint
buffersAL
[
MAL_MAX_PERIODS_OPENAL
];
((
MAL_LPALGENBUFFERS
)
pDevice
->
pContext
->
openal
.
alGenBuffers
)(
pDevice
->
periods
,
buffersAL
);
for
(
mal_uint32
i
=
0
;
i
<
pDevice
->
periods
;
++
i
)
{
pDevice
->
openal
.
buffersAL
[
i
]
=
buffersAL
[
i
];
}
return
MAL_SUCCESS
;
}
#if 0
static mal_result mal_device__start_backend__openal(mal_device* pDevice)
{
mal_assert(pDevice != NULL);
return MAL_SUCCESS;
}
static mal_result mal_device__stop_backend__openal(mal_device* pDevice)
{
mal_assert(pDevice != NULL);
return MAL_SUCCESS;
}
#endif
#endif // OpenAL
static
mal_result
mal_device__start_backend
(
mal_device
*
pDevice
)
static
mal_result
mal_device__start_backend
(
mal_device
*
pDevice
)
{
{
...
@@ -4104,6 +4686,7 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal
...
@@ -4104,6 +4686,7 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal
mal_zero_object
(
pContext
);
mal_zero_object
(
pContext
);
static
mal_backend
defaultBackends
[]
=
{
static
mal_backend
defaultBackends
[]
=
{
mal_backend_openal
,
// TODO: Move this below all platform-specific backends.
mal_backend_dsound
,
mal_backend_dsound
,
mal_backend_wasapi
,
mal_backend_wasapi
,
mal_backend_alsa
,
mal_backend_alsa
,
...
@@ -4162,6 +4745,16 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal
...
@@ -4162,6 +4745,16 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal
}
}
}
break
;
}
break
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
case
mal_backend_openal
:
{
mal_result
result
=
mal_context_init__openal
(
pContext
);
if
(
result
==
MAL_SUCCESS
)
{
pContext
->
backend
=
mal_backend_openal
;
return
result
;
}
}
break
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
case
mal_backend_null
:
case
mal_backend_null
:
{
{
...
@@ -4210,6 +4803,12 @@ mal_result mal_context_uninit(mal_context* pContext)
...
@@ -4210,6 +4803,12 @@ mal_result mal_context_uninit(mal_context* pContext)
return
mal_context_uninit__sles
(
pContext
);
return
mal_context_uninit__sles
(
pContext
);
}
break
;
}
break
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
case
mal_backend_openal
:
{
return
mal_context_uninit__openal
(
pContext
);
}
break
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
case
mal_backend_null
:
case
mal_backend_null
:
{
{
...
@@ -4255,6 +4854,12 @@ mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, ma
...
@@ -4255,6 +4854,12 @@ mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, ma
return
mal_enumerate_devices__sles
(
pContext
,
type
,
pCount
,
pInfo
);
return
mal_enumerate_devices__sles
(
pContext
,
type
,
pCount
,
pInfo
);
}
break
;
}
break
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
case
mal_backend_openal
:
{
return
mal_enumerate_devices__openal
(
pContext
,
type
,
pCount
,
pInfo
);
}
break
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
case
mal_backend_null
:
case
mal_backend_null
:
{
{
...
@@ -4360,6 +4965,12 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
...
@@ -4360,6 +4965,12 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
result
=
mal_device_init__sles
(
pContext
,
type
,
pDeviceID
,
pConfig
,
pDevice
);
result
=
mal_device_init__sles
(
pContext
,
type
,
pDeviceID
,
pConfig
,
pDevice
);
}
break
;
}
break
;
#endif
#endif
#ifdef MAL_ENABLE_OPENAL
case
mal_backend_openal
:
{
result
=
mal_device_init__openal
(
pContext
,
type
,
pDeviceID
,
pConfig
,
pDevice
);
}
break
;
#endif
#ifdef MAL_ENABLE_NULL
#ifdef MAL_ENABLE_NULL
case
mal_backend_null
:
case
mal_backend_null
:
{
{
...
@@ -4636,6 +5247,7 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format)
...
@@ -4636,6 +5247,7 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format)
// - Requires a large suite of conversion routines including channel shuffling, SRC and format conversion.
// - Requires a large suite of conversion routines including channel shuffling, SRC and format conversion.
// - Look into event callbacks: AUDCLNT_STREAMFLAGS_EVENTCALLBACK
// - Look into event callbacks: AUDCLNT_STREAMFLAGS_EVENTCALLBACK
// - Link to ole32.lib at run time.
// - Link to ole32.lib at run time.
// - Clean up that terrible "__cplusplus" mess by implementing wrapper functions.
//
//
//
//
// ALSA
// ALSA
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment