diff options
author | Leandro Nini <drfiemost@users.noreply.github.com> | 2022-08-05 23:34:40 +0300 |
---|---|---|
committer | kcgen <kcgen@users.noreply.github.com> | 2022-08-06 05:08:25 +0300 |
commit | e691d34bd2446a7dfec1ffc73903a3431f6056b9 (patch) | |
tree | 857fc393c98d7ee3f2620ac7a290ef4d19f2cc3a | |
parent | 16a9de34ebeedefeb7424e844dfb0e829382ffae (diff) |
Sync reSIDfp with upstreamkc/sync-resid-1
-rw-r--r-- | src/libs/residfp/EnvelopeGenerator.h | 20 | ||||
-rw-r--r-- | src/libs/residfp/ExternalFilter.cpp | 4 | ||||
-rw-r--r-- | src/libs/residfp/Integrator6581.h | 9 | ||||
-rw-r--r-- | src/libs/residfp/SID.cpp | 4 | ||||
-rw-r--r-- | src/libs/residfp/Voice.h | 43 | ||||
-rw-r--r-- | src/libs/residfp/WaveformGenerator.h | 25 |
6 files changed, 54 insertions, 51 deletions
diff --git a/src/libs/residfp/EnvelopeGenerator.h b/src/libs/residfp/EnvelopeGenerator.h index bf1096812..08347c833 100644 --- a/src/libs/residfp/EnvelopeGenerator.h +++ b/src/libs/residfp/EnvelopeGenerator.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2020 Leandro Nini <drfiemost@users.sourceforge.net> + * Copyright 2011-2022 Leandro Nini <drfiemost@users.sourceforge.net> * Copyright 2018 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem <resid@nimrod.no> @@ -110,9 +110,6 @@ private: /// The ENV3 value, sampled at the first phase of the clock unsigned char env3 = 0; - /// The DAC LUT for analog output - float* dac = nullptr; //-V730_NOINIT this is initialized in the SID constructor - private: static const unsigned int adsrtable[16]; @@ -123,25 +120,14 @@ private: public: /** - * Set the analog DAC emulation: - * 8580 is perfectly linear while 6581 is nonlinear. - * Must be called before any operation. - * - * @param dac - */ - void setDAC(float* dac) { this->dac = dac; } - - /** * SID clocking. */ void clock(); /** - * Get the Envelope Generator output. - * DAC imperfections are emulated by using envelope_counter as an index - * into a DAC lookup table. readENV() uses envelope_counter directly. + * Get the Envelope Generator digital output. */ - float output() const { return dac[envelope_counter]; } + unsigned int output() const { return envelope_counter; } /** * Constructor. diff --git a/src/libs/residfp/ExternalFilter.cpp b/src/libs/residfp/ExternalFilter.cpp index 0e06fbf47..eac790b31 100644 --- a/src/libs/residfp/ExternalFilter.cpp +++ b/src/libs/residfp/ExternalFilter.cpp @@ -50,11 +50,11 @@ void ExternalFilter::setClockFrequency(double frequency) const double dt = 1. / frequency; // Low-pass: R = 10kOhm, C = 1000pF; w0l = dt/(dt+RC) = 1e-6/(1e-6+1e4*1e-9) = 0.091 - // Cutoff 1/2*PI*RC = 1/2*PI*1e4*1e-9 = 15915.5 Hz + // Cutoff 1/2*PI*RC = 1/2*PI*1e4*1e-9 = 15915.5 Hz w0lp_1_s7 = static_cast<int>((dt / (dt + getRC(10e3, 1000e-12))) * (1 << 7) + 0.5); // High-pass: R = 10kOhm, C = 10uF; w0h = dt/(dt+RC) = 1e-6/(1e-6+1e4*1e-5) = 0.00000999 - // Cutoff 1/2*PI*RC = 1/2*PI*1e4*1e-5 = 1.59155 Hz + // Cutoff 1/2*PI*RC = 1/2*PI*1e4*1e-5 = 1.59155 Hz w0hp_1_s17 = static_cast<int>((dt / (dt + getRC(10e3, 10e-6))) * (1 << 17) + 0.5); } diff --git a/src/libs/residfp/Integrator6581.h b/src/libs/residfp/Integrator6581.h index 92012761a..79585f16b 100644 --- a/src/libs/residfp/Integrator6581.h +++ b/src/libs/residfp/Integrator6581.h @@ -236,7 +236,7 @@ int Integrator6581::solve(int vi) const const int nVg = static_cast<int>(fmc->getVcr_nVg((nVddt_Vw_2 + (Vgdt_2 >> 1)) >> 16)); #ifdef SLOPE_FACTOR const double nVp = static_cast<double>(nVg - nVt) / n; // Pinch-off voltage - const int kVg = static_cast<int>(nVp) - nVmin; + const int kVg = static_cast<int>(nVp + 0.5) - nVmin; #else const int kVg = (nVg - nVt) - nVmin; #endif @@ -251,9 +251,10 @@ int Integrator6581::solve(int vi) const const unsigned int If = static_cast<unsigned int>(fmc->getVcr_n_Ids_term(kVgt_Vs)) << 15; const unsigned int Ir = static_cast<unsigned int>(fmc->getVcr_n_Ids_term(kVgt_Vd)) << 15; #ifdef SLOPE_FACTOR - const int n_I_vcr = (If - Ir) * n; + const double iVcr = static_cast<double>(If - Ir); + const int n_I_vcr = static_cast<int>((iVcr * n) + 0.5); #else - const int n_I_vcr = (If - Ir); + const int n_I_vcr = If - Ir; #endif #ifdef SLOPE_FACTOR @@ -261,7 +262,7 @@ int Integrator6581::solve(int vi) const const double gamma = 1.0; // body effect factor const double phi = 0.8; // bulk Fermi potential const double Vp = nVp / fmc->getN16(); - n = 1. + (gamma / (2 * sqrt(Vp + phi + 4 * fmc->getUt()))); + n = 1. + (gamma / (2. * sqrt(Vp + phi + 4. * fmc->getUt()))); assert((n > 1.2) && (n < 1.8)); #endif diff --git a/src/libs/residfp/SID.cpp b/src/libs/residfp/SID.cpp index c50b58f15..a996d2230 100644 --- a/src/libs/residfp/SID.cpp +++ b/src/libs/residfp/SID.cpp @@ -258,8 +258,8 @@ void SID::setChipModel(ChipModel model) // set voice tables for (int i = 0; i < 3; i++) { - voice[i]->envelope()->setDAC(envDAC); - voice[i]->wave()->setDAC(oscDAC); + voice[i]->setEnvDAC(envDAC); + voice[i]->setWavDAC(oscDAC); voice[i]->wave()->setModel(is6581); voice[i]->wave()->setWaveformModels(tables); } diff --git a/src/libs/residfp/Voice.h b/src/libs/residfp/Voice.h index cc0558dc6..9af4b67fc 100644 --- a/src/libs/residfp/Voice.h +++ b/src/libs/residfp/Voice.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2015 Leandro Nini <drfiemost@users.sourceforge.net> + * Copyright 2011-2022 Leandro Nini <drfiemost@users.sourceforge.net> * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem <resid@nimrod.no> * @@ -42,25 +42,37 @@ private: std::unique_ptr<EnvelopeGenerator> const envelopeGenerator; + /// The DAC LUT for analog waveform output + float* wavDAC = nullptr; //-V730_NOINIT this is initialized in the SID constructor + + /// The DAC LUT for analog envelope output + float* envDAC = nullptr; //-V730_NOINIT this is initialized in the SID constructor + public: /** * Amplitude modulated waveform output. * - * The waveform DAC generates a voltage between 5 and 12 V - * (4,76 - 9 V for the 8580) corresponding to oscillator state 0 .. 4095. + * The waveform DAC generates a voltage between virtual ground and Vdd + * (5-12 V for the 6581 and 4.75-9 V for the 8580) + * corresponding to oscillator state 0 .. 4095. * * The envelope DAC generates a voltage between waveform gen output and - * the 5V level, corresponding to envelope state 0 .. 255. + * the virtual ground level, corresponding to envelope state 0 .. 255. * * Ideal range [-2048*255, 2047*255]. * * @param ringModulator Ring-modulator for waveform - * @return waveformgenerator output + * @return the voice analog output */ RESID_INLINE int output(const WaveformGenerator* ringModulator) const { - return static_cast<int>(waveformGenerator->output(ringModulator) * envelopeGenerator->output()); + unsigned int const wav = waveformGenerator->output(ringModulator); + unsigned int const env = envelopeGenerator->output(); + + // DAC imperfections are emulated by using the digital output + // as an index into a DAC lookup table. + return static_cast<int>(wavDAC[wav] * envDAC[env]); } /** @@ -70,6 +82,25 @@ public: waveformGenerator(new WaveformGenerator()), envelopeGenerator(new EnvelopeGenerator()) {} + Voice(const Voice&) = delete; // prevent copy-construction + Voice &operator=(const Voice&) = delete; // prevent assignment + + /** + * Set the analog DAC emulation for waveform generator. + * Must be called before any operation. + * + * @param dac + */ + void setWavDAC(float* dac) { wavDAC = dac; } + + /** + * Set the analog DAC emulation for envelope. + * Must be called before any operation. + * + * @param dac + */ + void setEnvDAC(float* dac) { envDAC = dac; } + WaveformGenerator* wave() const { return waveformGenerator.get(); } EnvelopeGenerator* envelope() const { return envelopeGenerator.get(); } diff --git a/src/libs/residfp/WaveformGenerator.h b/src/libs/residfp/WaveformGenerator.h index ce23dc3c2..66dde8302 100644 --- a/src/libs/residfp/WaveformGenerator.h +++ b/src/libs/residfp/WaveformGenerator.h @@ -136,10 +136,6 @@ private: bool msb_rising = false; bool is6581 = false; - - /// The DAC LUT for analog output - float* dac = nullptr; - private: void clock_shift_register(unsigned int bit0); @@ -159,15 +155,6 @@ public: void setWaveformModels(matrix_t* models); /** - * Set the analog DAC emulation: - * 8580 is perfectly linear while 6581 is nonlinear. - * Must be called before any operation. - * - * @param dac - */ - void setDAC(float* dac) { this->dac = dac; } - - /** * Set the chip model. * Must be called before any operation. * @@ -258,12 +245,12 @@ public: void reset(); /** - * 12-bit waveform output as an analogue float value. + * 12-bit waveform output. * * @param ringModulator The oscillator ring-modulating current one. - * @return output the waveform generator output + * @return the waveform generator digital output */ - float output(const WaveformGenerator* ringModulator); + unsigned int output(const WaveformGenerator* ringModulator); /** * Read OSC3 value. @@ -342,7 +329,7 @@ void WaveformGenerator::clock() } RESID_INLINE -float WaveformGenerator::output(const WaveformGenerator* ringModulator) +unsigned int WaveformGenerator::output(const WaveformGenerator* ringModulator) { // Set output value. if (likely(waveform != 0)) @@ -396,9 +383,7 @@ float WaveformGenerator::output(const WaveformGenerator* ringModulator) // Push next pulse level into pulse level pipeline. pulse_output = ((accumulator >> 12) >= pw) ? 0xfff : 0x000; - // DAC imperfections are emulated by using waveform_output as an index - // into a DAC lookup table. readOSC() uses waveform_output directly. - return dac[waveform_output]; + return waveform_output; } } // namespace reSIDfp |