libsidplayfp  2.12.0
SID.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2024 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 #include "ExternalFilter.h"
30 #include "Potentiometer.h"
31 #include "Voice.h"
32 
33 #include "sidcxx11.h"
34 
35 namespace reSIDfp
36 {
37 
38 class Filter;
39 class Filter6581;
40 class Filter8580;
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  Filter6581* const filter6581;
68 
70  Filter8580* const filter8580;
71 
73  std::unique_ptr<Resampler> resampler;
74 
79  ExternalFilter externalFilter;
80 
82  Potentiometer potX;
83 
85  Potentiometer potY;
86 
88  Voice voice[3];
89 
91  int scaleFactor;
92 
94  int busValueTtl;
95 
97  int modelTTL;
98 
100  unsigned int nextVoiceSync;
101 
103  ChipModel model;
104 
106  CombinedWaveforms cws;
107 
109  unsigned char busValue;
110 
116  float envDAC[256];
117 
123  float oscDAC[4096];
124 
125 private:
131  void ageBusValue(unsigned int n);
132 
138  int output();
139 
146  void voiceSync(bool sync);
147 
148 public:
149  SID();
150  ~SID();
151 
158  void setChipModel(ChipModel model);
159 
163  ChipModel getChipModel() const { return model; }
164 
171  void setCombinedWaveforms(CombinedWaveforms cws);
172 
176  void reset();
177 
186  void input(int value);
187 
208  unsigned char read(int offset);
209 
216  void write(int offset, unsigned char value);
217 
244  double clockFrequency,
245  SamplingMethod method,
246  double samplingFrequency
247  );
248 
256  int clock(unsigned int cycles, short* buf);
257 
268  void clockSilent(unsigned int cycles);
269 
275  void setFilter6581Curve(double filterCurve);
276 
282  void setFilter6581Range ( double adjustment );
283 
289  void setFilter8580Curve(double filterCurve);
290 
296  void enableFilter(bool enable);
297 };
298 
299 } // namespace reSIDfp
300 
301 #if RESID_INLINING || defined(SID_CPP)
302 
303 #include <algorithm>
304 
305 #include "Filter.h"
306 #include "ExternalFilter.h"
307 #include "Voice.h"
308 #include "resample/Resampler.h"
309 
310 namespace reSIDfp
311 {
312 
313 RESID_INLINE
314 void SID::ageBusValue(unsigned int n)
315 {
316  if (likely(busValueTtl != 0))
317  {
318  busValueTtl -= n;
319 
320  if (unlikely(busValueTtl <= 0))
321  {
322  busValue = 0;
323  busValueTtl = 0;
324  }
325  }
326 }
327 
328 RESID_INLINE
329 int SID::output()
330 {
331  const float o1 = voice[0].output(voice[2].wave());
332  const float o2 = voice[1].output(voice[0].wave());
333  const float o3 = voice[2].output(voice[1].wave());
334 
335  const unsigned int env1 = voice[0].envelope()->output();
336  const unsigned int env2 = voice[1].envelope()->output();
337  const unsigned int env3 = voice[2].envelope()->output();
338 
339  const int v1 = filter->getNormalizedVoice(o1, env1);
340  const int v2 = filter->getNormalizedVoice(o2, env2);
341  const int v3 = filter->getNormalizedVoice(o3, env3);
342 
343  const int input = static_cast<int>(filter->clock(v1, v2, v3));
344  return externalFilter.clock(input);
345 }
346 
347 
348 RESID_INLINE
349 int SID::clock(unsigned int cycles, short* buf)
350 {
351  ageBusValue(cycles);
352  int s = 0;
353 
354  while (cycles != 0)
355  {
356  unsigned int delta_t = std::min(nextVoiceSync, cycles);
357 
358  if (likely(delta_t > 0))
359  {
360  for (unsigned int i = 0; i < delta_t; i++)
361  {
362  // clock waveform generators
363  voice[0].wave()->clock();
364  voice[1].wave()->clock();
365  voice[2].wave()->clock();
366 
367  // clock envelope generators
368  voice[0].envelope()->clock();
369  voice[1].envelope()->clock();
370  voice[2].envelope()->clock();
371 
372  if (unlikely(resampler->input(output())))
373  {
374  buf[s++] = resampler->getOutput(scaleFactor);
375  }
376  }
377 
378  cycles -= delta_t;
379  nextVoiceSync -= delta_t;
380  }
381 
382  if (unlikely(nextVoiceSync == 0))
383  {
384  voiceSync(true);
385  }
386  }
387 
388  return s;
389 }
390 
391 } // namespace reSIDfp
392 
393 #endif
394 
395 #endif
unsigned int output() const
Definition: EnvelopeGenerator.h:130
void clock()
Definition: EnvelopeGenerator.h:177
Definition: ExternalFilter.h:66
int clock(int input)
Definition: ExternalFilter.h:112
Definition: Filter6581.h:321
Definition: Filter.h:37
virtual unsigned short clock(int v1, int v2, int v3)=0
Definition: Potentiometer.h:38
Definition: SID.h:47
Definition: SID.h:61
void setChipModel(ChipModel model)
Definition: SID.cpp:207
void input(int value)
Definition: SID.cpp:317
unsigned char read(int offset)
Definition: SID.cpp:323
void write(int offset, unsigned char value)
Definition: SID.cpp:358
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency)
Definition: SID.cpp:477
void setFilter6581Range(double adjustment)
Definition: SID.cpp:157
ChipModel getChipModel() const
Definition: SID.h:163
void setCombinedWaveforms(CombinedWaveforms cws)
Definition: SID.cpp:272
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:152
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:162
void enableFilter(bool enable)
Definition: SID.cpp:167
void reset()
Definition: SID.cpp:296
int clock(unsigned int cycles, short *buf)
Definition: SID.h:349
void clockSilent(unsigned int cycles)
Definition: SID.cpp:496
Definition: Voice.h:37
RESID_INLINE float output(const WaveformGenerator *ringModulator)
Definition: Voice.h:66
void clock()
Definition: WaveformGenerator.h:279