libsidplayfp  1.8.7
sid.h
Go to the documentation of this file.
1 
3 // ---------------------------------------------------------------------------
4 // This file is part of reSID, a MOS6581 SID emulator engine.
5 // Copyright (C) 2010 Dag Lem <resid@nimrod.no>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // ---------------------------------------------------------------------------
21 
22 #ifndef RESID_SID_H
23 #define RESID_SID_H
24 
25 #include "resid-config.h"
26 #include "voice.h"
27 #include "filter.h"
28 #include "extfilt.h"
29 #include "pot.h"
30 
31 namespace reSID
32 {
33 
34 class SID
35 {
36 public:
37  SID();
38  ~SID();
39 
40  void set_chip_model(chip_model model);
41  void set_voice_mask(reg4 mask);
42  void enable_filter(bool enable);
43  void adjust_filter_bias(double dac_bias);
44  void enable_external_filter(bool enable);
45  bool set_sampling_parameters(double clock_freq, sampling_method method,
46  double sample_freq, double pass_freq = -1,
47  double filter_scale = 0.97);
48  void adjust_sampling_frequency(double sample_freq);
49 
50  void clock();
51  void clock(cycle_count delta_t);
52  int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1);
53  void reset();
54 
55  // Read/write registers.
56  reg8 read(reg8 offset);
57  void write(reg8 offset, reg8 value);
58 
59  // Read/write state.
60  class State
61  {
62  public:
63  State();
64 
65  char sid_register[0x20];
66 
67  reg8 bus_value;
68  cycle_count bus_value_ttl;
69  cycle_count write_pipeline;
70  reg8 write_address;
71  reg4 voice_mask;
72 
73  reg24 accumulator[3];
74  reg24 shift_register[3];
75  cycle_count shift_register_reset[3];
76  cycle_count shift_pipeline[3];
77  reg16 pulse_output[3];
78  cycle_count floating_output_ttl[3];
79 
80  reg16 rate_counter[3];
81  reg16 rate_counter_period[3];
82  reg16 exponential_counter[3];
83  reg16 exponential_counter_period[3];
84  reg8 envelope_counter[3];
85  EnvelopeGenerator::State envelope_state[3];
86  bool hold_zero[3];
87  cycle_count envelope_pipeline[3];
88  };
89 
90  State read_state();
91  void write_state(const State& state);
92 
93  // 16-bit input (EXT IN).
94  void input(short sample);
95 
96  // 16-bit output (AUDIO OUT).
97  short output();
98 
99  protected:
100  static double I0(double x);
101  int clock_fast(cycle_count& delta_t, short* buf, int n, int interleave);
102  int clock_interpolate(cycle_count& delta_t, short* buf, int n,
103  int interleave);
104  int clock_resample(cycle_count& delta_t, short* buf, int n, int interleave);
105  int clock_resample_fastmem(cycle_count& delta_t, short* buf, int n,
106  int interleave);
107  void write();
108 
109  chip_model sid_model;
110  Voice voice[3];
111  Filter filter;
112  ExternalFilter extfilt;
113  Potentiometer potx;
114  Potentiometer poty;
115 
116  reg8 bus_value;
117  cycle_count bus_value_ttl;
118 
119  // Pipeline for writes on the MOS8580.
120  cycle_count write_pipeline;
121  reg8 write_address;
122 
123  double clock_frequency;
124 
125  enum {
126  // Resampling constants.
127  // The error in interpolated lookup is bounded by 1.234/L^2,
128  // while the error in non-interpolated lookup is bounded by
129  // 0.7854/L + 0.4113/L^2, see
130  // http://www-ccrma.stanford.edu/~jos/resample/Choice_Table_Size.html
131  // For a resolution of 16 bits this yields L >= 285 and L >= 51473,
132  // respectively.
133  FIR_N = 125,
134  FIR_RES = 285,
135  FIR_RES_FASTMEM = 51473,
136  FIR_SHIFT = 15,
137 
138  RINGSIZE = 1 << 14,
139  RINGMASK = RINGSIZE - 1,
140 
141  // Fixed point constants (16.16 bits).
142  FIXP_SHIFT = 16,
143  FIXP_MASK = 0xffff
144  };
145 
146  // Sampling variables.
147  sampling_method sampling;
148  cycle_count cycles_per_sample;
149  cycle_count sample_offset;
150  int sample_index;
151  short sample_prev, sample_now;
152  int fir_N;
153  int fir_RES;
154  double fir_beta;
155  double fir_f_cycles_per_sample;
156  double fir_filter_scale;
157 
158  // Ring buffer with overflow for contiguous storage of RINGSIZE samples.
159  short* sample;
160 
161  // FIR_RES filter tables (FIR_N*FIR_RES).
162  short* fir;
163 };
164 
165 
166 // ----------------------------------------------------------------------------
167 // Inline functions.
168 // The following functions are defined inline because they are called every
169 // time a sample is calculated.
170 // ----------------------------------------------------------------------------
171 
172 #if RESID_INLINING || defined(RESID_SID_CC)
173 
174 // ----------------------------------------------------------------------------
175 // Read 16-bit sample from audio output.
176 // ----------------------------------------------------------------------------
177 RESID_INLINE
178 short SID::output()
179 {
180  return extfilt.output();
181 }
182 
183 
184 // ----------------------------------------------------------------------------
185 // SID clocking - 1 cycle.
186 // ----------------------------------------------------------------------------
187 RESID_INLINE
188 void SID::clock()
189 {
190  int i;
191 
192  // Clock amplitude modulators.
193  for (i = 0; i < 3; i++) {
194  voice[i].envelope.clock();
195  }
196 
197  // Clock oscillators.
198  for (i = 0; i < 3; i++) {
199  voice[i].wave.clock();
200  }
201 
202  // Synchronize oscillators.
203  for (i = 0; i < 3; i++) {
204  voice[i].wave.synchronize();
205  }
206 
207  // Calculate waveform output.
208  for (i = 0; i < 3; i++) {
209  voice[i].wave.set_waveform_output();
210  }
211 
212  // Clock filter.
213  filter.clock(voice[0].output(), voice[1].output(), voice[2].output());
214 
215  // Clock external filter.
216  extfilt.clock(filter.output());
217 
218  // Pipelined writes on the MOS8580.
219  if (unlikely(write_pipeline)) {
220  write();
221  }
222 
223  // Age bus value.
224  if (unlikely(!--bus_value_ttl)) {
225  bus_value = 0;
226  }
227 }
228 
229 #endif // RESID_INLINING || defined(RESID_SID_CC)
230 
231 } // namespace reSID
232 
233 #endif // not RESID_SID_H
Definition: dac.cc:45
Definition: sid.h:60
Definition: pot.h:28
Definition: extfilt.h:41
Definition: sid.h:34
Definition: voice.h:30
Definition: filter.h:346