Allow sn76496 to output to mono.
This commit is contained in:
parent
c419f723bf
commit
2c71402654
|
@ -177,6 +177,131 @@ void SN76496Update(INT32 Num, INT16* pSoundBuf, INT32 Length)
|
|||
}
|
||||
}
|
||||
|
||||
void SN76496UpdateToBuffer(INT32 Num, INT16* pSoundBuf, INT32 Length)
|
||||
{
|
||||
#if defined FBA_DEBUG
|
||||
if (!DebugSnd_SN76496Initted) bprintf(PRINT_ERROR, _T("SN76496Update called without init\n"));
|
||||
if (Num > NumChips) bprintf(PRINT_ERROR, _T("SN76496Update called with invalid chip %x\n"), Num);
|
||||
#endif
|
||||
|
||||
INT32 i;
|
||||
struct SN76496 *R = Chip0;
|
||||
|
||||
if (Num >= MAX_SN76496_CHIPS) return;
|
||||
|
||||
if (Num == 1) R = Chip1;
|
||||
if (Num == 2) R = Chip2;
|
||||
if (Num == 3) R = Chip3;
|
||||
if (Num == 4) R = Chip4;
|
||||
|
||||
/* If the volume is 0, increase the counter */
|
||||
for (i = 0;i < 4;i++)
|
||||
{
|
||||
if (R->Volume[i] == 0)
|
||||
{
|
||||
/* note that I do count += length, NOT count = length + 1. You might think */
|
||||
/* it's the same since the volume is 0, but doing the latter could cause */
|
||||
/* interferencies when the program is rapidly modulating the volume. */
|
||||
if (R->Count[i] <= Length*STEP) R->Count[i] += Length*STEP;
|
||||
}
|
||||
}
|
||||
|
||||
while (Length > 0)
|
||||
{
|
||||
INT32 Vol[4];
|
||||
UINT32 Out;
|
||||
INT32 Left;
|
||||
|
||||
|
||||
/* vol[] keeps track of how long each square wave stays */
|
||||
/* in the 1 position during the sample period. */
|
||||
Vol[0] = Vol[1] = Vol[2] = Vol[3] = 0;
|
||||
|
||||
for (i = 0;i < 3;i++)
|
||||
{
|
||||
if (R->Output[i]) Vol[i] += R->Count[i];
|
||||
R->Count[i] -= STEP;
|
||||
/* Period[i] is the half period of the square wave. Here, in each */
|
||||
/* loop I add Period[i] twice, so that at the end of the loop the */
|
||||
/* square wave is in the same status (0 or 1) it was at the start. */
|
||||
/* vol[i] is also incremented by Period[i], since the wave has been 1 */
|
||||
/* exactly half of the time, regardless of the initial position. */
|
||||
/* If we exit the loop in the middle, Output[i] has to be inverted */
|
||||
/* and vol[i] incremented only if the exit status of the square */
|
||||
/* wave is 1. */
|
||||
while (R->Count[i] <= 0)
|
||||
{
|
||||
R->Count[i] += R->Period[i];
|
||||
if (R->Count[i] > 0)
|
||||
{
|
||||
R->Output[i] ^= 1;
|
||||
if (R->Output[i]) Vol[i] += R->Period[i];
|
||||
break;
|
||||
}
|
||||
R->Count[i] += R->Period[i];
|
||||
Vol[i] += R->Period[i];
|
||||
}
|
||||
if (R->Output[i]) Vol[i] -= R->Count[i];
|
||||
}
|
||||
|
||||
Left = STEP;
|
||||
do
|
||||
{
|
||||
INT32 NextEvent;
|
||||
|
||||
|
||||
if (R->Count[3] < Left) NextEvent = R->Count[3];
|
||||
else NextEvent = Left;
|
||||
|
||||
if (R->Output[3]) Vol[3] += R->Count[3];
|
||||
R->Count[3] -= NextEvent;
|
||||
if (R->Count[3] <= 0)
|
||||
{
|
||||
if (R->NoiseMode == 1) /* White Noise Mode */
|
||||
{
|
||||
if (((R->RNG & R->WhitenoiseTaps) != R->WhitenoiseTaps) && ((R->RNG & R->WhitenoiseTaps) != 0)) /* crappy xor! */
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
R->RNG |= R->FeedbackMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
}
|
||||
R->Output[3] = R->WhitenoiseInvert ? !(R->RNG & 1) : R->RNG & 1;
|
||||
}
|
||||
else /* Periodic noise mode */
|
||||
{
|
||||
if (R->RNG & 1)
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
R->RNG |= R->FeedbackMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
}
|
||||
R->Output[3] = R->RNG & 1;
|
||||
}
|
||||
R->Count[3] += R->Period[3];
|
||||
if (R->Output[3]) Vol[3] += R->Period[3];
|
||||
}
|
||||
if (R->Output[3]) Vol[3] -= R->Count[3];
|
||||
|
||||
Left -= NextEvent;
|
||||
} while (Left > 0);
|
||||
|
||||
Out = Vol[0] * R->Volume[0] + Vol[1] * R->Volume[1] +
|
||||
Vol[2] * R->Volume[2] + Vol[3] * R->Volume[3];
|
||||
|
||||
if (Out > MAX_OUTPUT * STEP) Out = MAX_OUTPUT * STEP;
|
||||
|
||||
pSoundBuf[0] = BURN_SND_CLIP(((INT32)((Out / STEP) * R->nVolume)));
|
||||
pSoundBuf++;
|
||||
Length--;
|
||||
}
|
||||
}
|
||||
|
||||
void SN76496Write(INT32 Num, INT32 Data)
|
||||
{
|
||||
#if defined FBA_DEBUG
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
void SN76496Update(INT32 Num, INT16* pSoundBuf, INT32 Length);
|
||||
void SN76496UpdateToBuffer(INT32 Num, INT16* pSoundBuf, INT32 Length); // output mono
|
||||
void SN76496Write(INT32 Num, INT32 Data);
|
||||
void SN76489Init(INT32 Num, INT32 Clock, INT32 SignalAdd);
|
||||
void SN76489AInit(INT32 Num, INT32 Clock, INT32 SignalAdd);
|
||||
|
|
Loading…
Reference in New Issue