libresidfp 1.2.1
SID.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2011-2026 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 <cassert>
29#include <cstdint>
30
32#include "siddefs-fp.h"
33#include "ExternalFilter.h"
34#include "Filter.h"
35#include "Voice.h"
36#include "State.h"
37
38namespace reSIDfp
39{
40
41class Filter;
42class Filter6581;
43class Filter8580;
44class Resampler;
45
50{
51private:
52 const char* message;
53
54public:
55 explicit SIDError(const char* msg) :
56 message(msg) {}
57 const char* getMessage() const { return message; }
58};
59
63class SID
64{
65 friend class State;
66
67private:
69 Filter* filter;
70
72 Filter6581* const filter6581;
73
75 Filter8580* const filter8580;
76
78 std::unique_ptr<Resampler> resampler;
79
84 ExternalFilter externalFilter;
85
87 Voice voice[3];
88
90 int scaleFactor;
91
93 int busValueTtl;
94
96 int modelTTL;
97
99 unsigned int nextVoiceSync;
100
101 unsigned int offset_6581;
102
104 ChipModel model;
105
108
109 // Dac leakage
110 double dacLeakage;
111
113 uint8_t busValue;
114
116
117 uint8_t paddleX = 0xff;
118 uint8_t paddleY = 0xff;
120
126 float envDAC[256];
127
133 float oscDAC[4096];
134
136 Params* p;
137
138private:
144 void ageBusValue(int n);
145
152 void voiceSync(bool sync);
153
155 inline void clockWaveGen()
156 {
157 voice[0].wave()->clock();
158 voice[1].wave()->clock();
159 voice[2].wave()->clock();
160 }
161
163 inline void clockEnvGen()
164 {
165 voice[0].envelope()->clock();
166 voice[1].envelope()->clock();
167 voice[2].envelope()->clock();
168 }
169
171 inline int32_t clockFilt()
172 {
173 uint16_t filtOutput = filter->clock(voice[0], voice[1], voice[2]);
174 int32_t exFiltInput = static_cast<int32_t>(filtOutput) + INT16_MIN;
175 return externalFilter.clock(exFiltInput);
176 }
177
178private:
179 SID(const SID&) = delete;
180 SID& operator=(const SID&) = delete;
181
182public:
183 SID();
184 ~SID();
185
192 void setChipModel(ChipModel model);
193
197 ChipModel getChipModel() const { return model; }
198
206
210 void reset();
211
220 void input(int value);
221
228 uint8_t peek(int offset) const;
229
250 uint8_t read(int offset);
251
258 void write(int offset, uint8_t value);
259
285 double clockFrequency,
286 SamplingMethod method,
287 double samplingFrequency
288 );
289
297 int clock(unsigned int cycles, int16_t* buf);
298
306 int clock(int16_t* buf, int bufSize);
307
315 void clockDigital(unsigned int cycles);
316
327 void clockSilent(unsigned int cycles);
328
334 void setFilter6581Curve(double filterCurve);
335
341 void setFilter6581Range(double adjustment);
342
348 void setFilter8580Curve(double filterCurve);
349
355 void enableFilter(bool enable);
356
360 void enableOld6581caps(bool enable);
361
365 void setPaddle(uint8_t x, uint8_t y);
366
367 /*
368 * Set the DAC leakage level.
369 */
370 void setDacLeakage(double level);
371
372 /*
373 * Set the 6581 wave offset.
374 */
375 void setOffset6581(double offset);
376
377 /*
378 * Set the DC-Blocker resistance.
379 */
380 void setDCBRes(double res);
381};
382
383} // namespace reSIDfp
384
385#if RESIDFP_INLINING || defined(SID_CPP)
386
387#include <algorithm>
388
389#include "resample/Resampler.h"
390
391namespace reSIDfp
392{
393
394RESIDFP_INLINE
395void SID::ageBusValue(int n)
396{
397 if (likely(busValueTtl != 0))
398 {
399 busValueTtl -= n;
400
401 if (unlikely(busValueTtl <= 0))
402 {
403 busValue = 0;
404 busValueTtl = 0;
405 }
406 }
407}
408
409RESIDFP_INLINE
410int SID::clock(unsigned int cycles, int16_t* buf)
411{
412 assert(buf);
413
414 ageBusValue(cycles);
415 int s = 0;
416
417 while (cycles != 0)
418 {
419 unsigned int delta_t = std::min(nextVoiceSync, cycles);
420
421 if (likely(delta_t > 0))
422 {
423 for (unsigned int i = 0; i < delta_t; i++)
424 {
425 clockWaveGen();
426 clockEnvGen();
427
428 int32_t output = clockFilt();
429 if (unlikely(resampler->input(output)))
430 {
431 buf[s++] = resampler->getOutput(scaleFactor);
432 }
433 }
434
435 cycles -= delta_t;
436 nextVoiceSync -= delta_t;
437 }
438
439 if (unlikely(nextVoiceSync == 0))
440 {
441 voiceSync(true);
442 }
443 }
444
445 return s;
446}
447
448RESIDFP_INLINE
449int SID::clock(int16_t* buf, int bufSize)
450{
451 assert(buf);
452 assert(bufSize > 0);
453
454 int cycles = 0;
455
456 for (int s = 0; s < bufSize;)
457 {
458 unsigned int delta_t = nextVoiceSync;
459
460 if (likely(delta_t > 0))
461 {
462 unsigned int i = 0;
463 do
464 {
465 i++;
466 clockWaveGen();
467 clockEnvGen();
468
469 int32_t output = clockFilt();
470 if (unlikely(resampler->input(output)))
471 {
472 buf[s++] = resampler->getOutput(scaleFactor);
473 if (unlikely(s == bufSize))
474 {
475 break;
476 }
477 }
478 }
479 while (i < delta_t);
480
481 cycles += i;
482 nextVoiceSync -= i;
483 }
484
485 if (likely(nextVoiceSync == 0))
486 {
487 voiceSync(true);
488 }
489 }
490
491 ageBusValue(cycles);
492
493 return cycles;
494}
495
496} // namespace reSIDfp
497
498#endif
499
500#endif
void clock()
Definition EnvelopeGenerator.h:181
Definition ExternalFilter.h:87
int32_t clock(int32_t input)
Definition ExternalFilter.h:150
Definition Filter6581.h:321
Definition Filter.h:39
uint16_t clock(Voice &voice1, Voice &voice2, Voice &voice3)
Definition Filter.h:216
Definition SID.h:50
Definition SID.h:64
void setChipModel(ChipModel model)
Definition SID.cpp:239
uint8_t peek(int offset) const
Definition SID.cpp:356
void input(int value)
Definition SID.cpp:350
int clock(unsigned int cycles, int16_t *buf)
Definition SID.h:410
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency)
Definition SID.cpp:531
void setFilter6581Range(double adjustment)
Definition SID.cpp:181
void setPaddle(uint8_t x, uint8_t y)
Definition SID.cpp:622
ChipModel getChipModel() const
Definition SID.h:197
void clockDigital(unsigned int cycles)
Definition SID.cpp:557
uint8_t read(int offset)
Definition SID.cpp:377
void setCombinedWaveforms(CombinedWaveforms cws)
Definition SID.cpp:305
void setFilter6581Curve(double filterCurve)
Definition SID.cpp:175
void setFilter8580Curve(double filterCurve)
Definition SID.cpp:187
void enableOld6581caps(bool enable)
Definition SID.cpp:199
void enableFilter(bool enable)
Definition SID.cpp:193
void reset()
Definition SID.cpp:329
void write(int offset, uint8_t value)
Definition SID.cpp:412
void clockSilent(unsigned int cycles)
Definition SID.cpp:588
Definition Voice.h:39
void clock()
Definition WaveformGenerator.h:315
SamplingMethod
Definition residfp_defs.h:67
CombinedWaveforms
Definition residfp_defs.h:62
ChipModel
Definition residfp_defs.h:54
Definition State.h:36
Definition State.h:46