libsidplayfp
1.0.3
|
00001 00003 // --------------------------------------------------------------------------- 00004 // This file is part of reSID, a MOS6581 SID emulator engine. 00005 // Copyright (C) 2010 Dag Lem <resid@nimrod.no> 00006 // 00007 // This program is free software; you can redistribute it and/or modify 00008 // it under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation; either version 2 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // This program is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with this program; if not, write to the Free Software 00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 // --------------------------------------------------------------------------- 00021 00022 #ifndef RESID_SID_H 00023 #define RESID_SID_H 00024 00025 #include "resid-config.h" 00026 #include "voice.h" 00027 #include "filter.h" 00028 #include "extfilt.h" 00029 #include "pot.h" 00030 00031 namespace reSID 00032 { 00033 00034 class SID 00035 { 00036 public: 00037 SID(); 00038 ~SID(); 00039 00040 void set_chip_model(chip_model model); 00041 void set_voice_mask(reg4 mask); 00042 void enable_filter(bool enable); 00043 void adjust_filter_bias(double dac_bias); 00044 void enable_external_filter(bool enable); 00045 bool set_sampling_parameters(double clock_freq, sampling_method method, 00046 double sample_freq, double pass_freq = -1, 00047 double filter_scale = 0.97); 00048 void adjust_sampling_frequency(double sample_freq); 00049 00050 void clock(); 00051 void clock(cycle_count delta_t); 00052 int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1); 00053 void reset(); 00054 00055 // Read/write registers. 00056 reg8 read(reg8 offset); 00057 void write(reg8 offset, reg8 value); 00058 00059 // Read/write state. 00060 class State 00061 { 00062 public: 00063 State(); 00064 00065 char sid_register[0x20]; 00066 00067 reg8 bus_value; 00068 cycle_count bus_value_ttl; 00069 cycle_count write_pipeline; 00070 reg8 write_address; 00071 reg4 voice_mask; 00072 00073 reg24 accumulator[3]; 00074 reg24 shift_register[3]; 00075 cycle_count shift_register_reset[3]; 00076 cycle_count shift_pipeline[3]; 00077 reg16 pulse_output[3]; 00078 cycle_count floating_output_ttl[3]; 00079 00080 reg16 rate_counter[3]; 00081 reg16 rate_counter_period[3]; 00082 reg16 exponential_counter[3]; 00083 reg16 exponential_counter_period[3]; 00084 reg8 envelope_counter[3]; 00085 EnvelopeGenerator::State envelope_state[3]; 00086 bool hold_zero[3]; 00087 cycle_count envelope_pipeline[3]; 00088 }; 00089 00090 State read_state(); 00091 void write_state(const State& state); 00092 00093 // 16-bit input (EXT IN). 00094 void input(short sample); 00095 00096 // 16-bit output (AUDIO OUT). 00097 short output(); 00098 00099 protected: 00100 static double I0(double x); 00101 int clock_fast(cycle_count& delta_t, short* buf, int n, int interleave); 00102 int clock_interpolate(cycle_count& delta_t, short* buf, int n, 00103 int interleave); 00104 int clock_resample(cycle_count& delta_t, short* buf, int n, int interleave); 00105 int clock_resample_fastmem(cycle_count& delta_t, short* buf, int n, 00106 int interleave); 00107 void write(); 00108 00109 chip_model sid_model; 00110 Voice voice[3]; 00111 Filter filter; 00112 ExternalFilter extfilt; 00113 Potentiometer potx; 00114 Potentiometer poty; 00115 00116 reg8 bus_value; 00117 cycle_count bus_value_ttl; 00118 00119 // Pipeline for writes on the MOS8580. 00120 cycle_count write_pipeline; 00121 reg8 write_address; 00122 00123 double clock_frequency; 00124 00125 enum { 00126 // Resampling constants. 00127 // The error in interpolated lookup is bounded by 1.234/L^2, 00128 // while the error in non-interpolated lookup is bounded by 00129 // 0.7854/L + 0.4113/L^2, see 00130 // http://www-ccrma.stanford.edu/~jos/resample/Choice_Table_Size.html 00131 // For a resolution of 16 bits this yields L >= 285 and L >= 51473, 00132 // respectively. 00133 FIR_N = 125, 00134 FIR_RES = 285, 00135 FIR_RES_FASTMEM = 51473, 00136 FIR_SHIFT = 15, 00137 00138 RINGSIZE = 1 << 14, 00139 RINGMASK = RINGSIZE - 1, 00140 00141 // Fixed point constants (16.16 bits). 00142 FIXP_SHIFT = 16, 00143 FIXP_MASK = 0xffff 00144 }; 00145 00146 // Sampling variables. 00147 sampling_method sampling; 00148 cycle_count cycles_per_sample; 00149 cycle_count sample_offset; 00150 int sample_index; 00151 short sample_prev, sample_now; 00152 int fir_N; 00153 int fir_RES; 00154 00155 // Ring buffer with overflow for contiguous storage of RINGSIZE samples. 00156 short* sample; 00157 00158 // FIR_RES filter tables (FIR_N*FIR_RES). 00159 short* fir; 00160 }; 00161 00162 00163 // ---------------------------------------------------------------------------- 00164 // Inline functions. 00165 // The following functions are defined inline because they are called every 00166 // time a sample is calculated. 00167 // ---------------------------------------------------------------------------- 00168 00169 #if RESID_INLINING || defined(RESID_SID_CC) 00170 00171 // ---------------------------------------------------------------------------- 00172 // Read 16-bit sample from audio output. 00173 // ---------------------------------------------------------------------------- 00174 RESID_INLINE 00175 short SID::output() 00176 { 00177 return extfilt.output(); 00178 } 00179 00180 00181 // ---------------------------------------------------------------------------- 00182 // SID clocking - 1 cycle. 00183 // ---------------------------------------------------------------------------- 00184 RESID_INLINE 00185 void SID::clock() 00186 { 00187 int i; 00188 00189 // Clock amplitude modulators. 00190 for (i = 0; i < 3; i++) { 00191 voice[i].envelope.clock(); 00192 } 00193 00194 // Clock oscillators. 00195 for (i = 0; i < 3; i++) { 00196 voice[i].wave.clock(); 00197 } 00198 00199 // Synchronize oscillators. 00200 for (i = 0; i < 3; i++) { 00201 voice[i].wave.synchronize(); 00202 } 00203 00204 // Calculate waveform output. 00205 for (i = 0; i < 3; i++) { 00206 voice[i].wave.set_waveform_output(); 00207 } 00208 00209 // Clock filter. 00210 filter.clock(voice[0].output(), voice[1].output(), voice[2].output()); 00211 00212 // Clock external filter. 00213 extfilt.clock(filter.output()); 00214 00215 // Pipelined writes on the MOS8580. 00216 if (unlikely(write_pipeline)) { 00217 write(); 00218 } 00219 00220 // Age bus value. 00221 if (unlikely(!--bus_value_ttl)) { 00222 bus_value = 0; 00223 } 00224 } 00225 00226 #endif // RESID_INLINING || defined(RESID_SID_CC) 00227 00228 } // namespace reSID 00229 00230 #endif // not RESID_SID_H