libsidplayfp  1.4.1
SID.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2004 Dag Lem <resid@nimrod.no>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef SIDFP_H
24 #define SIDFP_H
25 
26 #include "siddefs-fp.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 
42 class SIDError
43 {
44 private:
45  const char* message;
46 
47 public:
48  SIDError(const char* msg) :
49  message(msg) {}
50  const char* getMessage() { return message; }
51 };
52 
56 class SID
57 {
58 private:
60  static const int BUS_TTL;
61 
63  Filter* filter;
64 
66  Filter6581* filter6581;
67 
69  Filter8580* filter8580;
70 
75  ExternalFilter* externalFilter;
76 
78  Resampler* resampler;
79 
81  Potentiometer* potX;
82 
84  Potentiometer* potY;
85 
87  Voice* voice[3];
88 
90  int busValueTtl;
91 
93  int nextVoiceSync;
94 
96  int delayedOffset;
97 
99  ChipModel model;
100 
102  unsigned char delayedValue;
103 
105  unsigned char busValue;
106 
108  bool muted[3];
109 
110 private:
117  void writeImmediate(int offset, unsigned char value);
118 
124  void ageBusValue(int n);
125 
131  int output() const;
132 
139  void voiceSync(bool sync);
140 
141 public:
142  SID();
143  ~SID();
144 
150  void setChipModel(ChipModel model);
151 
155  ChipModel getChipModel() const { return model; }
156 
160  void reset();
161 
170  void input(int value);
171 
192  unsigned char read(int offset);
193 
200  void write(int offset, unsigned char value);
201 
208  void mute(int channel, bool enable) { muted[channel] = enable; }
209 
234  void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
235 
243  int clock(int cycles, short* buf);
244 
255  void clockSilent(int cycles);
256 
262  Filter6581* getFilter6581() const { return filter6581; }
263 
269  Filter8580* getFilter8580() const { return filter8580; }
270 };
271 
272 } // namespace reSIDfp
273 
274 #if RESID_INLINING || defined(SID_CPP)
275 
276 #include <algorithm>
277 
278 #include "Filter.h"
279 #include "ExternalFilter.h"
280 #include "Voice.h"
281 #include "resample/Resampler.h"
282 
283 namespace reSIDfp
284 {
285 
286 RESID_INLINE
287 void SID::ageBusValue(int n)
288 {
289  if (likely(busValueTtl != 0))
290  {
291  busValueTtl -= n;
292 
293  if (unlikely(busValueTtl <= 0))
294  {
295  busValue = 0;
296  busValueTtl = 0;
297  }
298  }
299 }
300 
301 RESID_INLINE
302 int SID::output() const
303 {
304  return externalFilter->clock(
305  filter->clock(
306  voice[0]->output(voice[2]->wave()),
307  voice[1]->output(voice[0]->wave()),
308  voice[2]->output(voice[1]->wave())
309  )
310  );
311 }
312 
313 
314 RESID_INLINE
315 int SID::clock(int cycles, short* buf)
316 {
317  ageBusValue(cycles);
318  int s = 0;
319 
320  while (cycles != 0)
321  {
322  int delta_t = std::min(nextVoiceSync, cycles);
323 
324  if (likely(delta_t > 0))
325  {
326  if (unlikely(delayedOffset != -1))
327  {
328  delta_t = 1;
329  }
330 
331  for (int i = 0; i < delta_t; i++)
332  {
333  /* clock waveform generators */
334  voice[0]->wave()->clock();
335  voice[1]->wave()->clock();
336  voice[2]->wave()->clock();
337 
338  /* clock envelope generators */
339  voice[0]->envelope()->clock();
340  voice[1]->envelope()->clock();
341  voice[2]->envelope()->clock();
342 
343  if (unlikely(resampler->input(output())))
344  {
345  buf[s++] = resampler->getOutput();
346  }
347  }
348 
349  if (unlikely(delayedOffset != -1))
350  {
351  writeImmediate(delayedOffset, delayedValue);
352  delayedOffset = -1;
353  }
354 
355  cycles -= delta_t;
356  nextVoiceSync -= delta_t;
357  }
358 
359  if (unlikely(nextVoiceSync == 0))
360  {
361  voiceSync(true);
362  }
363  }
364 
365  return s;
366 }
367 
368 } // namespace reSIDfp
369 
370 #endif
371 
372 #endif
Definition: Filter8580.h:74
Definition: SID.h:42
Definition: Potentiometer.h:37
void clockSilent(int cycles)
Definition: SID.cpp:356
Definition: Voice.h:36
Definition: SID.h:56
short getOutput() const
Definition: Resampler.h:55
void clock()
Definition: EnvelopeGenerator.h:204
void input(int value)
Definition: SID.cpp:276
Filter6581 * getFilter6581() const
Definition: SID.h:262
virtual int clock(int v1, int v2, int v3)=0
int clock(int cycles, short *buf)
Definition: SID.h:315
Definition: ExternalFilter.h:45
Definition: Resampler.h:32
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:333
Filter8580 * getFilter8580() const
Definition: SID.h:269
Definition: Filter6581.h:40
virtual bool input(int sample)=0
unsigned char read(int offset)
Definition: SID.cpp:282
void write(int offset, unsigned char value)
Definition: SID.cpp:317
void clock()
Definition: WaveformGenerator.h:283
void mute(int channel, bool enable)
Definition: SID.h:208
Definition: Filter.h:32
void setChipModel(ChipModel model)
Definition: SID.cpp:224
ChipModel getChipModel() const
Definition: SID.h:155
void reset()
Definition: SID.cpp:254
int clock(int Vi)
Definition: ExternalFilter.h:92