libsidplayfp  0.3.5
SID.h
1 /*
2  * This file is part of reSID, a MOS6581 SID emulator engine.
3  * Copyright (C) 2004 Dag Lem <resid@nimrod.no>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * @author Ken Händel
20  *
21  */
22 
23 #ifndef SIDFP_H
24 #define SIDFP_H
25 
26 #include "residfp-config.h"
27 
28 namespace reSIDfp
29 {
30 
31 class Filter;
32 class Filter6581;
33 class Filter8580;
34 class ExternalFilter;
35 class Potentiometer;
36 class Voice;
37 class Resampler;
38 
39 class SIDError {
40 
41 private:
42  const char* message;
43 
44 public:
45  SIDError(const char* msg) : message(msg) {}
46  const char* getMessage() { return message; }
47 };
48 
60 class SID {
61 
62 private:
66  static const int BUS_TTL;
67 
69  Filter* filter;
70 
72  Filter6581* filter6581;
73 
75  Filter8580* filter8580;
76 
81  ExternalFilter* externalFilter;
82 
84  Potentiometer* potX;
85 
87  Potentiometer* potY;
88 
90  int busValueTtl;
91 
95  int nextVoiceSync;
96 
100  Resampler* resampler;
101 
103  int delayedOffset;
104 
108  ChipModel model;
109 
111  unsigned char delayedValue;
112 
114  unsigned char busValue;
115 
116  bool muted[3];
117 
118 private:
119  void writeImmediate(const int offset, const unsigned char value);
120 
121  void ageBusValue(const int n);
122 
128  int output() const;
129 
134  void voiceSync(const bool sync);
135 
136 public:
139 
140 public:
141  SID();
142  ~SID();
143 
149  void setChipModel(const ChipModel model);
150 
151  ChipModel getChipModel() { return model; }
152 
156  void reset();
157 
166  void input(const int value);
167 
180  unsigned char read(const int offset);
181 
188  void write(const int offset, const unsigned char value);
189 
196  void mute(const int channel, const bool enable);
197 
216  void setSamplingParameters(const double clockFrequency, const SamplingMethod method, const double samplingFrequency, const double highestAccurateFrequency);
217 
225  int clock(int cycles, short* buf);
226 
237  void clockSilent(int cycles);
238 
244  Filter6581* getFilter6581() { return filter6581; }
245 
251  Filter8580* getFilter8580() { return filter8580; }
252 };
253 
254 } // namespace reSIDfp
255 
256 #if RESID_INLINING || defined(SID_CPP)
257 
258 #include <algorithm>
259 
260 #include "Filter.h"
261 #include "ExternalFilter.h"
262 #include "Voice.h"
263 #include "resample/Resampler.h"
264 
265 namespace reSIDfp
266 {
267 
268 RESID_INLINE
269 void SID::mute(const int channel, const bool enable) {
270  muted[channel] = enable;
271 }
272 
273 RESID_INLINE
274 int SID::output() const {
275  return externalFilter->clock(
276  filter->clock(
277  voice[0]->output(voice[2]->wave),
278  voice[1]->output(voice[0]->wave),
279  voice[2]->output(voice[1]->wave)
280  )
281  );
282 }
283 
284 
285 RESID_INLINE
286 int SID::clock(int cycles, short* buf) {
287  ageBusValue(cycles);
288  int s = 0;
289  while (cycles != 0) {
290  int delta_t = std::min(nextVoiceSync, cycles);
291  if (delta_t > 0) {
292  if (delayedOffset != -1) {
293  delta_t = 1;
294  }
295 
296  for (int i = 0; i < delta_t; i ++) {
297  if (resampler->input(output())) {
298  buf[s++] = resampler->getOutput();
299  }
300 
301  /* clock waveform generators */
302  voice[0]->wave->clock();
303  voice[1]->wave->clock();
304  voice[2]->wave->clock();
305 
306  /* clock envelope generators */
307  voice[0]->envelope->clock();
308  voice[1]->envelope->clock();
309  voice[2]->envelope->clock();
310  }
311 
312  if (delayedOffset != -1) {
313  writeImmediate(delayedOffset, delayedValue);
314  delayedOffset = -1;
315  }
316 
317  cycles -= delta_t;
318  nextVoiceSync -= delta_t;
319  }
320 
321  if (nextVoiceSync == 0) {
322  voiceSync(true);
323  }
324  }
325 
326  return s;
327 }
328 
329 } // namespace reSIDfp
330 
331 #endif
332 
333 #endif