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
35namespace reSIDfp
36{
37
38class Filter;
39class Filter6581;
40class Filter8580;
41class Resampler;
42
46class SIDError
47{
48private:
49 const char* message;
50
51public:
52 SIDError(const char* msg) :
53 message(msg) {}
54 const char* getMessage() const { return message; }
55};
56
60class SID
61{
62private:
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
125private:
131 void ageBusValue(unsigned int n);
132
138 int output();
139
146 void voiceSync(bool sync);
147
148public:
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
310namespace reSIDfp
311{
312
313RESID_INLINE
314void 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
328RESID_INLINE
329int 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
348RESID_INLINE
349int 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
Definition ExternalFilter.h:66
Definition Filter6581.h:321
Definition Filter.h:37
Definition Potentiometer.h:38
Definition Resampler.h:40
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