home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / resid-fp / extfilt.h < prev    next >
C/C++ Source or Header  |  2009-01-03  |  4KB  |  121 lines

  1. //  ---------------------------------------------------------------------------
  2. //  This file is part of reSID, a MOS6581 SID emulator engine.
  3. //  Copyright (C) 2004  Dag Lem <resid@nimrod.no>
  4. //
  5. //  This program is free software; you can redistribute it and/or modify
  6. //  it under the terms of the GNU General Public License as published by
  7. //  the Free Software Foundation; either version 2 of the License, or
  8. //  (at your option) any later version.
  9. //
  10. //  This program is distributed in the hope that it will be useful,
  11. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //  GNU General Public License for more details.
  14. //
  15. //  You should have received a copy of the GNU General Public License
  16. //  along with this program; if not, write to the Free Software
  17. //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. //  ---------------------------------------------------------------------------
  19.  
  20. #ifndef __EXTFILT_FP_H__
  21. #define __EXTFILT_FP_H__
  22.  
  23. #include <math.h>
  24.  
  25. #include "siddefs-fp.h"
  26.  
  27. // ----------------------------------------------------------------------------
  28. // The audio output stage in a Commodore 64 consists of two STC networks,
  29. // a low-pass filter with 3-dB frequency 16kHz followed by a high-pass
  30. // filter with 3-dB frequency 16Hz (the latter provided an audio equipment
  31. // input impedance of 1kOhm).
  32. // The STC networks are connected with a BJT supposedly meant to act as
  33. // a unity gain buffer, which is not really how it works. A more elaborate
  34. // model would include the BJT, however DC circuit analysis yields BJT
  35. // base-emitter and emitter-base impedances sufficiently low to produce
  36. // additional low-pass and high-pass 3dB-frequencies in the order of hundreds
  37. // of kHz. This calls for a sampling frequency of several MHz, which is far
  38. // too high for practical use.
  39. // ----------------------------------------------------------------------------
  40. class ExternalFilterFP
  41. {
  42. public:
  43.   ExternalFilterFP();
  44.  
  45.   void enable_filter(bool enable);
  46.   void set_sampling_parameter(float pass_freq);
  47.   void set_chip_model(chip_model model);
  48.   void set_clock_frequency(float);
  49.  
  50.   RESID_INLINE void clock(float Vi);
  51.   void reset();
  52.  
  53.   // Audio output (20 bits).
  54.   RESID_INLINE float output();
  55.  
  56. private:
  57.   void _set_sampling_parameter();
  58.   void nuke_denormals();
  59.  
  60.   // Filter enabled.
  61.   bool enabled;
  62.  
  63.   // Maximum mixer DC offset.
  64.   float mixer_DC;
  65.  
  66.   // Relevant clocks
  67.   float clock_frequency, pass_frequency;
  68.  
  69.   // State of filters.
  70.   float Vlp; // lowpass
  71.   float Vhp; // highpass
  72.   float Vo;
  73.  
  74.   // Cutoff frequencies.
  75.   float w0lp;
  76.   float w0hp;
  77.  
  78. friend class SIDFP;
  79. };
  80.  
  81. // ----------------------------------------------------------------------------
  82. // SID clocking - 1 cycle.
  83. // ----------------------------------------------------------------------------
  84. RESID_INLINE
  85. void ExternalFilterFP::clock(float Vi)
  86. {
  87.   // This is handy for testing.
  88.   if (! enabled) {
  89.     // Remove maximum DC level since there is no filter to do it.
  90.     Vlp = Vhp = 0.f;
  91.     Vo = Vi - mixer_DC;
  92.     return;
  93.   }
  94.  
  95.   float dVlp = w0lp * (Vi - Vlp);
  96.   float dVhp = w0hp * (Vlp - Vhp);
  97.   Vo = Vlp - Vhp;
  98.   Vlp += dVlp;
  99.   Vhp += dVhp;
  100. }
  101.  
  102. // ----------------------------------------------------------------------------
  103. // Audio output (19.5 bits).
  104. // ----------------------------------------------------------------------------
  105. RESID_INLINE
  106. float ExternalFilterFP::output()
  107. {
  108.   return Vo;
  109. }
  110.  
  111. RESID_INLINE
  112. void ExternalFilterFP::nuke_denormals()
  113. {
  114.     if (Vhp > -1e-12f && Vhp < 1e-12f)
  115.         Vhp = 0;
  116.     if (Vlp > -1e-12f && Vlp < 1e-12f)
  117.         Vlp = 0;
  118. }
  119.  
  120. #endif // not __EXTFILT_FP_H__
  121.