ref: 723ca0d4b4da52cf0c52e84fa9b81ba11ae5ad31
dir: /snd_masm.c/
#include "common.h"
#include "pmplay.h"
#include "pmp_mix.h"
#include "snd_masm.h"
/* 8bb: This is done in a slightly different way, but the result
** is the same (bit-accurate to FT2.08/FT2.09 w/ SB16, and WAV-writer).
**
** Mixer macros are stored in snd_masm.h
*/
void PMPMix32Proc(CIType *v, int32_t numSamples, int32_t bufferPos) // 8bb: numSamples = 1..65535
{
if (numSamples > 65535)
return;
if (v->SType & SType_Off)
return; // voice is not active
uint32_t volStatus = v->SLVol1 | v->SRVol1;
if (volumeRampingFlag)
volStatus |= v->SLVol2 | v->SRVol2;
if (volStatus == 0) // mix silence
{
const uint32_t addPos = (v->SFrq >> 16) * (uint32_t)numSamples;
uint32_t addFrac = (v->SFrq & 0xFFFF) * (uint32_t)numSamples;
addFrac += v->SPosDec >> 16;
int32_t realPos = v->SPos + addPos + (addFrac >> 16);
if (realPos >= v->SLen)
{
uint8_t SType = v->SType;
if (SType & (SType_Fwd+SType_Rev))
{
do
{
SType ^= SType_RevDir;
realPos -= v->SRepL;
}
while (realPos >= v->SLen);
v->SType = SType;
}
else
{
v->SType = SType_Off;
return;
}
}
v->SPosDec = (addFrac & 0xFFFF) << 16;
v->SPos = realPos;
}
else // normal mixing
{
bool mixInCenter;
if (volumeRampingFlag)
mixInCenter = (v->SLVol2 == v->SRVol2) && (v->SLVolIP == v->SRVolIP);
else
mixInCenter = v->SLVol1 == v->SRVol1;
mixRoutineTable[(mixInCenter * 8) + v->SMixType](v, numSamples, bufferPos);
}
}
static void mix8b(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_VOL
GET_MIXER_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT
MIX_8BIT
MIX_8BIT
MIX_8BIT
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix8bIntrp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_VOL
GET_MIXER_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_INTRP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_INTRP
MIX_8BIT_INTRP
MIX_8BIT_INTRP
MIX_8BIT_INTRP
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix8bRamp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT
VOL_RAMP
MIX_8BIT
VOL_RAMP
MIX_8BIT
VOL_RAMP
MIX_8BIT
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix8bRampIntrp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_INTRP
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_INTRP
VOL_RAMP
MIX_8BIT_INTRP
VOL_RAMP
MIX_8BIT_INTRP
VOL_RAMP
MIX_8BIT_INTRP
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix16b(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_VOL
GET_MIXER_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT
MIX_16BIT
MIX_16BIT
MIX_16BIT
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix16bIntrp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_VOL
GET_MIXER_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_INTRP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_INTRP
MIX_16BIT_INTRP
MIX_16BIT_INTRP
MIX_16BIT_INTRP
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix16bRamp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT
VOL_RAMP
MIX_16BIT
VOL_RAMP
MIX_16BIT
VOL_RAMP
MIX_16BIT
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix16bRampIntrp(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_INTRP
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_INTRP
VOL_RAMP
MIX_16BIT_INTRP
VOL_RAMP
MIX_16BIT_INTRP
VOL_RAMP
MIX_16BIT_INTRP
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix8bCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_VOL_CENTER
GET_MIXER_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_M
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_M
MIX_8BIT_M
MIX_8BIT_M
MIX_8BIT_M
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix8bIntrpCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_VOL_CENTER
GET_MIXER_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_INTRP_M
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_INTRP_M
MIX_8BIT_INTRP_M
MIX_8BIT_INTRP_M
MIX_8BIT_INTRP_M
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix8bRampCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_M
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_M
VOL_RAMP
MIX_8BIT_M
VOL_RAMP
MIX_8BIT_M
VOL_RAMP
MIX_8BIT_M
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix8bRampIntrpCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE8
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_8BIT_INTRP_M
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_8BIT_INTRP_M
VOL_RAMP
MIX_8BIT_INTRP_M
VOL_RAMP
MIX_8BIT_INTRP_M
VOL_RAMP
MIX_8BIT_INTRP_M
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix16bCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_VOL_CENTER
GET_MIXER_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_M
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_M
MIX_16BIT_M
MIX_16BIT_M
MIX_16BIT_M
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix16bIntrpCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_VOL_CENTER
GET_MIXER_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
CDA_BytesLeft -= samplesToMix;
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_INTRP_M
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_INTRP_M
MIX_16BIT_INTRP_M
MIX_16BIT_INTRP_M
MIX_16BIT_INTRP_M
}
HANDLE_POS_END
}
SET_BACK_MIXER_POS
}
static void mix16bRampCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_M
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_M
VOL_RAMP
MIX_16BIT_M
VOL_RAMP
MIX_16BIT_M
VOL_RAMP
MIX_16BIT_M
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
static void mix16bRampIntrpCenter(CIType *v, uint32_t numSamples, uint32_t bufferPos)
{
int32_t sample, sample2;
GET_MIXER_VARS
GET_RAMP_VARS
SET_BASE16
int32_t CDA_BytesLeft = numSamples;
while (CDA_BytesLeft > 0)
{
LIMIT_MIX_NUM
LIMIT_MIX_NUM_RAMP
CDA_BytesLeft -= samplesToMix;
GET_VOL_RAMP
HANDLE_POS_START
for (i = 0; i < (samplesToMix & 3); i++)
{
MIX_16BIT_INTRP_M
VOL_RAMP
}
samplesToMix >>= 2;
for (i = 0; i < samplesToMix; i++)
{
MIX_16BIT_INTRP_M
VOL_RAMP
MIX_16BIT_INTRP_M
VOL_RAMP
MIX_16BIT_INTRP_M
VOL_RAMP
MIX_16BIT_INTRP_M
VOL_RAMP
}
HANDLE_POS_END
SET_VOL_BACK
}
SET_BACK_MIXER_POS
}
mixRoutine mixRoutineTable[16] =
{
(mixRoutine)mix8b,
(mixRoutine)mix8bIntrp,
(mixRoutine)mix8bRamp,
(mixRoutine)mix8bRampIntrp,
(mixRoutine)mix16b,
(mixRoutine)mix16bIntrp,
(mixRoutine)mix16bRamp,
(mixRoutine)mix16bRampIntrp,
(mixRoutine)mix8bCenter,
(mixRoutine)mix8bIntrpCenter,
(mixRoutine)mix8bRampCenter,
(mixRoutine)mix8bRampIntrpCenter,
(mixRoutine)mix16bCenter,
(mixRoutine)mix16bIntrpCenter,
(mixRoutine)mix16bRampCenter,
(mixRoutine)mix16bRampIntrpCenter
};