libsidplayfp  1.6.0
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  void setFilter6581Curve(double filterCurve);
263 
269  void setFilter8580Curve(double filterCurve);
270 
276  void enableFilter(bool enable);
277 };
278 
279 } // namespace reSIDfp
280 
281 #if RESID_INLINING || defined(SID_CPP)
282 
283 #include <algorithm>
284 
285 #include "Filter.h"
286 #include "ExternalFilter.h"
287 #include "Voice.h"
288 #include "resample/Resampler.h"
289 
290 namespace reSIDfp
291 {
292 
293 RESID_INLINE
294 void SID::ageBusValue(int n)
295 {
296  if (likely(busValueTtl != 0))
297  {
298  busValueTtl -= n;
299 
300  if (unlikely(busValueTtl <= 0))
301  {
302  busValue = 0;
303  busValueTtl = 0;
304  }
305  }
306 }
307 
308 RESID_INLINE
309 int SID::output() const
310 {
311  const int v1 = voice[0]->output(voice[2]->wave());
312  const int v2 = voice[1]->output(voice[0]->wave());
313  const int v3 = voice[2]->output(voice[1]->wave());
314 
315  return externalFilter->clock(filter->clock(v1, v2, v3));
316 }
317 
318 
319 RESID_INLINE
320 int SID::clock(int cycles, short* buf)
321 {
322  ageBusValue(cycles);
323  int s = 0;
324 
325  while (cycles != 0)
326  {
327  int delta_t = std::min(nextVoiceSync, cycles);
328 
329  if (likely(delta_t > 0))
330  {
331  if (unlikely(delayedOffset != -1))
332  {
333  delta_t = 1;
334  }
335 
336  for (int i = 0; i < delta_t; i++)
337  {
338  /* clock waveform generators */
339  voice[0]->wave()->clock();
340  voice[1]->wave()->clock();
341  voice[2]->wave()->clock();
342 
343  /* clock envelope generators */
344  voice[0]->envelope()->clock();
345  voice[1]->envelope()->clock();
346  voice[2]->envelope()->clock();
347 
348  if (unlikely(resampler->input(output())))
349  {
350  buf[s++] = resampler->getOutput();
351  }
352  }
353 
354  if (unlikely(delayedOffset != -1))
355  {
356  writeImmediate(delayedOffset, delayedValue);
357  delayedOffset = -1;
358  }
359 
360  cycles -= delta_t;
361  nextVoiceSync -= delta_t;
362  }
363 
364  if (unlikely(nextVoiceSync == 0))
365  {
366  voiceSync(true);
367  }
368  }
369 
370  return s;
371 }
372 
373 } // namespace reSIDfp
374 
375 #endif
376 
377 #endif
Definition: Filter8580.h:85
Definition: SID.h:42
Definition: Potentiometer.h:37
void clockSilent(int cycles)
Definition: SID.cpp:372
Definition: Voice.h:36
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:75
Definition: SID.h:56
short getOutput() const
Definition: Resampler.h:55
void clock()
Definition: EnvelopeGenerator.h:208
void input(int value)
Definition: SID.cpp:292
Definition: Dac.cpp:25
virtual int clock(int v1, int v2, int v3)=0
void enableFilter(bool enable)
Definition: SID.cpp:85
int clock(int cycles, short *buf)
Definition: SID.h:320
Definition: ExternalFilter.h:47
Definition: Resampler.h:32
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:349
Definition: Filter6581.h:320
virtual bool input(int sample)=0
unsigned char read(int offset)
Definition: SID.cpp:298
void write(int offset, unsigned char value)
Definition: SID.cpp:333
void clock()
Definition: WaveformGenerator.h:282
RESID_INLINE int output(const WaveformGenerator *ringModulator) const
Definition: Voice.h:59
void mute(int channel, bool enable)
Definition: SID.h:208
Definition: Filter.h:32
void setChipModel(ChipModel model)
Definition: SID.cpp:240
ChipModel getChipModel() const
Definition: SID.h:155
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:80
void reset()
Definition: SID.cpp:270
int clock(int Vi)
Definition: ExternalFilter.h:94