ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

dbopl.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2002-2011  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 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 General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 // Last synch with DOSBox SVN trunk r3752
00020 
00021 #ifndef AUDIO_SOFTSYNTH_OPL_DBOPL_H
00022 #define AUDIO_SOFTSYNTH_OPL_DBOPL_H
00023 
00024 #include "common/scummsys.h"
00025 
00026 #ifndef DISABLE_DOSBOX_OPL
00027 
00028 namespace OPL {
00029 namespace DOSBox {
00030 
00031 //Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
00032 #define WAVE_HANDLER    10
00033 //Use a logarithmic wavetable with an exponential table for volume
00034 #define WAVE_TABLELOG   11
00035 //Use a linear wavetable with a multiply table for volume
00036 #define WAVE_TABLEMUL   12
00037 
00038 //Select the type of wave generator routine
00039 #define DBOPL_WAVE WAVE_TABLEMUL
00040 
00041 namespace DBOPL {
00042 
00043 // Type aliases for the DBOPL code
00044 typedef int Bits;
00045 typedef uint Bitu;
00046 
00047 typedef int8 Bit8s;
00048 typedef uint8 Bit8u;
00049 
00050 typedef int16 Bit16s;
00051 typedef uint16 Bit16u;
00052 
00053 typedef int32 Bit32s;
00054 typedef uint32 Bit32u;
00055 
00056 #define DB_FASTCALL
00057 #define GCC_UNLIKELY(x) (x)
00058 #define INLINE inline
00059 // -------------------------------
00060 
00061 struct Chip;
00062 struct Operator;
00063 struct Channel;
00064 
00065 #if (DBOPL_WAVE == WAVE_HANDLER)
00066 typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
00067 #endif
00068 
00069 typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
00070 typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output );
00071 
00072 //Different synth modes that can generate blocks of data
00073 typedef enum {
00074     sm2AM,
00075     sm2FM,
00076     sm3AM,
00077     sm3FM,
00078     sm4Start,
00079     sm3FMFM,
00080     sm3AMFM,
00081     sm3FMAM,
00082     sm3AMAM,
00083     sm6Start,
00084     sm2Percussion,
00085     sm3Percussion
00086 } SynthMode;
00087 
00088 //Shifts for the values contained in chandata variable
00089 enum {
00090     SHIFT_KSLBASE = 16,
00091     SHIFT_KEYCODE = 24
00092 };
00093 
00094 struct Operator {
00095 public:
00096     //Masks for operator 20 values
00097     enum {
00098         MASK_KSR = 0x10,
00099         MASK_SUSTAIN = 0x20,
00100         MASK_VIBRATO = 0x40,
00101         MASK_TREMOLO = 0x80
00102     };
00103 
00104     typedef enum {
00105         OFF,
00106         RELEASE,
00107         SUSTAIN,
00108         DECAY,
00109         ATTACK
00110     } State;
00111 
00112     VolumeHandler volHandler;
00113 
00114 #if (DBOPL_WAVE == WAVE_HANDLER)
00115     WaveHandler waveHandler;    //Routine that generate a wave
00116 #else
00117     Bit16s* waveBase;
00118     Bit32u waveMask;
00119     Bit32u waveStart;
00120 #endif
00121     Bit32u waveIndex;           //WAVE_BITS shifted counter of the frequency index
00122     Bit32u waveAdd;             //The base frequency without vibrato
00123     Bit32u waveCurrent;         //waveAdd + vibratao
00124 
00125     Bit32u chanData;            //Frequency/octave and derived data coming from whatever channel controls this
00126     Bit32u freqMul;             //Scale channel frequency with this, TODO maybe remove?
00127     Bit32u vibrato;             //Scaled up vibrato strength
00128     Bit32s sustainLevel;        //When stopping at sustain level stop here
00129     Bit32s totalLevel;          //totalLevel is added to every generated volume
00130     Bit32u currentLevel;        //totalLevel + tremolo
00131     Bit32s volume;              //The currently active volume
00132 
00133     Bit32u attackAdd;           //Timers for the different states of the envelope
00134     Bit32u decayAdd;
00135     Bit32u releaseAdd;
00136     Bit32u rateIndex;           //Current position of the evenlope
00137 
00138     Bit8u rateZero;             //Bits for the different states of the envelope having no changes
00139     Bit8u keyOn;                //Bitmask of different values that can generate keyon
00140     //Registers, also used to check for changes
00141     Bit8u reg20, reg40, reg60, reg80, regE0;
00142     //Active part of the envelope we're in
00143     Bit8u state;
00144     //0xff when tremolo is enabled
00145     Bit8u tremoloMask;
00146     //Strength of the vibrato
00147     Bit8u vibStrength;
00148     //Keep track of the calculated KSR so we can check for changes
00149     Bit8u ksr;
00150 private:
00151     void SetState( Bit8u s );
00152     void UpdateAttack( const Chip* chip );
00153     void UpdateRelease( const Chip* chip );
00154     void UpdateDecay( const Chip* chip );
00155 public:
00156     void UpdateAttenuation();
00157     void UpdateRates( const Chip* chip );
00158     void UpdateFrequency( );
00159 
00160     void Write20( const Chip* chip, Bit8u val );
00161     void Write40( const Chip* chip, Bit8u val );
00162     void Write60( const Chip* chip, Bit8u val );
00163     void Write80( const Chip* chip, Bit8u val );
00164     void WriteE0( const Chip* chip, Bit8u val );
00165 
00166     bool Silent() const;
00167     void Prepare( const Chip* chip );
00168 
00169     void KeyOn( Bit8u mask);
00170     void KeyOff( Bit8u mask);
00171 
00172     template< State state>
00173     Bits TemplateVolume( );
00174 
00175     Bit32s RateForward( Bit32u add );
00176     Bitu ForwardWave();
00177     Bitu ForwardVolume();
00178 
00179     Bits GetSample( Bits modulation );
00180     Bits GetWave( Bitu index, Bitu vol );
00181 public:
00182     Operator();
00183 };
00184 
00185 struct Channel {
00186     Operator op[2];
00187     inline Operator* Op( Bitu index ) {
00188         return &( ( this + (index >> 1) )->op[ index & 1 ]);
00189     }
00190     SynthHandler synthHandler;
00191     Bit32u chanData;        //Frequency/octave and derived values
00192     Bit32s old[2];          //Old data for feedback
00193 
00194     Bit8u feedback;         //Feedback shift
00195     Bit8u regB0;            //Register values to check for changes
00196     Bit8u regC0;
00197     //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
00198     Bit8u fourMask;
00199     Bit8s maskLeft;     //Sign extended values for both channel's panning
00200     Bit8s maskRight;
00201 
00202     //Forward the channel data to the operators of the channel
00203     void SetChanData( const Chip* chip, Bit32u data );
00204     //Change in the chandata, check for new values and if we have to forward to operators
00205     void UpdateFrequency( const Chip* chip, Bit8u fourOp );
00206     void WriteA0( const Chip* chip, Bit8u val );
00207     void WriteB0( const Chip* chip, Bit8u val );
00208     void WriteC0( const Chip* chip, Bit8u val );
00209     void ResetC0( const Chip* chip );
00210 
00211     //call this for the first channel
00212     template< bool opl3Mode >
00213     void GeneratePercussion( Chip* chip, Bit32s* output );
00214 
00215     //Generate blocks of data in specific modes
00216     template<SynthMode mode>
00217     Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output );
00218     Channel();
00219 };
00220 
00221 struct Chip {
00222     //This is used as the base counter for vibrato and tremolo
00223     Bit32u lfoCounter;
00224     Bit32u lfoAdd;
00225 
00226 
00227     Bit32u noiseCounter;
00228     Bit32u noiseAdd;
00229     Bit32u noiseValue;
00230 
00231     //Frequency scales for the different multiplications
00232     Bit32u freqMul[16];
00233     //Rates for decay and release for rate of this chip
00234     Bit32u linearRates[76];
00235     //Best match attack rates for the rate of this chip
00236     Bit32u attackRates[76];
00237 
00238     //18 channels with 2 operators each
00239     Channel chan[18];
00240 
00241     Bit8u reg104;
00242     Bit8u reg08;
00243     Bit8u reg04;
00244     Bit8u regBD;
00245     Bit8u vibratoIndex;
00246     Bit8u tremoloIndex;
00247     Bit8s vibratoSign;
00248     Bit8u vibratoShift;
00249     Bit8u tremoloValue;
00250     Bit8u vibratoStrength;
00251     Bit8u tremoloStrength;
00252     //Mask for allowed wave forms
00253     Bit8u waveFormMask;
00254     //0 or -1 when enabled
00255     Bit8s opl3Active;
00256 
00257     //Return the maximum amount of samples before and LFO change
00258     Bit32u ForwardLFO( Bit32u samples );
00259     Bit32u ForwardNoise();
00260 
00261     void WriteBD( Bit8u val );
00262     void WriteReg(Bit32u reg, Bit8u val );
00263 
00264     Bit32u WriteAddr( Bit32u port, Bit8u val );
00265 
00266     void GenerateBlock2( Bitu samples, Bit32s* output );
00267     void GenerateBlock3( Bitu samples, Bit32s* output );
00268 
00269     void Generate( Bit32u samples );
00270     void Setup( Bit32u r );
00271 
00272     Chip();
00273 };
00274 
00275 void InitTables();
00276 
00277 }       //Namespace
00278 } // End of namespace DOSBox
00279 } // End of namespace OPL
00280 
00281 #endif // !DISABLE_DOSBOX_OPL
00282 
00283 #endif


Generated on Sat May 18 2019 05:00:59 for ResidualVM by doxygen 1.7.1
curved edge   curved edge