DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/dbopl.cpp
00001 /*
00002  *  Copyright (C) 2002-2015  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 /*
00020         DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
00021         Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
00022         Except for the table generation it's all integer math
00023         Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
00024         The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
00025         MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
00026 
00027         //TODO Don't delay first operator 1 sample in opl3 mode
00028         //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
00029         //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
00030         //TODO Check if having the same accuracy in all frequency multipliers sounds better or not
00031 
00032         //DUNNO Keyon in 4op, switch to 2op without keyoff.
00033 */
00034 
00035 
00036 
00037 #include <math.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include "dosbox.h"
00041 #include "dbopl.h"
00042 
00043 
00044 #ifndef PI
00045 #define PI 3.14159265358979323846
00046 #endif
00047 
00048 namespace DBOPL {
00049 
00050 #define OPLRATE         ((double)(14318180.0 / 288.0))
00051 #define TREMOLO_TABLE 52
00052 
00053 //Try to use most precision for frequencies
00054 //Else try to keep different waves in synch
00055 //#define WAVE_PRECISION        1
00056 #ifndef WAVE_PRECISION
00057 //Wave bits available in the top of the 32bit range
00058 //Original adlib uses 10.10, we use 10.22
00059 #define WAVE_BITS       10
00060 #else
00061 //Need some extra bits at the top to have room for octaves and frequency multiplier
00062 //We support to 8 times lower rate
00063 //128 * 15 * 8 = 15350, 2^13.9, so need 14 bits
00064 #define WAVE_BITS       14
00065 #endif
00066 #define WAVE_SH         ( 32 - WAVE_BITS )
00067 #define WAVE_MASK       ( ( 1 << WAVE_SH ) - 1 )
00068 
00069 //Use the same accuracy as the waves
00070 #define LFO_SH ( WAVE_SH - 10 )
00071 //LFO is controlled by our tremolo 256 sample limit
00072 #define LFO_MAX ( 256 << ( LFO_SH ) )
00073 
00074 
00075 //Maximum amount of attenuation bits
00076 //Envelope goes to 511, 9 bits
00077 #if (DBOPL_WAVE == WAVE_TABLEMUL )
00078 //Uses the value directly
00079 #define ENV_BITS        ( 9 )
00080 #else
00081 //Add 3 bits here for more accuracy and would have to be shifted up either way
00082 #define ENV_BITS        ( 9 )
00083 #endif
00084 //Limits of the envelope with those bits and when the envelope goes silent
00085 #define ENV_MIN         0
00086 #define ENV_EXTRA       ( ENV_BITS - 9 )
00087 #define ENV_MAX         ( 511 << ENV_EXTRA )
00088 #define ENV_LIMIT       ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
00089 #define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT )
00090 
00091 //Attack/decay/release rate counter shift
00092 #define RATE_SH         24
00093 #define RATE_MASK       ( ( 1 << RATE_SH ) - 1 )
00094 //Has to fit within 16bit lookuptable
00095 #define MUL_SH          16
00096 
00097 //Check some ranges
00098 #if ENV_EXTRA > 3
00099 #error Too many envelope bits
00100 #endif
00101 
00102 
00103 //How much to substract from the base value for the final attenuation
00104 static const Bit8u KslCreateTable[16] = {
00105         //0 will always be be lower than 7 * 8
00106         64, 32, 24, 19, 
00107         16, 12, 11, 10, 
00108          8,  6,  5,  4,
00109          3,  2,  1,  0,
00110 };
00111 
00112 #define M(_X_) ((Bit8u)( (_X_) * 2))
00113 static const Bit8u FreqCreateTable[16] = {
00114         M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ),
00115         M(8  ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15)
00116 };
00117 #undef M
00118 
00119 //We're not including the highest attack rate, that gets a special value
00120 static const Bit8u AttackSamplesTable[13] = {
00121         69, 55, 46, 40,
00122         35, 29, 23, 20,
00123         19, 15, 11, 10,
00124         9
00125 };
00126 //On a real opl these values take 8 samples to reach and are based upon larger tables
00127 static const Bit8u EnvelopeIncreaseTable[13] = {
00128         4,  5,  6,  7,
00129         8, 10, 12, 14,
00130         16, 20, 24, 28,
00131         32, 
00132 };
00133 
00134 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
00135 static Bit16u ExpTable[ 256 ];
00136 #endif
00137 
00138 #if ( DBOPL_WAVE == WAVE_HANDLER )
00139 //PI table used by WAVEHANDLER
00140 static Bit16u SinTable[ 512 ];
00141 #endif
00142 
00143 #if ( DBOPL_WAVE > WAVE_HANDLER )
00144 //Layout of the waveform table in 512 entry intervals
00145 //With overlapping waves we reduce the table to half it's size
00146 
00147 //      |    |//\\|____|WAV7|//__|/\  |____|/\/\|
00148 //      |\\//|    |    |WAV7|    |  \/|    |    |
00149 //      |06  |0126|17  |7   |3   |4   |4 5 |5   |
00150 
00151 //6 is just 0 shifted and masked
00152 
00153 static Bit16s WaveTable[ 8 * 512 ];
00154 //Distance into WaveTable the wave starts
00155 static const Bit16u WaveBaseTable[8] = {
00156         0x000, 0x200, 0x200, 0x800,
00157         0xa00, 0xc00, 0x100, 0x400,
00158 
00159 };
00160 //Mask the counter with this
00161 static const Bit16u WaveMaskTable[8] = {
00162         1023, 1023, 511, 511,
00163         1023, 1023, 512, 1023,
00164 };
00165 
00166 //Where to start the counter on at keyon
00167 static const Bit16u WaveStartTable[8] = {
00168         512, 0, 0, 0,
00169         0, 512, 512, 256,
00170 };
00171 #endif
00172 
00173 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
00174 static Bit16u MulTable[ 384 ];
00175 #endif
00176 
00177 static Bit8u KslTable[ 8 * 16 ];
00178 static Bit8u TremoloTable[ TREMOLO_TABLE ];
00179 //Start of a channel behind the chip struct start
00180 static Bit16u ChanOffsetTable[32];
00181 //Start of an operator behind the chip struct start
00182 static Bit16u OpOffsetTable[64];
00183 
00184 //The lower bits are the shift of the operator vibrato value
00185 //The highest bit is right shifted to generate -1 or 0 for negation
00186 //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
00187 static const Bit8s VibratoTable[ 8 ] = {        
00188         1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, 
00189         1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 
00190 };
00191 
00192 //Shift strength for the ksl value determined by ksl strength
00193 static const Bit8u KslShiftTable[4] = {
00194         31,1,2,0
00195 };
00196 
00197 //Generate a table index and table shift value using input value from a selected rate
00198 static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) {
00199         if ( val < 13 * 4 ) {                           //Rate 0 - 12
00200                 shift = 12 - ( val >> 2 );
00201                 index = val & 3;
00202         } else if ( val < 15 * 4 ) {            //rate 13 - 14
00203                 shift = 0;
00204                 index = val - 12 * 4;
00205         } else {                                                        //rate 15 and up
00206                 shift = 0;
00207                 index = 12;
00208         }
00209 }
00210 
00211 #if ( DBOPL_WAVE == WAVE_HANDLER )
00212 /*
00213         Generate the different waveforms out of the sine/exponetial table using handlers
00214 */
00215 static /*inline*/ Bits MakeVolume( Bitu wave, Bitu volume ) {
00216         Bitu total = wave + volume;
00217         Bitu index = total & 0xff;
00218         Bitu sig = ExpTable[ index ];
00219         Bitu exp = total >> 8;
00220 #if 0
00221         //Check if we overflow the 31 shift limit
00222         if ( exp >= 32 ) {
00223                 LOG_MSG( "WTF %d %d", total, exp );
00224         }
00225 #endif
00226         return (sig >> exp);
00227 };
00228 
00229 static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) {
00230         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00231         Bitu wave = SinTable[i & 511];
00232         return (MakeVolume( wave, volume ) ^ neg) - neg;
00233 }
00234 static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) {
00235         Bit32u wave = SinTable[i & 511];
00236         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00237         return MakeVolume( wave, volume );
00238 }
00239 static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) {
00240         Bitu wave = SinTable[i & 511];
00241         return MakeVolume( wave, volume );
00242 }
00243 static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) {
00244         Bitu wave = SinTable[i & 255];
00245         wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 );
00246         return MakeVolume( wave, volume );
00247 }
00248 static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) {
00249         //Twice as fast
00250         i <<= 1;
00251         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00252         Bitu wave = SinTable[i & 511];
00253         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00254         return (MakeVolume( wave, volume ) ^ neg) - neg;
00255 }
00256 static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) {
00257         //Twice as fast
00258         i <<= 1;
00259         Bitu wave = SinTable[i & 511];
00260         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00261         return MakeVolume( wave, volume );
00262 }
00263 static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) {
00264         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00265         return (MakeVolume( 0, volume ) ^ neg) - neg;
00266 }
00267 static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) {
00268         //Negative is reversed here
00269         Bits neg = (( i >> 9) & 1) - 1;
00270         Bitu wave = (i << 3);
00271         //When negative the volume also runs backwards
00272         wave = ((wave ^ neg) - neg) & 4095;
00273         return (MakeVolume( wave, volume ) ^ neg) - neg;
00274 }
00275 
00276 static const WaveHandler WaveHandlerTable[8] = {
00277         WaveForm0, WaveForm1, WaveForm2, WaveForm3,
00278         WaveForm4, WaveForm5, WaveForm6, WaveForm7
00279 };
00280 
00281 #endif
00282 
00283 /*
00284         Operator
00285 */
00286 
00287 //We zero out when rate == 0
00288 /*inline*/ void Operator::UpdateAttack( const Chip* chip ) {
00289         Bit8u rate = reg60 >> 4;
00290         if ( rate ) {
00291                 Bit8u val = (rate << 2) + ksr;
00292                 attackAdd = chip->attackRates[ val ];
00293                 rateZero &= ~(1 << ATTACK);
00294         } else {
00295                 attackAdd = 0;
00296                 rateZero |= (1 << ATTACK);
00297         }
00298 }
00299 /*inline*/ void Operator::UpdateDecay( const Chip* chip ) {
00300         Bit8u rate = reg60 & 0xf;
00301         if ( rate ) {
00302                 Bit8u val = (rate << 2) + ksr;
00303                 decayAdd = chip->linearRates[ val ];
00304                 rateZero &= ~(1 << DECAY);
00305         } else {
00306                 decayAdd = 0;
00307                 rateZero |= (1 << DECAY);
00308         }
00309 }
00310 /*inline*/ void Operator::UpdateRelease( const Chip* chip ) {
00311         Bit8u rate = reg80 & 0xf;
00312         if ( rate ) {
00313                 Bit8u val = (rate << 2) + ksr;
00314                 releaseAdd = chip->linearRates[ val ];
00315                 rateZero &= ~(1 << RELEASE);
00316                 if ( !(reg20 & MASK_SUSTAIN ) ) {
00317                         rateZero &= ~( 1 << SUSTAIN );
00318                 }       
00319         } else {
00320                 rateZero |= (1 << RELEASE);
00321                 releaseAdd = 0;
00322                 if ( !(reg20 & MASK_SUSTAIN ) ) {
00323                         rateZero |= ( 1 << SUSTAIN );
00324                 }       
00325         }
00326 }
00327 
00328 /*inline*/ void Operator::UpdateAttenuation( ) {
00329         Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff);
00330         Bit32u tl = reg40 & 0x3f;
00331         Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
00332         //Make sure the attenuation goes to the right bits
00333         totalLevel = (Bit32s)(tl << ( ENV_BITS - 7 ));  //Total level goes 2 bits below max
00334         totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift;
00335 }
00336 
00337 void Operator::UpdateFrequency(  ) {
00338         Bit32u freq = chanData & (( 1 << 10 ) - 1);
00339         Bit32u block = (chanData >> 10) & 0xff;
00340 #ifdef WAVE_PRECISION
00341         block = 7u - block;
00342         waveAdd = ( freq * freqMul ) >> block;
00343 #else
00344         waveAdd = ( freq << block ) * freqMul;
00345 #endif
00346         if ( reg20 & MASK_VIBRATO ) {
00347                 vibStrength = (Bit8u)(freq >> 7u);
00348 
00349 #ifdef WAVE_PRECISION
00350                 vibrato = ( (Bitu)vibStrength * freqMul ) >> block;
00351 #else
00352                 vibrato = ( (Bitu)vibStrength << block ) * freqMul;
00353 #endif
00354         } else {
00355                 vibStrength = 0;
00356                 vibrato = 0;
00357         }
00358 }
00359 
00360 void Operator::UpdateRates( const Chip* chip ) {
00361         //Mame seems to reverse this where enabling ksr actually lowers
00362         //the rate, but pdf manuals says otherwise?
00363         Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff);
00364         if ( !( reg20 & MASK_KSR ) ) {
00365                 newKsr >>= 2;
00366         }
00367         if ( ksr == newKsr )
00368                 return;
00369         ksr = newKsr;
00370         UpdateAttack( chip );
00371         UpdateDecay( chip );
00372         UpdateRelease( chip );
00373 }
00374 
00375 /*INLINE*/ Bit32s Operator::RateForward( Bit32u add ) {
00376         rateIndex += add;
00377         Bit32s ret = (Bit32s)(rateIndex >> RATE_SH);
00378         rateIndex = rateIndex & RATE_MASK;
00379         return ret;
00380 }
00381 
00382 template< Operator::State yes>
00383 Bits Operator::TemplateVolume(  ) {
00384         Bit32s vol = volume;
00385         Bit32s change;
00386         switch ( yes ) {
00387         case OFF:
00388                 return ENV_MAX;
00389         case ATTACK:
00390                 change = RateForward( attackAdd );
00391                 if ( !change )
00392                         return vol;
00393                 vol += ( (~vol) * change ) >> 3;
00394                 if ( vol < ENV_MIN ) {
00395                         volume = ENV_MIN;
00396                         rateIndex = 0;
00397                         SetState( DECAY );
00398                         return ENV_MIN;
00399                 }
00400                 break;
00401         case DECAY:
00402                 vol += RateForward( decayAdd );
00403                 if ( GCC_UNLIKELY(vol >= sustainLevel) ) {
00404                         //Check if we didn't overshoot max attenuation, then just go off
00405                         if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
00406                                 volume = ENV_MAX;
00407                                 SetState( OFF );
00408                                 return ENV_MAX;
00409                         }
00410                         //Continue as sustain
00411                         rateIndex = 0;
00412                         SetState( SUSTAIN );
00413                 }
00414                 break;
00415         case SUSTAIN:
00416                 if ( reg20 & MASK_SUSTAIN ) {
00417                         return vol;
00418                 }
00419                 //In sustain phase, but not sustaining, do regular release
00420         case RELEASE: 
00421                 vol += RateForward( releaseAdd );;
00422                 if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
00423                         volume = ENV_MAX;
00424                         SetState( OFF );
00425                         return ENV_MAX;
00426                 }
00427                 break;
00428         }
00429         volume = vol;
00430         return vol;
00431 }
00432 
00433 static const VolumeHandler VolumeHandlerTable[5] = {
00434         &Operator::TemplateVolume< Operator::OFF >,
00435         &Operator::TemplateVolume< Operator::RELEASE >,
00436         &Operator::TemplateVolume< Operator::SUSTAIN >,
00437         &Operator::TemplateVolume< Operator::DECAY >,
00438         &Operator::TemplateVolume< Operator::ATTACK >
00439 };
00440 
00441 /*INLINE*/ Bitu Operator::ForwardVolume() {
00442         return (Bitu)(currentLevel + (this->*volHandler)());
00443 }
00444 
00445 
00446 /*INLINE*/ Bitu Operator::ForwardWave() {
00447         waveIndex += waveCurrent;       
00448         return waveIndex >> WAVE_SH;
00449 }
00450 
00451 void Operator::Write20( const Chip* chip, Bit8u val ) {
00452         Bit8u change = (reg20 ^ val );
00453         if ( !change ) 
00454                 return;
00455         reg20 = val;
00456         //Shift the tremolo bit over the entire register, saved a branch, YES!
00457         tremoloMask = (Bit8s)(val) >> 7;
00458         tremoloMask &= ~(( 1 << ENV_EXTRA ) -1);
00459         //Update specific features based on changes
00460         if ( change & MASK_KSR ) {
00461                 UpdateRates( chip );
00462         }
00463         //With sustain enable the volume doesn't change
00464         if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) {
00465                 rateZero |= ( 1 << SUSTAIN );
00466         } else {
00467                 rateZero &= ~( 1 << SUSTAIN );
00468         }
00469         //Frequency multiplier or vibrato changed
00470         if ( change & (0xf | MASK_VIBRATO) ) {
00471                 freqMul = chip->freqMul[ val & 0xf ];
00472                 UpdateFrequency();
00473         }
00474 }
00475 
00476 void Operator::Write40( const Chip* /*chip*/, Bit8u val ) {
00477         if (!(reg40 ^ val )) 
00478                 return;
00479         reg40 = val;
00480         UpdateAttenuation( );
00481 }
00482 
00483 void Operator::Write60( const Chip* chip, Bit8u val ) {
00484         Bit8u change = reg60 ^ val;
00485         reg60 = val;
00486         if ( change & 0x0f ) {
00487                 UpdateDecay( chip );
00488         }
00489         if ( change & 0xf0 ) {
00490                 UpdateAttack( chip );
00491         }
00492 }
00493 
00494 void Operator::Write80( const Chip* chip, Bit8u val ) {
00495         Bit8u change = (reg80 ^ val );
00496         if ( !change ) 
00497                 return;
00498         reg80 = val;
00499         Bit8u sustain = val >> 4;
00500         //Turn 0xf into 0x1f
00501         sustain |= ( sustain + 1) & 0x10;
00502         sustainLevel = sustain << ( ENV_BITS - 5 );
00503         if ( change & 0x0f ) {
00504                 UpdateRelease( chip );
00505         }
00506 }
00507 
00508 void Operator::WriteE0( const Chip* chip, Bit8u val ) {
00509         if ( !(regE0 ^ val) ) 
00510                 return;
00511         //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
00512         Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) );
00513         regE0 = val;
00514 #if ( DBOPL_WAVE == WAVE_HANDLER )
00515         waveHandler = WaveHandlerTable[ waveForm ];
00516 #else
00517         waveBase = WaveTable + WaveBaseTable[ waveForm ];
00518         waveStart = (Bitu)WaveStartTable[ waveForm ] << WAVE_SH;
00519         waveMask = WaveMaskTable[ waveForm ];
00520 #endif
00521 }
00522 
00523 /*INLINE*/ void Operator::SetState( Bit8u s ) {
00524         state = s;
00525         volHandler = VolumeHandlerTable[ s ];
00526 }
00527 
00528 /*INLINE*/ bool Operator::Silent() const {
00529         if ( !ENV_SILENT( totalLevel + volume ) )
00530                 return false;
00531         if ( !(rateZero & ( 1 << state ) ) )
00532                 return false;
00533         return true;
00534 }
00535 
00536 /*INLINE*/ void Operator::Prepare( const Chip* chip )  {
00537         currentLevel = (Bit32u)(totalLevel + (Bit32s)(chip->tremoloValue & tremoloMask));
00538         waveCurrent = waveAdd;
00539         if ( vibStrength >> chip->vibratoShift ) {
00540                 Bit32s add = (Bit32s)(vibrato >> chip->vibratoShift);
00541                 //Sign extend over the shift value
00542                 Bit32s neg = chip->vibratoSign;
00543                 //Negate the add with -1 or 0
00544                 add = ( add ^ neg ) - neg; 
00545                 waveCurrent += (Bitu)add;
00546         }
00547 }
00548 
00549 void Operator::KeyOn( Bit8u mask ) {
00550         if ( !keyOn ) {
00551                 //Restart the frequency generator
00552 #if ( DBOPL_WAVE > WAVE_HANDLER )
00553                 waveIndex = waveStart;
00554 #else
00555                 waveIndex = 0;
00556 #endif
00557                 rateIndex = 0;
00558                 SetState( ATTACK );
00559         }
00560         keyOn |= mask;
00561 }
00562 
00563 void Operator::KeyOff( Bit8u mask ) {
00564         keyOn &= ~mask;
00565         if ( !keyOn ) {
00566                 if ( state != OFF ) {
00567                         SetState( RELEASE );
00568                 }
00569         }
00570 }
00571 
00572 /*INLINE*/ Bits Operator::GetWave( Bitu index, Bitu vol ) {
00573 #if ( DBOPL_WAVE == WAVE_HANDLER )
00574         return waveHandler( index, vol << ( 3 - ENV_EXTRA ) );
00575 #elif ( DBOPL_WAVE == WAVE_TABLEMUL )
00576         return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
00577 #elif ( DBOPL_WAVE == WAVE_TABLELOG )
00578         Bit32s wave = waveBase[ index & waveMask ];
00579         Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA );
00580         Bit32s sig = ExpTable[ total & 0xff ];
00581         Bit32u exp = total >> 8;
00582         Bit32s neg = wave >> 16;
00583         return ((sig ^ neg) - neg) >> exp;
00584 #else
00585 #error "No valid wave routine"
00586 #endif
00587 }
00588 
00589 Bits /*INLINE*/ Operator::GetSample( Bits modulation ) {
00590         Bitu vol = ForwardVolume();
00591         if ( ENV_SILENT( vol ) ) {
00592                 //Simply forward the wave
00593                 waveIndex += waveCurrent;
00594                 return 0;
00595         } else {
00596                 Bitu index = ForwardWave();
00597                 index += (unsigned long)modulation;
00598                 return GetWave( index, vol );
00599         }
00600 }
00601 
00602 Operator::Operator() {
00603         chanData = 0;
00604         freqMul = 0;
00605         waveIndex = 0;
00606         waveAdd = 0;
00607         waveCurrent = 0;
00608         keyOn = 0;
00609         ksr = 0;
00610         reg20 = 0;
00611         reg40 = 0;
00612         reg60 = 0;
00613         reg80 = 0;
00614         regE0 = 0;
00615         SetState( OFF );
00616         rateZero = (1 << OFF);
00617         sustainLevel = ENV_MAX;
00618         currentLevel = ENV_MAX;
00619         totalLevel = ENV_MAX;
00620         volume = ENV_MAX;
00621         releaseAdd = 0;
00622 }
00623 
00624 /*
00625         Channel
00626 */
00627 
00628 Channel::Channel() {
00629         old[0] = old[1] = 0;
00630         chanData = 0;
00631         regB0 = 0;
00632         regC0 = 0;
00633         maskLeft = -1;
00634         maskRight = -1;
00635         feedback = 31;
00636         fourMask = 0;
00637         synthHandler = &Channel::BlockTemplate< sm2FM >;
00638 }
00639 
00640 void Channel::SetChanData( const Chip* chip, Bit32u data ) {
00641         Bit32u change = chanData ^ data;
00642         chanData = data;
00643         Op( 0 )->chanData = data;
00644         Op( 1 )->chanData = data;
00645         //Since a frequency update triggered this, always update frequency
00646         Op( 0 )->UpdateFrequency();
00647         Op( 1 )->UpdateFrequency();
00648         if ( change & ( 0xffu << SHIFT_KSLBASE ) ) {
00649                 Op( 0 )->UpdateAttenuation();
00650                 Op( 1 )->UpdateAttenuation();
00651         }
00652         if ( change & ( 0xffu << SHIFT_KEYCODE ) ) {
00653                 Op( 0 )->UpdateRates( chip );
00654                 Op( 1 )->UpdateRates( chip );
00655         }
00656 }
00657 
00658 void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) {
00659         //Extrace the frequency bits
00660         Bit32u data = chanData & 0xffff;
00661         Bit32u kslBase = KslTable[ data >> 6 ];
00662         Bit32u keyCode = ( data & 0x1c00) >> 9;
00663         if ( chip->reg08 & 0x40 ) {
00664                 keyCode |= ( data & 0x100)>>8;  /* notesel == 1 */
00665         } else {
00666                 keyCode |= ( data & 0x200)>>9;  /* notesel == 0 */
00667         }
00668         //Add the keycode and ksl into the highest bits of chanData
00669         data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE );
00670         ( this + 0 )->SetChanData( chip, data );
00671         if ( fourOp & 0x3f ) {
00672                 ( this + 1 )->SetChanData( chip, data );
00673         }
00674 }
00675 
00676 void Channel::WriteA0( const Chip* chip, Bit8u val ) {
00677         Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
00678         //Don't handle writes to silent fourop channels
00679         if ( fourOp > 0x80 )
00680                 return;
00681         Bit32u change = (chanData ^ val ) & 0xff;
00682         if ( change ) {
00683                 chanData ^= change;
00684                 UpdateFrequency( chip, fourOp );
00685         }
00686 }
00687 
00688 void Channel::WriteB0( const Chip* chip, Bit8u val ) {
00689         Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
00690         //Don't handle writes to silent fourop channels
00691         if ( fourOp > 0x80 )
00692                 return;
00693         Bitu change = (chanData ^ ( (unsigned int)val << 8u ) ) & 0x1f00u;
00694         if ( change ) {
00695                 chanData ^= change;
00696                 UpdateFrequency( chip, fourOp );
00697         }
00698         //Check for a change in the keyon/off state
00699         if ( !(( val ^ regB0) & 0x20))
00700                 return;
00701         regB0 = val;
00702         if ( val & 0x20 ) {
00703                 Op(0)->KeyOn( 0x1 );
00704                 Op(1)->KeyOn( 0x1 );
00705                 if ( fourOp & 0x3f ) {
00706                         ( this + 1 )->Op(0)->KeyOn( 1 );
00707                         ( this + 1 )->Op(1)->KeyOn( 1 );
00708                 }
00709         } else {
00710                 Op(0)->KeyOff( 0x1 );
00711                 Op(1)->KeyOff( 0x1 );
00712                 if ( fourOp & 0x3f ) {
00713                         ( this + 1 )->Op(0)->KeyOff( 1 );
00714                         ( this + 1 )->Op(1)->KeyOff( 1 );
00715                 }
00716         }
00717 }
00718 
00719 void Channel::WriteC0( const Chip* chip, Bit8u val ) {
00720         Bit8u change = val ^ regC0;
00721         if ( !change )
00722                 return;
00723         regC0 = val;
00724         feedback = ( val >> 1 ) & 7;
00725         if ( feedback ) {
00726                 //We shift the input to the right 10 bit wave index value
00727                 feedback = 9 - feedback;
00728         } else {
00729                 feedback = 31;
00730         }
00731         //Select the new synth mode
00732         if ( chip->opl3Active ) {
00733                 //4-op mode enabled for this channel
00734                 if ( (chip->reg104 & fourMask) & 0x3f ) {
00735                         Channel* chan0, *chan1;
00736                         //Check if it's the 2nd channel in a 4-op
00737                         if ( !(fourMask & 0x80 ) ) {
00738                                 chan0 = this;
00739                                 chan1 = this + 1;
00740                         } else {
00741                                 chan0 = this - 1;
00742                                 chan1 = this;
00743                         }
00744 
00745                         Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 );
00746                         switch ( synth ) {
00747                         case 0:
00748                                 chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
00749                                 break;
00750                         case 1:
00751                                 chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
00752                                 break;
00753                         case 2:
00754                                 chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
00755                                 break;
00756                         case 3:
00757                                 chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
00758                                 break;
00759                         }
00760                 //Disable updating percussion channels
00761                 } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) {
00762 
00763                 //Regular dual op, am or fm
00764                 } else if ( val & 1 ) {
00765                         synthHandler = &Channel::BlockTemplate< sm3AM >;
00766                 } else {
00767                         synthHandler = &Channel::BlockTemplate< sm3FM >;
00768                 }
00769                 maskLeft = ( val & 0x10 ) ? -1 : 0;
00770                 maskRight = ( val & 0x20 ) ? -1 : 0;
00771         //opl2 active
00772         } else { 
00773                 //Disable updating percussion channels
00774                 if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) {
00775 
00776                 //Regular dual op, am or fm
00777                 } else if ( val & 1 ) {
00778                         synthHandler = &Channel::BlockTemplate< sm2AM >;
00779                 } else {
00780                         synthHandler = &Channel::BlockTemplate< sm2FM >;
00781                 }
00782         }
00783 }
00784 
00785 void Channel::ResetC0( const Chip* chip ) {
00786         Bit8u val = regC0;
00787         regC0 ^= 0xff;
00788         WriteC0( chip, val );
00789 }
00790 
00791 template< bool opl3Mode>
00792 /*INLINE*/ void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
00793         Channel* chan = this;
00794 
00795         //BassDrum
00796         Bit32s mod = (Bit32s)((Bit32u)((old[0] + old[1])) >> feedback);
00797         old[0] = old[1];
00798         old[1] = Op(0)->GetSample( mod ); 
00799 
00800         //When bassdrum is in AM mode first operator is ignoed
00801         if ( chan->regC0 & 1 ) {
00802                 mod = 0;
00803         } else {
00804                 mod = old[0];
00805         }
00806         Bit32s sample = Op(1)->GetSample( mod ); 
00807 
00808 
00809         //Precalculate stuff used by other outputs
00810         Bit32u noiseBit = chip->ForwardNoise() & 0x1;
00811         Bit32u c2 = Op(2)->ForwardWave();
00812         Bit32u c5 = Op(5)->ForwardWave();
00813         Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
00814 
00815         //Hi-Hat
00816         Bit32u hhVol = Op(2)->ForwardVolume();
00817         if ( !ENV_SILENT( hhVol ) ) {
00818                 Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 )));
00819                 sample += Op(2)->GetWave( hhIndex, hhVol );
00820         }
00821         //Snare Drum
00822         Bit32u sdVol = Op(3)->ForwardVolume();
00823         if ( !ENV_SILENT( sdVol ) ) {
00824                 Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 );
00825                 sample += Op(3)->GetWave( sdIndex, sdVol );
00826         }
00827         //Tom-tom
00828         sample += Op(4)->GetSample( 0 );
00829 
00830         //Top-Cymbal
00831         Bit32u tcVol = Op(5)->ForwardVolume();
00832         if ( !ENV_SILENT( tcVol ) ) {
00833                 Bit32u tcIndex = (1 + phaseBit) << 8;
00834                 sample += Op(5)->GetWave( tcIndex, tcVol );
00835         }
00836         sample <<= 1;
00837         if ( opl3Mode ) {
00838                 output[0] += sample;
00839                 output[1] += sample;
00840         } else {
00841                 output[0] += sample;
00842         }
00843 }
00844 
00845 template<SynthMode mode>
00846 Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) {
00847         switch( mode ) {
00848         case sm2AM:
00849         case sm3AM:
00850                 if ( Op(0)->Silent() && Op(1)->Silent() ) {
00851                         old[0] = old[1] = 0;
00852                         return (this + 1);
00853                 }
00854                 break;
00855         case sm2FM:
00856         case sm3FM:
00857                 if ( Op(1)->Silent() ) {
00858                         old[0] = old[1] = 0;
00859                         return (this + 1);
00860                 }
00861                 break;
00862         case sm3FMFM:
00863                 if ( Op(3)->Silent() ) {
00864                         old[0] = old[1] = 0;
00865                         return (this + 2);
00866                 }
00867                 break;
00868         case sm3AMFM:
00869                 if ( Op(0)->Silent() && Op(3)->Silent() ) {
00870                         old[0] = old[1] = 0;
00871                         return (this + 2);
00872                 }
00873                 break;
00874         case sm3FMAM:
00875                 if ( Op(1)->Silent() && Op(3)->Silent() ) {
00876                         old[0] = old[1] = 0;
00877                         return (this + 2);
00878                 }
00879                 break;
00880         case sm3AMAM:
00881                 if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) {
00882                         old[0] = old[1] = 0;
00883                         return (this + 2);
00884                 }
00885                 break;
00886         default:
00887                 break;
00888         }
00889         //Init the operators with the the current vibrato and tremolo values
00890         Op( 0 )->Prepare( chip );
00891         Op( 1 )->Prepare( chip );
00892         if ( mode > sm4Start ) {
00893                 Op( 2 )->Prepare( chip );
00894                 Op( 3 )->Prepare( chip );
00895         }
00896         if ( mode > sm6Start ) {
00897                 Op( 4 )->Prepare( chip );
00898                 Op( 5 )->Prepare( chip );
00899         }
00900         for ( Bitu i = 0; i < samples; i++ ) {
00901                 //Early out for percussion handlers
00902                 if ( mode == sm2Percussion ) {
00903                         GeneratePercussion<false>( chip, output + i );
00904                         continue;       //Prevent some unitialized value bitching
00905                 } else if ( mode == sm3Percussion ) {
00906                         GeneratePercussion<true>( chip, output + i * 2 );
00907                         continue;       //Prevent some unitialized value bitching
00908                 }
00909 
00910                 //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
00911                 Bit32s mod = (Bit32s)((Bit32u)((old[0] + old[1])) >> feedback);
00912                 old[0] = old[1];
00913                 old[1] = Op(0)->GetSample( mod );
00914                 Bit32s sample;
00915                 Bit32s out0 = old[0];
00916                 if ( mode == sm2AM || mode == sm3AM ) {
00917                         sample = out0 + Op(1)->GetSample( 0 );
00918                 } else if ( mode == sm2FM || mode == sm3FM ) {
00919                         sample = Op(1)->GetSample( out0 );
00920                 } else if ( mode == sm3FMFM ) {
00921                         Bits next = Op(1)->GetSample( out0 ); 
00922                         next = Op(2)->GetSample( next );
00923                         sample = Op(3)->GetSample( next );
00924                 } else if ( mode == sm3AMFM ) {
00925                         sample = out0;
00926                         Bits next = Op(1)->GetSample( 0 ); 
00927                         next = Op(2)->GetSample( next );
00928                         sample += Op(3)->GetSample( next );
00929                 } else if ( mode == sm3FMAM ) {
00930                         sample = Op(1)->GetSample( out0 );
00931                         Bits next = Op(2)->GetSample( 0 );
00932                         sample += Op(3)->GetSample( next );
00933                 } else if ( mode == sm3AMAM ) {
00934                         sample = out0;
00935                         Bits next = Op(1)->GetSample( 0 ); 
00936                         sample += Op(2)->GetSample( next );
00937                         sample += Op(3)->GetSample( 0 );
00938                 }
00939                 switch( mode ) {
00940                 case sm2AM:
00941                 case sm2FM:
00942                         output[ i ] += sample;
00943                         break;
00944                 case sm3AM:
00945                 case sm3FM:
00946                 case sm3FMFM:
00947                 case sm3AMFM:
00948                 case sm3FMAM:
00949                 case sm3AMAM:
00950                         output[ i * 2 + 0 ] += sample & maskLeft;
00951                         output[ i * 2 + 1 ] += sample & maskRight;
00952                         break;
00953                 default:
00954                         break;
00955                 }
00956         }
00957         switch( mode ) {
00958         case sm2AM:
00959         case sm2FM:
00960         case sm3AM:
00961         case sm3FM:
00962                 return ( this + 1 );
00963         case sm3FMFM:
00964         case sm3AMFM:
00965         case sm3FMAM:
00966         case sm3AMAM:
00967                 return( this + 2 );
00968         case sm2Percussion:
00969         case sm3Percussion:
00970                 return( this + 3 );
00971         }
00972         return 0;
00973 }
00974 
00975 /*
00976         Chip
00977 */
00978 
00979 Chip::Chip() {
00980         reg08 = 0;
00981         reg04 = 0;
00982         regBD = 0;
00983         reg104 = 0;
00984         opl3Active = 0;
00985 }
00986 
00987 /*INLINE*/ Bit32u Chip::ForwardNoise() {
00988         noiseCounter += noiseAdd;
00989         Bitu count = noiseCounter >> LFO_SH;
00990         noiseCounter &= WAVE_MASK;
00991         for ( ; count > 0; --count ) {
00992                 //Noise calculation from mame
00993                 noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) );
00994                 noiseValue >>= 1;
00995         }
00996         return noiseValue;
00997 }
00998 
00999 /*INLINE*/ Bit32u Chip::ForwardLFO( Bit32u samples ) {
01000         //Current vibrato value, runs 4x slower than tremolo
01001         vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7;
01002         vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; 
01003         tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength;
01004 
01005         //Check hom many samples there can be done before the value changes
01006         Bit32u todo = LFO_MAX - lfoCounter;
01007         Bit32u count = (todo + lfoAdd - 1) / lfoAdd;
01008         if ( count > samples ) {
01009                 count = samples;
01010                 lfoCounter += count * lfoAdd;
01011         } else {
01012                 lfoCounter += count * lfoAdd;
01013                 lfoCounter &= (LFO_MAX - 1);
01014                 //Maximum of 7 vibrato value * 4
01015                 vibratoIndex = ( vibratoIndex + 1 ) & 31;
01016                 //Clip tremolo to the the table size
01017                 if ( tremoloIndex + 1 < TREMOLO_TABLE  )
01018                         ++tremoloIndex;
01019                 else
01020                         tremoloIndex = 0;
01021         }
01022         return count;
01023 }
01024 
01025 
01026 void Chip::WriteBD( Bit8u val ) {
01027         Bit8u change = regBD ^ val;
01028         if ( !change )
01029                 return;
01030         regBD = val;
01031         //TODO could do this with shift and xor?
01032         vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
01033         tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
01034         if ( val & 0x20 ) {
01035                 //Drum was just enabled, make sure channel 6 has the right synth
01036                 if ( change & 0x20 ) {
01037                         if ( opl3Active ) {
01038                                 chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; 
01039                         } else {
01040                                 chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; 
01041                         }
01042                 }
01043                 //Bass Drum
01044                 if ( val & 0x10 ) {
01045                         chan[6].op[0].KeyOn( 0x2 );
01046                         chan[6].op[1].KeyOn( 0x2 );
01047                 } else {
01048                         chan[6].op[0].KeyOff( 0x2 );
01049                         chan[6].op[1].KeyOff( 0x2 );
01050                 }
01051                 //Hi-Hat
01052                 if ( val & 0x1 ) {
01053                         chan[7].op[0].KeyOn( 0x2 );
01054                 } else {
01055                         chan[7].op[0].KeyOff( 0x2 );
01056                 }
01057                 //Snare
01058                 if ( val & 0x8 ) {
01059                         chan[7].op[1].KeyOn( 0x2 );
01060                 } else {
01061                         chan[7].op[1].KeyOff( 0x2 );
01062                 }
01063                 //Tom-Tom
01064                 if ( val & 0x4 ) {
01065                         chan[8].op[0].KeyOn( 0x2 );
01066                 } else {
01067                         chan[8].op[0].KeyOff( 0x2 );
01068                 }
01069                 //Top Cymbal
01070                 if ( val & 0x2 ) {
01071                         chan[8].op[1].KeyOn( 0x2 );
01072                 } else {
01073                         chan[8].op[1].KeyOff( 0x2 );
01074                 }
01075         //Toggle keyoffs when we turn off the percussion
01076         } else if ( change & 0x20 ) {
01077                 //Trigger a reset to setup the original synth handler
01078                 chan[6].ResetC0( this );
01079                 chan[6].op[0].KeyOff( 0x2 );
01080                 chan[6].op[1].KeyOff( 0x2 );
01081                 chan[7].op[0].KeyOff( 0x2 );
01082                 chan[7].op[1].KeyOff( 0x2 );
01083                 chan[8].op[0].KeyOff( 0x2 );
01084                 chan[8].op[1].KeyOff( 0x2 );
01085         }
01086 }
01087 
01088 
01089 #define REGOP( _FUNC_ )                                                                                                                 \
01090         index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f );                                                                \
01091         if ( OpOffsetTable[ index ] ) {                                                                                                 \
01092                 Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] );      \
01093                 regOp->_FUNC_( this, val );                                                                                                     \
01094         }
01095 
01096 #define REGCHAN( _FUNC_ )                                                                                                                               \
01097         index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf );                                                                         \
01098         if ( ChanOffsetTable[ index ] ) {                                                                                                       \
01099                 Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] );    \
01100                 regChan->_FUNC_( this, val );                                                                                                   \
01101         }
01102 
01103 void Chip::WriteReg( Bit32u reg, Bit8u val ) {
01104         Bitu index;
01105         switch ( (reg & 0xf0) >> 4 ) {
01106         case 0x00 >> 4:
01107                 if ( reg == 0x01 ) {
01108                         waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; 
01109                 } else if ( reg == 0x104 ) {
01110                         //Only detect changes in lowest 6 bits
01111                         if ( !((reg104 ^ val) & 0x3f) )
01112                                 return;
01113                         //Always keep the highest bit enabled, for checking > 0x80
01114                         reg104 = 0x80 | ( val & 0x3f );
01115                 } else if ( reg == 0x105 ) {
01116                         //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
01117                         if ( !((opl3Active ^ val) & 1 ) )
01118                                 return;
01119                         opl3Active = ( val & 1 ) ? 0xff : 0;
01120                         //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
01121                         for ( int i = 0; i < 18;i++ ) {
01122                                 chan[i].ResetC0( this );
01123                         }
01124                 } else if ( reg == 0x08 ) {
01125                         reg08 = val;
01126                 }
01127         case 0x10 >> 4:
01128                 break;
01129         case 0x20 >> 4:
01130         case 0x30 >> 4:
01131                 REGOP( Write20 );
01132                 break;
01133         case 0x40 >> 4:
01134         case 0x50 >> 4:
01135                 REGOP( Write40 );
01136                 break;
01137         case 0x60 >> 4:
01138         case 0x70 >> 4:
01139                 REGOP( Write60 );
01140                 break;
01141         case 0x80 >> 4:
01142         case 0x90 >> 4:
01143                 REGOP( Write80 );
01144                 break;
01145         case 0xa0 >> 4:
01146                 REGCHAN( WriteA0 );
01147                 break;
01148         case 0xb0 >> 4:
01149                 if ( reg == 0xbd ) {
01150                         WriteBD( val );
01151                 } else {
01152                         REGCHAN( WriteB0 );
01153                 }
01154                 break;
01155         case 0xc0 >> 4:
01156                 REGCHAN( WriteC0 );
01157         case 0xd0 >> 4:
01158                 break;
01159         case 0xe0 >> 4:
01160         case 0xf0 >> 4:
01161                 REGOP( WriteE0 );
01162                 break;
01163         }
01164 }
01165 
01166 
01167 Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
01168         switch ( port & 3 ) {
01169         case 0:
01170                 return val;
01171         case 2:
01172                 if ( opl3Active || (val == 0x05u) )
01173                         return 0x100u | val;
01174                 else 
01175                         return val;
01176         }
01177         return 0u;
01178 }
01179 
01180 void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
01181         while ( total > 0 ) {
01182                 Bit32u samples = ForwardLFO( total );
01183                 memset(output, 0, sizeof(Bit32s) * samples);
01184                 int count = 0;
01185                 for( Channel* ch = chan; ch < chan + 9; ) {
01186                         count++;
01187                         ch = (ch->*(ch->synthHandler))( this, samples, output );
01188                 }
01189                 total -= samples;
01190                 output += samples;
01191         }
01192 }
01193 
01194 void Chip::GenerateBlock3( Bitu total, Bit32s* output  ) {
01195         while ( total > 0 ) {
01196                 Bit32u samples = ForwardLFO( total );
01197                 memset(output, 0, sizeof(Bit32s) * samples *2);
01198                 int count = 0;
01199                 for( Channel* ch = chan; ch < chan + 18; ) {
01200                         count++;
01201                         ch = (ch->*(ch->synthHandler))( this, samples, output );
01202                 }
01203                 total -= samples;
01204                 output += samples * 2;
01205         }
01206 }
01207 
01208 void Chip::Setup( Bit32u rate ) {
01209         double original = OPLRATE;
01210 //      double original = rate;
01211         double scale = original / (double)rate;
01212 
01213         //Noise counter is run at the same precision as general waves
01214         noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
01215         noiseCounter = 0;
01216         noiseValue = 1; //Make sure it triggers the noise xor the first time
01217         //The low frequency oscillation counter
01218         //Every time his overflows vibrato and tremoloindex are increased
01219         lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
01220         lfoCounter = 0;
01221         vibratoIndex = 0;
01222         tremoloIndex = 0;
01223 
01224         //With higher octave this gets shifted up
01225         //-1 since the freqCreateTable = *2
01226 #ifdef WAVE_PRECISION
01227         double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10));
01228         for ( int i = 0; i < 16; i++ ) {
01229                 freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] );
01230         }
01231 #else
01232         Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10)));
01233         for ( int i = 0; i < 16; i++ ) {
01234                 freqMul[i] = freqScale * FreqCreateTable[ i ];
01235         }
01236 #endif
01237 
01238         //-3 since the real envelope takes 8 steps to reach the single value we supply
01239         for ( Bit8u i = 0; i < 76; i++ ) {
01240                 Bit8u index, shift;
01241                 EnvelopeSelect( i, index, shift );
01242                 linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
01243         }
01244         //Generate the best matching attack rate
01245         for ( Bit8u i = 0; i < 62; i++ ) {
01246                 Bit8u index, shift;
01247                 EnvelopeSelect( i, index, shift );
01248                 //Original amount of samples the attack would take
01249                 Bit32s original = (Bit32s)((Bit32u)( (AttackSamplesTable[ index ] << shift) / scale));
01250                  
01251                 Bit32s guessAdd = (Bit32s)((Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))));
01252                 Bit32s bestAdd = guessAdd;
01253                 Bit32u bestDiff = 1 << 30;
01254                 for( Bit32u passes = 0; passes < 16; passes ++ ) {
01255                         Bit32s volume = ENV_MAX;
01256                         Bit32s samples = 0;
01257                         Bit32u count = 0;
01258                         while ( volume > 0 && samples < original * 2 ) {
01259                                 count += (Bit32u)guessAdd;
01260                                 Bit32s change = (Bit32s)(count >> RATE_SH);
01261                                 count &= RATE_MASK;
01262                                 if ( GCC_UNLIKELY(change) ) { // less than 1 % 
01263                                         volume += ( ~volume * change ) >> 3;
01264                                 }
01265                                 samples++;
01266 
01267                         }
01268                         Bit32s diff = original - samples;
01269                         Bit32u lDiff = labs( diff );
01270                         //Init last on first pass
01271                         if ( lDiff < bestDiff ) {
01272                                 bestDiff = lDiff;
01273                                 bestAdd = guessAdd;
01274                                 if ( !bestDiff )
01275                                         break;
01276                         }
01277                         //Below our target
01278                         if ( diff < 0 ) {
01279                                 //Better than the last time
01280                                 Bit32s mul = ((original - diff) << 12) / original;
01281                                 guessAdd = ((guessAdd * mul) >> 12);
01282                                 guessAdd++;
01283                         } else if ( diff > 0 ) {
01284                                 Bit32s mul = ((original - diff) << 12) / original;
01285                                 guessAdd = (guessAdd * mul) >> 12;
01286                                 guessAdd--;
01287                         }
01288                 }
01289                 attackRates[i] = (Bit32u)bestAdd;
01290         }
01291         for ( Bit8u i = 62; i < 76; i++ ) {
01292                 //This should provide instant volume maximizing
01293                 attackRates[i] = 8u << RATE_SH;
01294         }
01295         //Setup the channels with the correct four op flags
01296         //Channels are accessed through a table so they appear linear here
01297         chan[ 0].fourMask = 0x00 | ( 1 << 0 );
01298         chan[ 1].fourMask = 0x80 | ( 1 << 0 );
01299         chan[ 2].fourMask = 0x00 | ( 1 << 1 );
01300         chan[ 3].fourMask = 0x80 | ( 1 << 1 );
01301         chan[ 4].fourMask = 0x00 | ( 1 << 2 );
01302         chan[ 5].fourMask = 0x80 | ( 1 << 2 );
01303 
01304         chan[ 9].fourMask = 0x00 | ( 1 << 3 );
01305         chan[10].fourMask = 0x80 | ( 1 << 3 );
01306         chan[11].fourMask = 0x00 | ( 1 << 4 );
01307         chan[12].fourMask = 0x80 | ( 1 << 4 );
01308         chan[13].fourMask = 0x00 | ( 1 << 5 );
01309         chan[14].fourMask = 0x80 | ( 1 << 5 );
01310 
01311         //mark the percussion channels
01312         chan[ 6].fourMask = 0x40;
01313         chan[ 7].fourMask = 0x40;
01314         chan[ 8].fourMask = 0x40;
01315 
01316         //Clear Everything in opl3 mode
01317         WriteReg( 0x105, 0x1 );
01318         for ( unsigned int i = 0; i < 512; i++ ) {
01319                 if ( i == 0x105 )
01320                         continue;
01321                 WriteReg( i, 0xff );
01322                 WriteReg( i, 0x0 );
01323         }
01324         WriteReg( 0x105, 0x0 );
01325         //Clear everything in opl2 mode
01326         for ( unsigned int i = 0; i < 255; i++ ) {
01327                 WriteReg( i, 0xff );
01328                 WriteReg( i, 0x0 );
01329         }
01330 }
01331 
01332 static bool doneTables = false;
01333 void InitTables( void ) {
01334         if ( doneTables )
01335                 return;
01336         doneTables = true;
01337 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
01338         //Exponential volume table, same as the real adlib
01339         for ( int i = 0; i < 256; i++ ) {
01340                 //Save them in reverse
01341                 ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 );
01342                 ExpTable[i] += 1024; //or remove the -1 oh well :)
01343                 //Preshift to the left once so the final volume can shift to the right
01344                 ExpTable[i] *= 2;
01345         }
01346 #endif
01347 #if ( DBOPL_WAVE == WAVE_HANDLER )
01348         //Add 0.5 for the trunc rounding of the integer cast
01349         //Do a PI sinetable instead of the original 0.5 PI
01350         for ( int i = 0; i < 512; i++ ) {
01351                 SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
01352         }
01353 #endif
01354 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
01355         //Multiplication based tables
01356         for ( int i = 0; i < 384; i++ ) {
01357                 int s = i * 8;
01358                 //TODO maybe keep some of the precision errors of the original table?
01359                 double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
01360                 MulTable[i] = (Bit16u)(val);
01361         }
01362 
01363         //Sine Wave Base
01364         for ( int i = 0; i < 512; i++ ) {
01365                 WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084);
01366                 WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
01367         }
01368         //Exponential wave
01369         for ( int i = 0; i < 256; i++ ) {
01370                 WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
01371                 WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
01372         }
01373 #endif
01374 #if ( DBOPL_WAVE == WAVE_TABLELOG )
01375         //Sine Wave Base
01376         for ( int i = 0; i < 512; i++ ) {
01377                 WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
01378                 WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
01379         }
01380         //Exponential wave
01381         for ( int i = 0; i < 256; i++ ) {
01382                 WaveTable[ 0x700 + i ] = i * 8;
01383                 WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
01384         } 
01385 #endif
01386 
01387         //      |    |//\\|____|WAV7|//__|/\  |____|/\/\|
01388         //      |\\//|    |    |WAV7|    |  \/|    |    |
01389         //      |06  |0126|27  |7   |3   |4   |4 5 |5   |
01390 
01391 #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
01392         for ( int i = 0; i < 256; i++ ) {
01393                 //Fill silence gaps
01394                 WaveTable[ 0x400 + i ] = WaveTable[0];
01395                 WaveTable[ 0x500 + i ] = WaveTable[0];
01396                 WaveTable[ 0x900 + i ] = WaveTable[0];
01397                 WaveTable[ 0xc00 + i ] = WaveTable[0];
01398                 WaveTable[ 0xd00 + i ] = WaveTable[0];
01399                 //Replicate sines in other pieces
01400                 WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
01401                 //double speed sines
01402                 WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
01403                 WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
01404                 WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
01405                 WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
01406         } 
01407 #endif
01408 
01409         //Create the ksl table
01410         for ( int oct = 0; oct < 8; oct++ ) {
01411                 int base = oct * 8;
01412                 for ( int i = 0; i < 16; i++ ) {
01413                         int val = base - KslCreateTable[i];
01414                         if ( val < 0 )
01415                                 val = 0;
01416                         //*4 for the final range to match attenuation range
01417                         KslTable[ oct * 16 + i ] = val * 4;
01418                 }
01419         }
01420         //Create the Tremolo table, just increase and decrease a triangle wave
01421         for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) {
01422                 Bit8u val = i << ENV_EXTRA;
01423                 TremoloTable[i] = val;
01424                 TremoloTable[TREMOLO_TABLE - 1 - i] = val;
01425         }
01426         //Create a table with offsets of the channels from the start of the chip
01427         DBOPL::Chip* chip = 0;
01428         for ( Bitu i = 0; i < 32; i++ ) {
01429                 Bitu index = i & 0xf;
01430                 if ( index >= 9 ) {
01431                         ChanOffsetTable[i] = 0;
01432                         continue;
01433                 }
01434                 //Make sure the four op channels follow eachother
01435                 if ( index < 6 ) {
01436                         index = (index % 3) * 2 + ( index / 3 );
01437                 }
01438                 //Add back the bits for highest ones
01439                 if ( i >= 16 )
01440                         index += 9;
01441                 Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) );
01442                 ChanOffsetTable[i] = blah;
01443         }
01444         //Same for operators
01445         for ( Bitu i = 0; i < 64; i++ ) {
01446                 if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) {
01447                         OpOffsetTable[i] = 0;
01448                         continue;
01449                 }
01450                 Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
01451                 //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
01452                 if ( chNum >= 12 )
01453                         chNum += 16 - 12;
01454                 Bitu opNum = ( i % 8 ) / 3;
01455                 DBOPL::Channel* chan = 0;
01456                 Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) );
01457                 OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah;
01458         }
01459 #if 0
01460         //Stupid checks if table's are correct
01461         for ( Bitu i = 0; i < 18; i++ ) {
01462                 Bit32u find = (Bit16u)( &(chip->chan[ i ]) );
01463                 for ( Bitu c = 0; c < 32; c++ ) {
01464                         if ( ChanOffsetTable[c] == find ) {
01465                                 find = 0;
01466                                 break;
01467                         }
01468                 }
01469                 if ( find ) {
01470                         find = find;
01471                 }
01472         }
01473         for ( Bitu i = 0; i < 36; i++ ) {
01474                 Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) );
01475                 for ( Bitu c = 0; c < 64; c++ ) {
01476                         if ( OpOffsetTable[c] == find ) {
01477                                 find = 0;
01478                                 break;
01479                         }
01480                 }
01481                 if ( find ) {
01482                         find = find;
01483                 }
01484         }
01485 #endif
01486 }
01487 
01488 Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) {
01489         return chip.WriteAddr( port, val );
01490 
01491 }
01492 void Handler::WriteReg( Bit32u addr, Bit8u val ) {
01493         chip.WriteReg( addr, val );
01494 }
01495 
01496 void Handler::Generate( MixerChannel* chan, Bitu samples ) {
01497         Bit32s buffer[ 512 * 2 ];
01498         if ( GCC_UNLIKELY(samples > 512) )
01499                 samples = 512;
01500         if ( !chip.opl3Active ) {
01501                 chip.GenerateBlock2( samples, buffer );
01502                 chan->AddSamples_m32( samples, buffer );
01503         } else {
01504                 chip.GenerateBlock3( samples, buffer );
01505                 chan->AddSamples_s32( samples, buffer );
01506         }
01507 }
01508 
01509 void Handler::Init( Bitu rate ) {
01510         InitTables();
01511         chip.Setup( rate );
01512 }
01513 }
01514