aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/alu.cpp27
-rw-r--r--OpenAL32/Include/alMain.h10
-rw-r--r--OpenAL32/alSource.cpp18
-rw-r--r--OpenAL32/event.cpp21
4 files changed, 36 insertions, 40 deletions
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index b9fe95f0..197d554d 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -287,31 +287,12 @@ aluVector aluMatrixfVector(const aluMatrixf *mtx, const aluVector *vec)
void SendSourceStoppedEvent(ALCcontext *context, ALuint id)
{
- AsyncEvent evt = ASYNC_EVENT(EventType_SourceStateChange);
- ALbitfieldSOFT enabledevt;
- size_t strpos;
- ALuint scale;
-
- enabledevt = context->EnabledEvts.load(std::memory_order_acquire);
+ ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)};
if(!(enabledevt&EventType_SourceStateChange)) return;
- evt.u.user.type = AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT;
- evt.u.user.id = id;
- evt.u.user.param = AL_STOPPED;
-
- /* Normally snprintf would be used, but this is called from the mixer and
- * that function's not real-time safe, so we have to construct it manually.
- */
- strcpy(evt.u.user.msg, "Source ID "); strpos = 10;
- scale = 1000000000;
- while(scale > 0 && scale > id)
- scale /= 10;
- while(scale > 0)
- {
- evt.u.user.msg[strpos++] = '0' + ((id/scale)%10);
- scale /= 10;
- }
- strcpy(evt.u.user.msg+strpos, " state changed to AL_STOPPED");
+ AsyncEvent evt{ASYNC_EVENT(EventType_SourceStateChange)};
+ evt.u.srcstate.id = id;
+ evt.u.srcstate.state = AL_STOPPED;
if(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) == 1)
context->EventSem.post();
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 898c8a08..bff3d52e 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -841,11 +841,15 @@ enum {
EventType_ReleaseEffectState = 65536,
};
-typedef struct AsyncEvent {
+struct AsyncEvent {
unsigned int EnumType;
union {
char dummy;
struct {
+ ALuint id;
+ ALenum state;
+ } srcstate;
+ struct {
ALenum type;
ALuint id;
ALuint param;
@@ -853,8 +857,8 @@ typedef struct AsyncEvent {
} user;
EffectState *mEffectState;
} u;
-} AsyncEvent;
-#define ASYNC_EVENT(t) { t, { 0 } }
+};
+#define ASYNC_EVENT(t) AsyncEvent{ t, { 0 } }
void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp
index 87729c73..11cea945 100644
--- a/OpenAL32/alSource.cpp
+++ b/OpenAL32/alSource.cpp
@@ -684,21 +684,13 @@ inline bool SourceShouldUpdate(ALsource *source, ALCcontext *context)
/** Can only be called while the mixer is locked! */
void SendStateChangeEvent(ALCcontext *context, ALuint id, ALenum state)
{
- AsyncEvent evt = ASYNC_EVENT(EventType_SourceStateChange);
- ALbitfieldSOFT enabledevt;
-
- enabledevt = context->EnabledEvts.load(std::memory_order_acquire);
+ ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)};
if(!(enabledevt&EventType_SourceStateChange)) return;
- evt.u.user.type = AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT;
- evt.u.user.id = id;
- evt.u.user.param = state;
- snprintf(evt.u.user.msg, sizeof(evt.u.user.msg), "Source ID %u state changed to %s", id,
- (state==AL_INITIAL) ? "AL_INITIAL" :
- (state==AL_PLAYING) ? "AL_PLAYING" :
- (state==AL_PAUSED) ? "AL_PAUSED" :
- (state==AL_STOPPED) ? "AL_STOPPED" : "<unknown>"
- );
+ AsyncEvent evt{ASYNC_EVENT(EventType_SourceStateChange)};
+ evt.u.srcstate.id = id;
+ evt.u.srcstate.state = state;
+
/* The mixer may have queued a state change that's not yet been processed,
* and we don't want state change messages to occur out of order, so send
* it through the async queue to ensure proper ordering.
diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp
index b7599a02..4980abee 100644
--- a/OpenAL32/event.cpp
+++ b/OpenAL32/event.cpp
@@ -39,7 +39,26 @@ static int EventThread(ALCcontext *context)
}
ALbitfieldSOFT enabledevts{context->EnabledEvts.load(std::memory_order_acquire)};
- if(context->EventCb && (enabledevts&evt.EnumType) == evt.EnumType)
+ if(!context->EventCb) continue;
+
+ if(evt.EnumType == EventType_SourceStateChange)
+ {
+ if(!(enabledevts&EventType_SourceStateChange))
+ continue;
+ char msg[1024]{};
+ int msglen{snprintf(msg, sizeof(msg), "Source ID %u state changed to %s",
+ evt.u.srcstate.id,
+ (evt.u.srcstate.state==AL_INITIAL) ? "AL_INITIAL" :
+ (evt.u.srcstate.state==AL_PLAYING) ? "AL_PLAYING" :
+ (evt.u.srcstate.state==AL_PAUSED) ? "AL_PAUSED" :
+ (evt.u.srcstate.state==AL_STOPPED) ? "AL_STOPPED" : "<unknown>"
+ )};
+ if(msglen < 1) msglen = strlen(msg);
+ context->EventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.u.srcstate.id,
+ evt.u.srcstate.state, msglen, msg, context->EventParam
+ );
+ }
+ else if((enabledevts&evt.EnumType) == evt.EnumType)
context->EventCb(evt.u.user.type, evt.u.user.id, evt.u.user.param,
(ALsizei)strlen(evt.u.user.msg), evt.u.user.msg, context->EventParam
);