libsidplayfp 1.0.3
SID.h
00001 /*
00002  * This file is part of libsidplayfp, a SID player engine.
00003  *
00004  * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
00005  * Copyright 2007-2010 Antti Lankila
00006  * Copyright 2004 Dag Lem <resid@nimrod.no>
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021  */
00022 
00023 #ifndef SIDFP_H
00024 #define SIDFP_H
00025 
00026 #include "residfp-config.h"
00027 
00028 namespace reSIDfp
00029 {
00030 
00031 class Filter;
00032 class Filter6581;
00033 class Filter8580;
00034 class ExternalFilter;
00035 class Potentiometer;
00036 class Voice;
00037 class Resampler;
00038 
00042 class SIDError
00043 {
00044 private:
00045     const char* message;
00046 
00047 public:
00048     SIDError(const char* msg) :
00049         message(msg) {}
00050     const char* getMessage() { return message; }
00051 };
00052 
00064 class SID
00065 {
00066 private:
00070     static const int BUS_TTL;
00071 
00073     Filter* filter;
00074 
00076     Filter6581* filter6581;
00077 
00079     Filter8580* filter8580;
00080 
00085     ExternalFilter* externalFilter;
00086 
00090     Resampler* resampler;
00091 
00093     Potentiometer* potX;
00094 
00096     Potentiometer* potY;
00097 
00099     Voice* voice[3];
00100 
00102     int busValueTtl;
00103 
00107     int nextVoiceSync;
00108 
00110     int delayedOffset;
00111 
00115     ChipModel model;
00116 
00118     unsigned char delayedValue;
00119 
00121     unsigned char busValue;
00122 
00123     bool muted[3];
00124 
00125 private:
00132     void writeImmediate(int offset, unsigned char value);
00133 
00139     void ageBusValue(int n);
00140 
00146     int output() const;
00147 
00154     void voiceSync(bool sync);
00155 
00156 public:
00157     SID();
00158     ~SID();
00159 
00165     void setChipModel(ChipModel model);
00166 
00167     ChipModel getChipModel() const { return model; }
00168 
00172     void reset();
00173 
00182     void input(int value);
00183 
00204     unsigned char read(int offset);
00205 
00212     void write(int offset, unsigned char value);
00213 
00220     void mute(int channel, bool enable) { muted[channel] = enable; }
00221 
00246     void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency);
00247 
00255     int clock(int cycles, short* buf);
00256 
00267     void clockSilent(int cycles);
00268 
00274     Filter6581* getFilter6581() const { return filter6581; }
00275 
00281     Filter8580* getFilter8580() const { return filter8580; }
00282 };
00283 
00284 } // namespace reSIDfp
00285 
00286 #if RESID_INLINING || defined(SID_CPP)
00287 
00288 #include <algorithm>
00289 
00290 #include "Filter.h"
00291 #include "ExternalFilter.h"
00292 #include "Voice.h"
00293 #include "resample/Resampler.h"
00294 
00295 namespace reSIDfp
00296 {
00297 RESID_INLINE
00298 int SID::output() const
00299 {
00300     return externalFilter->clock(
00301                filter->clock(
00302                    voice[0]->output(voice[2]->wave()),
00303                    voice[1]->output(voice[0]->wave()),
00304                    voice[2]->output(voice[1]->wave())
00305                )
00306            );
00307 }
00308 
00309 
00310 RESID_INLINE
00311 int SID::clock(int cycles, short* buf)
00312 {
00313     ageBusValue(cycles);
00314     int s = 0;
00315 
00316     while (cycles != 0)
00317     {
00318         int delta_t = std::min(nextVoiceSync, cycles);
00319 
00320         if (delta_t > 0)
00321         {
00322             if (delayedOffset != -1)
00323             {
00324                 delta_t = 1;
00325             }
00326 
00327             for (int i = 0; i < delta_t; i ++)
00328             {
00329                 if (resampler->input(output()))
00330                 {
00331                     buf[s++] = resampler->getOutput();
00332                 }
00333 
00334                 /* clock waveform generators */
00335                 voice[0]->wave()->clock();
00336                 voice[1]->wave()->clock();
00337                 voice[2]->wave()->clock();
00338 
00339                 /* clock envelope generators */
00340                 voice[0]->envelope()->clock();
00341                 voice[1]->envelope()->clock();
00342                 voice[2]->envelope()->clock();
00343             }
00344 
00345             if (delayedOffset != -1)
00346             {
00347                 writeImmediate(delayedOffset, delayedValue);
00348                 delayedOffset = -1;
00349             }
00350 
00351             cycles -= delta_t;
00352             nextVoiceSync -= delta_t;
00353         }
00354 
00355         if (nextVoiceSync == 0)
00356         {
00357             voiceSync(true);
00358         }
00359     }
00360 
00361     return s;
00362 }
00363 
00364 } // namespace reSIDfp
00365 
00366 #endif
00367 
00368 #endif