libsidplayfp 1.8.8
SID.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2011-2014 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 "siddefs-fp.h"
27
28namespace reSIDfp
29{
30
31class Filter;
32class Filter6581;
33class Filter8580;
34class ExternalFilter;
35class Potentiometer;
36class Voice;
37class Resampler;
38
43{
44private:
45 const char* message;
46
47public:
48 SIDError(const char* msg) :
49 message(msg) {}
50 const char* getMessage() { return message; }
51};
52
56class SID
57{
58private:
60 static const int BUS_TTL;
61
63 Filter* filter;
64
66 Filter6581* filter6581;
67
69 Filter8580* filter8580;
70
75 ExternalFilter* externalFilter;
76
78 Resampler* resampler;
79
81 Potentiometer* potX;
82
84 Potentiometer* potY;
85
87 Voice* voice[3];
88
90 int busValueTtl;
91
93 int modelTTL;
94
96 int nextVoiceSync;
97
99 int delayedOffset;
100
102 ChipModel model;
103
105 unsigned char delayedValue;
106
108 unsigned char busValue;
109
111 bool muted[3];
112
113private:
120 void writeImmediate(int offset, unsigned char value);
121
127 void ageBusValue(int n);
128
134 int output() const;
135
142 void voiceSync(bool sync);
143
144public:
145 SID();
146 ~SID();
147
153 void setChipModel(ChipModel model);
154
158 ChipModel getChipModel() const { return model; }
159
163 void reset();
164
173 void input(int value);
174
195 unsigned char read(int offset);
196
203 void write(int offset, unsigned char value);
204
211 void mute(int channel, bool enable) { muted[channel] = enable; }
212
237 void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
238
246 int clock(int cycles, short* buf);
247
258 void clockSilent(int cycles);
259
265 void setFilter6581Curve(double filterCurve);
266
272 void setFilter8580Curve(double filterCurve);
273
279 void enableFilter(bool enable);
280};
281
282} // namespace reSIDfp
283
284#if RESID_INLINING || defined(SID_CPP)
285
286#include <algorithm>
287
288#include "Filter.h"
289#include "ExternalFilter.h"
290#include "Voice.h"
291#include "resample/Resampler.h"
292
293namespace reSIDfp
294{
295
296RESID_INLINE
297void SID::ageBusValue(int n)
298{
299 if (likely(busValueTtl != 0))
300 {
301 busValueTtl -= n;
302
303 if (unlikely(busValueTtl <= 0))
304 {
305 busValue = 0;
306 busValueTtl = 0;
307 }
308 }
309}
310
311RESID_INLINE
312int SID::output() const
313{
314 const int v1 = voice[0]->output(voice[2]->wave());
315 const int v2 = voice[1]->output(voice[0]->wave());
316 const int v3 = voice[2]->output(voice[1]->wave());
317
318 return externalFilter->clock(filter->clock(v1, v2, v3));
319}
320
321
322RESID_INLINE
323int SID::clock(int cycles, short* buf)
324{
325 ageBusValue(cycles);
326 int s = 0;
327
328 while (cycles != 0)
329 {
330 int delta_t = std::min(nextVoiceSync, cycles);
331
332 if (likely(delta_t > 0))
333 {
334 if (unlikely(delayedOffset != -1))
335 {
336 delta_t = 1;
337 }
338
339 for (int i = 0; i < delta_t; i++)
340 {
341 /* clock waveform generators */
342 voice[0]->wave()->clock();
343 voice[1]->wave()->clock();
344 voice[2]->wave()->clock();
345
346 /* clock envelope generators */
347 voice[0]->envelope()->clock();
348 voice[1]->envelope()->clock();
349 voice[2]->envelope()->clock();
350
351 if (unlikely(resampler->input(output())))
352 {
353 buf[s++] = resampler->getOutput();
354 }
355 }
356
357 if (unlikely(delayedOffset != -1))
358 {
359 writeImmediate(delayedOffset, delayedValue);
360 delayedOffset = -1;
361 }
362
363 cycles -= delta_t;
364 nextVoiceSync -= delta_t;
365 }
366
367 if (unlikely(nextVoiceSync == 0))
368 {
369 voiceSync(true);
370 }
371 }
372
373 return s;
374}
375
376} // namespace reSIDfp
377
378#endif
379
380#endif
void clock()
Definition: EnvelopeGenerator.h:208
Definition: ExternalFilter.h:48
int clock(int Vi)
Definition: ExternalFilter.h:94
Definition: Filter6581.h:321
Definition: Filter8580.h:86
Definition: Filter.h:33
virtual int clock(int v1, int v2, int v3)=0
Definition: Potentiometer.h:38
Definition: Resampler.h:33
short getOutput() const
Definition: Resampler.h:55
virtual bool input(int sample)=0
Definition: SID.h:43
Definition: SID.h:57
void setChipModel(ChipModel model)
Definition: SID.cpp:248
void input(int value)
Definition: SID.cpp:302
unsigned char read(int offset)
Definition: SID.cpp:308
void clockSilent(int cycles)
Definition: SID.cpp:378
void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency)
Definition: SID.cpp:357
void write(int offset, unsigned char value)
Definition: SID.cpp:341
ChipModel getChipModel() const
Definition: SID.h:158
void setFilter6581Curve(double filterCurve)
Definition: SID.cpp:83
void setFilter8580Curve(double filterCurve)
Definition: SID.cpp:88
void enableFilter(bool enable)
Definition: SID.cpp:93
void reset()
Definition: SID.cpp:280
int clock(int cycles, short *buf)
Definition: SID.h:323
void mute(int channel, bool enable)
Definition: SID.h:211
Definition: Voice.h:37
RESID_INLINE int output(const WaveformGenerator *ringModulator) const
Definition: Voice.h:59
void clock()
Definition: WaveformGenerator.h:282