summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/sid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/sid.cpp')
-rw-r--r--src/devices/sound/sid.cpp168
1 files changed, 73 insertions, 95 deletions
diff --git a/src/devices/sound/sid.cpp b/src/devices/sound/sid.cpp
index 1535c56a69e..de56c65106e 100644
--- a/src/devices/sound/sid.cpp
+++ b/src/devices/sound/sid.cpp
@@ -32,7 +32,7 @@ float filterResTable[16];
const int mix16monoMiddleIndex = 256*maxLogicalVoices/2;
uint16_t mix16mono[256*maxLogicalVoices];
-uint16_t zero16bit=0; /* either signed or unsigned */
+uint16_t zero16bit = 0; /* either signed or unsigned */
//uint32_t splitBufferLen;
void MixerInit(int threeVoiceAmplify)
@@ -49,7 +49,7 @@ void MixerInit(int threeVoiceAmplify)
/* Mixing formulas are optimized by sample input value. */
si = (-128*maxLogicalVoices) * 256;
- for (ui = 0; ui < sizeof(mix16mono)/sizeof(uint16_t); ui++ )
+ for (ui = 0; ui < sizeof(mix16mono)/sizeof(uint16_t); ui++)
{
mix16mono[ui] = (uint16_t)(si/ampDiv) + zero16bit;
si+=256;
@@ -62,43 +62,25 @@ void MixerInit(int threeVoiceAmplify)
inline void SID6581_t::syncEm()
{
- bool const sync1(optr1.modulator->cycleLenCount <= 0);
- bool const sync2(optr2.modulator->cycleLenCount <= 0);
- bool const sync3(optr3.modulator->cycleLenCount <= 0);
-
- optr1.cycleLenCount--;
- optr2.cycleLenCount--;
- optr3.cycleLenCount--;
-
- if (optr1.sync && sync1)
- {
- optr1.cycleLenCount = 0;
- optr1.outProc = &sidOperator::wave_calc_normal;
-#if defined(DIRECT_FIXPOINT)
- optr1.waveStep.l = 0;
-#else
- optr1.waveStep = optr1.waveStepPnt = 0;
-#endif
- }
- if (optr2.sync && sync2)
+ bool sync[3];
+ for (int v = 0; v < max_voices; v++)
{
- optr2.cycleLenCount = 0;
- optr2.outProc = &sidOperator::wave_calc_normal;
-#if defined(DIRECT_FIXPOINT)
- optr2.waveStep.l = 0;
-#else
- optr2.waveStep = optr2.waveStepPnt = 0;
-#endif
+ sync[v] = optr[v].modulator->cycleLenCount <= 0;
+ optr[v].cycleLenCount--;
}
- if (optr3.sync && sync3)
+
+ for (int v = 0; v < max_voices; v++)
{
- optr3.cycleLenCount = 0;
- optr3.outProc = &sidOperator::wave_calc_normal;
+ if (optr[v].sync && sync[v])
+ {
+ optr[v].cycleLenCount = 0;
+ optr[v].outProc = &sidOperator::wave_calc_normal;
#if defined(DIRECT_FIXPOINT)
- optr3.waveStep.l = 0;
+ optr[v].waveStep.l = 0;
#else
- optr3.waveStep = optr3.waveStepPnt = 0;
+ optr[v].waveStep = optr[v].waveStepPnt = 0;
#endif
+ }
}
}
@@ -107,12 +89,12 @@ void SID6581_t::fill_buffer(stream_sample_t *buffer, uint32_t bufferLen)
{
//void* SID6581_t::fill16bitMono(void* buffer, uint32_t numberOfSamples)
- for ( ; bufferLen > 0; bufferLen-- )
+ for (; bufferLen > 0; bufferLen--)
{
*buffer++ = (int16_t) mix16mono[unsigned(mix16monoMiddleIndex
- +(*optr1.outProc)(&optr1)
- +(*optr2.outProc)(&optr2)
- +(optr3.outProc(&optr3)&optr3_outputmask)
+ +(*optr[0].outProc)(&optr[0])
+ +(*optr[1].outProc)(&optr[1])
+ +(optr[2].outProc(&optr[2])&optr3_outputmask)
/* hack for digi sounds
does n't seam to come from a tone operator
ghostbusters and goldrunner everything except volume zeroed */
@@ -130,12 +112,11 @@ void SID6581_t::fill_buffer(stream_sample_t *buffer, uint32_t bufferLen)
bool SID6581_t::reset()
{
- optr1.clear();
- enveEmuResetOperator( &optr1 );
- optr2.clear();
- enveEmuResetOperator( &optr2 );
- optr3.clear();
- enveEmuResetOperator( &optr3 );
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].clear();
+ enveEmuResetOperator(&optr[v]);
+ }
optr3_outputmask = ~0; /* on */
//sampleEmuReset();
@@ -144,17 +125,24 @@ bool SID6581_t::reset()
filter.Value = 0;
filter.Dy = filter.ResDy = 0;
- optr1.set();
- optr2.set();
- optr3.set();
-
- optr1.set2();
- optr2.set2();
- optr3.set2();
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].set();
+ optr[v].set2();
+ }
return true;
}
+void SID6581_t::postload()
+{
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].set();
+ optr[v].set2();
+ }
+}
+
static void filterTableInit(running_machine &machine)
{
@@ -177,13 +165,13 @@ static void filterTableInit(running_machine &machine)
bandPassParam = std::make_unique<float[]>(0x800);
uk = 0;
- for ( rk = 0; rk < 0x800; rk++ )
+ for (rk = 0; rk < 0x800; rk++)
{
filterTable[uk] = (((expf(rk/0x800*logf(400.0f))/60.0f)+0.05f)
*filterRefFreq) / sample_rate;
- if ( filterTable[uk] < yMin )
+ if (filterTable[uk] < yMin)
filterTable[uk] = yMin;
- if ( filterTable[uk] > yMax )
+ if (filterTable[uk] > yMax)
filterTable[uk] = yMax;
uk++;
}
@@ -195,7 +183,7 @@ static void filterTableInit(running_machine &machine)
yTmp = yMin;
uk = 0;
/* Some C++ compilers still have non-local scope! */
- for ( rk2 = 0; rk2 < 0x800; rk2++ )
+ for (rk2 = 0; rk2 < 0x800; rk2++)
{
bandPassParam[uk] = (yTmp*filterRefFreq) / sample_rate;
yTmp += yAdd;
@@ -206,10 +194,10 @@ static void filterTableInit(running_machine &machine)
resDyMax = 1.0f;
resDyMin = 2.0f;
resDy = resDyMin;
- for ( uk = 0; uk < 16; uk++ )
+ for (uk = 0; uk < 16; uk++)
{
filterResTable[uk] = resDy;
- resDy -= (( resDyMin - resDyMax ) / 15 );
+ resDy -= ((resDyMin - resDyMax) / 15);
}
filterResTable[0] = resDyMin;
filterResTable[15] = resDyMax;
@@ -217,22 +205,15 @@ static void filterTableInit(running_machine &machine)
void SID6581_t::init()
{
- optr1.sid = this;
- optr2.sid = this;
- optr3.sid = this;
-
- optr1.modulator = &optr3;
- optr3.carrier = &optr1;
- optr1.filtVoiceMask = 1;
-
- optr2.modulator = &optr1;
- optr1.carrier = &optr2;
- optr2.filtVoiceMask = 2;
-
- optr3.modulator = &optr2;
- optr2.carrier = &optr3;
- optr3.filtVoiceMask = 4;
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].sid = this;
+ int mod_voi = (v - 1) % max_voices;
+ optr[v].modulator = &optr[mod_voi];
+ optr[mod_voi].carrier = &optr[v];
+ optr[v].filtVoiceMask = 1 << v;
+ }
PCMsid = uint32_t(PCMfreq * (16777216.0 / clock));
PCMsidNoise = uint32_t((clock * 256.0) / PCMfreq);
@@ -275,7 +256,7 @@ void SID6581_t::port_w(int offset, int data)
masterVolume = reg[0x18] & 15;
masterVolumeAmplIndex = masterVolume << 8;
- if ((reg[0x18] & 0x80) && !(reg[0x17] & optr3.filtVoiceMask))
+ if ((reg[0x18] & 0x80) && !(reg[0x17] & optr[2].filtVoiceMask))
optr3_outputmask = 0; /* off */
else
optr3_outputmask = ~0; /* on */
@@ -284,11 +265,10 @@ void SID6581_t::port_w(int offset, int data)
if (filter.Type != filter.CurType)
{
filter.CurType = filter.Type;
- optr1.filtLow = optr1.filtRef = 0;
- optr2.filtLow = optr2.filtRef = 0;
- optr3.filtLow = optr3.filtRef = 0;
+ for (int v = 0; v < max_voices; v++)
+ optr[v].filtLow = optr[v].filtRef = 0;
}
- if (filter.Enabled )
+ if (filter.Enabled)
{
filter.Value = 0x7ff & ((reg[0x15] & 7) | (uint16_t(reg[0x16]) << 3));
if (filter.Type == 0x20)
@@ -300,14 +280,13 @@ void SID6581_t::port_w(int offset, int data)
filter.ResDy = 1.0f;
}
- optr1.set();
- optr3.set();
- optr2.set();
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].set();
- // relies on sidEmuSet also for other channels!
- optr1.set2();
- optr2.set2();
- optr3.set2();
+ // relies on sidEmuSet also for other channels!
+ optr[v].set2();
+ }
break;
default:
@@ -315,20 +294,19 @@ void SID6581_t::port_w(int offset, int data)
reg[offset] = data;
if (offset < 7)
- optr1.reg[offset] = data;
+ optr[0].reg[offset] = data;
else if (offset < 14)
- optr2.reg[offset - 7] = data;
+ optr[1].reg[offset - 7] = data;
else if (offset < 21)
- optr3.reg[offset - 14] = data;
+ optr[2].reg[offset - 14] = data;
- optr1.set();
- optr3.set();
- optr2.set();
+ for (int v = 0; v < max_voices; v++)
+ {
+ optr[v].set();
- // relies on sidEmuSet also for other channels!
- optr1.set2();
- optr2.set2();
- optr3.set2();
+ // relies on sidEmuSet also for other channels!
+ optr[v].set2();
+ }
break;
}
}
@@ -348,11 +326,11 @@ int SID6581_t::port_r(running_machine &machine, int offset)
break;
case 0x1b:
mixer_channel->update();
- data = optr3.output;
+ data = optr[2].output;
break;
case 0x1c:
mixer_channel->update();
- data = optr3.enveVol;
+ data = optr[2].enveVol;
break;
default:
data = reg[offset];