libresidfp 1.1.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
102 ChipModel model;
103
106
108 uint8_t busValue;
109
111
112 uint8_t paddleX = 0xff;
113 uint8_t paddleY = 0xff;
115
121 float envDAC[256];
122
128 float oscDAC[4096];
129
131 Params* p;
132
133private:
139 void ageBusValue(int n);
140
147 void voiceSync(bool sync);
148
150 inline void clockWaveGen()
151 {
152 voice[0].wave()->clock();
153 voice[1].wave()->clock();
154 voice[2].wave()->clock();
155 }
156
158 inline void clockEnvGen()
159 {
160 voice[0].envelope()->clock();
161 voice[1].envelope()->clock();
162 voice[2].envelope()->clock();
163 }
164
166 inline int32_t clockFilt()
167 {
168 uint16_t filtOutput = filter->clock(voice[0], voice[1], voice[2]);
169 int32_t exFiltInput = static_cast<int32_t>(filtOutput) + INT16_MIN;
170 return externalFilter.clock(exFiltInput);
171 }
172
173private:
174 SID(const SID&) = delete;
175 SID& operator=(const SID&) = delete;
176
177public:
178 SID();
179 ~SID();
180
187 void setChipModel(ChipModel model);
188
192 ChipModel getChipModel() const { return model; }
193
201
205 void reset();
206
215 void input(int value);
216
223 uint8_t peek(int offset) const;
224
245 uint8_t read(int offset);
246
253 void write(int offset, uint8_t value);
254
280 double clockFrequency,
281 SamplingMethod method,
282 double samplingFrequency
283 );
284
292 int clock(unsigned int cycles, int16_t* buf);
293
301 int clock(int16_t* buf, int bufSize);
302
310 void clockDigital(unsigned int cycles);
311
322 void clockSilent(unsigned int cycles);
323
329 void setFilter6581Curve(double filterCurve);
330
336 void setFilter6581Range(double adjustment);
337
343 void setFilter8580Curve(double filterCurve);
344
350 void enableFilter(bool enable);
351
355 void enableOld6581caps(bool enable);
356
360 void setPaddle(uint8_t x, uint8_t y);
361};
362
363} // namespace reSIDfp
364
365#if RESIDFP_INLINING || defined(SID_CPP)
366
367#include <algorithm>
368
369#include "resample/Resampler.h"
370
371namespace reSIDfp
372{
373
374RESIDFP_INLINE
375void SID::ageBusValue(int n)
376{
377 if (likely(busValueTtl != 0))
378 {
379 busValueTtl -= n;
380
381 if (unlikely(busValueTtl <= 0))
382 {
383 busValue = 0;
384 busValueTtl = 0;
385 }
386 }
387}
388
389RESIDFP_INLINE
390int SID::clock(unsigned int cycles, int16_t* buf)
391{
392 assert(buf);
393
394 ageBusValue(cycles);
395 int s = 0;
396
397 while (cycles != 0)
398 {
399 unsigned int delta_t = std::min(nextVoiceSync, cycles);
400
401 if (likely(delta_t > 0))
402 {
403 for (unsigned int i = 0; i < delta_t; i++)
404 {
405 clockWaveGen();
406 clockEnvGen();
407
408 int32_t output = clockFilt();
409 if (unlikely(resampler->input(output)))
410 {
411 buf[s++] = resampler->getOutput(scaleFactor);
412 }
413 }
414
415 cycles -= delta_t;
416 nextVoiceSync -= delta_t;
417 }
418
419 if (unlikely(nextVoiceSync == 0))
420 {
421 voiceSync(true);
422 }
423 }
424
425 return s;
426}
427
428RESIDFP_INLINE
429int SID::clock(int16_t* buf, int bufSize)
430{
431 assert(buf);
432 assert(bufSize > 0);
433
434 int cycles = 0;
435
436 for (int s = 0; s < bufSize;)
437 {
438 unsigned int delta_t = nextVoiceSync;
439
440 if (likely(delta_t > 0))
441 {
442 unsigned int i = 0;
443 do
444 {
445 i++;
446 clockWaveGen();
447 clockEnvGen();
448
449 int32_t output = clockFilt();
450 if (unlikely(resampler->input(output)))
451 {
452 buf[s++] = resampler->getOutput(scaleFactor);
453 if (unlikely(s == bufSize))
454 {
455 break;
456 }
457 }
458 }
459 while (i < delta_t);
460
461 cycles += i;
462 nextVoiceSync -= i;
463 }
464
465 if (likely(nextVoiceSync == 0))
466 {
467 voiceSync(true);
468 }
469 }
470
471 ageBusValue(cycles);
472
473 return cycles;
474}
475
476} // namespace reSIDfp
477
478#endif
479
480#endif
void clock()
Definition EnvelopeGenerator.h:181
Definition ExternalFilter.h:87
int32_t clock(int32_t input)
Definition ExternalFilter.h:136
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:226
uint8_t peek(int offset) const
Definition SID.cpp:344
void input(int value)
Definition SID.cpp:338
int clock(unsigned int cycles, int16_t *buf)
Definition SID.h:390
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency)
Definition SID.cpp:519
void setFilter6581Range(double adjustment)
Definition SID.cpp:168
void setPaddle(uint8_t x, uint8_t y)
Definition SID.cpp:611
ChipModel getChipModel() const
Definition SID.h:192
void clockDigital(unsigned int cycles)
Definition SID.cpp:546
uint8_t read(int offset)
Definition SID.cpp:365
void setCombinedWaveforms(CombinedWaveforms cws)
Definition SID.cpp:293
void setFilter6581Curve(double filterCurve)
Definition SID.cpp:162
void setFilter8580Curve(double filterCurve)
Definition SID.cpp:174
void enableOld6581caps(bool enable)
Definition SID.cpp:186
void enableFilter(bool enable)
Definition SID.cpp:180
void reset()
Definition SID.cpp:317
void write(int offset, uint8_t value)
Definition SID.cpp:400
void clockSilent(unsigned int cycles)
Definition SID.cpp:577
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:47