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 "audio/sid.h"
31
32// Inlining on/off.
33#define RESID_INLINE inline
34
35namespace 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
44typedef unsigned int reg4;
45typedef unsigned int reg8;
46typedef unsigned int reg12;
47typedef unsigned int reg16;
48typedef unsigned int reg24;
49
50typedef int cycle_count;
51typedef int sound_sample;
52
53typedef unsigned char data8;
54typedef unsigned short data16;
55typedef unsigned short fc_point[2];
56
57
59public:
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
78protected:
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
131class Filter {
132public:
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
150protected:
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
200public:
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
216protected:
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
244public:
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
256protected:
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
275class Voice {
276public:
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
291protected:
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
305class SID final : public ::SID::SID, public Audio::EmulatedChip {
306public:
307 SID(::SID::Config::SidType videoSystem);
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
319 bool init() override;
320 void reset() override;
321
322 // Read/write registers.
323 reg8 read(reg8 offset);
324 void writeReg(int offset, int value) override;
325
326 // 16-bit output (AUDIO OUT).
327 int output();
328
329 bool isStereo() const override { return false; }
330
331protected:
332 void generateSamples(int16 *buffer, int numSamples) override;
333
334 Voice voice[3];
335 Filter filter;
336 ExternalFilter extfilt;
337
338 reg8 bus_value;
339 cycle_count bus_value_ttl;
340
341 double clock_frequency;
342
343 // Fixpoint constants.
344 static const int FIXP_SHIFT;
345 static const int FIXP_MASK;
346
347 // Sampling variables.
348 cycle_count cycles_per_sample;
349 cycle_count sample_offset;
350 short sample_prev;
351
352 ::SID::Config::SidType _videoSystem;
353 cycle_count _cpuCyclesLeft;
354};
355
356}
357
358#endif // not AUDIO_SOFTSYNTH_SID_H
Definition: chip.h:112
Definition: sid.h:199
Definition: sid.h:243
Definition: sid.h:131
Definition: sid.h:305
void reset() override
bool isStereo() const override
Definition: sid.h:329
void writeReg(int offset, int value) override
void generateSamples(int16 *buffer, int numSamples) override
bool init() override
Definition: sid.h:275
Definition: sid.h:58
Definition: sid.h:50