home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.73.zip / src / resid-fp / filterfp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2014-07-23  |  4.7 KB  |  169 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. //  Filter distortion code written by Antti S. Lankila 2007 - 2009.
  20.  
  21. #include "filterfp.h"
  22. #include "sidfp.h"
  23.  
  24. // ----------------------------------------------------------------------------
  25. // Constructor.
  26. // ----------------------------------------------------------------------------
  27. FilterFP::FilterFP()
  28. {
  29.   model = (chip_model) 0; // neither 6581/8580; init time only
  30.   enable_filter(true);
  31.   /* approximate; sid.cc calls us when set_sampling_parameters() occurs. */
  32.   set_clock_frequency(1e6f);
  33.   /* these parameters are a work-in-progress. */
  34.   set_distortion_properties(0.5f, 3.3e6f, 3.0e-4f);
  35.   /* sound similar to alankila6581r4ar3789 */
  36.   set_type3_properties(1299501.5675945764f, 284015710.29875594f, 1.0065089724604026f, 18741.324073610594f);
  37.   /* sound similar to trurl8580r5_3691 */
  38.   set_type4_properties(6.55f, 20.f);
  39.   reset();
  40.   set_chip_model(MOS6581);
  41. }
  42.  
  43.  
  44. // ----------------------------------------------------------------------------
  45. // Enable filter.
  46. // ----------------------------------------------------------------------------
  47. void FilterFP::enable_filter(bool enable)
  48. {
  49.   enabled = enable;
  50.   if (! enabled)
  51.     filt = 0; // XXX should also restore this...
  52. }
  53.  
  54. // ----------------------------------------------------------------------------
  55. // Set chip model.
  56. // ----------------------------------------------------------------------------
  57. void FilterFP::set_chip_model(chip_model model)
  58. {
  59.     this->model = model;
  60.     set_Q();
  61.     set_w0();
  62. }
  63.  
  64. void FilterFP::set_nonlinearity(float nl)
  65. {
  66.     nonlinearity = nl;
  67.     set_w0();
  68. }
  69.  
  70. /* dist_CT eliminates 1/x at hot spot */
  71. void FilterFP::set_clock_frequency(float clock) {
  72.     clock_frequency = clock;
  73.     distortion_CT = 1.f / (sidcaps_6581 * clock_frequency);
  74.     set_w0();
  75. }
  76.  
  77. void FilterFP::set_distortion_properties(float a, float nl, float il)
  78. {
  79.     attenuation = a;
  80.     distortion_nonlinearity = nl;
  81.     intermixing_leaks = il;
  82.     set_w0();
  83. }
  84.  
  85. void FilterFP::set_type4_properties(float k, float b)
  86. {
  87.     type4_k = k;
  88.     type4_b = b;
  89.     set_w0();
  90. }
  91.  
  92. void FilterFP::set_type3_properties(float br, float o, float s, float mfr)
  93. {
  94.     type3_baseresistance = br;
  95.     type3_offset = o;
  96.     type3_steepness = -logf(s) / FC_TO_OSC; /* s^x to e^(x*ln(s)), 1/e^x == e^-x. */
  97.     type3_minimumfetresistance = mfr;
  98.     set_w0();
  99. }
  100.  
  101. // ----------------------------------------------------------------------------
  102. // SID reset.
  103. // ----------------------------------------------------------------------------
  104. void FilterFP::reset()
  105. {
  106.   fc = 0;
  107.   res = filt = voice3off = hp_bp_lp = 0; 
  108.   vol = 0;
  109.   volf = Vhp = Vbp = Vlp = 0;
  110.   type3_fc_kink_exp = 0;
  111.   type4_w0_cache = 0;
  112.   set_w0();
  113.   set_Q();
  114. }
  115.  
  116. // ----------------------------------------------------------------------------
  117. // Register functions.
  118. // ----------------------------------------------------------------------------
  119. void FilterFP::writeFC_LO(reg8 fc_lo)
  120. {
  121.   fc = (fc & 0x7f8) | (fc_lo & 0x007);
  122.   set_w0();
  123. }
  124.  
  125. void FilterFP::writeFC_HI(reg8 fc_hi)
  126. {
  127.   fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007);
  128.   set_w0();
  129. }
  130.  
  131. void FilterFP::writeRES_FILT(reg8 res_filt)
  132. {
  133.   res = (res_filt >> 4) & 0x0f;
  134.   set_Q();
  135.   filt = enabled ? res_filt & 0x0f : 0;
  136. }
  137.  
  138. void FilterFP::writeMODE_VOL(reg8 mode_vol)
  139. {
  140.   voice3off = mode_vol & 0x80;
  141.  
  142.   hp_bp_lp = mode_vol >> 4;
  143.  
  144.   vol = mode_vol & 0x0f;
  145.   volf = static_cast<float>(vol) / 15.f;
  146. }
  147.  
  148. // Set filter cutoff frequency.
  149. void FilterFP::set_w0()
  150. {
  151.   if (model == MOS6581) {
  152.     float type3_fc_kink = SIDFP::kinked_dac(fc, nonlinearity, 11);
  153.     type3_fc_kink_exp = type3_offset * expf(type3_fc_kink * type3_steepness * FC_TO_OSC);
  154.   }
  155.   if (model == MOS8580) {
  156.     type4_w0_cache = type4_w0();
  157.   }
  158. }
  159.  
  160. // Set filter resonance.
  161. void FilterFP::set_Q()
  162. {
  163.   if (model == MOS6581) {
  164.     _1_div_Q = 1.f / (0.5f + res / 20.f);
  165.   } else {
  166.     _1_div_Q = 1.f / (0.707f + res / 15.f);
  167.   }
  168. }
  169.