ScummVM API documentation
sid.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
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 3 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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * This file is based on reSID, a MOS6581 SID emulator engine.
24  * Copyright (C) 2004 Dag Lem <resid@nimrod.no>
25  */
26 
27 #ifndef AUDIO_SOFTSYNTH_SID_H
28 #define AUDIO_SOFTSYNTH_SID_H
29 
30 #include "common/scummsys.h"
31 
32 // Inlining on/off.
33 #define RESID_INLINE inline
34 
35 namespace Resid {
36 
37 // We could have used the smallest possible data type for each SID register,
38 // however this would give a slower engine because of data type conversions.
39 // An int is assumed to be at least 32 bits (necessary in the types reg24,
40 // cycle_count, and sound_sample). GNU does not support 16-bit machines
41 // (GNU Coding Standards: Portability between CPUs), so this should be
42 // a valid assumption.
43 
44 typedef unsigned int reg4;
45 typedef unsigned int reg8;
46 typedef unsigned int reg12;
47 typedef unsigned int reg16;
48 typedef unsigned int reg24;
49 
50 typedef int cycle_count;
51 typedef int sound_sample;
52 
53 typedef unsigned char data8;
54 typedef unsigned short data16;
55 typedef unsigned short fc_point[2];
56 
57 
59 public:
61 
62  void set_sync_source(WaveformGenerator *);
63 
64  void updateClock(cycle_count delta_t);
65  void synchronize();
66  void reset();
67 
68  void writeFREQ_LO(reg8);
69  void writeFREQ_HI(reg8);
70  void writePW_LO(reg8);
71  void writePW_HI(reg8);
72  void writeCONTROL_REG(reg8);
73  reg8 readOSC();
74 
75  // 12-bit waveform output.
76  reg12 output();
77 
78 protected:
79  const WaveformGenerator* sync_source;
80  WaveformGenerator* sync_dest;
81 
82  // Tell whether the accumulator MSB was set high on this cycle.
83  bool msb_rising;
84 
85  reg24 accumulator;
86  reg24 shift_register;
87 
88  // Fout = (Fn*Fclk/16777216)Hz
89  reg16 freq;
90  // PWout = (PWn/40.95)%
91  reg12 pw;
92 
93  // The control register right-shifted 4 bits; used for output function
94  // table lookup.
95  reg8 waveform;
96 
97  // The remaining control register bits.
98  reg8 test;
99  reg8 ring_mod;
100  reg8 sync;
101  // The gate bit is handled by the EnvelopeGenerator.
102 
103  // 16 possible combinations of waveforms.
104  reg12 output____();
105  reg12 output___T();
106  reg12 output__S_();
107  reg12 output__ST();
108  reg12 output_P__();
109  reg12 output_P_T();
110  reg12 output_PS_();
111  reg12 output_PST();
112  reg12 outputN___();
113  reg12 outputN__T();
114  reg12 outputN_S_();
115  reg12 outputN_ST();
116  reg12 outputNP__();
117  reg12 outputNP_T();
118  reg12 outputNPS_();
119  reg12 outputNPST();
120 
121  // Sample data for combinations of waveforms.
122  static const data8 wave6581__ST[];
123  static const data8 wave6581_P_T[];
124  static const data8 wave6581_PS_[];
125  static const data8 wave6581_PST[];
126 
127  friend class Voice;
128  friend class SID;
129 };
130 
131 class Filter {
132 public:
133  Filter();
134 
135  void enable_filter(bool enable);
136 
137  void updateClock(cycle_count delta_t,
138  sound_sample voice1, sound_sample voice2, sound_sample voice3);
139  void reset();
140 
141  // Write registers.
142  void writeFC_LO(reg8);
143  void writeFC_HI(reg8);
144  void writeRES_FILT(reg8);
145  void writeMODE_VOL(reg8);
146 
147  // SID audio output (16 bits).
148  sound_sample output();
149 
150 protected:
151  void set_w0();
152  void set_Q();
153 
154  // Filter enabled.
155  bool enabled;
156 
157  // Filter cutoff frequency.
158  reg12 fc;
159 
160  // Filter resonance.
161  reg8 res;
162 
163  // Selects which inputs to route through filter.
164  reg8 filt;
165 
166  // Switch voice 3 off.
167  reg8 voice3off;
168 
169  // Highpass, bandpass, and lowpass filter modes.
170  reg8 hp_bp_lp;
171 
172  // Output master volume.
173  reg4 vol;
174 
175  // Mixer DC offset.
176  sound_sample mixer_DC;
177 
178  // State of filter.
179  sound_sample Vhp; // highpass
180  sound_sample Vbp; // bandpass
181  sound_sample Vlp; // lowpass
182  sound_sample Vnf; // not filtered
183 
184  // Cutoff frequency, resonance.
185  sound_sample w0, w0_ceil_1, w0_ceil_dt;
186  sound_sample _1024_div_Q;
187 
188  // Cutoff frequency tables.
189  // FC is an 11 bit register.
190  sound_sample f0_6581[2048];
191  sound_sample* f0;
192  static const fc_point f0_points_6581[];
193  const fc_point* f0_points;
194  int f0_count;
195 
196  friend class SID;
197 };
198 
200 public:
202 
203  enum State { ATTACK, DECAY_SUSTAIN, RELEASE };
204 
205  void updateClock(cycle_count delta_t);
206  void reset();
207 
208  void writeCONTROL_REG(reg8);
209  void writeATTACK_DECAY(reg8);
210  void writeSUSTAIN_RELEASE(reg8);
211  reg8 readENV();
212 
213  // 8-bit envelope output.
214  reg8 output();
215 
216 protected:
217  reg16 rate_counter;
218  reg16 rate_period;
219  reg8 exponential_counter;
220  reg8 exponential_counter_period;
221  reg8 envelope_counter;
222  bool hold_zero;
223 
224  reg4 attack;
225  reg4 decay;
226  reg4 sustain;
227  reg4 release;
228 
229  reg8 gate;
230 
231  State state;
232 
233  // Lookup table to convert from attack, decay, or release value to rate
234  // counter period.
235  static const data16 rate_counter_period[];
236 
237  // The 16 selectable sustain levels.
238  static const data8 sustain_level[];
239 
240  friend class SID;
241 };
242 
244 public:
245  ExternalFilter();
246 
247  void enable_filter(bool enable);
248  void set_sampling_parameter(double pass_freq);
249 
250  void updateClock(cycle_count delta_t, sound_sample Vi);
251  void reset();
252 
253  // Audio output (20 bits).
254  sound_sample output();
255 
256 protected:
257  // Filter enabled.
258  bool enabled;
259 
260  // Maximum mixer DC offset.
261  sound_sample mixer_DC;
262 
263  // State of filters.
264  sound_sample Vlp; // lowpass
265  sound_sample Vhp; // highpass
266  sound_sample Vo;
267 
268  // Cutoff frequencies.
269  sound_sample w0lp;
270  sound_sample w0hp;
271 
272  friend class SID;
273 };
274 
275 class Voice {
276 public:
277  Voice();
278 
279  void set_sync_source(Voice *);
280  void reset();
281 
282  void writeCONTROL_REG(reg8);
283 
284  // Amplitude modulated waveform output.
285  // Range [-2048*255, 2047*255].
286  sound_sample output() {
287  // Multiply oscillator output with envelope output.
288  return (wave.output() - wave_zero)*envelope.output() + voice_DC;
289  }
290 
291 protected:
292  WaveformGenerator wave;
293  EnvelopeGenerator envelope;
294 
295  // Waveform D/A zero level.
296  sound_sample wave_zero;
297 
298  // Multiplying D/A DC offset.
299  sound_sample voice_DC;
300 
301  friend class SID;
302 };
303 
304 
305 class SID {
306 public:
307  SID();
308  ~SID();
309 
310  void enable_filter(bool enable);
311  void enable_external_filter(bool enable);
312  bool set_sampling_parameters(double clock_freq,
313  double sample_freq, double pass_freq = -1,
314  double filter_scale = 0.97);
315 
316  void updateClock(cycle_count delta_t);
317  int updateClock(cycle_count& delta_t, short* buf, int n, int interleave = 1);
318  void reset();
319 
320  // Read/write registers.
321  reg8 read(reg8 offset);
322  void write(reg8 offset, reg8 value);
323 
324  // 16-bit output (AUDIO OUT).
325  int output();
326 
327 protected:
328  Voice voice[3];
329  Filter filter;
330  ExternalFilter extfilt;
331 
332  reg8 bus_value;
333  cycle_count bus_value_ttl;
334 
335  double clock_frequency;
336 
337  // Fixpoint constants.
338  static const int FIXP_SHIFT;
339  static const int FIXP_MASK;
340 
341  // Sampling variables.
342  cycle_count cycles_per_sample;
343  cycle_count sample_offset;
344  short sample_prev;
345 };
346 
347 }
348 
349 #endif // not AUDIO_SOFTSYNTH_SID_H
Definition: sid.h:58
Definition: sid.h:275
Definition: sid.h:305
Definition: sid.h:35
Definition: sid.h:131
Definition: sid.h:243
Definition: sid.h:199