libresidfp 1.0.2
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
37namespace reSIDfp
38{
39
40class Filter;
41class Filter6581;
42class Filter8580;
43class Resampler;
44
49{
50private:
51 const char* message;
52
53public:
54 explicit SIDError(const char* msg) :
55 message(msg) {}
56 const char* getMessage() const { return message; }
57};
58
62class SID
63{
64private:
66 Filter* filter;
67
69 Filter6581* const filter6581;
70
72 Filter8580* const filter8580;
73
75 std::unique_ptr<Resampler> resampler;
76
81 ExternalFilter externalFilter;
82
84 Voice voice[3];
85
87 int scaleFactor;
88
90 int busValueTtl;
91
93 int modelTTL;
94
96 unsigned int nextVoiceSync;
97
99 ChipModel model;
100
103
105 unsigned char busValue;
106
112 float envDAC[256];
113
119 float oscDAC[4096];
120
121private:
127 void ageBusValue(unsigned int n);
128
135 void voiceSync(bool sync);
136
138 inline void clockWaveGen()
139 {
140 voice[0].wave()->clock();
141 voice[1].wave()->clock();
142 voice[2].wave()->clock();
143 }
144
146 inline void clockEnvGen()
147 {
148 voice[0].envelope()->clock();
149 voice[1].envelope()->clock();
150 voice[2].envelope()->clock();
151 }
152
154 inline int clockFilt()
155 {
156 unsigned short filtOutput = filter->clock(voice[0], voice[1], voice[2]);
157 int exFiltInput = static_cast<int>(filtOutput) + INT16_MIN;
158 return externalFilter.clock(exFiltInput);
159 }
160
161private:
162 SID(const SID&) = delete;
163 SID& operator=(const SID&) = delete;
164
165public:
166 SID();
167 ~SID();
168
175 void setChipModel(ChipModel model);
176
180 ChipModel getChipModel() const { return model; }
181
189
193 void reset();
194
203 void input(int value);
204
225 unsigned char read(int offset);
226
233 void write(int offset, unsigned char value);
234
260 double clockFrequency,
261 SamplingMethod method,
262 double samplingFrequency
263 );
264
272 int clock(unsigned int cycles, short* buf);
273
281 int clock(short* buf, int bufSize);
282
293 void clockSilent(unsigned int cycles);
294
300 void setFilter6581Curve(double filterCurve);
301
307 void setFilter6581Range(double adjustment);
308
314 void setFilter8580Curve(double filterCurve);
315
321 void enableFilter(bool enable);
322
326 void enableOld6581caps(bool enable);
327};
328
329} // namespace reSIDfp
330
331#if RESIDFP_INLINING || defined(SID_CPP)
332
333#include <algorithm>
334
335#include "resample/Resampler.h"
336
337namespace reSIDfp
338{
339
340RESIDFP_INLINE
341void SID::ageBusValue(unsigned int n)
342{
343 if (likely(busValueTtl != 0))
344 {
345 busValueTtl -= n;
346
347 if (unlikely(busValueTtl <= 0))
348 {
349 busValue = 0;
350 busValueTtl = 0;
351 }
352 }
353}
354
355RESIDFP_INLINE
356int SID::clock(unsigned int cycles, short* buf)
357{
358 assert(buf);
359
360 ageBusValue(cycles);
361 int s = 0;
362
363 while (cycles != 0)
364 {
365 unsigned int delta_t = std::min(nextVoiceSync, cycles);
366
367 if (likely(delta_t > 0))
368 {
369 for (unsigned int i = 0; i < delta_t; i++)
370 {
371 clockWaveGen();
372 clockEnvGen();
373
374 int output = clockFilt();
375 if (unlikely(resampler->input(output)))
376 {
377 buf[s++] = resampler->getOutput(scaleFactor);
378 }
379 }
380
381 cycles -= delta_t;
382 nextVoiceSync -= delta_t;
383 }
384
385 if (unlikely(nextVoiceSync == 0))
386 {
387 voiceSync(true);
388 }
389 }
390
391 return s;
392}
393
394RESIDFP_INLINE
395int SID::clock(short* buf, int bufSize)
396{
397 assert(buf);
398 assert(bufSize > 0);
399
400 int cycles = 0;
401
402 for (int s = 0; s < bufSize;)
403 {
404 unsigned int delta_t = nextVoiceSync;
405
406 if (likely(delta_t > 0))
407 {
408 unsigned int i = 0;
409 do
410 {
411 i++;
412 clockWaveGen();
413 clockEnvGen();
414
415 int output = clockFilt();
416 if (unlikely(resampler->input(output)))
417 {
418 buf[s++] = resampler->getOutput(scaleFactor);
419 if (unlikely(s == bufSize))
420 {
421 break;
422 }
423 }
424 }
425 while (i < delta_t);
426
427 cycles += i;
428 nextVoiceSync -= i;
429 }
430
431 if (likely(nextVoiceSync == 0))
432 {
433 voiceSync(true);
434 }
435 }
436
437 ageBusValue(cycles);
438
439 return cycles;
440}
441
442} // namespace reSIDfp
443
444#endif
445
446#endif
void clock()
Definition EnvelopeGenerator.h:177
Definition ExternalFilter.h:85
int clock(int input)
Definition ExternalFilter.h:132
Definition Filter6581.h:321
Definition Filter.h:38
unsigned short clock(Voice &voice1, Voice &voice2, Voice &voice3)
Definition Filter.h:214
Definition SID.h:49
Definition SID.h:63
int clock(unsigned int cycles, short *buf)
Definition SID.h:356
void setChipModel(ChipModel model)
Definition SID.cpp:221
void input(int value)
Definition SID.cpp:331
unsigned char read(int offset)
Definition SID.cpp:337
void write(int offset, unsigned char value)
Definition SID.cpp:372
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency)
Definition SID.cpp:491
void setFilter6581Range(double adjustment)
Definition SID.cpp:166
ChipModel getChipModel() const
Definition SID.h:180
void setCombinedWaveforms(CombinedWaveforms cws)
Definition SID.cpp:286
void setFilter6581Curve(double filterCurve)
Definition SID.cpp:161
void setFilter8580Curve(double filterCurve)
Definition SID.cpp:171
void enableOld6581caps(bool enable)
Definition SID.cpp:182
void enableFilter(bool enable)
Definition SID.cpp:176
void reset()
Definition SID.cpp:310
void clockSilent(unsigned int cycles)
Definition SID.cpp:514
Definition Voice.h:37
void clock()
Definition WaveformGenerator.h:285
SamplingMethod
Definition residfp_defs.h:67
CombinedWaveforms
Definition residfp_defs.h:62
ChipModel
Definition residfp_defs.h:54