mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 01:04:02 +02:00
Add onStop callback which is called when a device is stopped either explicitly or internally as a result of an error.
This commit is contained in:
@@ -244,6 +244,7 @@ typedef struct mal_device mal_device;
|
||||
|
||||
typedef void (* mal_recv_proc)(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples);
|
||||
typedef mal_uint32 (* mal_send_proc)(mal_device* pDevice, mal_uint32 frameCount, void* pSamples);
|
||||
typedef void (* mal_stop_proc)(mal_device* pDevice);
|
||||
typedef void (* mal_log_proc) (mal_device* pDevice, const char* message);
|
||||
|
||||
typedef enum
|
||||
@@ -303,6 +304,7 @@ struct mal_device
|
||||
mal_uint32 state;
|
||||
mal_recv_proc onRecv;
|
||||
mal_send_proc onSend;
|
||||
mal_stop_proc onStop;
|
||||
mal_log_proc onLog;
|
||||
void* pUserData; // Application defined data.
|
||||
mal_mutex lock;
|
||||
@@ -443,6 +445,15 @@ void mal_device_uninit(mal_device* pDevice);
|
||||
// This is just an atomic assignment.
|
||||
void mal_device_set_recv_callback(mal_device* pDevice, mal_recv_proc proc);
|
||||
|
||||
// Sets the callback to use when the device has stopped, either explicitly or as a result of an error.
|
||||
//
|
||||
// Thread Safety: SAFE
|
||||
// This API is implemented as a simple atomic assignment.
|
||||
//
|
||||
// Efficiency: HIGH
|
||||
// This is just an atomic assignment.
|
||||
void mal_device_set_stop_callback(mal_device* pDevice, mal_stop_proc proc);
|
||||
|
||||
// Sets the callback to use when the application needs to send data to the device for playback.
|
||||
//
|
||||
// Note that the implementation of this callback must copy over as many samples as is available. The
|
||||
@@ -2831,11 +2842,24 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
|
||||
{
|
||||
mal_device* pDevice = (mal_device*)pData;
|
||||
mal_assert(pDevice != NULL);
|
||||
|
||||
// This is only used to prevent posting onStop() when the device is first initialized.
|
||||
mal_bool32 skipNextStopEvent = MAL_TRUE;
|
||||
|
||||
for (;;) {
|
||||
// At the start of iteration the device is stopped - we must explicitly mark it as such.
|
||||
mal_device__stop_backend(pDevice);
|
||||
|
||||
if (!skipNextStopEvent) {
|
||||
mal_stop_proc onStop = pDevice->onStop;
|
||||
if (onStop) {
|
||||
onStop(pDevice);
|
||||
}
|
||||
} else {
|
||||
skipNextStopEvent = MAL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Let the other threads know that the device has stopped.
|
||||
mal_device__set_state(pDevice, MAL_STATE_STOPPED);
|
||||
mal_event_signal(&pDevice->stopEvent);
|
||||
@@ -3051,6 +3075,12 @@ void mal_device_set_send_callback(mal_device* pDevice, mal_send_proc proc)
|
||||
mal_atomic_exchange_ptr(&pDevice->onSend, proc);
|
||||
}
|
||||
|
||||
void mal_device_set_stop_callback(mal_device* pDevice, mal_stop_proc proc)
|
||||
{
|
||||
if (pDevice == NULL) return;
|
||||
mal_atomic_exchange_ptr(&pDevice->onStop, proc);
|
||||
}
|
||||
|
||||
mal_result mal_device_start(mal_device* pDevice)
|
||||
{
|
||||
if (pDevice == NULL) return mal_post_error(pDevice, "mal_device_start() called with invalid arguments.", MAL_INVALID_ARGS);
|
||||
@@ -3244,7 +3274,6 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format)
|
||||
|
||||
// TODO
|
||||
// ====
|
||||
// - Examples.
|
||||
//
|
||||
// ALSA
|
||||
// ----
|
||||
|
||||
Reference in New Issue
Block a user