diff options
Diffstat (limited to 'arm7/lib/src/SND_exChannel.c')
-rw-r--r-- | arm7/lib/src/SND_exChannel.c | 434 |
1 files changed, 265 insertions, 169 deletions
diff --git a/arm7/lib/src/SND_exChannel.c b/arm7/lib/src/SND_exChannel.c index c2231640..dfaabeda 100644 --- a/arm7/lib/src/SND_exChannel.c +++ b/arm7/lib/src/SND_exChannel.c @@ -2,8 +2,8 @@ #include "SND_channel.h" #include "SND_main.h" -#include "SND_work.h" #include "SND_util.h" +#include "SND_work.h" #include "registers.h" @@ -21,15 +21,18 @@ static int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step); static int ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step); static void ExChannelStart(struct SNDExChannel *chn, int length); static int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b); -static void ExChannelSetup(struct SNDExChannel *, SNDExChannelCallback callback, void *callbackUserData, int priority); +static void ExChannelSetup( + struct SNDExChannel *, SNDExChannelCallback callback, void *callbackUserData, int priority); -void SND_ExChannelInit(void) { +void SND_ExChannelInit(void) +{ struct SNDExChannel *chn; s32 i; - for (i = 0; i < SND_CHANNEL_COUNT; i++) { + for (i = 0; i < SND_CHANNEL_COUNT; i++) + { chn = &SNDi_Work.channels[i]; - + chn->id = (u8)i; chn->flags.syncFlag = 0; chn->flags.active = FALSE; @@ -39,11 +42,13 @@ void SND_ExChannelInit(void) { sWeakLockedChannelMask = 0; } -void SND_UpdateExChannel(void) { +void SND_UpdateExChannel(void) +{ struct SNDExChannel *chn; s32 i; - for (i = 0; i < SND_CHANNEL_COUNT; i++) { + for (i = 0; i < SND_CHANNEL_COUNT; i++) + { chn = &SNDi_Work.channels[i]; if (chn->flags.syncFlag == 0) @@ -51,69 +56,69 @@ void SND_UpdateExChannel(void) { if (chn->flags.syncFlag & SND_CHN_SYNC_STOP) SND_StopChannel(i, 0); - - if (chn->flags.syncFlag & SND_CHN_SYNC_START) { - switch (chn->type) { - case SND_CHN_TYPE_PCM: - SND_SetupChannelPcm( - i, - chn->waveDataPtr, - chn->waveParam.format, - chn->waveParam.loopEnabled ? 1 : 2, - (s32)chn->waveParam.loopStart, - (s32)chn->waveParam.loopLength, - chn->volume & 0xFF, - chn->volume >> 8, - chn->timer, - chn->pan - ); - break; - case SND_CHN_TYPE_PSG: - SND_SetupChannelPsg( - i, - chn->dutyCycle, - chn->volume & 0xFF, - chn->volume >> 8, - chn->timer, - chn->pan - ); - break; - case SND_CHN_TYPE_NOISE: - SND_SetupChannelNoise( - i, - chn->volume & 0xFF, - chn->volume >> 8, - chn->timer, - chn->pan - ); - break; + + if (chn->flags.syncFlag & SND_CHN_SYNC_START) + { + switch (chn->type) + { + case SND_CHN_TYPE_PCM: + SND_SetupChannelPcm(i, + chn->waveDataPtr, + chn->waveParam.format, + chn->waveParam.loopEnabled ? 1 : 2, + (s32)chn->waveParam.loopStart, + (s32)chn->waveParam.loopLength, + chn->volume & 0xFF, + chn->volume >> 8, + chn->timer, + chn->pan); + break; + case SND_CHN_TYPE_PSG: + SND_SetupChannelPsg(i, + chn->dutyCycle, + chn->volume & 0xFF, + chn->volume >> 8, + chn->timer, + chn->pan); + break; + case SND_CHN_TYPE_NOISE: + SND_SetupChannelNoise( + i, chn->volume & 0xFF, chn->volume >> 8, chn->timer, chn->pan); + break; } - } else { - if (chn->flags.syncFlag & SND_CHN_SYNC_TIMER) { + } + else + { + if (chn->flags.syncFlag & SND_CHN_SYNC_TIMER) + { SND_SetChannelTimer(i, chn->timer); } - if (chn->flags.syncFlag & SND_CHN_SYNC_VOLUME) { + if (chn->flags.syncFlag & SND_CHN_SYNC_VOLUME) + { SND_SetChannelVolume(i, chn->volume & 0xFF, chn->volume >> 8); } - if (chn->flags.syncFlag & SND_CHN_SYNC_PAN) { + if (chn->flags.syncFlag & SND_CHN_SYNC_PAN) + { SND_SetChannelPan(i, chn->pan); } } } - for (i = 0; i < SND_CHANNEL_COUNT; i++) { + for (i = 0; i < SND_CHANNEL_COUNT; i++) + { chn = &SNDi_Work.channels[i]; if (!chn->flags.syncFlag) continue; - + if (chn->flags.syncFlag & SND_CHN_SYNC_START) reg_SOUNDxCNT_STAT(i) |= 0x80; chn->flags.syncFlag = 0; } } -void SND_ExChannelMain(BOOL step) { +void SND_ExChannelMain(BOOL step) +{ struct SNDExChannel *chn; s32 i; s32 vol; @@ -122,7 +127,8 @@ void SND_ExChannelMain(BOOL step) { s32 lfo; u16 newTimer; - for (i = 0; i < SND_CHANNEL_COUNT; i++) { + for (i = 0; i < SND_CHANNEL_COUNT; i++) + { vol = 0; pitch = 0; pan = 0; @@ -130,11 +136,14 @@ void SND_ExChannelMain(BOOL step) { if (!chn->flags.active) continue; - - if (chn->flags.start) { + + if (chn->flags.start) + { chn->flags.syncFlag |= SND_CHN_SYNC_START; chn->flags.start = FALSE; - } else if (!SND_IsChannelActive(i)) { + } + else if (!SND_IsChannelActive(i)) + { if (chn->callback) chn->callback(chn, 1, chn->callbackUserData); else @@ -143,7 +152,7 @@ void SND_ExChannelMain(BOOL step) { chn->flags.active = FALSE; continue; } - + vol += SNDi_DecibelSquareTable[chn->velocity]; pitch += (chn->midiKey - chn->rootMidiKey) * 0x40; @@ -156,26 +165,29 @@ void SND_ExChannelMain(BOOL step) { lfo = ExChannelLfoUpdate(chn, step); - switch (chn->lfo.param.target) { - case SND_LFO_VOLUME: - if (vol > -0x8000) - vol += lfo; - break; - case SND_LFO_PAN: - pan += lfo; - break; - case SND_LFO_PITCH: - pitch += lfo; - break; + switch (chn->lfo.param.target) + { + case SND_LFO_VOLUME: + if (vol > -0x8000) + vol += lfo; + break; + case SND_LFO_PAN: + pan += lfo; + break; + case SND_LFO_PITCH: + pitch += lfo; + break; } pan += chn->initPan; - if (chn->panRange != 127) { + if (chn->panRange != 127) + { pan = (pan * chn->panRange + 0x40) >> 7; } pan += chn->userPan; - if (chn->envStatus == SND_ENV_RELEASE && vol <= -723) { + if (chn->envStatus == SND_ENV_RELEASE && vol <= -723) + { chn->flags.syncFlag = SND_CHN_SYNC_STOP; if (chn->callback) chn->callback(chn, 1, chn->callbackUserData); @@ -183,28 +195,33 @@ void SND_ExChannelMain(BOOL step) { chn->priority = 0; chn->volume = 0; chn->flags.active = 0; - } else { + } + else + { vol = SND_CalcChannelVolume(vol); newTimer = SND_CalcTimer(chn->waveParam.timer, pitch); if (chn->type == SND_CHN_TYPE_PSG) newTimer &= 0xFFFC; - + pan += 0x40; if (pan < 0) pan = 0; else if (pan > 127) pan = 127; - - if (vol != chn->volume) { + + if (vol != chn->volume) + { chn->volume = (u16)vol; chn->flags.syncFlag |= SND_CHN_SYNC_VOLUME; } - if (newTimer != chn->timer) { + if (newTimer != chn->timer) + { chn->timer = (u16)newTimer; chn->flags.syncFlag |= SND_CHN_SYNC_TIMER; } - if (pan != chn->pan) { + if (pan != chn->pan) + { chn->pan = (u8)pan; chn->flags.syncFlag |= SND_CHN_SYNC_PAN; } @@ -212,7 +229,9 @@ void SND_ExChannelMain(BOOL step) { } } -BOOL SND_StartExChannelPcm(struct SNDExChannel *chn, const struct SNDWaveParam *wave, const void *data, s32 length) { +BOOL SND_StartExChannelPcm( + struct SNDExChannel *chn, const struct SNDWaveParam *wave, const void *data, s32 length) +{ chn->type = SND_CHN_TYPE_PCM; chn->waveParam = *wave; chn->waveDataPtr = data; @@ -220,12 +239,18 @@ BOOL SND_StartExChannelPcm(struct SNDExChannel *chn, const struct SNDWaveParam * return TRUE; } -BOOL SND_StartExChannelPsg(struct SNDExChannel *chn, s32 duty, s32 length) { - if (chn->id < 8) { +BOOL SND_StartExChannelPsg(struct SNDExChannel *chn, s32 duty, s32 length) +{ + if (chn->id < 8) + { return FALSE; - } else if (chn->id > 13) { + } + else if (chn->id > 13) + { return FALSE; - } else { + } + else + { chn->type = SND_CHN_TYPE_PSG; chn->dutyCycle = duty; chn->waveParam.timer = 8006; @@ -234,12 +259,18 @@ BOOL SND_StartExChannelPsg(struct SNDExChannel *chn, s32 duty, s32 length) { } } -BOOL SND_StartExChannelNoise(struct SNDExChannel *chn, s32 length) { - if (chn->id < 14) { +BOOL SND_StartExChannelNoise(struct SNDExChannel *chn, s32 length) +{ + if (chn->id < 14) + { return FALSE; - } else if (chn->id > 15) { + } + else if (chn->id > 15) + { return FALSE; - } else { + } + else + { chn->type = SND_CHN_TYPE_NOISE; chn->waveParam.timer = 8006; ExChannelStart(chn, length); @@ -247,63 +278,75 @@ BOOL SND_StartExChannelNoise(struct SNDExChannel *chn, s32 length) { } } -s32 SND_UpdateExChannelEnvelope(struct SNDExChannel *chn, BOOL step) { +s32 SND_UpdateExChannelEnvelope(struct SNDExChannel *chn, BOOL step) +{ s32 sustain; - if (step) { - switch (chn->envStatus) { - case SND_ENV_ATTACK: - chn->envAttenuation = -((-chn->envAttenuation * chn->envAttack) >> 8); - if (chn->envAttenuation == 0) - chn->envStatus = SND_ENV_DECAY; - break; - case SND_ENV_DECAY: - sustain = SNDi_DecibelSquareTable[chn->envSustain] << 7; - chn->envAttenuation -= chn->envDecay; - if (chn->envAttenuation <= sustain) { - chn->envAttenuation = sustain; - chn->envStatus = SND_ENV_SUSTAIN; - } - break; - case SND_ENV_SUSTAIN: - break; - case SND_ENV_RELEASE: - chn->envAttenuation -= chn->envRelease; - break; + if (step) + { + switch (chn->envStatus) + { + case SND_ENV_ATTACK: + chn->envAttenuation = -((-chn->envAttenuation * chn->envAttack) >> 8); + if (chn->envAttenuation == 0) + chn->envStatus = SND_ENV_DECAY; + break; + case SND_ENV_DECAY: + sustain = SNDi_DecibelSquareTable[chn->envSustain] << 7; + chn->envAttenuation -= chn->envDecay; + if (chn->envAttenuation <= sustain) + { + chn->envAttenuation = sustain; + chn->envStatus = SND_ENV_SUSTAIN; + } + break; + case SND_ENV_SUSTAIN: + break; + case SND_ENV_RELEASE: + chn->envAttenuation -= chn->envRelease; + break; } } return chn->envAttenuation >> 7; } -void SND_SetExChannelAttack(struct SNDExChannel *chn, s32 attack) { +void SND_SetExChannelAttack(struct SNDExChannel *chn, s32 attack) +{ if (attack < 109) chn->envAttack = (u8)(255 - attack); else chn->envAttack = sAttackCoeffTable[127 - attack]; } -void SND_SetExChannelDecay(struct SNDExChannel *chn, s32 decay) { +void SND_SetExChannelDecay(struct SNDExChannel *chn, s32 decay) +{ chn->envDecay = CalcDecayCoeff(decay); } -void SND_SetExChannelSustain(struct SNDExChannel *chn, s32 sustain) { +void SND_SetExChannelSustain(struct SNDExChannel *chn, s32 sustain) +{ chn->envSustain = (u8)sustain; } -void SND_SetExChannelRelease(struct SNDExChannel *chn, s32 release) { +void SND_SetExChannelRelease(struct SNDExChannel *chn, s32 release) +{ chn->envRelease = CalcDecayCoeff(release); } -void SND_ReleaseExChannel(struct SNDExChannel *chn) { +void SND_ReleaseExChannel(struct SNDExChannel *chn) +{ chn->envStatus = SND_ENV_RELEASE; } -BOOL SND_IsExChannelActive(struct SNDExChannel *chn) { +BOOL SND_IsExChannelActive(struct SNDExChannel *chn) +{ return chn->flags.active; } -struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData) { +struct SNDExChannel *SND_AllocExChannel( + u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData) +{ struct SNDExChannel *chnPrev; int i; struct SNDExChannel *chn; @@ -315,20 +358,23 @@ struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags chnPrev = NULL; - for (i = 0; i < SND_CHANNEL_COUNT; i++) { + for (i = 0; i < SND_CHANNEL_COUNT; i++) + { channelCandidate = sChannelAllocationOrder[i]; - if (channelMask & (1 << channelCandidate)) { + if (channelMask & (1 << channelCandidate)) + { chn = &SNDi_Work.channels[channelCandidate]; - if (chnPrev == NULL) { + if (chnPrev == NULL) + { chnPrev = chn; continue; } - + if (chn->priority > chnPrev->priority) continue; - + if (chn->priority != chnPrev->priority || ExChannelVolumeCmp(chnPrev, chn) < 0) chnPrev = chn; } @@ -336,35 +382,39 @@ struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags if (chnPrev == NULL) return NULL; - + if (priority < chnPrev->priority) return NULL; if (chnPrev->callback) chnPrev->callback(chnPrev, 0, chnPrev->callbackUserData); - + chnPrev->flags.syncFlag = 2; chnPrev->flags.active = 0; ExChannelSetup(chnPrev, callback, callbackUserData, priority); return chnPrev; } -void SND_FreeExChannel(struct SNDExChannel *chn) { - if (chn) { +void SND_FreeExChannel(struct SNDExChannel *chn) +{ + if (chn) + { chn->callback = NULL; chn->callbackUserData = NULL; } } -void SND_StopUnlockedChannel(u32 channelMask, u32 weak) { +void SND_StopUnlockedChannel(u32 channelMask, u32 weak) +{ (void)weak; struct SNDExChannel *chn; - - for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) { + + for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) + { if ((channelMask & 1) == 0) continue; - + chn = &SNDi_Work.channels[i]; if (sLockedChannelMask & (1 << i)) @@ -381,12 +431,14 @@ void SND_StopUnlockedChannel(u32 channelMask, u32 weak) { } } -void SND_LockChannel(u32 channelMask, u32 weak) { +void SND_LockChannel(u32 channelMask, u32 weak) +{ struct SNDExChannel *chn; u32 j = channelMask; int i = 0; - for (; i < SND_CHANNEL_COUNT && j != 0; i++, j >>= 1) { + for (; i < SND_CHANNEL_COUNT && j != 0; i++, j >>= 1) + { if ((j & 1) == 0) continue; @@ -405,41 +457,57 @@ void SND_LockChannel(u32 channelMask, u32 weak) { chn->flags.active = 0; } - if (weak & 1) { + if (weak & 1) + { sWeakLockedChannelMask |= channelMask; - } else { + } + else + { sLockedChannelMask |= channelMask; } } -void SND_UnlockChannel(u32 channelMask, u32 weak) { - if (weak & 1) { +void SND_UnlockChannel(u32 channelMask, u32 weak) +{ + if (weak & 1) + { sWeakLockedChannelMask &= ~channelMask; - } else { + } + else + { sLockedChannelMask &= ~channelMask; } } -u32 SND_GetLockedChannel(u32 weak) { - if (weak & 1) { +u32 SND_GetLockedChannel(u32 weak) +{ + if (weak & 1) + { return sWeakLockedChannelMask; - } else { + } + else + { return sLockedChannelMask; } } -void SND_InvalidateWave(const void *start, const void *end) { - for (u8 i = 0; i < SND_CHANNEL_COUNT; i++) { +void SND_InvalidateWave(const void *start, const void *end) +{ + for (u8 i = 0; i < SND_CHANNEL_COUNT; i++) + { struct SNDExChannel *chn = &SNDi_Work.channels[i]; - if (chn->flags.active && chn->type == 0 && start <= chn->waveDataPtr && chn->waveDataPtr <= end) { + if (chn->flags.active && chn->type == 0 && start <= chn->waveDataPtr && + chn->waveDataPtr <= end) + { chn->flags.start = FALSE; SND_StopChannel(i, 0); } } } -void SND_InitLfoParam(struct SNDLfoParam *lfoParam) { +void SND_InitLfoParam(struct SNDLfoParam *lfoParam) +{ lfoParam->target = SND_LFO_PITCH; lfoParam->depth = 0; lfoParam->range = 1; @@ -447,19 +515,25 @@ void SND_InitLfoParam(struct SNDLfoParam *lfoParam) { lfoParam->delay = 0; } -void SND_StartLfo(struct SNDLfo *lfo) { +void SND_StartLfo(struct SNDLfo *lfo) +{ lfo->counter = 0; lfo->delayCounter = 0; } -void SND_UpdateLfo(struct SNDLfo *lfo) { - if (lfo->delayCounter < lfo->param.delay) { +void SND_UpdateLfo(struct SNDLfo *lfo) +{ + if (lfo->delayCounter < lfo->param.delay) + { lfo->delayCounter++; - } else { + } + else + { u32 tmp = lfo->counter; tmp += lfo->param.speed << 6; tmp >>= 8; - while (tmp >= 0x80) { + while (tmp >= 0x80) + { tmp -= 0x80; } lfo->counter += lfo->param.speed << 6; @@ -468,17 +542,24 @@ void SND_UpdateLfo(struct SNDLfo *lfo) { } } -int SND_GetLfoValue(struct SNDLfo *lfo) { - if (lfo->param.depth == 0) { +int SND_GetLfoValue(struct SNDLfo *lfo) +{ + if (lfo->param.depth == 0) + { return 0; - } else if (lfo->delayCounter < lfo->param.delay) { + } + else if (lfo->delayCounter < lfo->param.delay) + { return 0; - } else { + } + else + { return SND_SinIdx((s32)((u32)lfo->counter >> 8)) * lfo->param.depth * lfo->param.range; } } -static u16 CalcDecayCoeff(int vol) { +static u16 CalcDecayCoeff(int vol) +{ if (vol == 127) return 0xFFFF; else if (vol == 126) @@ -489,7 +570,9 @@ static u16 CalcDecayCoeff(int vol) { return (u16)(0x1E00 / (126 - vol)); } -static void ExChannelSetup(struct SNDExChannel *chn, SNDExChannelCallback callback, void *callbackUserData, int priority) { +static void ExChannelSetup( + struct SNDExChannel *chn, SNDExChannelCallback callback, void *callbackUserData, int priority) +{ chn->channelLLNext = NULL; chn->callback = callback; chn->callbackUserData = callbackUserData; @@ -518,7 +601,8 @@ static void ExChannelSetup(struct SNDExChannel *chn, SNDExChannelCallback callba SND_InitLfoParam(&chn->lfo.param); } -static void ExChannelStart(struct SNDExChannel *chn, int length) { +static void ExChannelStart(struct SNDExChannel *chn, int length) +{ chn->envAttenuation = -92544; chn->envStatus = 0; chn->length = length; @@ -527,7 +611,8 @@ static void ExChannelStart(struct SNDExChannel *chn, int length) { chn->flags.active = TRUE; } -static int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b) { +static int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b) +{ int vol_a = chn_a->volume & 0xFF; int vol_b = chn_b->volume & 0xFF; @@ -537,7 +622,8 @@ static int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *c vol_a >>= sSampleDataShiftTable[chn_a->volume >> 8]; vol_b >>= sSampleDataShiftTable[chn_b->volume >> 8]; - if (vol_a != vol_b) { + if (vol_a != vol_b) + { if (vol_a < vol_b) return 1; else @@ -546,14 +632,20 @@ static int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *c return 0; } -static int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step) { +static int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step) +{ s64 result; - if (chn->sweepPitch == 0) { + if (chn->sweepPitch == 0) + { result = 0; - } else if (chn->sweepCounter >= chn->sweepLength) { + } + else if (chn->sweepCounter >= chn->sweepLength) + { result = 0; - } else { + } + else + { result = (s64)chn->sweepPitch * (chn->sweepLength - chn->sweepCounter) / chn->sweepLength; if (step && chn->flags.autoSweep) @@ -563,25 +655,29 @@ static int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step) { return (int)result; } -static int ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step) { +static int ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step) +{ s64 result = SND_GetLfoValue(&chn->lfo); - if (result != 0) { - switch (chn->lfo.param.target) { - case SND_LFO_VOLUME: - result *= 60; - break; - case SND_LFO_PITCH: - result <<= 6; - break; - case SND_LFO_PAN: - result <<= 6; - break; + if (result != 0) + { + switch (chn->lfo.param.target) + { + case SND_LFO_VOLUME: + result *= 60; + break; + case SND_LFO_PITCH: + result <<= 6; + break; + case SND_LFO_PAN: + result <<= 6; + break; } result >>= 14; } - if (step) { + if (step) + { SND_UpdateLfo(&chn->lfo); } |