00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00056 reg8 read(reg8 offset);
00057 void write(reg8 offset, reg8 value);
00058
00059
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
00094 void input(short sample);
00095
00096
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
00120 cycle_count write_pipeline;
00121 reg8 write_address;
00122
00123 double clock_frequency;
00124
00125 enum {
00126
00127
00128
00129
00130
00131
00132
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
00142 FIXP_SHIFT = 16,
00143 FIXP_MASK = 0xffff
00144 };
00145
00146
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
00156 short* sample;
00157
00158
00159 short* fir;
00160 };
00161
00162
00163
00164
00165
00166
00167
00168
00169 #if RESID_INLINING || defined(RESID_SID_CC)
00170
00171
00172
00173
00174 RESID_INLINE
00175 short SID::output()
00176 {
00177 return extfilt.output();
00178 }
00179
00180
00181
00182
00183
00184 RESID_INLINE
00185 void SID::clock()
00186 {
00187 int i;
00188
00189
00190 for (i = 0; i < 3; i++) {
00191 voice[i].envelope.clock();
00192 }
00193
00194
00195 for (i = 0; i < 3; i++) {
00196 voice[i].wave.clock();
00197 }
00198
00199
00200 for (i = 0; i < 3; i++) {
00201 voice[i].wave.synchronize();
00202 }
00203
00204
00205 for (i = 0; i < 3; i++) {
00206 voice[i].wave.set_waveform_output();
00207 }
00208
00209
00210 filter.clock(voice[0].output(), voice[1].output(), voice[2].output());
00211
00212
00213 extfilt.clock(filter.output());
00214
00215
00216 if (unlikely(write_pipeline)) {
00217 write();
00218 }
00219
00220
00221 if (unlikely(!--bus_value_ttl)) {
00222 bus_value = 0;
00223 }
00224 }
00225
00226 #endif // RESID_INLINING || defined(RESID_SID_CC)
00227
00228 }
00229
00230 #endif // not RESID_SID_H