diff --git a/src/Dac.cpp b/src/Dac.cpp index 017e8df..c87ee69 100644 --- a/src/Dac.cpp +++ b/src/Dac.cpp @@ -69,7 +69,7 @@ double Dac::getOutput(unsigned int input, bool saturate) const return dacValue; } -void Dac::kinkedDac(ChipModel chipModel) +void Dac::kinkedDac(ChipModel chipModel, double leakLevel) { constexpr double R_INFINITY = 1e6; @@ -79,7 +79,7 @@ void Dac::kinkedDac(ChipModel chipModel) // 6581 DACs are not terminated by a 2R resistor const bool term = chipModel == CSG8580; - leakage = chipModel == MOS6581 ? MOSFET_LEAKAGE_6581 : MOSFET_LEAKAGE_8580; + leakage = leakLevel * (chipModel == MOS6581 ? MOSFET_LEAKAGE_6581 : MOSFET_LEAKAGE_8580); double Vsum = 0.; diff --git a/src/Dac.h b/src/Dac.h index 206ade0..4770d1b 100644 --- a/src/Dac.h +++ b/src/Dac.h @@ -108,8 +108,9 @@ class Dac * Build DAC model for specific chip. * * @param chipModel 6581 or 8580 + * @param leakLevel the level of the transistor leakage */ - void kinkedDac(ChipModel chipModel); + void kinkedDac(ChipModel chipModel, double leakLevel=1.0); /** * Get the Vo output for a given combination of input bits. diff --git a/src/SID.cpp b/src/SID.cpp index 6f63903..04ec837 100644 --- a/src/SID.cpp +++ b/src/SID.cpp @@ -24,6 +24,7 @@ #include "SID.h" +#include #include #include "array.h" @@ -142,6 +143,7 @@ SID::SID() : filter8580(new Filter8580()), resampler(nullptr), cws(AVERAGE), + dacLeakage(1.0), p(new Params) { voice[0].setOtherVoices(voice[2], voice[1]); @@ -252,7 +254,7 @@ void SID::setChipModel(ChipModel new_model) // calculate envelope DAC table { Dac dacBuilder(ENV_DAC_BITS); - dacBuilder.kinkedDac(model); + dacBuilder.kinkedDac(model, dacLeakage); for (unsigned int i = 0; i < (1 << ENV_DAC_BITS); i++) { @@ -265,7 +267,7 @@ void SID::setChipModel(ChipModel new_model) { Dac dacBuilder(OSC_DAC_BITS); - dacBuilder.kinkedDac(model); + dacBuilder.kinkedDac(model, dacLeakage); //const double offset = dacBuilder.getOutput(is6581 ? OFFSET_6581 : OFFSET_8580); const double offset = dacBuilder.getOutput(is6581 ? OFFSET_6581 : 0x7ff, is6581); @@ -614,4 +616,15 @@ void SID::setPaddle(uint8_t x, uint8_t y) paddleY = y; } + +void SID::setDacLeakage(double level) +{ +#ifdef HAVE_CXX17 + dacLeakage = std::clamp(level, 0.0, 1.0); +#else + dacLeakage = std::max(std::min(level, 1.0), 0.0); +#endif + setChipModel(model); +} + } // namespace reSIDfp diff --git a/src/SID.h b/src/SID.h index d25a87f..b939405 100644 --- a/src/SID.h +++ b/src/SID.h @@ -104,6 +104,9 @@ class SID /// Currently selected combined waveforms strength. CombinedWaveforms cws; + // Dac leakage + double dacLeakage; + /// Last written value uint8_t busValue; @@ -358,6 +361,11 @@ class SID * Set paddle coordinates. */ void setPaddle(uint8_t x, uint8_t y); + + /* + * Set the DAC leakage level. + */ + void setDacLeakage(double level); }; } // namespace reSIDfp diff --git a/src/State.cpp b/src/State.cpp index 88669e7..27c843e 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -84,6 +84,7 @@ int State::saveState(SID &s, char* buffer, int size) state.env3[i] = envelope->env3; } + state.dacLeakage = s.dacLeakage; state.bus_value = s.busValue; state.bus_value_ttl = s.busValueTtl; state.nextVoiceSync = s.nextVoiceSync; @@ -194,6 +195,7 @@ void State::restoreState(SID &s, char* buffer, int size) State state; std::memcpy(&state, buffer, cnt); + s.dacLeakage = state.dacLeakage; s.busValue = state.bus_value; s.busValueTtl = state.bus_value_ttl; s.nextVoiceSync = state.nextVoiceSync; diff --git a/src/State.h b/src/State.h index 0d5bf1e..4593fe4 100644 --- a/src/State.h +++ b/src/State.h @@ -65,6 +65,7 @@ struct State unsigned int nextVoiceSync; ChipModel model; CombinedWaveforms cws; + double dacLeakage; uint8_t bus_value; uint8_t paddle_x; uint8_t paddle_y; diff --git a/src/residfp/residfp.cpp b/src/residfp/residfp.cpp index 266e678..e82449c 100644 --- a/src/residfp/residfp.cpp +++ b/src/residfp/residfp.cpp @@ -174,3 +174,8 @@ void residfp::restoreState(char* buffer, int size) { State::restoreState(sid, buffer, size); } + +void residfp::setDacLeakage(double level) +{ + sid.setDacLeakage(level); +} diff --git a/src/residfp/residfp.h b/src/residfp/residfp.h index 7d7dce4..2bb23ce 100644 --- a/src/residfp/residfp.h +++ b/src/residfp/residfp.h @@ -280,6 +280,16 @@ class RESIDFP_EXTERN residfp * @since 1.1 */ void restoreState(char* buffer, int size); + + /** + * Set the DAC leakage level. + * Affects the envelope and waveforms. + * + * @param level the leakage level, between 0 (no leakage) and 1 + * + * @since 1.2 + */ + void setDacLeakage(double level); }; }