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
fbecb5de
Commit
fbecb5de
authored
Nov 18, 2017
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial work on an experimental SDL backend for Emscripten.
parent
0f409ac3
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
279 additions
and
9 deletions
+279
-9
mini_al.h
mini_al.h
+279
-9
No files found.
mini_al.h
View file @
fbecb5de
...
...
@@ -233,8 +233,14 @@ extern "C" {
#define MAL_SUPPORT_OSS
#endif
#endif
#define MAL_SUPPORT_OPENAL // All platforms support OpenAL (at least for now).
#define MAL_SUPPORT_NULL // All platforms support the null device.
// Explicitly disable OpenAL for Emscripten - prefer SDL for this.
#if !defined(MAL_EMSCRIPTEN)
#define MAL_SUPPORT_OPENAL
#endif
#define MAL_SUPPORT_SDL // All platforms support SDL.
#define MAL_SUPPORT_NULL // All platforms support the null backend.
#if !defined(MAL_NO_WASAPI) && defined(MAL_SUPPORT_WASAPI)
...
...
@@ -261,6 +267,9 @@ extern "C" {
#if !defined(MAL_NO_OPENAL) && defined(MAL_SUPPORT_OPENAL)
#define MAL_ENABLE_OPENAL
#endif
#if !defined(MAL_NO_SDL) && defined(MAL_SUPPORT_SDL)
#define MAL_ENABLE_SDL
#endif
#if !defined(MAL_NO_NULL) && defined(MAL_SUPPORT_NULL)
#define MAL_ENABLE_NULL
#endif
...
...
@@ -469,7 +478,8 @@ typedef enum
mal_backend_alsa
,
mal_backend_oss
,
mal_backend_opensl
,
mal_backend_openal
mal_backend_openal
,
mal_backend_sdl
}
mal_backend
;
typedef
enum
...
...
@@ -522,6 +532,9 @@ typedef union
#ifdef MAL_SUPPORT_OPENAL
char
openal
[
256
];
// OpenAL seems to use human-readable device names as the ID.
#endif
#ifdef MAL_SUPPORT_SDL
int
sdl
;
//
#endif
#ifdef MAL_SUPPORT_NULL
int
nullbackend
;
// Always 0.
#endif
...
...
@@ -844,11 +857,17 @@ struct mal_context
mal_uint32
isMCFormatsSupported
:
1
;
}
openal
;
#endif
#ifdef MAL_SUPPORT_SDL
struct
{
int
_unused
;
}
sdl
;
#endif
#ifdef MAL_SUPPORT_NULL
struct
{
int
_unused
;
}
null_
device
;
}
null_
backend
;
#endif
};
...
...
@@ -1017,6 +1036,12 @@ struct mal_device
mal_bool32
breakFromMainLoop
;
}
openal
;
#endif
#ifdef MAL_SUPPORT_SDL
struct
{
mal_uint32
deviceID
;
}
sdl
;
#endif
#ifdef MAL_SUPPORT_NULL
struct
{
...
...
@@ -1575,12 +1600,26 @@ void mal_pcm_convert(void* pOut, mal_format formatOut, const void* pIn, mal_form
#ifdef MAL_ENABLE_OPENAL
#define MAL_HAS_OPENAL // mini_al inlines the necessary OpenAL stuff.
#endif
#ifdef MAL_ENABLE_SDL
#define MAL_HAS_SDL
#ifdef __has_include
#ifdef MAL_EMSCRIPTEN
#if !__has_include(<SDL/SDL_audio.h>)
#undef MAL_HAS_SDL
#endif
#else
#if !__has_include(<SDL2/SDL_audio.h>)
#undef MAL_HAS_SDL
#endif
#endif
#endif
#endif
#ifdef MAL_ENABLE_NULL
#define MAL_HAS_NULL // Everything supports the null backend.
#endif
// Disable run-time linking on certain backends.
#if defined(MAL_ANDROID) || defined(MAL_EMSCRIPTE
D
)
#if defined(MAL_ANDROID) || defined(MAL_EMSCRIPTE
N
)
#define MAL_NO_RUNTIME_LINKING
#endif
...
...
@@ -7768,7 +7807,7 @@ mal_result mal_enumerate_devices__openal(mal_context* pContext, mal_device_type
return
MAL_SUCCESS
;
}
static
void
mal_device_uninit__openal
(
mal_device
*
pDevice
)
void
mal_device_uninit__openal
(
mal_device
*
pDevice
)
{
mal_assert
(
pDevice
!=
NULL
);
...
...
@@ -7784,7 +7823,7 @@ static void mal_device_uninit__openal(mal_device* pDevice)
mal_free
(
pDevice
->
openal
.
pIntermediaryBuffer
);
}
static
mal_result
mal_device_init__openal
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
const
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
mal_result
mal_device_init__openal
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
const
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
{
if
(
pDevice
->
periods
>
MAL_MAX_PERIODS_OPENAL
)
{
pDevice
->
periods
=
MAL_MAX_PERIODS_OPENAL
;
...
...
@@ -8167,6 +8206,196 @@ static mal_result mal_device__main_loop__openal(mal_device* pDevice)
#endif // OpenAL
///////////////////////////////////////////////////////////////////////////////
//
// SDL Backend
//
///////////////////////////////////////////////////////////////////////////////
#ifdef MAL_HAS_SDL
#define SDL_MAIN_HANDLED
#ifdef MAL_EMSCRIPTEN
#include <SDL/SDL.h>
#else
#include <SDL2/SDL.h>
#endif
SDL_AudioFormat
mal_format_to_sdl
(
mal_format
format
)
{
switch
(
format
)
{
case
mal_format_unknown
:
return
0
;
case
mal_format_u8
:
return
AUDIO_U8
;
case
mal_format_s16
:
return
AUDIO_S16
;
case
mal_format_s24
:
return
AUDIO_S32
;
// Closest match.
case
mal_format_s32
:
return
AUDIO_S32
;
default:
return
0
;
}
}
mal_format
mal_format_from_sdl
(
SDL_AudioFormat
format
)
{
switch
(
format
)
{
case
AUDIO_U8
:
return
mal_format_u8
;
case
AUDIO_S16
:
return
mal_format_s16
;
case
AUDIO_S32
:
return
mal_format_s32
;
case
AUDIO_F32
:
return
mal_format_f32
;
default:
return
mal_format_unknown
;
}
}
mal_result
mal_context_init__sdl
(
mal_context
*
pContext
)
{
mal_assert
(
pContext
!=
NULL
);
int
resultSDL
=
SDL_InitSubSystem
(
SDL_INIT_AUDIO
);
if
(
resultSDL
!=
0
)
{
return
MAL_ERROR
;
}
return
MAL_SUCCESS
;
}
mal_result
mal_context_uninit__sdl
(
mal_context
*
pContext
)
{
mal_assert
(
pContext
!=
NULL
);
mal_assert
(
pContext
->
backend
==
mal_backend_sdl
);
SDL_QuitSubSystem
(
SDL_INIT_AUDIO
);
return
MAL_SUCCESS
;
}
mal_result
mal_enumerate_devices__sdl
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_uint32
*
pCount
,
mal_device_info
*
pInfo
)
{
(
void
)
pContext
;
mal_uint32
infoSize
=
*
pCount
;
*
pCount
=
0
;
// For now I'm restricting the SDL backend to default devices.
if
(
pInfo
!=
NULL
)
{
if
(
infoSize
>
0
)
{
if
(
type
==
mal_device_type_playback
)
{
pInfo
->
id
.
sdl
=
0
;
mal_strncpy_s
(
pInfo
->
name
,
sizeof
(
pInfo
->
name
),
"Default Playback Device"
,
(
size_t
)
-
1
);
}
else
{
pInfo
->
id
.
sdl
=
0
;
mal_strncpy_s
(
pInfo
->
name
,
sizeof
(
pInfo
->
name
),
"Default Capture Device"
,
(
size_t
)
-
1
);
}
pInfo
+=
1
;
*
pCount
+=
1
;
}
}
else
{
*
pCount
+=
1
;
}
return
MAL_SUCCESS
;
}
void
mal_device_uninit__sdl
(
mal_device
*
pDevice
)
{
mal_assert
(
pDevice
!=
NULL
);
#if 1
SDL_CloseAudioDevice
(
pDevice
->
sdl
.
deviceID
);
#else
SDL_CloseAudio
();
#endif
}
static
void
mal_audio_callback__sdl
(
void
*
pUserData
,
Uint8
*
pBuffer
,
int
bufferSizeInBytes
)
{
mal_device
*
pDevice
=
(
mal_device
*
)
pUserData
;
mal_assert
(
pDevice
!=
NULL
);
mal_uint32
bufferSizeInFrames
=
(
mal_uint32
)
bufferSizeInBytes
/
mal_get_sample_size_in_bytes
(
pDevice
->
format
)
/
pDevice
->
channels
;
if
(
pDevice
->
type
==
mal_device_type_playback
)
{
mal_device__read_frames_from_client
(
pDevice
,
bufferSizeInFrames
,
pBuffer
);
}
else
{
mal_device__send_frames_to_client
(
pDevice
,
bufferSizeInFrames
,
pBuffer
);
}
}
mal_result
mal_device_init__sdl
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
const
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
{
mal_assert
(
pContext
!=
NULL
);
mal_assert
(
pConfig
!=
NULL
);
mal_assert
(
pDevice
!=
NULL
);
SDL_AudioSpec
desiredSpec
,
obtainedSpec
;
mal_zero_memory
(
&
desiredSpec
,
sizeof
(
desiredSpec
));
desiredSpec
.
freq
=
(
int
)
pConfig
->
sampleRate
;
desiredSpec
.
format
=
mal_format_to_sdl
(
pConfig
->
format
);
desiredSpec
.
channels
=
(
Uint8
)
pConfig
->
channels
;
desiredSpec
.
samples
=
(
Uint16
)
mal_next_power_of_2
(
pConfig
->
bufferSizeInFrames
*
pConfig
->
periods
*
pConfig
->
channels
);
desiredSpec
.
callback
=
mal_audio_callback__sdl
;
desiredSpec
.
userdata
=
pDevice
;
// Fall back to f32 if we don't have an appropriate mapping between mini_al and SDL.
if
(
desiredSpec
.
format
==
0
)
{
desiredSpec
.
format
=
AUDIO_F32
;
}
// For now, only using the default device.
(
void
)
pDeviceID
;
#if 1
pDevice
->
sdl
.
deviceID
=
SDL_OpenAudioDevice
(
NULL
,
(
type
==
mal_device_type_playback
)
?
0
:
1
,
&
desiredSpec
,
&
obtainedSpec
,
0
);
if
(
pDevice
->
sdl
.
deviceID
==
0
)
{
return
mal_post_error
(
pDevice
,
"Failed to open SDL device."
,
MAL_FAILED_TO_OPEN_BACKEND_DEVICE
);
}
#else
pDevice
->
sdl
.
deviceID
=
SDL_OpenAudio
(
&
desiredSpec
,
&
obtainedSpec
);
if
(
pDevice
->
sdl
.
deviceID
!=
0
)
{
return
mal_post_error
(
pDevice
,
"Failed to open SDL device."
,
MAL_FAILED_TO_OPEN_BACKEND_DEVICE
);
}
#endif
pDevice
->
internalFormat
=
mal_format_from_sdl
(
obtainedSpec
.
format
);
pDevice
->
internalChannels
=
obtainedSpec
.
channels
;
pDevice
->
internalSampleRate
=
(
mal_uint32
)
obtainedSpec
.
freq
;
pDevice
->
bufferSizeInFrames
=
obtainedSpec
.
samples
/
obtainedSpec
.
channels
;
pDevice
->
periods
=
1
;
// SDL doesn't seem to tell us what the period count is. Just set this 1.
return
MAL_SUCCESS
;
}
static
mal_result
mal_device__start_backend__sdl
(
mal_device
*
pDevice
)
{
mal_assert
(
pDevice
!=
NULL
);
#if 1
SDL_PauseAudioDevice
(
pDevice
->
sdl
.
deviceID
,
0
);
#else
SDL_PauseAudio
(
0
);
#endif
return
MAL_SUCCESS
;
}
static
mal_result
mal_device__stop_backend__sdl
(
mal_device
*
pDevice
)
{
mal_assert
(
pDevice
!=
NULL
);
#if 1
SDL_PauseAudioDevice
(
pDevice
->
sdl
.
deviceID
,
1
);
#else
SDL_PauseAudio
(
1
);
#endif
return
MAL_SUCCESS
;
}
#endif // SDL
mal_bool32
mal__is_channel_map_valid
(
const
mal_channel
*
channelMap
,
mal_uint32
channels
)
{
mal_assert
(
channels
>
0
);
...
...
@@ -8585,6 +8814,7 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con
mal_backend_oss
,
mal_backend_opensl
,
mal_backend_openal
,
mal_backend_sdl
,
mal_backend_null
};
...
...
@@ -8642,6 +8872,12 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con
result
=
mal_context_init__openal
(
pContext
);
}
break
;
#endif
#ifdef MAL_HAS_SDL
case
mal_backend_sdl
:
{
result
=
mal_context_init__sdl
(
pContext
);
}
break
;
#endif
#ifdef MAL_HAS_NULL
case
mal_backend_null
:
{
...
...
@@ -8710,6 +8946,12 @@ mal_result mal_context_uninit(mal_context* pContext)
return
mal_context_uninit__openal
(
pContext
);
}
break
;
#endif
#ifdef MAL_HAS_SDL
case
mal_backend_sdl
:
{
return
mal_context_uninit__sdl
(
pContext
);
}
break
;
#endif
#ifdef MAL_HAS_NULL
case
mal_backend_null
:
{
...
...
@@ -8775,6 +9017,12 @@ mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, ma
return
mal_enumerate_devices__openal
(
pContext
,
type
,
pCount
,
pInfo
);
}
break
;
#endif
#ifdef MAL_HAS_SDL
case
mal_backend_sdl
:
{
return
mal_enumerate_devices__sdl
(
pContext
,
type
,
pCount
,
pInfo
);
}
break
;
#endif
#ifdef MAL_HAS_NULL
case
mal_backend_null
:
{
...
...
@@ -8934,6 +9182,12 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
result
=
mal_device_init__openal
(
pContext
,
type
,
pDeviceID
,
&
config
,
pDevice
);
}
break
;
#endif
#ifdef MAL_HAS_SDL
case
mal_backend_sdl
:
{
result
=
mal_device_init__sdl
(
pContext
,
type
,
pDeviceID
,
&
config
,
pDevice
);
}
break
;
#endif
#ifdef MAL_HAS_NULL
case
mal_backend_null
:
{
...
...
@@ -8979,7 +9233,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
// Some backends don't require the worker thread.
if
(
pContext
->
backend
!=
mal_backend_opensl
)
{
if
(
pContext
->
backend
!=
mal_backend_opensl
&&
pContext
->
backend
!=
mal_backend_sdl
)
{
// The worker thread.
if
(
mal_thread_create
(
pContext
,
&
pDevice
->
thread
,
mal_worker_thread
,
pDevice
)
!=
MAL_SUCCESS
)
{
mal_device_uninit
(
pDevice
);
...
...
@@ -9012,7 +9266,7 @@ void mal_device_uninit(mal_device* pDevice)
mal_device__set_state
(
pDevice
,
MAL_STATE_UNINITIALIZED
);
// Wake up the worker thread and wait for it to properly terminate.
if
(
pDevice
->
pContext
->
backend
!=
mal_backend_opensl
)
{
if
(
pDevice
->
pContext
->
backend
!=
mal_backend_opensl
&&
pDevice
->
pContext
->
backend
!=
mal_backend_sdl
)
{
mal_event_signal
(
&
pDevice
->
wakeupEvent
);
mal_thread_wait
(
&
pDevice
->
thread
);
}
...
...
@@ -9057,6 +9311,11 @@ void mal_device_uninit(mal_device* pDevice)
mal_device_uninit__openal
(
pDevice
);
}
#endif
#ifdef MAL_HAS_SDL
if
(
pDevice
->
pContext
->
backend
==
mal_backend_sdl
)
{
mal_device_uninit__sdl
(
pDevice
);
}
#endif
#ifdef MAL_HAS_NULL
if
(
pDevice
->
pContext
->
backend
==
mal_backend_null
)
{
mal_device_uninit__null
(
pDevice
);
...
...
@@ -9117,6 +9376,12 @@ mal_result mal_device_start(mal_device* pDevice)
mal_device__start_backend__opensl
(
pDevice
);
mal_device__set_state
(
pDevice
,
MAL_STATE_STARTED
);
}
else
#endif
#ifdef MAL_HAS_SDL
if
(
pDevice
->
pContext
->
backend
==
mal_backend_sdl
)
{
mal_device__start_backend__sdl
(
pDevice
);
mal_device__set_state
(
pDevice
,
MAL_STATE_STARTED
);
}
else
#endif
// Synchronous backends.
{
...
...
@@ -9167,6 +9432,11 @@ mal_result mal_device_stop(mal_device* pDevice)
if
(
pDevice
->
pContext
->
backend
==
mal_backend_opensl
)
{
mal_device__stop_backend__opensl
(
pDevice
);
}
else
#endif
#ifdef MAL_HAS_SDL
if
(
pDevice
->
pContext
->
backend
==
mal_backend_sdl
)
{
mal_device__stop_backend__sdl
(
pDevice
);
}
else
#endif
// Synchronous backends.
{
...
...
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