DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/mt32/LegacyWaveGenerator.h
00001 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
00002  * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
00003  *
00004  *  This program is free software: you can redistribute it and/or modify
00005  *  it under the terms of the GNU Lesser General Public License as published by
00006  *  the Free Software Foundation, either version 2.1 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Lesser General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Lesser General Public License
00015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #if MT32EMU_ACCURATE_WG == 1
00019 
00020 #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
00021 #define MT32EMU_LA32_WAVE_GENERATOR_H
00022 
00023 namespace MT32Emu {
00024 
00033 class LA32WaveGenerator {
00034         //***************************************************************************
00035         //  The local copy of partial parameters below
00036         //***************************************************************************
00037 
00038         bool active;
00039 
00040         // True means the resulting square wave is to be multiplied by the synchronous cosine
00041         bool sawtoothWaveform;
00042 
00043         // Logarithmic amp of the wave generator
00044         Bit32u amp;
00045 
00046         // Logarithmic frequency of the resulting wave
00047         Bit16u pitch;
00048 
00049         // Values in range [1..31]
00050         // Value 1 correspong to the minimum resonance
00051         Bit8u resonance;
00052 
00053         // Processed value in range [0..255]
00054         // Values in range [0..128] have no effect and the resulting wave remains symmetrical
00055         // Value 255 corresponds to the maximum possible asymmetric of the resulting wave
00056         Bit8u pulseWidth;
00057 
00058         // Composed of the base cutoff in range [78..178] left-shifted by 18 bits and the TVF modifier
00059         Bit32u cutoffVal;
00060 
00061         // Logarithmic PCM sample start address
00062         const Bit16s *pcmWaveAddress;
00063 
00064         // Logarithmic PCM sample length
00065         Bit32u pcmWaveLength;
00066 
00067         // true for looped logarithmic PCM samples
00068         bool pcmWaveLooped;
00069 
00070         // false for slave PCM partials in the structures with the ring modulation
00071         bool pcmWaveInterpolated;
00072 
00073         //***************************************************************************
00074         // Internal variables below
00075         //***************************************************************************
00076 
00077         float wavePos;
00078         float lastFreq;
00079         float pcmPosition;
00080 
00081         float getPCMSample(unsigned int position);
00082 
00083 public:
00084         // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters
00085         void initSynth(const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance);
00086 
00087         // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters
00088         void initPCM(const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped, const bool pcmWaveInterpolated);
00089 
00090         // Update parameters with respect to TVP, TVA and TVF, and generate next sample
00091         float generateNextSample(const Bit32u amp, const Bit16u pitch, const Bit32u cutoff);
00092 
00093         // Deactivate the WG engine
00094         void deactivate();
00095 
00096         // Return active state of the WG engine
00097         bool isActive() const;
00098 
00099         // Return true if the WG engine generates PCM wave samples
00100         bool isPCMWave() const;
00101 };
00102 
00103 // LA32PartialPair contains a structure of two partials being mixed / ring modulated
00104 class LA32PartialPair {
00105         LA32WaveGenerator master;
00106         LA32WaveGenerator slave;
00107         bool ringModulated;
00108         bool mixed;
00109         float masterOutputSample;
00110         float slaveOutputSample;
00111 
00112 public:
00113         enum PairType {
00114                 MASTER,
00115                 SLAVE
00116         };
00117 
00118         // ringModulated should be set to false for the structures with mixing or stereo output
00119         // ringModulated should be set to true for the structures with ring modulation
00120         // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output
00121         void init(const bool ringModulated, const bool mixed);
00122 
00123         // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters
00124         void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance);
00125 
00126         // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters
00127         void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped);
00128 
00129         // Update parameters with respect to TVP, TVA and TVF, and generate next sample
00130         void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff);
00131 
00132         // Perform mixing / ring modulation and return the result
00133         Bit16s nextOutSample();
00134 
00135         // Deactivate the WG engine
00136         void deactivate(const PairType master);
00137 
00138         // Return active state of the WG engine
00139         bool isActive(const PairType master) const;
00140 };
00141 
00142 } // namespace MT32Emu
00143 
00144 #endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
00145 
00146 #endif // #if MT32EMU_ACCURATE_WG == 1