perfect_dark/src/lib/naudio/n_sndplayer.c

958 lines
22 KiB
C

#include <os_internal.h>
#include <ultraerror.h>
#include <libaudio.h>
#include "n_sndp.h"
#include "lib/snd.h"
#include "lib/lib_317f0.h"
#include "bss.h"
#include "data.h"
#include "types.h"
u32 var8009c330;
s16 *var8009c334;
struct sndstate *g_SndpAllocStatesHead = NULL;
struct sndstate *g_SndpAllocStatesTail = NULL;
struct sndstate *g_SndpFreeStatesHead = NULL;
N_ALSndPlayer *g_SndPlayer = &var8009c2d0;
s16 var8005f130 = 0;
s32 var8005f134 = 0;
s32 var8005f138 = 0;
void (*g_SndpAddRefCallback)(ALSound *) = NULL;
void (*g_SndpRemoveRefCallback)(ALSound *) = NULL;
void sndpSetAddRefCallback(void *fn);
void sndpSetRemoveRefCallback(void *fn);
void sndpFreeState(struct sndstate *state);
void func00033bc0(struct sndstate *state);
void n_alSndpNew(ALSndpConfig *config)
{
u32 i;
void *ptr;
N_ALEvent evt;
// Init member variables
g_SndPlayer->maxSounds = config->maxSounds;
g_SndPlayer->target = NULL;
g_SndPlayer->frameTime = AL_USEC_PER_FRAME;
ptr = alHeapAlloc(config->heap, 1, config->maxStates * sizeof(struct sndstate));
g_SndPlayer->sndState = ptr;
// Init the event queue
ptr = alHeapAlloc(config->heap, 1, config->maxEvents * sizeof(N_ALEventListItem));
n_alEvtqNew(&g_SndPlayer->evtq, ptr, config->maxEvents);
g_SndpFreeStatesHead = g_SndPlayer->sndState;
for (i = 1; i < config->maxStates; i++) {
struct sndstate *sndstate = g_SndPlayer->sndState;
alLink(&sndstate[i].node, &sndstate[i - 1].node);
}
sndpSetAddRefCallback(NULL);
sndpSetRemoveRefCallback(NULL);
var8009c334 = alHeapAlloc(config->heap, sizeof(s16), config->unk10);
for (i = 0; i < config->unk10; i++) {
var8009c334[i] = 0x7fff;
}
// Add ourselves to the driver
g_SndPlayer->node.next = NULL;
g_SndPlayer->node.handler = (ALVoiceHandler) _n_sndpVoiceHandler;
g_SndPlayer->node.clientData = g_SndPlayer;
n_alSynAddSndPlayer(&g_SndPlayer->node);
// Start responding to API events
evt.type = AL_SNDP_API_EVT;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, g_SndPlayer->frameTime, 1);
g_SndPlayer->nextDelta = n_alEvtqNextEvent(&g_SndPlayer->evtq, &g_SndPlayer->nextEvent);
}
ALMicroTime _n_sndpVoiceHandler(void *node)
{
N_ALSndPlayer *sndp = (N_ALSndPlayer *) node;
N_ALSndpEvent evt;
do {
switch (sndp->nextEvent.type) {
case (AL_SNDP_API_EVT):
evt.common.type = AL_SNDP_API_EVT;
n_alEvtqPostEvent(&sndp->evtq, (N_ALEvent *)&evt, sndp->frameTime, 1);
break;
default:
_n_handleEvent((N_ALSndpEvent *)&sndp->nextEvent);
break;
}
sndp->nextDelta = n_alEvtqNextEvent(&sndp->evtq, &sndp->nextEvent);
} while (sndp->nextDelta == 0);
sndp->curTime += sndp->nextDelta;
return sndp->nextDelta;
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
void _n_handleEvent(N_ALSndpEvent *event)
{
ALVoiceConfig config;
ALSound *sound;
ALKeyMap *keymap;
ALPan pan;
N_ALSndpEvent sp94;
N_ALSndpEvent sp84;
ALMicroTime delta;
s32 fxmix;
s32 vol;
s32 tmppan;
s32 sp70;
s32 isspecial;
bool done = true;
bool hasvoice = false;
struct sndstate *state = NULL;
struct sndstate *nextstate = NULL;
s16 numfree;
s16 numalloced;
struct sndstate *iterstate;
N_ALSndpEvent sp44;
ALMicroTime sp40;
do {
if (nextstate != NULL) {
sp84.common.state = (N_ALSoundState *)state;
sp84.common.type = event->common.type;
sp84.common.unk08 = event->common.unk08;
event = &sp84;
}
state = (struct sndstate *)event->common.state;
if (((uintptr_t) state & 0x80000000) == 0) {
// empty
}
sound = state->sound;
if (sound == NULL) {
sndpCountStates(&numfree, &numalloced);
return;
}
keymap = sound->keyMap;
nextstate = (struct sndstate *)state->node.next;
switch (event->common.type) {
case AL_SNDP_PLAY_EVT:
if (state->state != AL_STATE5 && state->state != AL_STATE4) {
return;
}
config.fxBus = state->fxbus;
config.priority = state->priority;
config.unityPitch = 0;
sp70 = var8005f130 >= g_SndPlayer->maxSounds;
if (!sp70 || (state->flags & SNDSTATEFLAG_10)) {
hasvoice = n_alSynAllocVoice(&state->voice, &config);
}
if (!hasvoice) {
if (state->flags & (SNDSTATEFLAG_02 | SNDSTATEFLAG_10) || state->unk34 > 0) {
state->state = AL_STATE4;
state->unk34--;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &event->msg, 33333, 0);
} else if (sp70) {
iterstate = g_SndpAllocStatesTail;
do {
if ((iterstate->flags & (SNDSTATEFLAG_02 | SNDSTATEFLAG_10)) == 0
&& (iterstate->flags & SNDSTATEFLAG_04)
&& iterstate->state != AL_STATE3) {
sp70 = 0;
sp44.common.type = AL_SNDP_END_EVT;
sp44.common.state = (N_ALSoundState *)iterstate;
iterstate->state = AL_STATE3;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &sp44.msg, 1000, 0);
n_alSynSetVol(&iterstate->voice, 0, 1000);
}
iterstate = (struct sndstate *)iterstate->node.prev;
} while (sp70 && iterstate);
if (sp70 == 0) {
state->unk34 = 2;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &event->msg, 1001, 0);
} else {
func00033090(state);
}
} else {
func00033090(state);
}
return;
}
#if VERSION >= VERSION_NTSC_1_0
delta = sound->envelope->attackTime / state->pitch / state->basepitch;
if (state->flags & SNDSTATEFLAG_02) {
state->unk48 = 0;
} else {
sp40 = sound->envelope->decayTime / state->pitch / state->basepitch;
if (sp40 > 5500000) {
sp40 = 5500000;
}
state->unk48 = 1000000 + sp40 + g_SndPlayer->curTime;
if (state->unk48 < 0) {
state->unk48 = 0;
}
}
if (delta > 5500000) {
func00033090(state);
return;
}
state->flags |= SNDSTATEFLAG_04;
state->envvol = sound->envelope->attackVolume;
state->fxbus = config.fxBus;
state->endtime = g_SndPlayer->curTime + delta;
#else
// This is the same as above, but delta is calculated later
state->flags |= SNDSTATEFLAG_04;
state->envvol = sound->envelope->attackVolume;
state->fxbus = config.fxBus;
delta = sound->envelope->attackTime / state->pitch / state->basepitch;
state->endtime = g_SndPlayer->curTime + delta;
#endif
vol = MAX(0, (var8009c334[keymap->keyMin & 0x1f] * (state->envvol * state->vol * sound->sampleVolume / 0x3f01)) / 0x7fff - 1);
tmppan = state->pan + sound->samplePan - AL_PAN_CENTER;
pan = MIN(MAX(tmppan, 0), 127);
fxmix = (state->fxmix & 0x7f) + (keymap->keyMax & 0xf) * 8;
fxmix = MIN(127, MAX(0, fxmix));
fxmix |= state->fxmix & 0x80;
n_alSynStartVoiceParams(&state->voice, sound->wavetable, state->pitch * state->basepitch, vol, pan, fxmix, 0, 0, 0, delta);
state->state = AL_PLAYING;
var8005f130++;
if ((state->flags & SNDSTATEFLAG_02) == 0) {
if (delta == 0) {
state->envvol = sound->envelope->decayVolume;
vol = MAX(0, (var8009c334[keymap->keyMin & 0x1f] * (state->envvol * state->vol * sound->sampleVolume / 0x3f01)) / 0x7fff - 1);
delta = sound->envelope->decayTime / state->basepitch / state->pitch;
#if VERSION >= VERSION_NTSC_1_0
if (delta > 5500000) {
func00033090(state);
return;
}
#endif
state->endtime = g_SndPlayer->curTime + delta;
n_alSynSetVol(&state->voice, vol, delta);
sp94.common.type = AL_SNDP_STOP_EVT;
sp94.common.state = (N_ALSoundState *)state;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &sp94.msg, delta, 0);
if (state->flags & SNDSTATEFLAG_20) {
func00033100(state);
}
} else {
sp94.common.type = AL_SNDP_DECAY_EVT;
sp94.common.state = (N_ALSoundState *)state;
delta = sound->envelope->attackTime / state->pitch / state->basepitch;
#if VERSION >= VERSION_NTSC_1_0
if (delta > 5500000) {
func00033090(state);
return;
}
#endif
n_alEvtqPostEvent(&g_SndPlayer->evtq, &sp94.msg, delta, 0);
}
}
break;
case AL_SNDP_STOP_EVT:
case AL_SNDP_0400_EVT:
case AL_SNDP_1000_EVT:
if (event->common.type != AL_SNDP_1000_EVT || (state->flags & SNDSTATEFLAG_02)) {
switch (state->state) {
case AL_PLAYING:
_removeEvents(&g_SndPlayer->evtq, (N_ALSoundState *)state, AL_SNDP_DECAY_EVT);
delta = sound->envelope->releaseTime / state->basepitch / state->pitch;
#if VERSION >= VERSION_NTSC_1_0
if (delta > 5500000) {
func00033090(state);
break;
}
#endif
n_alSynSetVol(&state->voice, 0, delta);
if (delta) {
sp94.common.type = AL_SNDP_END_EVT;
sp94.common.state = (N_ALSoundState *)state;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &sp94.msg, delta, 0);
state->state = AL_STOPPING;
} else {
func00033090(state);
}
break;
case AL_STATE4:
case AL_STATE5:
func00033090(state);
break;
default:
break;
}
if (event->common.type == AL_SNDP_STOP_EVT) {
event->common.type = AL_SNDP_1000_EVT;
}
}
break;
case AL_SNDP_PAN_EVT:
state->pan = event->common.unk08;
if (state->state == AL_PLAYING) {
tmppan = state->pan - AL_PAN_CENTER + sound->samplePan;
pan = MIN(MAX(tmppan, AL_PAN_LEFT), AL_PAN_RIGHT);
n_alSynSetPan(&state->voice, pan);
}
break;
case AL_SNDP_PITCH_EVT:
state->pitch = event->pitch.pitch;
if (state->state == AL_PLAYING) {
n_alSynSetPitch(&state->voice, state->pitch * state->basepitch);
if (state->flags & SNDSTATEFLAG_20) {
func00033100(state);
}
}
break;
case AL_SNDP_FX_EVT:
state->fxmix = event->common.unk08;
if (state->state == AL_PLAYING) {
fxmix = (state->fxmix & 0x7f) + (keymap->keyMax & 0xf) * 8;
fxmix = MIN(127, MAX(0, fxmix));
fxmix |= state->fxmix & 0x80;
n_alSynSetFXMix(&state->voice, fxmix);
}
break;
case AL_SNDP_4000_EVT:
state->fxmix = (u8)(state->fxmix & 0x7f) | (u8)(event->common.unk08 & 0x80);
if (state->state == AL_PLAYING) {
fxmix = (state->fxmix & 0x7f) + (keymap->keyMax & 0xf) * 8;
fxmix = MIN(127, MAX(0, fxmix));
fxmix |= state->fxmix & 0x80;
n_alSynSetFXMix(&state->voice, fxmix);
}
break;
case AL_SNDP_FXBUS_EVT:
state->fxbus = event->common.unk08;
if (state->fxbus >= n_syn->maxAuxBusses) {
state->fxbus = 0;
}
if (state->state == AL_PLAYING) {
state->voice.fxBus = state->fxbus;
}
break;
case AL_SNDP_VOL_EVT:
state->vol = event->common.unk08;
if (state->state == AL_PLAYING) {
vol = MAX(0, (var8009c334[keymap->keyMin & 0x1f] * (state->envvol * state->vol * sound->sampleVolume / 0x3f01)) / 0x7fff - 1);
n_alSynSetVol(&state->voice, vol, MAX(1000, state->endtime - g_SndPlayer->curTime));
}
break;
case AL_SNDP_0800_EVT:
if (state->state == AL_PLAYING) {
delta = sound->envelope->releaseTime / state->basepitch / state->pitch;
#if VERSION >= VERSION_NTSC_1_0
if (delta > 5500000) {
func00033090(state);
break;
}
#endif
vol = MAX(0, var8009c334[keymap->keyMin & 0x1f] * (state->envvol * state->vol * sound->sampleVolume / 0x3f01) / 0x7fff - 1);
n_alSynSetVol(&state->voice, vol, delta);
}
break;
case AL_SNDP_DECAY_EVT:
if ((state->flags & SNDSTATEFLAG_02) == 0) {
state->envvol = sound->envelope->decayVolume;
vol = MAX(0, var8009c334[keymap->keyMin & 0x1f] * (state->envvol * state->vol * sound->sampleVolume / 0x3f01) / 0x7fff - 1);
delta = sound->envelope->decayTime / state->basepitch / state->pitch;
#if VERSION >= VERSION_NTSC_1_0
if (delta > 5500000) {
func00033090(state);
break;
}
#endif
state->endtime = g_SndPlayer->curTime + delta;
n_alSynSetVol(&state->voice, vol, delta);
sp94.common.type = AL_SNDP_STOP_EVT;
sp94.common.state = (N_ALSoundState *)state;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &sp94.msg, delta, 0);
if (state->flags & SNDSTATEFLAG_20) {
func00033100(state);
}
}
break;
case AL_SNDP_END_EVT:
func00033090(state);
break;
case AL_SNDP_0200_EVT:
if (state->flags & SNDSTATEFLAG_10) {
func00033820(event->msg.msg.generic.data2, event->msg.msg.generic.data, state->vol, state->pan,
state->pitch, state->fxmix, state->fxbus, state->unk30);
}
break;
default:
break;
}
isspecial = event->common.type & (AL_SNDP_PLAY_EVT
| AL_SNDP_PITCH_EVT
| AL_SNDP_DECAY_EVT
| AL_SNDP_END_EVT
| AL_SNDP_0200_EVT);
if ((state = nextstate) && !isspecial) {
done = state->flags & SNDSTATEFLAG_01;
}
} while (!done && state && !isspecial);
}
void func00033090(struct sndstate *state)
{
if (state->flags & SNDSTATEFLAG_04) {
n_alSynStopVoice(&state->voice);
n_alSynFreeVoice(&state->voice);
}
sndpFreeState(state);
// @todo: Remove cast
_removeEvents(&g_SndPlayer->evtq, (N_ALSoundState *)state, 0xffff);
}
void func00033100(struct sndstate *state)
{
N_ALSndpEvent evt;
f32 pitch = alCents2Ratio(state->sound->keyMap->detune) * state->pitch;
evt.common.type = AL_SNDP_PITCH_EVT;
evt.common.state = (N_ALSoundState *)state;
evt.common.unk08 = *(u32 *)&pitch;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt.msg, 33333, 0);
}
void _removeEvents(ALEventQueue *evtq, N_ALSoundState *state, u16 typemask)
{
ALLink *thisNode;
ALLink *nextNode;
N_ALEventListItem *thisItem;
N_ALEventListItem *nextItem;
N_ALSndpEvent *thisEvent;
OSIntMask mask;
mask = osSetIntMask(OS_IM_NONE);
thisNode = evtq->allocList.next;
while (thisNode != 0) {
nextNode = thisNode->next;
thisItem = (N_ALEventListItem *)thisNode;
nextItem = (N_ALEventListItem *)nextNode;
thisEvent = (N_ALSndpEvent *) &thisItem->evt;
if (thisEvent->common.state == state && thisEvent->common.type & typemask) {
if (nextItem) {
nextItem->delta += thisItem->delta;
}
alUnlink(thisNode);
alLink(thisNode, &evtq->freeList);
}
thisNode = nextNode;
}
osSetIntMask(mask);
}
u16 sndpCountStates(s16 *numfreeptr, s16 *numallocedptr)
{
OSIntMask mask = osSetIntMask(1);
u16 numalloced;
u16 numfree;
u16 numalloced2;
struct sndstate *state1 = g_SndpAllocStatesHead;
struct sndstate *state2 = g_SndpFreeStatesHead;
struct sndstate *state3 = g_SndpAllocStatesTail;
for (numalloced = 0; state1; numalloced++, state1 = (struct sndstate *)state1->node.next);
for (numfree = 0; state2; numfree++, state2 = (struct sndstate *)state2->node.next);
for (numalloced2 = 0; state3; numalloced2++, state3 = (struct sndstate *)state3->node.prev);
*numfreeptr = numfree;
*numallocedptr = numalloced;
osSetIntMask(mask);
return numalloced2;
}
void sndpSetAddRefCallback(void *fn)
{
g_SndpAddRefCallback = fn;
}
struct sndstate *func00033390(s32 arg0, ALSound *sound)
{
struct sndstate *state;
ALKeyMap *keymap;
OSIntMask mask;
s32 sp18;
keymap = sound->keyMap;
if (++var8005f134 > var8005f138) {
var8005f138 = var8005f134;
if (var8005f134 > 16) {
// empty
}
}
mask = osSetIntMask(1);
state = g_SndpFreeStatesHead;
if (state != NULL) {
g_SndpFreeStatesHead = (struct sndstate *)state->node.next;
alUnlink(&state->node);
if (g_SndpAllocStatesHead) {
state->node.next = &g_SndpAllocStatesHead->node;
state->node.prev = NULL;
g_SndpAllocStatesHead->node.prev = &state->node;
g_SndpAllocStatesHead = state;
} else {
state->node.next = state->node.prev = NULL;
g_SndpAllocStatesHead = state;
g_SndpAllocStatesTail = state;
}
osSetIntMask(mask);
sp18 = sound->envelope->decayTime + 1 == 0;
state->sound = sound;
state->priority = sp18 + 64;
state->state = AL_STATE5;
state->pitch = 1;
state->unk34 = 2;
state->flags = keymap->keyMax & 0xf0;
state->unk30 = NULL;
if (state->flags & SNDSTATEFLAG_20) {
state->basepitch = alCents2Ratio(keymap->keyBase * 100 - 6000);
} else {
state->basepitch = alCents2Ratio(keymap->keyBase * 100 + keymap->detune - 6000);
}
if (sp18) {
state->flags |= SNDSTATEFLAG_02;
}
state->fxmix = 0;
state->pan = AL_PAN_CENTER;
state->vol = 0x7fff;
if (g_SndpAddRefCallback != NULL) {
g_SndpAddRefCallback(state->sound);
}
} else {
osSetIntMask(mask);
}
return state;
}
void sndpSetRemoveRefCallback(void *fn)
{
g_SndpRemoveRefCallback = fn;
}
void sndpFreeState(struct sndstate *state)
{
var8005f134--;
if (g_SndpAllocStatesHead == state) {
g_SndpAllocStatesHead = (struct sndstate *)state->node.next;
}
if (g_SndpAllocStatesTail == state) {
g_SndpAllocStatesTail = (struct sndstate *)state->node.prev;
}
alUnlink(&state->node);
if (g_SndpFreeStatesHead) {
state->node.next = &g_SndpFreeStatesHead->node;
state->node.prev = NULL;
g_SndpFreeStatesHead->node.prev = &state->node;
g_SndpFreeStatesHead = state;
} else {
state->node.next = state->node.prev = NULL;
g_SndpFreeStatesHead = state;
}
if (state->flags & SNDSTATEFLAG_04) {
var8005f130--;
}
state->state = AL_STOPPED;
if (state->unk30) {
if (*state->unk30 == state) {
*state->unk30 = 0;
}
state->unk30 = NULL;
}
if (g_SndpRemoveRefCallback != NULL) {
g_SndpRemoveRefCallback(state->sound);
}
}
void sndSetPriority(struct sndstate *state, u8 priority)
{
if (state) {
state->priority = (s16)priority;
}
}
s32 sndGetState(struct sndstate *state)
{
if (state) {
return state->state;
} else {
return false;
}
}
struct sndstate *func00033820(s32 arg0, s16 soundnum, u16 vol, ALPan pan, f32 pitch, u8 fxmix, u8 fxbus, struct sndstate **handleptr)
{
struct sndstate *state;
struct sndstate *state2 = NULL;
ALKeyMap *keymap;
ALSound *sound;
s16 sp4e = 0;
s32 sp48;
s32 sp44;
s32 sp40 = 0;
s32 abspan;
N_ALEvent evt;
N_ALEvent evt2;
if (sndIsDisabled()) {
return NULL;
}
if (soundnum != 0) {
do {
sound = sndLoadSound(soundnum);
state = func00033390(arg0, sound);
if (state != NULL) {
g_SndPlayer->target = state;
evt.type = AL_SNDP_PLAY_EVT;
evt.msg.generic.sndstate = state;
abspan = pan + state->pan - AL_PAN_CENTER;
if (abspan > 127) {
abspan = 127;
} else if (abspan < 0) {
abspan = 0;
}
state->pan = abspan;
state->vol = (u32)(vol * state->vol) >> 15;
state->pitch *= pitch;
state->fxmix = fxmix;
state->fxbus = fxbus;
#if VERSION >= VERSION_NTSC_1_0
state->soundnum = soundnum;
state->unk48 = 0;
#endif
sp44 = sound->keyMap->velocityMax * 33333;
if (state->flags & SNDSTATEFLAG_10) {
state->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, sp40 + 1, 0);
sp48 = sp44 + 1;
sp4e = soundnum;
} else {
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, sp44 + 1, 0);
}
state2 = state;
}
sp40 += sp44;
keymap = sound->keyMap;
soundnum = keymap->velocityMin + (keymap->keyMin & 0xc0) * 4;
} while (soundnum && state);
if (state2 != NULL) {
state2->flags |= SNDSTATEFLAG_01;
state2->unk30 = handleptr;
if (sp4e != 0) {
state2->flags |= SNDSTATEFLAG_10;
evt2.type = AL_SNDP_0200_EVT;
evt2.msg.generic.sndstate = state2;
evt2.msg.generic.data = sp4e;
evt2.msg.generic.data2 = arg0;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt2, sp48, 0);
}
}
}
if (handleptr != NULL) {
*handleptr = state2;
}
return state2;
}
void audioStop(struct sndstate *state)
{
N_ALEvent evt;
#if VERSION >= VERSION_NTSC_FINAL
if (state && (state->flags & SNDSTATEFLAG_02)) {
func00033bc0(state);
} else {
evt.type = AL_SNDP_0400_EVT;
evt.msg.generic.sndstate = state;
if (state != NULL) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
}
#elif VERSION >= VERSION_NTSC_1_0
// NTSC 1.0 lacks the null state check
if (state->flags & SNDSTATEFLAG_02) {
func00033bc0(state);
} else {
evt.type = AL_SNDP_0400_EVT;
evt.msg.generic.sndstate = state;
if (state != NULL) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
}
#else
evt.type = AL_SNDP_0400_EVT;
evt.msg.generic.sndstate = state;
if (state != NULL) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
#endif
}
#if VERSION >= VERSION_NTSC_1_0
void func00033bc0(struct sndstate *state)
{
N_ALEvent evt;
evt.type = AL_SNDP_END_EVT;
evt.msg.generic.sndstate = state;
if (state) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
}
#endif
void func00033c30(u8 flags)
{
OSIntMask mask = osSetIntMask(1);
N_ALEvent evt;
struct sndstate *state = g_SndpAllocStatesHead;
while (state) {
evt.type = AL_SNDP_0400_EVT;
evt.msg.generic.sndstate = state;
if ((state->flags & flags) == flags) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
state = (struct sndstate *)state->node.next;
}
osSetIntMask(mask);
}
#if VERSION >= VERSION_NTSC_1_0
void func00033cf0(u8 flags)
{
OSIntMask mask = osSetIntMask(1);
N_ALEvent evt;
struct sndstate *state = g_SndpAllocStatesHead;
while (state) {
evt.type = AL_SNDP_END_EVT;
evt.msg.generic.sndstate = state;
if ((state->flags & flags) == flags) {
evt.msg.generic.sndstate->flags &= ~SNDSTATEFLAG_10;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
state = (struct sndstate *)state->node.next;
}
osSetIntMask(mask);
}
#endif
#if VERSION >= VERSION_NTSC_1_0
void func00033db0(void)
{
func00033cf0(SNDSTATEFLAG_01);
}
#endif
void func00033dd8(void)
{
func00033c30(SNDSTATEFLAG_01);
}
void func00033e00(void)
{
func00033c30(SNDSTATEFLAG_01 | SNDSTATEFLAG_10);
}
void func00033e28(void)
{
func00033c30(SNDSTATEFLAG_01 | SNDSTATEFLAG_02);
}
void audioPostEvent(struct sndstate *state, s16 type, s32 data)
{
N_ALEvent evt;
evt.type = type;
evt.msg.generic.sndstate = state;
evt.msg.generic.data = data;
if (state) {
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
} else {
// empty
}
}
u16 func00033ec4(u8 index)
{
return var8009c334 ? var8009c334[index] : 0;
}
#if VERSION >= VERSION_NTSC_1_0
struct sndstate *sndpGetHeadState(void)
{
return g_SndpAllocStatesHead;
}
#endif
#if VERSION >= VERSION_NTSC_1_0
ALMicroTime sndpGetCurTime(void)
{
return g_SndPlayer->curTime;
}
#endif
void func00033f44(u8 index, u16 volume)
{
if (var8009c334) {
OSIntMask mask = osSetIntMask(1);
struct sndstate *state = g_SndpAllocStatesHead;
s32 i;
N_ALEvent evt;
var8009c334[index] = volume;
for (i = 0; state != NULL; i++, state = (struct sndstate *)state->node.next) {
if ((state->sound->keyMap->keyMin & 0x1f) == index) {
evt.type = AL_SNDP_0800_EVT;
evt.msg.generic.sndstate = state;
n_alEvtqPostEvent(&g_SndPlayer->evtq, &evt, 0, 0);
}
}
osSetIntMask(mask);
}
}