diff options
Diffstat (limited to 'src/devices/sound/sid.cpp')
-rw-r--r-- | src/devices/sound/sid.cpp | 168 |
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]; |