cog/Frameworks/libsidplay/sidplay-residfp-code/.svn/pristine/e0/e050682e30c5da45c8efa9f78e1...

119 lines
3.6 KiB
Plaintext

/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2007-2010 Antti Lankila
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef WAVEFORMCALCULATOR_h
#define WAVEFORMCALCULATOR_h
#include <map>
#include "siddefs-fp.h"
#include "array.h"
namespace reSIDfp
{
/**
* Combined waveform model parameters.
*/
typedef struct
{
float bias;
float pulsestrength;
float topbit;
float distance;
float stmix;
} CombinedWaveformConfig;
/**
* Combined waveform calculator for WaveformGenerator.
* By combining waveforms, the bits of each waveform are effectively short
* circuited. A zero bit in one waveform will result in a zero output bit
* (thus the infamous claim that the waveforms are AND'ed).
* However, a zero bit in one waveform may also affect the neighboring bits
* in the output.
*
* Example:
*
* 1 1
* Bit # 1 0 9 8 7 6 5 4 3 2 1 0
* -----------------------
* Sawtooth 0 0 0 1 1 1 1 1 1 0 0 0
*
* Triangle 0 0 1 1 1 1 1 1 0 0 0 0
*
* AND 0 0 0 1 1 1 1 1 0 0 0 0
*
* Output 0 0 0 0 1 1 1 0 0 0 0 0
*
*
* Re-vectorized die photographs reveal the mechanism behind this behavior.
* Each waveform selector bit acts as a switch, which directly connects
* internal outputs into the waveform DAC inputs as follows:
*
* - Noise outputs the shift register bits to DAC inputs as described above.
* Each output is also used as input to the next bit when the shift register
* is shifted.
* - Pulse connects a single line to all DAC inputs. The line is connected to
* either 5V (pulse on) or 0V (pulse off) at bit 11, and ends at bit 0.
* - Triangle connects the upper 11 bits of the (MSB EOR'ed) accumulator to the
* DAC inputs, so that DAC bit 0 = 0, DAC bit n = accumulator bit n - 1.
* - Sawtooth connects the upper 12 bits of the accumulator to the DAC inputs,
* so that DAC bit n = accumulator bit n. Sawtooth blocks out the MSB from
* the EOR used to generate the triangle waveform.
*
* We can thus draw the following conclusions:
*
* - The shift register may be written to by combined waveforms.
* - The pulse waveform interconnects all bits in combined waveforms via the
* pulse line.
* - The combination of triangle and sawtooth interconnects neighboring bits
* of the sawtooth waveform.
*/
class WaveformCalculator
{
private:
typedef std::map<const CombinedWaveformConfig*, matrix_t> cw_cache_t;
private:
cw_cache_t CACHE;
WaveformCalculator() {}
public:
/**
* Get the singleton instance.
*/
static WaveformCalculator* getInstance();
/**
* Build waveform tables for use by WaveformGenerator.
*
* @param model Chip model to use
* @return Waveform table
*/
matrix_t* buildTable(ChipModel model);
};
} // namespace reSIDfp
#endif