libsidplayfp  2.15.0
SID.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2025 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 #include <cstdint>
28 
29 #include "siddefs-fp.h"
30 #include "ExternalFilter.h"
31 #include "Potentiometer.h"
32 #include "Voice.h"
33 
34 #include "sidcxx11.h"
35 
36 namespace reSIDfp
37 {
38 
39 class Filter;
40 class Filter6581;
41 class Filter8580;
42 class Resampler;
43 
47 class SIDError
48 {
49 private:
50  const char* message;
51 
52 public:
53  SIDError(const char* msg) :
54  message(msg) {}
55  const char* getMessage() const { return message; }
56 };
57 
61 class SID
62 {
63 private:
65  Filter* filter;
66 
68  Filter6581* const filter6581;
69 
71  Filter8580* const filter8580;
72 
74  std::unique_ptr<Resampler> resampler;
75 
80  ExternalFilter externalFilter;
81 
83  Potentiometer potX;
84 
86  Potentiometer potY;
87 
89  Voice voice[3];
90 
92  int scaleFactor;
93 
95  int busValueTtl;
96 
98  int modelTTL;
99 
101  unsigned int nextVoiceSync;
102 
104  ChipModel model;
105 
107  CombinedWaveforms cws;
108 
110  unsigned char busValue;
111 
117  float envDAC[256];
118 
124  float oscDAC[4096];
125 
126 private:
132  void ageBusValue(unsigned int n);
133 
140  void voiceSync(bool sync);
141 
142 public:
143  SID();
144  ~SID();
145 
152  void setChipModel(ChipModel model);
153 
157  ChipModel getChipModel() const { return model; }
158 
165  void setCombinedWaveforms(CombinedWaveforms cws);
166 
170  void reset();
171 
180  void input(int value);
181 
202  unsigned char read(int offset);
203 
210  void write(int offset, unsigned char value);
211 
238  double clockFrequency,
239  SamplingMethod method,
240  double samplingFrequency
241  );
242 
250  int clock(unsigned int cycles, short* buf);
251 
262  void clockSilent(unsigned int cycles);
263 
269  void setFilter6581Curve(double filterCurve);
270 
276  void setFilter6581Range ( double adjustment );
277 
283  void setFilter8580Curve(double filterCurve);
284 
290  void enableFilter(bool enable);
291 };
292 
293 } // namespace reSIDfp
294 
295 #if RESID_INLINING || defined(SID_CPP)
296 
297 #include <algorithm>
298 
299 #include "Filter.h"
300 #include "ExternalFilter.h"
301 #include "Voice.h"
302 #include "resample/Resampler.h"
303 
304 namespace reSIDfp
305 {
306 
307 RESID_INLINE
308 void SID::ageBusValue(unsigned int n)
309 {
310  if (likely(busValueTtl != 0))
311  {
312  busValueTtl -= n;
313 
314  if (unlikely(busValueTtl <= 0))
315  {
316  busValue = 0;
317  busValueTtl = 0;
318  }
319  }
320 }
321 
322 RESID_INLINE
323 int SID::clock(unsigned int cycles, short* buf)
324 {
325  ageBusValue(cycles);
326  int s = 0;
327 
328  while (cycles != 0)
329  {
330  unsigned int delta_t = std::min(nextVoiceSync, cycles);
331 
332  if (likely(delta_t > 0))
333  {
334  for (unsigned int i = 0; i < delta_t; i++)
335  {
336  // clock waveform generators
337  voice[0].wave()->clock();
338  voice[1].wave()->clock();
339  voice[2].wave()->clock();
340 
341  // clock envelope generators
342  voice[0].envelope()->clock();
343  voice[1].envelope()->clock();
344  voice[2].envelope()->clock();
345 
346  const int sidOutput = static_cast<int>(filter->clock(voice[0], voice[1], voice[2]));
347  const int c64Output = externalFilter.clock(sidOutput + INT16_MIN);
348  if (unlikely(resampler->input(c64Output)))
349  {
350  buf[s++] = resampler->getOutput(scaleFactor);
351  }
352  }
353 
354  cycles -= delta_t;
355  nextVoiceSync -= delta_t;
356  }
357 
358  if (unlikely(nextVoiceSync == 0))
359  {
360  voiceSync(true);
361  }
362  }
363 
364  return s;
365 }
366 
367 } // namespace reSIDfp
368 
369 #endif
370 
371 #endif
void clock()
Definition: EnvelopeGenerator.h:177
Definition: ExternalFilter.h:66
int clock(int input)
Definition: ExternalFilter.h:113
Definition: Filter6581.h:321
Definition: Filter.h:38
unsigned short clock(Voice &v1, Voice &v2, Voice &v3)
Definition: Filter.h:207
Definition: Potentiometer.h:38
Definition: SID.h:48
Definition: SID.h:62
void setChipModel(ChipModel model)
Definition: SID.cpp:217
void input(int value)
Definition: SID.cpp:327
unsigned char read(int offset)
Definition: SID.cpp:333
void write(int offset, unsigned char value)
Definition: SID.cpp:368
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency)
Definition: SID.cpp:487
void setFilter6581Range(double adjustment)
Definition: SID.cpp:167
ChipModel getChipModel() const
Definition: SID.h:157
void setCombinedWaveforms(CombinedWaveforms cws)
Definition: SID.cpp:282
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:162
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:172
void enableFilter(bool enable)
Definition: SID.cpp:177
void reset()
Definition: SID.cpp:306
int clock(unsigned int cycles, short *buf)
Definition: SID.h:323
void clockSilent(unsigned int cycles)
Definition: SID.cpp:506
Definition: Voice.h:37
void clock()
Definition: WaveformGenerator.h:287