1 /* 2 * Copyright (C) 2002-2010 The DOSBox Team 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19 #if defined(_arch_dreamcast) 20 # include "dc/dc_main.h" 21 #elif !defined(_WIN32) 22 # include <stdint.h> 23 #endif 24 #include "id_sd.h" 25 #include <SDL.h> 26 27 //typedef uintptr_t Bitu; 28 //typedef intptr_t Bits; 29 typedef uint32_t Bitu; 30 typedef int32_t Bits; 31 typedef uint32_t Bit32u; 32 typedef int32_t Bit32s; 33 typedef uint16_t Bit16u; 34 typedef int16_t Bit16s; 35 typedef uint8_t Bit8u; 36 typedef int8_t Bit8s; 37 38 //#include "adlib.h" 39 //#include "dosbox.h" 40 41 //Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume 42 #define WAVE_HANDLER 10 43 //Use a logarithmic wavetable with an exponential table for volume 44 #define WAVE_TABLELOG 11 45 //Use a linear wavetable with a multiply table for volume 46 #define WAVE_TABLEMUL 12 47 48 //Select the type of wave generator routine 49 #define DBOPL_WAVE WAVE_TABLEMUL 50 51 namespace DBOPL { 52 53 struct Chip; 54 struct Operator; 55 struct Channel; 56 57 #if (DBOPL_WAVE == WAVE_HANDLER) 58 typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); 59 #endif 60 61 typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); 62 typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output ); 63 64 //Different synth modes that can generate blocks of data 65 typedef enum { 66 sm2AM, 67 sm2FM, 68 sm3AM, 69 sm3FM, 70 sm4Start, 71 sm3FMFM, 72 sm3AMFM, 73 sm3FMAM, 74 sm3AMAM, 75 sm6Start, 76 sm2Percussion, 77 sm3Percussion, 78 } SynthMode; 79 80 //Shifts for the values contained in chandata variable 81 enum { 82 SHIFT_KSLBASE = 16, 83 SHIFT_KEYCODE = 24, 84 }; 85 86 struct Operator { 87 public: 88 //Masks for operator 20 values 89 enum { 90 MASK_KSR = 0x10, 91 MASK_SUSTAIN = 0x20, 92 MASK_VIBRATO = 0x40, 93 MASK_TREMOLO = 0x80, 94 }; 95 96 typedef enum { 97 OFF, 98 RELEASE, 99 SUSTAIN, 100 DECAY, 101 ATTACK, 102 } State; 103 104 VolumeHandler volHandler; 105 106 #if (DBOPL_WAVE == WAVE_HANDLER) 107 WaveHandler waveHandler; //Routine that generate a wave 108 #else 109 Bit16s* waveBase; 110 Bit32u waveMask; 111 Bit32u waveStart; 112 #endif 113 Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index 114 Bit32u waveAdd; //The base frequency without vibrato 115 Bit32u waveCurrent; //waveAdd + vibratao 116 117 Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this 118 Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? 119 Bit32u vibrato; //Scaled up vibrato strength 120 Bit32s sustainLevel; //When stopping at sustain level stop here 121 Bit32s totalLevel; //totalLevel is added to every generated volume 122 Bit32u currentLevel; //totalLevel + tremolo 123 Bit32s volume; //The currently active volume 124 125 Bit32u attackAdd; //Timers for the different states of the envelope 126 Bit32u decayAdd; 127 Bit32u releaseAdd; 128 Bit32u rateIndex; //Current position of the evenlope 129 130 Bit8u rateZero; //Bits for the different states of the envelope having no changes 131 Bit8u keyOn; //Bitmask of different values that can generate keyon 132 //Registers, also used to check for changes 133 Bit8u reg20, reg40, reg60, reg80, regE0; 134 //Active part of the envelope we're in 135 Bit8u state; 136 //0xff when tremolo is enabled 137 Bit8u tremoloMask; 138 //Strength of the vibrato 139 Bit8u vibStrength; 140 //Keep track of the calculated KSR so we can check for changes 141 Bit8u ksr; 142 private: 143 void SetState( Bit8u s ); 144 void UpdateAttack( const Chip* chip ); 145 void UpdateRelease( const Chip* chip ); 146 void UpdateDecay( const Chip* chip ); 147 public: 148 void UpdateAttenuation(); 149 void UpdateRates( const Chip* chip ); 150 void UpdateFrequency( ); 151 152 void Write20( const Chip* chip, Bit8u val ); 153 void Write40( const Chip* chip, Bit8u val ); 154 void Write60( const Chip* chip, Bit8u val ); 155 void Write80( const Chip* chip, Bit8u val ); 156 void WriteE0( const Chip* chip, Bit8u val ); 157 158 bool Silent() const; 159 void Prepare( const Chip* chip ); 160 161 void KeyOn( Bit8u mask); 162 void KeyOff( Bit8u mask); 163 164 template< State state> 165 Bits TemplateVolume( ); 166 167 Bit32s RateForward( Bit32u add ); 168 Bitu ForwardWave(); 169 Bitu ForwardVolume(); 170 171 Bits GetSample( Bits modulation ); 172 Bits GetWave( Bitu index, Bitu vol ); 173 public: 174 Operator(); 175 }; 176 177 struct Channel { 178 Operator op[2]; OpChannel179 inline Operator* Op( Bitu index ) { 180 return &( ( this + (index >> 1) )->op[ index & 1 ]); 181 } 182 SynthHandler synthHandler; 183 Bit32u chanData; //Frequency/octave and derived values 184 Bit32s old[2]; //Old data for feedback 185 186 Bit8u feedback; //Feedback shift 187 Bit8u regB0; //Register values to check for changes 188 Bit8u regC0; 189 //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel 190 Bit8u fourMask; 191 Bit8s maskLeft; //Sign extended values for both channel's panning 192 Bit8s maskRight; 193 const int *playVolume; // ECWolf 194 195 //Forward the channel data to the operators of the channel 196 void SetChanData( const Chip* chip, Bit32u data ); 197 //Change in the chandata, check for new values and if we have to forward to operators 198 void UpdateFrequency( const Chip* chip, Bit8u fourOp ); 199 void WriteA0( const Chip* chip, Bit8u val ); 200 void WriteB0( const Chip* chip, Bit8u val ); 201 void WriteC0( const Chip* chip, Bit8u val ); 202 void ResetC0( const Chip* chip ); 203 204 //call this for the first channel 205 template< bool opl3Mode > 206 void GeneratePercussion( Chip* chip, Bit32s* output ); 207 208 //Generate blocks of data in specific modes 209 template<SynthMode mode> 210 Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); 211 Channel(); 212 }; 213 214 struct Chip { 215 //This is used as the base counter for vibrato and tremolo 216 Bit32u lfoCounter; 217 Bit32u lfoAdd; 218 219 220 Bit32u noiseCounter; 221 Bit32u noiseAdd; 222 Bit32u noiseValue; 223 224 //Frequency scales for the different multiplications 225 Bit32u freqMul[16]; 226 //Rates for decay and release for rate of this chip 227 Bit32u linearRates[76]; 228 //Best match attack rates for the rate of this chip 229 Bit32u attackRates[76]; 230 231 //18 channels with 2 operators each 232 Channel chan[18]; 233 234 Bit8u reg104; 235 Bit8u reg08; 236 Bit8u reg04; 237 Bit8u regBD; 238 Bit8u vibratoIndex; 239 Bit8u tremoloIndex; 240 Bit8s vibratoSign; 241 Bit8u vibratoShift; 242 Bit8u tremoloValue; 243 Bit8u vibratoStrength; 244 Bit8u tremoloStrength; 245 //Mask for allowed wave forms 246 Bit8u waveFormMask; 247 //0 or -1 when enabled 248 Bit8s opl3Active; 249 const int *volume; // ECWolf 250 251 //Return the maximum amount of samples before and LFO change 252 Bit32u ForwardLFO( Bit32u samples ); 253 Bit32u ForwardNoise(); 254 255 void WriteBD( Bit8u val ); 256 void WriteReg(Bit32u reg, Bit8u val); 257 void SetVolume(const int &volume); 258 259 Bit32u WriteAddr( Bit32u port, Bit8u val ); 260 261 void GenerateBlock2( Bitu samples, Bit32s* output ); 262 void GenerateBlock3( Bitu samples, Bit32s* output ); 263 264 void Generate( Bit32u samples ); 265 void Setup( Bit32u r ); 266 267 Chip(); 268 }; 269 270 /*struct Handler : public Adlib::Handler { 271 DBOPL::Chip chip; 272 virtual Bit32u WriteAddr( Bit32u port, Bit8u val ); 273 virtual void WriteReg( Bit32u addr, Bit8u val ); 274 virtual void Generate( MixerChannel* chan, Bitu samples ); 275 virtual void Init( Bitu rate ); 276 };*/ 277 278 279 }; //Namespace 280