libsidplayfp  2.0.2
SID.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2016 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 <memory>
27 
28 #include "siddefs-fp.h"
29 
30 #include "sidcxx11.h"
31 
32 namespace reSIDfp
33 {
34 
35 class Filter;
36 class Filter6581;
37 class Filter8580;
38 class ExternalFilter;
39 class Potentiometer;
40 class Voice;
41 class Resampler;
42 
46 class SIDError
47 {
48 private:
49  const char* message;
50 
51 public:
52  SIDError(const char* msg) :
53  message(msg) {}
54  const char* getMessage() const { return message; }
55 };
56 
60 class SID
61 {
62 private:
64  Filter* filter;
65 
67  std::unique_ptr<Filter6581> const filter6581;
68 
70  std::unique_ptr<Filter8580> const filter8580;
71 
76  std::unique_ptr<ExternalFilter> const externalFilter;
77 
79  std::unique_ptr<Resampler> resampler;
80 
82  std::unique_ptr<Potentiometer> const potX;
83 
85  std::unique_ptr<Potentiometer> const potY;
86 
88  std::unique_ptr<Voice> voice[3];
89 
91  int busValueTtl;
92 
94  int modelTTL;
95 
97  unsigned int nextVoiceSync;
98 
100  ChipModel model;
101 
103  unsigned char busValue;
104 
106  bool muted[3];
107 
108 private:
114  void ageBusValue(unsigned int n);
115 
121  int output() const;
122 
129  void voiceSync(bool sync);
130 
131 public:
132  SID();
133  ~SID();
134 
141  void setChipModel(ChipModel model);
142 
146  ChipModel getChipModel() const { return model; }
147 
151  void reset();
152 
161  void input(int value);
162 
183  unsigned char read(int offset);
184 
191  void write(int offset, unsigned char value);
192 
199  void mute(int channel, bool enable) { muted[channel] = enable; }
200 
226  void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
227 
235  int clock(unsigned int cycles, short* buf);
236 
247  void clockSilent(unsigned int cycles);
248 
254  void setFilter6581Curve(double filterCurve);
255 
261  void setFilter8580Curve(double filterCurve);
262 
268  void enableFilter(bool enable);
269 };
270 
271 } // namespace reSIDfp
272 
273 #if RESID_INLINING || defined(SID_CPP)
274 
275 #include <algorithm>
276 
277 #include "Filter.h"
278 #include "ExternalFilter.h"
279 #include "Voice.h"
280 #include "resample/Resampler.h"
281 
282 namespace reSIDfp
283 {
284 
285 RESID_INLINE
286 void SID::ageBusValue(unsigned int n)
287 {
288  if (likely(busValueTtl != 0))
289  {
290  busValueTtl -= n;
291 
292  if (unlikely(busValueTtl <= 0))
293  {
294  busValue = 0;
295  busValueTtl = 0;
296  }
297  }
298 }
299 
300 RESID_INLINE
301 int SID::output() const
302 {
303  const int v1 = voice[0]->output(voice[2]->wave());
304  const int v2 = voice[1]->output(voice[0]->wave());
305  const int v3 = voice[2]->output(voice[1]->wave());
306 
307  return externalFilter->clock(filter->clock(v1, v2, v3));
308 }
309 
310 
311 RESID_INLINE
312 int SID::clock(unsigned int cycles, short* buf)
313 {
314  ageBusValue(cycles);
315  int s = 0;
316 
317  while (cycles != 0)
318  {
319  unsigned int delta_t = std::min(nextVoiceSync, cycles);
320 
321  if (likely(delta_t > 0))
322  {
323  for (unsigned int i = 0; i < delta_t; i++)
324  {
325  // clock waveform generators
326  voice[0]->wave()->clock();
327  voice[1]->wave()->clock();
328  voice[2]->wave()->clock();
329 
330  // clock envelope generators
331  voice[0]->envelope()->clock();
332  voice[1]->envelope()->clock();
333  voice[2]->envelope()->clock();
334 
335  if (unlikely(resampler->input(output())))
336  {
337  buf[s++] = resampler->getOutput();
338  }
339  }
340 
341  cycles -= delta_t;
342  nextVoiceSync -= delta_t;
343  }
344 
345  if (unlikely(nextVoiceSync == 0))
346  {
347  voiceSync(true);
348  }
349  }
350 
351  return s;
352 }
353 
354 } // namespace reSIDfp
355 
356 #endif
357 
358 #endif
reSIDfp::SID::getChipModel
ChipModel getChipModel() const
Definition: SID.h:146
reSIDfp::SID::read
unsigned char read(int offset)
Definition: SID.cpp:193
reSIDfp::SID::enableFilter
void enableFilter(bool enable)
Definition: SID.cpp:95
reSIDfp::SID::write
void write(int offset, unsigned char value)
Definition: SID.cpp:228
reSIDfp::Filter
Definition: Filter.h:33
reSIDfp::Filter::clock
virtual int clock(int v1, int v2, int v3)=0
reSIDfp::SID::clock
int clock(unsigned int cycles, short *buf)
Definition: SID.h:312
reSIDfp::SID::mute
void mute(int channel, bool enable)
Definition: SID.h:199
reSIDfp::SID::setChipModel
void setChipModel(ChipModel model)
Definition: SID.cpp:134
reSIDfp::SID::reset
void reset()
Definition: SID.cpp:166
reSIDfp::SID::input
void input(int value)
Definition: SID.cpp:187
reSIDfp::SID::setFilter6581Curve
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:85
reSIDfp::SID::setFilter8580Curve
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:90
reSIDfp::SIDError
Definition: SID.h:47
reSIDfp::SID
Definition: SID.h:61
reSIDfp::SID::clockSilent
void clockSilent(unsigned int cycles)
Definition: SID.cpp:366
reSIDfp::SID::setSamplingParameters
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:347