libsidplayfp  2.3.0
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 
113  float envDAC[256];
114 
120  float oscDAC[4096];
121 
122 private:
128  void ageBusValue(unsigned int n);
129 
135  int output() const;
136 
143  void voiceSync(bool sync);
144 
145 public:
146  SID();
147  ~SID();
148 
155  void setChipModel(ChipModel model);
156 
160  ChipModel getChipModel() const { return model; }
161 
165  void reset();
166 
175  void input(int value);
176 
197  unsigned char read(int offset);
198 
205  void write(int offset, unsigned char value);
206 
213  void mute(int channel, bool enable) { muted[channel] = enable; }
214 
240  void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
241 
249  int clock(unsigned int cycles, short* buf);
250 
261  void clockSilent(unsigned int cycles);
262 
268  void setFilter6581Curve(double filterCurve);
269 
275  void setFilter8580Curve(double filterCurve);
276 
282  void enableFilter(bool enable);
283 };
284 
285 } // namespace reSIDfp
286 
287 #if RESID_INLINING || defined(SID_CPP)
288 
289 #include <algorithm>
290 
291 #include "Filter.h"
292 #include "ExternalFilter.h"
293 #include "Voice.h"
294 #include "resample/Resampler.h"
295 
296 namespace reSIDfp
297 {
298 
299 RESID_INLINE
300 void SID::ageBusValue(unsigned int n)
301 {
302  if (likely(busValueTtl != 0))
303  {
304  busValueTtl -= n;
305 
306  if (unlikely(busValueTtl <= 0))
307  {
308  busValue = 0;
309  busValueTtl = 0;
310  }
311  }
312 }
313 
314 RESID_INLINE
315 int SID::output() const
316 {
317  const int v1 = voice[0]->output(voice[2]->wave());
318  const int v2 = voice[1]->output(voice[0]->wave());
319  const int v3 = voice[2]->output(voice[1]->wave());
320 
321  return externalFilter->clock(filter->clock(v1, v2, v3));
322 }
323 
324 
325 RESID_INLINE
326 int SID::clock(unsigned int cycles, short* buf)
327 {
328  ageBusValue(cycles);
329  int s = 0;
330 
331  while (cycles != 0)
332  {
333  unsigned int delta_t = std::min(nextVoiceSync, cycles);
334 
335  if (likely(delta_t > 0))
336  {
337  for (unsigned int i = 0; i < delta_t; i++)
338  {
339  // clock waveform generators
340  voice[0]->wave()->clock();
341  voice[1]->wave()->clock();
342  voice[2]->wave()->clock();
343 
344  // clock envelope generators
345  voice[0]->envelope()->clock();
346  voice[1]->envelope()->clock();
347  voice[2]->envelope()->clock();
348 
349  if (unlikely(resampler->input(output())))
350  {
351  buf[s++] = resampler->getOutput();
352  }
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: Filter.h:33
virtual unsigned short clock(int v1, int v2, int v3)=0
Definition: SID.h:47
Definition: SID.h:61
void setChipModel(ChipModel model)
Definition: SID.cpp:140
void input(int value)
Definition: SID.cpp:221
unsigned char read(int offset)
Definition: SID.cpp:227
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:381
void write(int offset, unsigned char value)
Definition: SID.cpp:262
ChipModel getChipModel() const
Definition: SID.h:160
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:90
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:95
void enableFilter(bool enable)
Definition: SID.cpp:100
void reset()
Definition: SID.cpp:200
int clock(unsigned int cycles, short *buf)
Definition: SID.h:326
void clockSilent(unsigned int cycles)
Definition: SID.cpp:400
void mute(int channel, bool enable)
Definition: SID.h:213