DOSBox-X
|
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