Skip to content

Commit

Permalink
Add new ma_device_notification_type_unlocked notification
Browse files Browse the repository at this point in the history
Unlocked notification fires on emscripten upon successful resume of
audio context attached to a device.  This occurs only once per device
and it happens after the browser has received the input event
necessary to begin playing audio on most webpages.  This is due
to autoplay rules.

It is recommended to wait until this event is fired to start a
'main game loop' on the web.
  • Loading branch information
mlabbe authored and mackron committed Nov 15, 2023
1 parent f9ce463 commit 8fcf688
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
22 changes: 20 additions & 2 deletions extras/miniaudio_split/miniaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -7245,6 +7245,14 @@ static void ma_device__on_notification_rerouted(ma_device* pDevice)
}
#endif

#if defined(MA_EMSCRIPTEN)
EMSCRIPTEN_KEEPALIVE
void ma_device__on_notification_unlocked(ma_device* pDevice)
{
ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_unlocked));
}
#endif


static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
Expand Down Expand Up @@ -28377,6 +28385,7 @@ static ma_result ma_device_uninit__webaudio(ma_device* pDevice)
*/
device.webaudio.close();
device.webaudio = undefined;
device.pDevice = undefined;
}, pDevice->webaudio.deviceIndex);
}
#endif
Expand Down Expand Up @@ -28872,6 +28881,8 @@ static ma_result ma_device_init__webaudio(ma_device* pDevice, const ma_device_co
device.scriptNode.connect(device.webaudio.destination);
}

device.pDevice = pDevice;

return miniaudio.track_device(device);
}, pConfig->deviceType, channels, sampleRate, periodSizeInFrames, pDevice->webaudio.pIntermediaryBuffer, pDevice);

Expand Down Expand Up @@ -29044,8 +29055,15 @@ static ma_result ma_context_init__webaudio(ma_context* pContext, const ma_contex
miniaudio.unlock = function() {
for(var i = 0; i < miniaudio.devices.length; ++i) {
var device = miniaudio.devices[i];
if (device != null && device.webaudio != null && device.state === 2 /* ma_device_state_started */) {
device.webaudio.resume();
if (device != null &&
device.webaudio != null &&
device.state === window.miniaudio.device_state.started) {

device.webaudio.resume().then(() => {
Module._ma_device__on_notification_unlocked(device.pDevice);
},
(error) => {console.error("Failed to resume audiocontext", error);
});
}
}
miniaudio.unlock_event_types.map(function(event_type) {
Expand Down
3 changes: 2 additions & 1 deletion extras/miniaudio_split/miniaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -3013,7 +3013,8 @@ typedef enum
ma_device_notification_type_stopped,
ma_device_notification_type_rerouted,
ma_device_notification_type_interruption_began,
ma_device_notification_type_interruption_ended
ma_device_notification_type_interruption_ended,
ma_device_notification_type_unlocked
} ma_device_notification_type;

typedef struct
Expand Down

0 comments on commit 8fcf688

Please sign in to comment.