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
6ca0ec20
Commit
6ca0ec20
authored
Nov 13, 2017
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improvements to event and thread APIs.
parent
824e3a46
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
139 additions
and
102 deletions
+139
-102
mini_al.h
mini_al.h
+139
-102
No files found.
mini_al.h
View file @
6ca0ec20
...
@@ -295,6 +295,29 @@ typedef void (* mal_proc)();
...
@@ -295,6 +295,29 @@ typedef void (* mal_proc)();
typedef
struct
mal_context
mal_context
;
typedef
struct
mal_context
mal_context
;
typedef
struct
mal_device
mal_device
;
typedef
struct
mal_device
mal_device
;
typedef
struct
{
mal_context
*
pContext
;
union
{
#ifdef MAL_WIN32
struct
{
/*HANDLE*/
mal_handle
hThread
;
}
win32
;
#endif
#ifdef MAL_POSIX
struct
{
pthread_t
thread
;
}
posix
;
#endif
int
_unused
;
};
}
mal_thread
;
typedef
struct
typedef
struct
{
{
mal_context
*
pContext
;
mal_context
*
pContext
;
...
@@ -318,19 +341,31 @@ typedef struct
...
@@ -318,19 +341,31 @@ typedef struct
};
};
}
mal_mutex
;
}
mal_mutex
;
#ifdef MAL_WIN32
typedef
struct
typedef
mal_handle
mal_thread
;
{
typedef
mal_handle
mal_event
;
mal_context
*
pContext
;
#else
typedef
pthread_t
mal_thread
;
union
typedef
struct
{
{
pthread_mutex_t
mutex
;
#ifdef MAL_WIN32
pthread_cond_t
condition
;
struct
mal_uint32
value
;
{
}
mal_event
;
/*HANDLE*/
mal_handle
hEvent
;
}
win32
;
#endif
#ifdef MAL_POSIX
struct
{
pthread_mutex_t
mutex
;
pthread_cond_t
condition
;
mal_uint32
value
;
}
posix
;
#endif
#endif
int
_unused
;
};
}
mal_event
;
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
typedef
mal_uint16
wchar_t
;
typedef
mal_uint16
wchar_t
;
#endif
#endif
...
@@ -1942,23 +1977,21 @@ mal_proc mal_dlsym(mal_handle handle, const char* symbol)
...
@@ -1942,23 +1977,21 @@ mal_proc mal_dlsym(mal_handle handle, const char* symbol)
//
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifdef MAL_WIN32
#ifdef MAL_WIN32
mal_
bool32
mal_thread_create__win32
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
mal_
result
mal_thread_create__win32
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
{
{
(
void
)
pContext
;
(
void
)
pContext
;
*
p
Thread
=
CreateThread
(
NULL
,
0
,
entryProc
,
pData
,
0
,
NULL
);
pThread
->
win32
.
h
Thread
=
CreateThread
(
NULL
,
0
,
entryProc
,
pData
,
0
,
NULL
);
if
(
*
p
Thread
==
NULL
)
{
if
(
pThread
->
win32
.
h
Thread
==
NULL
)
{
return
MAL_FA
LSE
;
return
MAL_FA
ILED_TO_CREATE_THREAD
;
}
}
return
MAL_
TRUE
;
return
MAL_
SUCCESS
;
}
}
void
mal_thread_wait__win32
(
mal_
context
*
pContext
,
mal_
thread
*
pThread
)
void
mal_thread_wait__win32
(
mal_thread
*
pThread
)
{
{
(
void
)
pContext
;
WaitForSingleObject
(
pThread
->
win32
.
hThread
,
INFINITE
);
WaitForSingleObject
(
*
pThread
,
INFINITE
);
}
}
void
mal_sleep__win32
(
mal_uint32
milliseconds
)
void
mal_sleep__win32
(
mal_uint32
milliseconds
)
...
@@ -1995,37 +2028,31 @@ void mal_mutex_unlock__win32(mal_mutex* pMutex)
...
@@ -1995,37 +2028,31 @@ void mal_mutex_unlock__win32(mal_mutex* pMutex)
}
}
mal_
bool32
mal_event_create
__win32
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
mal_
result
mal_event_init
__win32
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
{
{
(
void
)
pContext
;
(
void
)
pContext
;
*
p
Event
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
pEvent
->
win32
.
h
Event
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
*
p
Event
==
NULL
)
{
if
(
pEvent
->
win32
.
h
Event
==
NULL
)
{
return
MAL_FA
LSE
;
return
MAL_FA
ILED_TO_CREATE_EVENT
;
}
}
return
MAL_
TRUE
;
return
MAL_
SUCCESS
;
}
}
void
mal_event_
delete__win32
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
void
mal_event_
uninit__win32
(
mal_event
*
pEvent
)
{
{
(
void
)
pContext
;
CloseHandle
(
pEvent
->
win32
.
hEvent
);
CloseHandle
(
*
pEvent
);
}
}
mal_bool32
mal_event_wait__win32
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_wait__win32
(
mal_event
*
pEvent
)
{
{
(
void
)
pContext
;
return
WaitForSingleObject
(
pEvent
->
win32
.
hEvent
,
INFINITE
)
==
WAIT_OBJECT_0
;
return
WaitForSingleObject
(
*
pEvent
,
INFINITE
)
==
WAIT_OBJECT_0
;
}
}
mal_bool32
mal_event_signal__win32
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_signal__win32
(
mal_event
*
pEvent
)
{
{
(
void
)
pContext
;
return
SetEvent
(
pEvent
->
win32
.
hEvent
);
return
SetEvent
(
*
pEvent
);
}
}
#endif
#endif
...
@@ -2044,12 +2071,17 @@ typedef int (* mal_pthread_cond_wait_proc)(pthread_cond_t *__restrict __cond, pt
...
@@ -2044,12 +2071,17 @@ typedef int (* mal_pthread_cond_wait_proc)(pthread_cond_t *__restrict __cond, pt
mal_bool32
mal_thread_create__posix
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
mal_bool32
mal_thread_create__posix
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
{
{
return
((
mal_pthread_create_proc
)
pContext
->
posix
.
pthread_create
)(
pThread
,
NULL
,
entryProc
,
pData
)
==
0
;
int
result
=
((
mal_pthread_create_proc
)
pContext
->
posix
.
pthread_create
)(
&
pThread
->
posix
.
thread
,
NULL
,
entryProc
,
pData
);
if
(
result
!=
0
)
{
return
MAL_FAILED_TO_CREATE_THREAD
;
}
return
MAL_SUCCESS
;
}
}
void
mal_thread_wait__posix
(
mal_
context
*
pContext
,
mal_
thread
*
pThread
)
void
mal_thread_wait__posix
(
mal_thread
*
pThread
)
{
{
((
mal_pthread_join_proc
)
p
Context
->
posix
.
pthread_join
)(
*
pT
hread
,
NULL
);
((
mal_pthread_join_proc
)
p
Thread
->
pContext
->
posix
.
pthread_join
)(
pThread
->
posix
.
t
hread
,
NULL
);
}
}
void
mal_sleep__posix
(
mal_uint32
milliseconds
)
void
mal_sleep__posix
(
mal_uint32
milliseconds
)
...
@@ -2084,57 +2116,59 @@ void mal_mutex_unlock__posix(mal_mutex* pMutex)
...
@@ -2084,57 +2116,59 @@ void mal_mutex_unlock__posix(mal_mutex* pMutex)
}
}
mal_
bool32
mal_event_create
__posix
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
mal_
result
mal_event_init
__posix
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
{
{
if
(((
mal_pthread_mutex_init_proc
)
pContext
->
posix
.
pthread_mutex_init
)(
&
pEvent
->
mutex
,
NULL
)
!=
0
)
{
if
(((
mal_pthread_mutex_init_proc
)
pContext
->
posix
.
pthread_mutex_init
)(
&
pEvent
->
posix
.
mutex
,
NULL
)
!=
0
)
{
return
MAL_FA
LSE
;
return
MAL_FA
ILED_TO_CREATE_MUTEX
;
}
}
if
(((
mal_pthread_cond_init_proc
)
pContext
->
posix
.
pthread_cond_init
)(
&
pEvent
->
condition
,
NULL
)
!=
0
)
{
if
(((
mal_pthread_cond_init_proc
)
pContext
->
posix
.
pthread_cond_init
)(
&
pEvent
->
posix
.
condition
,
NULL
)
!=
0
)
{
return
MAL_FA
LSE
;
return
MAL_FA
ILED_TO_CREATE_EVENT
;
}
}
pEvent
->
value
=
0
;
pEvent
->
posix
.
value
=
0
;
return
MAL_
TRUE
;
return
MAL_
SUCCESS
;
}
}
void
mal_event_
delete__posix
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
void
mal_event_
uninit__posix
(
mal_event
*
pEvent
)
{
{
((
mal_pthread_cond_destroy_proc
)
p
Context
->
posix
.
pthread_cond_destroy
)(
&
pEvent
->
condition
);
((
mal_pthread_cond_destroy_proc
)
p
Event
->
pContext
->
posix
.
pthread_cond_destroy
)(
&
pEvent
->
posix
.
condition
);
((
mal_pthread_mutex_destroy_proc
)
p
Context
->
posix
.
pthread_mutex_destroy
)(
&
pEvent
->
mutex
);
((
mal_pthread_mutex_destroy_proc
)
p
Event
->
pContext
->
posix
.
pthread_mutex_destroy
)(
&
pEvent
->
posix
.
mutex
);
}
}
mal_bool32
mal_event_wait__posix
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_wait__posix
(
mal_event
*
pEvent
)
{
{
((
mal_pthread_mutex_lock_proc
)
p
Context
->
posix
.
pthread_mutex_lock
)(
&
pEvent
->
mutex
);
((
mal_pthread_mutex_lock_proc
)
p
Event
->
pContext
->
posix
.
pthread_mutex_lock
)(
&
pEvent
->
posix
.
mutex
);
{
{
while
(
pEvent
->
value
==
0
)
{
while
(
pEvent
->
posix
.
value
==
0
)
{
((
mal_pthread_cond_wait_proc
)
p
Context
->
posix
.
pthread_cond_wait
)(
&
pEvent
->
condition
,
&
pEvent
->
mutex
);
((
mal_pthread_cond_wait_proc
)
p
Event
->
pContext
->
posix
.
pthread_cond_wait
)(
&
pEvent
->
posix
.
condition
,
&
pEvent
->
posix
.
mutex
);
}
}
pEvent
->
value
=
0
;
// Auto-reset.
pEvent
->
posix
.
value
=
0
;
// Auto-reset.
}
}
((
mal_pthread_mutex_unlock_proc
)
p
Context
->
posix
.
pthread_mutex_unlock
)(
&
pEvent
->
mutex
);
((
mal_pthread_mutex_unlock_proc
)
p
Event
->
pContext
->
posix
.
pthread_mutex_unlock
)(
&
pEvent
->
posix
.
mutex
);
return
MAL_TRUE
;
return
MAL_TRUE
;
}
}
mal_bool32
mal_event_signal__posix
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_signal__posix
(
mal_event
*
pEvent
)
{
{
((
mal_pthread_mutex_lock_proc
)
p
Context
->
posix
.
pthread_mutex_lock
)(
&
pEvent
->
mutex
);
((
mal_pthread_mutex_lock_proc
)
p
Event
->
pContext
->
posix
.
pthread_mutex_lock
)(
&
pEvent
->
posix
.
mutex
);
{
{
pEvent
->
value
=
1
;
pEvent
->
posix
.
value
=
1
;
((
mal_pthread_cond_signal_proc
)
p
Context
->
posix
.
pthread_cond_signal
)(
&
pEvent
->
condition
);
((
mal_pthread_cond_signal_proc
)
p
Event
->
pContext
->
posix
.
pthread_cond_signal
)(
&
pEvent
->
posix
.
condition
);
}
}
((
mal_pthread_mutex_unlock_proc
)
p
Context
->
posix
.
pthread_mutex_unlock
)(
&
pEvent
->
mutex
);
((
mal_pthread_mutex_unlock_proc
)
p
Event
->
pContext
->
posix
.
pthread_mutex_unlock
)(
&
pEvent
->
posix
.
mutex
);
return
MAL_TRUE
;
return
MAL_TRUE
;
}
}
#endif
#endif
mal_
bool32
mal_thread_create
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
mal_
result
mal_thread_create
(
mal_context
*
pContext
,
mal_thread
*
pThread
,
mal_thread_entry_proc
entryProc
,
void
*
pData
)
{
{
if
(
pThread
==
NULL
||
entryProc
==
NULL
)
return
MAL_FALSE
;
if
(
pContext
==
NULL
||
pThread
==
NULL
||
entryProc
==
NULL
)
return
MAL_FALSE
;
pThread
->
pContext
=
pContext
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
return
mal_thread_create__win32
(
pContext
,
pThread
,
entryProc
,
pData
);
return
mal_thread_create__win32
(
pContext
,
pThread
,
entryProc
,
pData
);
...
@@ -2144,15 +2178,15 @@ mal_bool32 mal_thread_create(mal_context* pContext, mal_thread* pThread, mal_thr
...
@@ -2144,15 +2178,15 @@ mal_bool32 mal_thread_create(mal_context* pContext, mal_thread* pThread, mal_thr
#endif
#endif
}
}
void
mal_thread_wait
(
mal_
context
*
pContext
,
mal_
thread
*
pThread
)
void
mal_thread_wait
(
mal_thread
*
pThread
)
{
{
if
(
pThread
==
NULL
)
return
;
if
(
pThread
==
NULL
)
return
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
mal_thread_wait__win32
(
p
Context
,
p
Thread
);
mal_thread_wait__win32
(
pThread
);
#endif
#endif
#ifdef MAL_POSIX
#ifdef MAL_POSIX
mal_thread_wait__posix
(
p
Context
,
p
Thread
);
mal_thread_wait__posix
(
pThread
);
#endif
#endif
}
}
...
@@ -2218,51 +2252,53 @@ void mal_mutex_unlock(mal_mutex* pMutex)
...
@@ -2218,51 +2252,53 @@ void mal_mutex_unlock(mal_mutex* pMutex)
}
}
mal_
bool32
mal_event_create
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
mal_
result
mal_event_init
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
{
{
if
(
pEvent
==
NULL
)
return
MAL_FALSE
;
if
(
pContext
==
NULL
||
pEvent
==
NULL
)
return
MAL_FALSE
;
pEvent
->
pContext
=
pContext
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
return
mal_event_
create
__win32
(
pContext
,
pEvent
);
return
mal_event_
init
__win32
(
pContext
,
pEvent
);
#endif
#endif
#ifdef MAL_POSIX
#ifdef MAL_POSIX
return
mal_event_
create
__posix
(
pContext
,
pEvent
);
return
mal_event_
init
__posix
(
pContext
,
pEvent
);
#endif
#endif
}
}
void
mal_event_
delete
(
mal_context
*
pContext
,
mal_event
*
pEvent
)
void
mal_event_
uninit
(
mal_event
*
pEvent
)
{
{
if
(
pEvent
==
NULL
)
return
;
if
(
pEvent
==
NULL
||
pEvent
->
pContext
==
NULL
)
return
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
mal_event_
delete__win32
(
pContext
,
pEvent
);
mal_event_
uninit__win32
(
pEvent
);
#endif
#endif
#ifdef MAL_POSIX
#ifdef MAL_POSIX
mal_event_
delete__posix
(
pContext
,
pEvent
);
mal_event_
uninit__posix
(
pEvent
);
#endif
#endif
}
}
mal_bool32
mal_event_wait
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_wait
(
mal_event
*
pEvent
)
{
{
if
(
pEvent
==
NULL
)
return
MAL_FALSE
;
if
(
pEvent
==
NULL
||
pEvent
->
pContext
==
NULL
)
return
MAL_FALSE
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
return
mal_event_wait__win32
(
p
Context
,
p
Event
);
return
mal_event_wait__win32
(
pEvent
);
#endif
#endif
#ifdef MAL_POSIX
#ifdef MAL_POSIX
return
mal_event_wait__posix
(
p
Context
,
p
Event
);
return
mal_event_wait__posix
(
pEvent
);
#endif
#endif
}
}
mal_bool32
mal_event_signal
(
mal_
context
*
pContext
,
mal_
event
*
pEvent
)
mal_bool32
mal_event_signal
(
mal_event
*
pEvent
)
{
{
if
(
pEvent
==
NULL
)
return
MAL_FALSE
;
if
(
pEvent
==
NULL
||
pEvent
->
pContext
==
NULL
)
return
MAL_FALSE
;
#ifdef MAL_WIN32
#ifdef MAL_WIN32
return
mal_event_signal__win32
(
p
Context
,
p
Event
);
return
mal_event_signal__win32
(
pEvent
);
#endif
#endif
#ifdef MAL_POSIX
#ifdef MAL_POSIX
return
mal_event_signal__posix
(
p
Context
,
p
Event
);
return
mal_event_signal__posix
(
pEvent
);
#endif
#endif
}
}
...
@@ -8264,10 +8300,10 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
...
@@ -8264,10 +8300,10 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
// Let the other threads know that the device has stopped.
// Let the other threads know that the device has stopped.
mal_device__set_state
(
pDevice
,
MAL_STATE_STOPPED
);
mal_device__set_state
(
pDevice
,
MAL_STATE_STOPPED
);
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
stopEvent
);
mal_event_signal
(
&
pDevice
->
stopEvent
);
// We use an event to wait for a request to wake up.
// We use an event to wait for a request to wake up.
mal_event_wait
(
pDevice
->
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_wait
(
&
pDevice
->
wakeupEvent
);
// Default result code.
// Default result code.
pDevice
->
workResult
=
MAL_SUCCESS
;
pDevice
->
workResult
=
MAL_SUCCESS
;
...
@@ -8284,21 +8320,21 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
...
@@ -8284,21 +8320,21 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
pDevice
->
workResult
=
mal_device__start_backend
(
pDevice
);
pDevice
->
workResult
=
mal_device__start_backend
(
pDevice
);
if
(
pDevice
->
workResult
!=
MAL_SUCCESS
)
{
if
(
pDevice
->
workResult
!=
MAL_SUCCESS
)
{
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
startEvent
);
mal_event_signal
(
&
pDevice
->
startEvent
);
continue
;
continue
;
}
}
// The thread that requested the device to start playing is waiting for this thread to start the
// The thread that requested the device to start playing is waiting for this thread to start the
// device for real, which is now.
// device for real, which is now.
mal_device__set_state
(
pDevice
,
MAL_STATE_STARTED
);
mal_device__set_state
(
pDevice
,
MAL_STATE_STARTED
);
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
startEvent
);
mal_event_signal
(
&
pDevice
->
startEvent
);
// Now we just enter the main loop. The main loop can be broken with mal_device__break_main_loop().
// Now we just enter the main loop. The main loop can be broken with mal_device__break_main_loop().
mal_device__main_loop
(
pDevice
);
mal_device__main_loop
(
pDevice
);
}
}
// Make sure we aren't continuously waiting on a stop event.
// Make sure we aren't continuously waiting on a stop event.
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
stopEvent
);
// <-- Is this still needed?
mal_event_signal
(
&
pDevice
->
stopEvent
);
// <-- Is this still needed?
#ifdef MAL_WIN32
#ifdef MAL_WIN32
mal_CoUninitialize
(
pDevice
->
pContext
);
mal_CoUninitialize
(
pDevice
->
pContext
);
...
@@ -8735,18 +8771,18 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
...
@@ -8735,18 +8771,18 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
//
//
// Each of these semaphores is released internally by the worker thread when the work is completed. The start
// Each of these semaphores is released internally by the worker thread when the work is completed. The start
// semaphore is also used to wake up the worker thread.
// semaphore is also used to wake up the worker thread.
if
(
!
mal_event_create
(
pContext
,
&
pDevice
->
wakeupEvent
)
)
{
if
(
mal_event_init
(
pContext
,
&
pDevice
->
wakeupEvent
)
!=
MAL_SUCCESS
)
{
mal_mutex_uninit
(
&
pDevice
->
lock
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread wakeup event."
,
MAL_FAILED_TO_CREATE_EVENT
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread wakeup event."
,
MAL_FAILED_TO_CREATE_EVENT
);
}
}
if
(
!
mal_event_create
(
pContext
,
&
pDevice
->
startEvent
)
)
{
if
(
mal_event_init
(
pContext
,
&
pDevice
->
startEvent
)
!=
MAL_SUCCESS
)
{
mal_event_
delete
(
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_
uninit
(
&
pDevice
->
wakeupEvent
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread start event."
,
MAL_FAILED_TO_CREATE_EVENT
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread start event."
,
MAL_FAILED_TO_CREATE_EVENT
);
}
}
if
(
!
mal_event_create
(
pContext
,
&
pDevice
->
stopEvent
)
)
{
if
(
mal_event_init
(
pContext
,
&
pDevice
->
stopEvent
)
!=
MAL_SUCCESS
)
{
mal_event_
delete
(
pContext
,
&
pDevice
->
startEvent
);
mal_event_
uninit
(
&
pDevice
->
startEvent
);
mal_event_
delete
(
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_
uninit
(
&
pDevice
->
wakeupEvent
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread stop event."
,
MAL_FAILED_TO_CREATE_EVENT
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread stop event."
,
MAL_FAILED_TO_CREATE_EVENT
);
}
}
...
@@ -8844,13 +8880,13 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
...
@@ -8844,13 +8880,13 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
// Some backends don't require the worker thread.
// Some backends don't require the worker thread.
if
(
pContext
->
backend
!=
mal_backend_opensl
)
{
if
(
pContext
->
backend
!=
mal_backend_opensl
)
{
// The worker thread.
// The worker thread.
if
(
!
mal_thread_create
(
pContext
,
&
pDevice
->
thread
,
mal_worker_thread
,
pDevice
)
)
{
if
(
mal_thread_create
(
pContext
,
&
pDevice
->
thread
,
mal_worker_thread
,
pDevice
)
!=
MAL_SUCCESS
)
{
mal_device_uninit
(
pDevice
);
mal_device_uninit
(
pDevice
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread."
,
MAL_FAILED_TO_CREATE_THREAD
);
return
mal_post_error
(
pDevice
,
"Failed to create worker thread."
,
MAL_FAILED_TO_CREATE_THREAD
);
}
}
// Wait for the worker thread to put the device into it's stopped state for real.
// Wait for the worker thread to put the device into it's stopped state for real.
mal_event_wait
(
pContext
,
&
pDevice
->
stopEvent
);
mal_event_wait
(
&
pDevice
->
stopEvent
);
}
else
{
}
else
{
mal_device__set_state
(
pDevice
,
MAL_STATE_STOPPED
);
mal_device__set_state
(
pDevice
,
MAL_STATE_STOPPED
);
}
}
...
@@ -8876,13 +8912,13 @@ void mal_device_uninit(mal_device* pDevice)
...
@@ -8876,13 +8912,13 @@ void mal_device_uninit(mal_device* pDevice)
// Wake up the worker thread and wait for it to properly terminate.
// 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
)
{
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_signal
(
&
pDevice
->
wakeupEvent
);
mal_thread_wait
(
pDevice
->
pContext
,
&
pDevice
->
thread
);
mal_thread_wait
(
&
pDevice
->
thread
);
}
}
mal_event_
delete
(
pDevice
->
pContext
,
&
pDevice
->
stopEvent
);
mal_event_
uninit
(
&
pDevice
->
stopEvent
);
mal_event_
delete
(
pDevice
->
pContext
,
&
pDevice
->
startEvent
);
mal_event_
uninit
(
&
pDevice
->
startEvent
);
mal_event_
delete
(
pDevice
->
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_
uninit
(
&
pDevice
->
wakeupEvent
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
mal_mutex_uninit
(
&
pDevice
->
lock
);
#ifdef MAL_ENABLE_WASAPI
#ifdef MAL_ENABLE_WASAPI
...
@@ -8983,11 +9019,11 @@ mal_result mal_device_start(mal_device* pDevice)
...
@@ -8983,11 +9019,11 @@ mal_result mal_device_start(mal_device* pDevice)
#endif
#endif
// Synchronous backends.
// Synchronous backends.
{
{
mal_event_signal
(
pDevice
->
pContext
,
&
pDevice
->
wakeupEvent
);
mal_event_signal
(
&
pDevice
->
wakeupEvent
);
// Wait for the worker thread to finish starting the device. Note that the worker thread will be the one
// Wait for the worker thread to finish starting the device. Note that the worker thread will be the one
// who puts the device into the started state. Don't call mal_device__set_state() here.
// who puts the device into the started state. Don't call mal_device__set_state() here.
mal_event_wait
(
pDevice
->
pContext
,
&
pDevice
->
startEvent
);
mal_event_wait
(
&
pDevice
->
startEvent
);
result
=
pDevice
->
workResult
;
result
=
pDevice
->
workResult
;
}
}
}
}
...
@@ -9039,7 +9075,7 @@ mal_result mal_device_stop(mal_device* pDevice)
...
@@ -9039,7 +9075,7 @@ mal_result mal_device_stop(mal_device* pDevice)
// We need to wait for the worker thread to become available for work before returning. Note that the worker thread will be
// We need to wait for the worker thread to become available for work before returning. Note that the worker thread will be
// the one who puts the device into the stopped state. Don't call mal_device__set_state() here.
// the one who puts the device into the stopped state. Don't call mal_device__set_state() here.
mal_event_wait
(
pDevice
->
pContext
,
&
pDevice
->
stopEvent
);
mal_event_wait
(
&
pDevice
->
stopEvent
);
result
=
MAL_SUCCESS
;
result
=
MAL_SUCCESS
;
}
}
}
}
...
@@ -10375,6 +10411,7 @@ void mal_pcm_f32_to_s32(int* pOut, const float* pIn, unsigned int count)
...
@@ -10375,6 +10411,7 @@ void mal_pcm_f32_to_s32(int* pOut, const float* pIn, unsigned int count)
// - API CHANGE: Expose and improve mutex APIs. If you were using the mutex APIs before this version you'll
// - API CHANGE: Expose and improve mutex APIs. If you were using the mutex APIs before this version you'll
// need to update.
// need to update.
// - API CHANGE: SRC and DSP callbacks now take a pointer to a mal_src and mal_dsp object respectively.
// - API CHANGE: SRC and DSP callbacks now take a pointer to a mal_src and mal_dsp object respectively.
// - API CHANGE: Improvements to event and thread APIs. These changes make these APIs more consistent.
// - Add mal_convert_frames(). This is a high-level helper API for performing a one-time, bulk conversion of
// - Add mal_convert_frames(). This is a high-level helper API for performing a one-time, bulk conversion of
// audio data to a different format.
// audio data to a different format.
//
//
...
...
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