DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 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 along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 waveBase = 0; 00616 waveMask = 0; 00617 waveStart = 0; 00618 vibrato = 0; 00619 attackAdd = 0; 00620 decayAdd = 0; 00621 rateIndex = 0; 00622 tremoloMask = 0; 00623 vibStrength = 0; 00624 SetState( OFF ); 00625 rateZero = (1 << OFF); 00626 sustainLevel = ENV_MAX; 00627 currentLevel = ENV_MAX; 00628 totalLevel = ENV_MAX; 00629 volume = ENV_MAX; 00630 releaseAdd = 0; 00631 } 00632 00633 /* 00634 Channel 00635 */ 00636 00637 Channel::Channel() { 00638 old[0] = old[1] = 0; 00639 chanData = 0; 00640 regB0 = 0; 00641 regC0 = 0; 00642 maskLeft = -1; 00643 maskRight = -1; 00644 feedback = 31; 00645 fourMask = 0; 00646 synthHandler = &Channel::BlockTemplate< sm2FM >; 00647 } 00648 00649 void Channel::SetChanData( const Chip* chip, Bit32u data ) { 00650 Bit32u change = chanData ^ data; 00651 chanData = data; 00652 Op( 0 )->chanData = data; 00653 Op( 1 )->chanData = data; 00654 //Since a frequency update triggered this, always update frequency 00655 Op( 0 )->UpdateFrequency(); 00656 Op( 1 )->UpdateFrequency(); 00657 if ( change & ( 0xffu << SHIFT_KSLBASE ) ) { 00658 Op( 0 )->UpdateAttenuation(); 00659 Op( 1 )->UpdateAttenuation(); 00660 } 00661 if ( change & ( 0xffu << SHIFT_KEYCODE ) ) { 00662 Op( 0 )->UpdateRates( chip ); 00663 Op( 1 )->UpdateRates( chip ); 00664 } 00665 } 00666 00667 void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) { 00668 //Extrace the frequency bits 00669 Bit32u data = chanData & 0xffff; 00670 Bit32u kslBase = KslTable[ data >> 6 ]; 00671 Bit32u keyCode = ( data & 0x1c00) >> 9; 00672 if ( chip->reg08 & 0x40 ) { 00673 keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ 00674 } else { 00675 keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ 00676 } 00677 //Add the keycode and ksl into the highest bits of chanData 00678 data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); 00679 ( this + 0 )->SetChanData( chip, data ); 00680 if ( fourOp & 0x3f ) { 00681 ( this + 1 )->SetChanData( chip, data ); 00682 } 00683 } 00684 00685 void Channel::WriteA0( const Chip* chip, Bit8u val ) { 00686 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; 00687 //Don't handle writes to silent fourop channels 00688 if ( fourOp > 0x80 ) 00689 return; 00690 Bit32u change = (chanData ^ val ) & 0xff; 00691 if ( change ) { 00692 chanData ^= change; 00693 UpdateFrequency( chip, fourOp ); 00694 } 00695 } 00696 00697 void Channel::WriteB0( const Chip* chip, Bit8u val ) { 00698 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; 00699 //Don't handle writes to silent fourop channels 00700 if ( fourOp > 0x80 ) 00701 return; 00702 Bitu change = (chanData ^ ( (unsigned int)val << 8u ) ) & 0x1f00u; 00703 if ( change ) { 00704 chanData ^= change; 00705 UpdateFrequency( chip, fourOp ); 00706 } 00707 //Check for a change in the keyon/off state 00708 if ( !(( val ^ regB0) & 0x20)) 00709 return; 00710 regB0 = val; 00711 if ( val & 0x20 ) { 00712 Op(0)->KeyOn( 0x1 ); 00713 Op(1)->KeyOn( 0x1 ); 00714 if ( fourOp & 0x3f ) { 00715 ( this + 1 )->Op(0)->KeyOn( 1 ); 00716 ( this + 1 )->Op(1)->KeyOn( 1 ); 00717 } 00718 } else { 00719 Op(0)->KeyOff( 0x1 ); 00720 Op(1)->KeyOff( 0x1 ); 00721 if ( fourOp & 0x3f ) { 00722 ( this + 1 )->Op(0)->KeyOff( 1 ); 00723 ( this + 1 )->Op(1)->KeyOff( 1 ); 00724 } 00725 } 00726 } 00727 00728 void Channel::WriteC0(const Chip* chip, Bit8u val) { 00729 Bit8u change = val ^ regC0; 00730 if (!change) 00731 return; 00732 regC0 = val; 00733 feedback = (regC0 >> 1) & 7; 00734 if (feedback) { 00735 //We shift the input to the right 10 bit wave index value 00736 feedback = 9 - feedback; 00737 } 00738 else { 00739 feedback = 31; 00740 } 00741 UpdateSynth(chip); 00742 } 00743 00744 void Channel::UpdateSynth( const Chip* chip ) { 00745 //Select the new synth mode 00746 if ( chip->opl3Active ) { 00747 //4-op mode enabled for this channel 00748 if ( (chip->reg104 & fourMask) & 0x3f ) { 00749 Channel* chan0, *chan1; 00750 //Check if it's the 2nd channel in a 4-op 00751 if ( !(fourMask & 0x80 ) ) { 00752 chan0 = this; 00753 chan1 = this + 1; 00754 } else { 00755 chan0 = this - 1; 00756 chan1 = this; 00757 } 00758 00759 Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); 00760 switch ( synth ) { 00761 case 0: 00762 chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; 00763 break; 00764 case 1: 00765 chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; 00766 break; 00767 case 2: 00768 chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; 00769 break; 00770 case 3: 00771 chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; 00772 break; 00773 } 00774 //Disable updating percussion channels 00775 } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { 00776 00777 //Regular dual op, am or fm 00778 } else if (regC0 & 1 ) { 00779 synthHandler = &Channel::BlockTemplate< sm3AM >; 00780 } else { 00781 synthHandler = &Channel::BlockTemplate< sm3FM >; 00782 } 00783 maskLeft = (regC0 & 0x10 ) ? -1 : 0; 00784 maskRight = (regC0 & 0x20 ) ? -1 : 0; 00785 //opl2 active 00786 } else { 00787 //Disable updating percussion channels 00788 if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { 00789 00790 //Regular dual op, am or fm 00791 } else if (regC0 & 1 ) { 00792 synthHandler = &Channel::BlockTemplate< sm2AM >; 00793 } else { 00794 synthHandler = &Channel::BlockTemplate< sm2FM >; 00795 } 00796 } 00797 } 00798 00799 template< bool opl3Mode> 00800 /*INLINE*/ void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { 00801 Channel* chan = this; 00802 00803 //BassDrum 00804 Bit32s mod = (Bit32s)((Bit32u)(old[0] + old[1]) >> feedback); 00805 old[0] = old[1]; 00806 old[1] = (Bit32s)Op(0)->GetSample( mod ); 00807 00808 //When bassdrum is in AM mode first operator is ignoed 00809 if ( chan->regC0 & 1 ) { 00810 mod = 0; 00811 } else { 00812 mod = old[0]; 00813 } 00814 Bit32s sample = (Bit32s)Op(1)->GetSample( mod ); 00815 00816 00817 //Precalculate stuff used by other outputs 00818 Bit32u noiseBit = chip->ForwardNoise() & 0x1; 00819 Bit32u c2 = (Bit32u)Op(2)->ForwardWave(); 00820 Bit32u c5 = (Bit32u)Op(5)->ForwardWave(); 00821 Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; 00822 00823 //Hi-Hat 00824 Bit32u hhVol = (Bit32u)Op(2)->ForwardVolume(); 00825 if ( !ENV_SILENT( hhVol ) ) { 00826 Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); 00827 sample += (Bit32s)Op(2)->GetWave( hhIndex, hhVol ); 00828 } 00829 //Snare Drum 00830 Bit32u sdVol = (Bit32u)Op(3)->ForwardVolume(); 00831 if ( !ENV_SILENT( sdVol ) ) { 00832 Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); 00833 sample += (Bit32s)Op(3)->GetWave( sdIndex, sdVol ); 00834 } 00835 //Tom-tom 00836 sample += (Bit32s)Op(4)->GetSample( 0 ); 00837 00838 //Top-Cymbal 00839 Bit32u tcVol = (Bit32u)Op(5)->ForwardVolume(); 00840 if ( !ENV_SILENT( tcVol ) ) { 00841 Bit32u tcIndex = (1 + phaseBit) << 8; 00842 sample += (Bit32s)Op(5)->GetWave( tcIndex, tcVol ); 00843 } 00844 sample <<= 1; 00845 if ( opl3Mode ) { 00846 output[0] += sample; 00847 output[1] += sample; 00848 } else { 00849 output[0] += sample; 00850 } 00851 } 00852 00853 template<SynthMode mode> 00854 Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { 00855 switch( mode ) { 00856 case sm2AM: 00857 case sm3AM: 00858 if ( Op(0)->Silent() && Op(1)->Silent() ) { 00859 old[0] = old[1] = 0; 00860 return (this + 1); 00861 } 00862 break; 00863 case sm2FM: 00864 case sm3FM: 00865 if ( Op(1)->Silent() ) { 00866 old[0] = old[1] = 0; 00867 return (this + 1); 00868 } 00869 break; 00870 case sm3FMFM: 00871 if ( Op(3)->Silent() ) { 00872 old[0] = old[1] = 0; 00873 return (this + 2); 00874 } 00875 break; 00876 case sm3AMFM: 00877 if ( Op(0)->Silent() && Op(3)->Silent() ) { 00878 old[0] = old[1] = 0; 00879 return (this + 2); 00880 } 00881 break; 00882 case sm3FMAM: 00883 if ( Op(1)->Silent() && Op(3)->Silent() ) { 00884 old[0] = old[1] = 0; 00885 return (this + 2); 00886 } 00887 break; 00888 case sm3AMAM: 00889 if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) { 00890 old[0] = old[1] = 0; 00891 return (this + 2); 00892 } 00893 break; 00894 default: 00895 break; 00896 } 00897 //Init the operators with the the current vibrato and tremolo values 00898 Op( 0 )->Prepare( chip ); 00899 Op( 1 )->Prepare( chip ); 00900 if ( mode > sm4Start ) { 00901 Op( 2 )->Prepare( chip ); 00902 Op( 3 )->Prepare( chip ); 00903 } 00904 if ( mode > sm6Start ) { 00905 Op( 4 )->Prepare( chip ); 00906 Op( 5 )->Prepare( chip ); 00907 } 00908 for ( Bitu i = 0; i < samples; i++ ) { 00909 //Early out for percussion handlers 00910 if ( mode == sm2Percussion ) { 00911 GeneratePercussion<false>( chip, output + i ); 00912 continue; //Prevent some unitialized value bitching 00913 } else if ( mode == sm3Percussion ) { 00914 GeneratePercussion<true>( chip, output + i * 2 ); 00915 continue; //Prevent some unitialized value bitching 00916 } 00917 00918 //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise 00919 Bit32s mod = (Bit32s)((Bit32u)((old[0] + old[1])) >> feedback); 00920 old[0] = old[1]; 00921 old[1] = (Bit32s)Op(0)->GetSample( mod ); 00922 Bit32s sample; 00923 Bit32s out0 = old[0]; 00924 if ( mode == sm2AM || mode == sm3AM ) { 00925 sample = (Bit32s)(out0 + Op(1)->GetSample( 0 )); 00926 } else if ( mode == sm2FM || mode == sm3FM ) { 00927 sample = (Bit32s)Op(1)->GetSample( out0 ); 00928 } else if ( mode == sm3FMFM ) { 00929 Bits next = Op(1)->GetSample( out0 ); 00930 next = Op(2)->GetSample( next ); 00931 sample = (Bit32s)Op(3)->GetSample( next ); 00932 } else if ( mode == sm3AMFM ) { 00933 sample = out0; 00934 Bits next = Op(1)->GetSample( 0 ); 00935 next = Op(2)->GetSample( next ); 00936 sample += (Bit32s)Op(3)->GetSample( next ); 00937 } else if ( mode == sm3FMAM ) { 00938 sample = (Bit32s)Op(1)->GetSample( out0 ); 00939 Bits next = Op(2)->GetSample( 0 ); 00940 sample += (Bit32s)Op(3)->GetSample( next ); 00941 } else if ( mode == sm3AMAM ) { 00942 sample = out0; 00943 Bits next = Op(1)->GetSample( 0 ); 00944 sample += (Bit32s)Op(2)->GetSample( next ); 00945 sample += (Bit32s)Op(3)->GetSample( 0 ); 00946 } 00947 switch( mode ) { 00948 case sm2AM: 00949 case sm2FM: 00950 output[ i ] += sample; 00951 break; 00952 case sm3AM: 00953 case sm3FM: 00954 case sm3FMFM: 00955 case sm3AMFM: 00956 case sm3FMAM: 00957 case sm3AMAM: 00958 output[ i * 2 + 0 ] += sample & maskLeft; 00959 output[ i * 2 + 1 ] += sample & maskRight; 00960 break; 00961 default: 00962 break; 00963 } 00964 } 00965 switch( mode ) { 00966 case sm2AM: 00967 case sm2FM: 00968 case sm3AM: 00969 case sm3FM: 00970 return ( this + 1 ); 00971 case sm3FMFM: 00972 case sm3AMFM: 00973 case sm3FMAM: 00974 case sm3AMAM: 00975 return( this + 2 ); 00976 case sm2Percussion: 00977 case sm3Percussion: 00978 return( this + 3 ); 00979 } 00980 return 0; 00981 } 00982 00983 /* 00984 Chip 00985 */ 00986 00987 Chip::Chip() { 00988 reg08 = 0; 00989 reg04 = 0; 00990 regBD = 0; 00991 reg104 = 0; 00992 opl3Active = 0; 00993 } 00994 00995 /*INLINE*/ Bit32u Chip::ForwardNoise() { 00996 noiseCounter += noiseAdd; 00997 Bitu count = noiseCounter >> LFO_SH; 00998 noiseCounter &= WAVE_MASK; 00999 for ( ; count > 0; --count ) { 01000 //Noise calculation from mame 01001 noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) ); 01002 noiseValue >>= 1; 01003 } 01004 return noiseValue; 01005 } 01006 01007 /*INLINE*/ Bit32u Chip::ForwardLFO( Bit32u samples ) { 01008 //Current vibrato value, runs 4x slower than tremolo 01009 vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7; 01010 vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; 01011 tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength; 01012 01013 //Check hom many samples there can be done before the value changes 01014 Bit32u todo = LFO_MAX - lfoCounter; 01015 Bit32u count = (todo + lfoAdd - 1) / lfoAdd; 01016 if ( count > samples ) { 01017 count = samples; 01018 lfoCounter += count * lfoAdd; 01019 } else { 01020 lfoCounter += count * lfoAdd; 01021 lfoCounter &= (LFO_MAX - 1); 01022 //Maximum of 7 vibrato value * 4 01023 vibratoIndex = ( vibratoIndex + 1 ) & 31; 01024 //Clip tremolo to the the table size 01025 if ( tremoloIndex + 1 < TREMOLO_TABLE ) 01026 ++tremoloIndex; 01027 else 01028 tremoloIndex = 0; 01029 } 01030 return count; 01031 } 01032 01033 01034 void Chip::WriteBD( Bit8u val ) { 01035 Bit8u change = regBD ^ val; 01036 if ( !change ) 01037 return; 01038 regBD = val; 01039 //TODO could do this with shift and xor? 01040 vibratoStrength = (val & 0x40) ? 0x00 : 0x01; 01041 tremoloStrength = (val & 0x80) ? 0x00 : 0x02; 01042 if ( val & 0x20 ) { 01043 //Drum was just enabled, make sure channel 6 has the right synth 01044 if ( change & 0x20 ) { 01045 if ( opl3Active ) { 01046 chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; 01047 } else { 01048 chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; 01049 } 01050 } 01051 //Bass Drum 01052 if ( val & 0x10 ) { 01053 chan[6].op[0].KeyOn( 0x2 ); 01054 chan[6].op[1].KeyOn( 0x2 ); 01055 } else { 01056 chan[6].op[0].KeyOff( 0x2 ); 01057 chan[6].op[1].KeyOff( 0x2 ); 01058 } 01059 //Hi-Hat 01060 if ( val & 0x1 ) { 01061 chan[7].op[0].KeyOn( 0x2 ); 01062 } else { 01063 chan[7].op[0].KeyOff( 0x2 ); 01064 } 01065 //Snare 01066 if ( val & 0x8 ) { 01067 chan[7].op[1].KeyOn( 0x2 ); 01068 } else { 01069 chan[7].op[1].KeyOff( 0x2 ); 01070 } 01071 //Tom-Tom 01072 if ( val & 0x4 ) { 01073 chan[8].op[0].KeyOn( 0x2 ); 01074 } else { 01075 chan[8].op[0].KeyOff( 0x2 ); 01076 } 01077 //Top Cymbal 01078 if ( val & 0x2 ) { 01079 chan[8].op[1].KeyOn( 0x2 ); 01080 } else { 01081 chan[8].op[1].KeyOff( 0x2 ); 01082 } 01083 //Toggle keyoffs when we turn off the percussion 01084 } else if ( change & 0x20 ) { 01085 //Trigger a reset to setup the original synth handler 01086 //This makes it call 01087 chan[6].UpdateSynth( this ); 01088 chan[6].op[0].KeyOff( 0x2 ); 01089 chan[6].op[1].KeyOff( 0x2 ); 01090 chan[7].op[0].KeyOff( 0x2 ); 01091 chan[7].op[1].KeyOff( 0x2 ); 01092 chan[8].op[0].KeyOff( 0x2 ); 01093 chan[8].op[1].KeyOff( 0x2 ); 01094 } 01095 } 01096 01097 01098 #define REGOP( _FUNC_ ) \ 01099 index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ 01100 if ( OpOffsetTable[ index ] ) { \ 01101 Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ 01102 regOp->_FUNC_( this, val ); \ 01103 } 01104 01105 #define REGCHAN( _FUNC_ ) \ 01106 index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ 01107 if ( ChanOffsetTable[ index ] ) { \ 01108 Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ 01109 regChan->_FUNC_( this, val ); \ 01110 } 01111 01112 //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers 01113 void Chip::UpdateSynths() { 01114 for (int i = 0; i < 18; i++) { 01115 chan[i].UpdateSynth(this); 01116 } 01117 } 01118 01119 void Chip::WriteReg( Bit32u reg, Bit8u val ) { 01120 Bitu index; 01121 switch ( (reg & 0xf0) >> 4 ) { 01122 case 0x00 >> 4: 01123 if ( reg == 0x01 ) { 01124 waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; 01125 } else if ( reg == 0x104 ) { 01126 //Only detect changes in lowest 6 bits 01127 if ( !((reg104 ^ val) & 0x3f) ) 01128 return; 01129 //Always keep the highest bit enabled, for checking > 0x80 01130 reg104 = 0x80 | ( val & 0x3f ); 01131 //Switch synths when changing the 4op combinations 01132 UpdateSynths(); 01133 } else if ( reg == 0x105 ) { 01134 //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register 01135 if ( !((opl3Active ^ val) & 1 ) ) 01136 return; 01137 opl3Active = ( val & 1 ) ? 0xff : 0; 01138 //Just update the synths now that opl3 must have been enabled 01139 //This isn't how the real card handles it but need to switch to stereo generating handlers 01140 UpdateSynths(); 01141 } else if ( reg == 0x08 ) { 01142 reg08 = val; 01143 } 01144 case 0x10 >> 4: 01145 break; 01146 case 0x20 >> 4: 01147 case 0x30 >> 4: 01148 REGOP( Write20 ); 01149 break; 01150 case 0x40 >> 4: 01151 case 0x50 >> 4: 01152 REGOP( Write40 ); 01153 break; 01154 case 0x60 >> 4: 01155 case 0x70 >> 4: 01156 REGOP( Write60 ); 01157 break; 01158 case 0x80 >> 4: 01159 case 0x90 >> 4: 01160 REGOP( Write80 ); 01161 break; 01162 case 0xa0 >> 4: 01163 REGCHAN( WriteA0 ); 01164 break; 01165 case 0xb0 >> 4: 01166 if ( reg == 0xbd ) { 01167 WriteBD( val ); 01168 } else { 01169 REGCHAN( WriteB0 ); 01170 } 01171 break; 01172 case 0xc0 >> 4: 01173 REGCHAN( WriteC0 ); 01174 case 0xd0 >> 4: 01175 break; 01176 case 0xe0 >> 4: 01177 case 0xf0 >> 4: 01178 REGOP( WriteE0 ); 01179 break; 01180 } 01181 } 01182 01183 01184 Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { 01185 switch ( port & 3 ) { 01186 case 0: 01187 return val; 01188 case 2: 01189 if ( opl3Active || (val == 0x05u) ) 01190 return 0x100u | val; 01191 else 01192 return val; 01193 } 01194 return 0u; 01195 } 01196 01197 void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { 01198 while ( total > 0 ) { 01199 Bit32u samples = ForwardLFO( (Bit32u)total ); 01200 memset(output, 0, sizeof(Bit32s) * samples); 01201 // int count = 0; 01202 for( Channel* ch = chan; ch < chan + 9; ) { 01203 // count++; 01204 ch = (ch->*(ch->synthHandler))( this, samples, output ); 01205 } 01206 total -= samples; 01207 output += samples; 01208 } 01209 } 01210 01211 void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { 01212 while ( total > 0 ) { 01213 Bit32u samples = ForwardLFO( (Bit32u)total ); 01214 memset(output, 0, sizeof(Bit32s) * samples *2); 01215 // int count = 0; 01216 for( Channel* ch = chan; ch < chan + 18; ) { 01217 // count++; 01218 ch = (ch->*(ch->synthHandler))( this, samples, output ); 01219 } 01220 total -= samples; 01221 output += samples * 2; 01222 } 01223 } 01224 01225 void Chip::Setup( Bit32u rate ) { 01226 double original = OPLRATE; 01227 // double original = rate; 01228 double scale = original / (double)rate; 01229 01230 //Noise counter is run at the same precision as general waves 01231 noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); 01232 noiseCounter = 0; 01233 noiseValue = 1; //Make sure it triggers the noise xor the first time 01234 //The low frequency oscillation counter 01235 //Every time his overflows vibrato and tremoloindex are increased 01236 lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); 01237 lfoCounter = 0; 01238 vibratoIndex = 0; 01239 tremoloIndex = 0; 01240 01241 //With higher octave this gets shifted up 01242 //-1 since the freqCreateTable = *2 01243 #ifdef WAVE_PRECISION 01244 double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); 01245 for ( int i = 0; i < 16; i++ ) { 01246 freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); 01247 } 01248 #else 01249 Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); 01250 for ( int i = 0; i < 16; i++ ) { 01251 freqMul[i] = freqScale * FreqCreateTable[ i ]; 01252 } 01253 #endif 01254 01255 //-3 since the real envelope takes 8 steps to reach the single value we supply 01256 for ( Bit8u i = 0; i < 76; i++ ) { 01257 Bit8u index, shift; 01258 EnvelopeSelect( i, index, shift ); 01259 linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); 01260 } 01261 // Bit32s attackDiffs[62]; 01262 //Generate the best matching attack rate 01263 for ( Bit8u i = 0; i < 62; i++ ) { 01264 Bit8u index, shift; 01265 EnvelopeSelect( i, index, shift ); 01266 //Original amount of samples the attack would take 01267 Bit32s originalAmount = (Bit32s)((Bit32u)( (AttackSamplesTable[ index ] << shift) / scale)); 01268 01269 Bit32s guessAdd = (Bit32s)((Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 )))); 01270 Bit32s bestAdd = guessAdd; 01271 Bit32u bestDiff = 1 << 30; 01272 for( Bit32u passes = 0; passes < 16; passes ++ ) { 01273 Bit32s volume = ENV_MAX; 01274 Bit32s samples = 0; 01275 Bit32u count = 0; 01276 while ( volume > 0 && samples < originalAmount * 2 ) { 01277 count += (Bit32u)guessAdd; 01278 Bit32s change = (Bit32s)(count >> RATE_SH); 01279 count &= RATE_MASK; 01280 if ( GCC_UNLIKELY(change) ) { // less than 1 % 01281 volume += ( ~volume * change ) >> 3; 01282 } 01283 samples++; 01284 01285 } 01286 Bit32s diff = originalAmount - samples; 01287 Bit32u lDiff = labs( diff ); 01288 //Init last on first pass 01289 if ( lDiff < bestDiff ) { 01290 bestDiff = lDiff; 01291 bestAdd = guessAdd; 01292 //We hit an exactly matching sample count 01293 if ( !bestDiff ) 01294 break; 01295 } 01296 //Linear correction factor, not exactly perfect but seems to work 01297 double correct = (originalAmount - diff) / (double)originalAmount; 01298 guessAdd = (Bit32s)(guessAdd * correct); 01299 //Below our target 01300 if ( diff < 0 ) { 01301 //Always add one here for rounding, an overshoot will get corrected by another pass decreasing 01302 guessAdd++; 01303 } 01304 } 01305 attackRates[i] = (Bit32u)bestAdd; 01306 //Keep track of the diffs for some debugging 01307 // attackDiffs[i] = bestDiff; 01308 } 01309 for ( Bit8u i = 62; i < 76; i++ ) { 01310 //This should provide instant volume maximizing 01311 attackRates[i] = 8u << RATE_SH; 01312 } 01313 //Setup the channels with the correct four op flags 01314 //Channels are accessed through a table so they appear linear here 01315 chan[ 0].fourMask = 0x00 | ( 1 << 0 ); 01316 chan[ 1].fourMask = 0x80 | ( 1 << 0 ); 01317 chan[ 2].fourMask = 0x00 | ( 1 << 1 ); 01318 chan[ 3].fourMask = 0x80 | ( 1 << 1 ); 01319 chan[ 4].fourMask = 0x00 | ( 1 << 2 ); 01320 chan[ 5].fourMask = 0x80 | ( 1 << 2 ); 01321 01322 chan[ 9].fourMask = 0x00 | ( 1 << 3 ); 01323 chan[10].fourMask = 0x80 | ( 1 << 3 ); 01324 chan[11].fourMask = 0x00 | ( 1 << 4 ); 01325 chan[12].fourMask = 0x80 | ( 1 << 4 ); 01326 chan[13].fourMask = 0x00 | ( 1 << 5 ); 01327 chan[14].fourMask = 0x80 | ( 1 << 5 ); 01328 01329 //mark the percussion channels 01330 chan[ 6].fourMask = 0x40; 01331 chan[ 7].fourMask = 0x40; 01332 chan[ 8].fourMask = 0x40; 01333 01334 //Clear Everything in opl3 mode 01335 WriteReg( 0x105, 0x1 ); 01336 for ( unsigned int i = 0; i < 512; i++ ) { 01337 if ( i == 0x105 ) 01338 continue; 01339 WriteReg( i, 0xff ); 01340 WriteReg( i, 0x0 ); 01341 } 01342 WriteReg( 0x105, 0x0 ); 01343 //Clear everything in opl2 mode 01344 for ( unsigned int i = 0; i < 255; i++ ) { 01345 WriteReg( i, 0xff ); 01346 WriteReg( i, 0x0 ); 01347 } 01348 } 01349 01350 static bool doneTables = false; 01351 void InitTables( void ) { 01352 if ( doneTables ) 01353 return; 01354 doneTables = true; 01355 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) 01356 //Exponential volume table, same as the real adlib 01357 for ( int i = 0; i < 256; i++ ) { 01358 //Save them in reverse 01359 ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); 01360 ExpTable[i] += 1024; //or remove the -1 oh well :) 01361 //Preshift to the left once so the final volume can shift to the right 01362 ExpTable[i] *= 2; 01363 } 01364 #endif 01365 #if ( DBOPL_WAVE == WAVE_HANDLER ) 01366 //Add 0.5 for the trunc rounding of the integer cast 01367 //Do a PI sinetable instead of the original 0.5 PI 01368 for ( int i = 0; i < 512; i++ ) { 01369 SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); 01370 } 01371 #endif 01372 #if ( DBOPL_WAVE == WAVE_TABLEMUL ) 01373 //Multiplication based tables 01374 for ( int i = 0; i < 384; i++ ) { 01375 int s = i * 8; 01376 //TODO maybe keep some of the precision errors of the original table? 01377 double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); 01378 MulTable[i] = (Bit16u)(val); 01379 } 01380 01381 //Sine Wave Base 01382 for ( int i = 0; i < 512; i++ ) { 01383 WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); 01384 WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; 01385 } 01386 //Exponential wave 01387 for ( int i = 0; i < 256; i++ ) { 01388 WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); 01389 WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; 01390 } 01391 #endif 01392 #if ( DBOPL_WAVE == WAVE_TABLELOG ) 01393 //Sine Wave Base 01394 for ( int i = 0; i < 512; i++ ) { 01395 WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); 01396 WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; 01397 } 01398 //Exponential wave 01399 for ( int i = 0; i < 256; i++ ) { 01400 WaveTable[ 0x700 + i ] = i * 8; 01401 WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; 01402 } 01403 #endif 01404 01405 // | |//\\|____|WAV7|//__|/\ |____|/\/\| 01406 // |\\//| | |WAV7| | \/| | | 01407 // |06 |0126|27 |7 |3 |4 |4 5 |5 | 01408 01409 #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) 01410 for ( int i = 0; i < 256; i++ ) { 01411 //Fill silence gaps 01412 WaveTable[ 0x400 + i ] = WaveTable[0]; 01413 WaveTable[ 0x500 + i ] = WaveTable[0]; 01414 WaveTable[ 0x900 + i ] = WaveTable[0]; 01415 WaveTable[ 0xc00 + i ] = WaveTable[0]; 01416 WaveTable[ 0xd00 + i ] = WaveTable[0]; 01417 //Replicate sines in other pieces 01418 WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; 01419 //double speed sines 01420 WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; 01421 WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; 01422 WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; 01423 WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; 01424 } 01425 #endif 01426 01427 //Create the ksl table 01428 for ( int oct = 0; oct < 8; oct++ ) { 01429 int base = oct * 8; 01430 for ( int i = 0; i < 16; i++ ) { 01431 int val = base - KslCreateTable[i]; 01432 if ( val < 0 ) 01433 val = 0; 01434 //*4 for the final range to match attenuation range 01435 KslTable[ oct * 16 + i ] = val * 4; 01436 } 01437 } 01438 //Create the Tremolo table, just increase and decrease a triangle wave 01439 for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) { 01440 Bit8u val = i << ENV_EXTRA; 01441 TremoloTable[i] = val; 01442 TremoloTable[TREMOLO_TABLE - 1 - i] = val; 01443 } 01444 //Create a table with offsets of the channels from the start of the chip 01445 DBOPL::Chip* chip = 0; 01446 for ( Bitu i = 0; i < 32; i++ ) { 01447 Bitu index = i & 0xf; 01448 if ( index >= 9 ) { 01449 ChanOffsetTable[i] = 0; 01450 continue; 01451 } 01452 //Make sure the four op channels follow eachother 01453 if ( index < 6 ) { 01454 index = (index % 3) * 2 + ( index / 3 ); 01455 } 01456 //Add back the bits for highest ones 01457 if ( i >= 16 ) 01458 index += 9; 01459 Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) ); 01460 ChanOffsetTable[i] = (Bit16u)blah; 01461 } 01462 //Same for operators 01463 for ( Bitu i = 0; i < 64; i++ ) { 01464 if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { 01465 OpOffsetTable[i] = 0; 01466 continue; 01467 } 01468 Bitu chNum = (i / 8) * 3 + (i % 8) % 3; 01469 //Make sure we use 16 and up for the 2nd range to match the chanoffset gap 01470 if ( chNum >= 12 ) 01471 chNum += 16 - 12; 01472 Bitu opNum = ( i % 8 ) / 3; 01473 DBOPL::Channel* chan = 0; 01474 Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) ); 01475 OpOffsetTable[i] = (Bit16u)(ChanOffsetTable[ chNum ] + blah); 01476 } 01477 #if 0 01478 //Stupid checks if table's are correct 01479 for ( Bitu i = 0; i < 18; i++ ) { 01480 Bit32u find = (Bit16u)( &(chip->chan[ i ]) ); 01481 for ( Bitu c = 0; c < 32; c++ ) { 01482 if ( ChanOffsetTable[c] == find ) { 01483 find = 0; 01484 break; 01485 } 01486 } 01487 if ( find ) { 01488 find = find; 01489 } 01490 } 01491 for ( Bitu i = 0; i < 36; i++ ) { 01492 Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) ); 01493 for ( Bitu c = 0; c < 64; c++ ) { 01494 if ( OpOffsetTable[c] == find ) { 01495 find = 0; 01496 break; 01497 } 01498 } 01499 if ( find ) { 01500 find = find; 01501 } 01502 } 01503 #endif 01504 } 01505 01506 Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) { 01507 return chip.WriteAddr( port, val ); 01508 01509 } 01510 void Handler::WriteReg( Bit32u addr, Bit8u val ) { 01511 chip.WriteReg( addr, val ); 01512 } 01513 01514 void Handler::Generate( MixerChannel* chan, Bitu samples ) { 01515 Bit32s buffer[ 512 * 2 ]; 01516 if ( GCC_UNLIKELY(samples > 512) ) 01517 samples = 512; 01518 if ( !chip.opl3Active ) { 01519 chip.GenerateBlock2( samples, buffer ); 01520 chan->AddSamples_m32( samples, buffer ); 01521 } else { 01522 chip.GenerateBlock3( samples, buffer ); 01523 chan->AddSamples_s32( samples, buffer ); 01524 } 01525 } 01526 01527 void Handler::Init( Bitu rate ) { 01528 InitTables(); 01529 chip.Setup( (Bit32u)rate ); 01530 } 01531 01532 // save state support 01533 void Handler::SaveState( std::ostream& stream ) 01534 { 01535 const char pod_name[32] = "DBOPL"; 01536 01537 if( stream.fail() ) return; 01538 01539 01540 WRITE_POD( &pod_name, pod_name ); 01541 01542 //************************************************ 01543 //************************************************ 01544 //************************************************ 01545 01546 Bit8u volhandler_idx[18][2]; 01547 Bit32u wavebase_idx[18][2]; 01548 Bit8u synthhandler_idx[18]; 01549 01550 01551 for( int lcv1=0; lcv1<18; lcv1++ ) { 01552 for( int lcv2=0; lcv2<2; lcv2++ ) { 01553 volhandler_idx[lcv1][lcv2] = 0xff; 01554 01555 for( int lcv3=0; lcv3<5; lcv3++ ) { 01556 if( chip.chan[lcv1].op[lcv2].volHandler == VolumeHandlerTable[lcv3] ) { 01557 volhandler_idx[lcv1][lcv2] = lcv3; 01558 break; 01559 } 01560 } 01561 01562 wavebase_idx[lcv1][lcv2] = (Bitu) chip.chan[lcv1].op[lcv2].waveBase - (Bitu) &WaveTable; 01563 } 01564 01565 01566 synthhandler_idx[lcv1] = 0xff; 01567 if(0) {} 01568 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMFM > ) synthhandler_idx[lcv1] = 0x00; 01569 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMFM > ) synthhandler_idx[lcv1] = 0x01; 01570 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMAM > ) synthhandler_idx[lcv1] = 0x02; 01571 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMAM > ) synthhandler_idx[lcv1] = 0x03; 01572 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AM > ) synthhandler_idx[lcv1] = 0x04; 01573 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FM > ) synthhandler_idx[lcv1] = 0x05; 01574 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2AM > ) synthhandler_idx[lcv1] = 0x06; 01575 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2FM > ) synthhandler_idx[lcv1] = 0x07; 01576 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3Percussion > ) synthhandler_idx[lcv1] = 0x08; 01577 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2Percussion > ) synthhandler_idx[lcv1] = 0x09; 01578 } 01579 01580 //*************************************************** 01581 //*************************************************** 01582 //*************************************************** 01583 01584 // dbopl.cpp 01585 01586 // - pure data 01587 WRITE_POD( &WaveTable, WaveTable ); 01588 WRITE_POD( &doneTables, doneTables ); 01589 01590 //*************************************************** 01591 //*************************************************** 01592 //*************************************************** 01593 01594 // dbopl.h 01595 01596 // - near-pure data 01597 WRITE_POD( &chip, chip ); 01598 01599 01600 01601 01602 // - reloc ptr (!!!) 01603 WRITE_POD( &volhandler_idx, volhandler_idx ); 01604 WRITE_POD( &wavebase_idx, wavebase_idx ); 01605 WRITE_POD( &synthhandler_idx, synthhandler_idx ); 01606 } 01607 01608 void Handler::LoadState( std::istream& stream ) 01609 { 01610 char pod_name[32] = {0}; 01611 01612 if( stream.fail() ) return; 01613 01614 01615 // error checking 01616 READ_POD( &pod_name, pod_name ); 01617 if( strcmp( pod_name, "DBOPL" ) ) { 01618 stream.clear( std::istream::failbit | std::istream::badbit ); 01619 return; 01620 } 01621 01622 //************************************************ 01623 //************************************************ 01624 //************************************************ 01625 01626 Bit8u volhandler_idx[18][2]; 01627 Bit32u wavebase_idx[18][2]; 01628 Bit8u synthhandler_idx[18]; 01629 01630 //*************************************************** 01631 //*************************************************** 01632 //*************************************************** 01633 01634 // dbopl.cpp 01635 01636 // - pure data 01637 READ_POD( &WaveTable, WaveTable ); 01638 READ_POD( &doneTables, doneTables ); 01639 01640 //*************************************************** 01641 //*************************************************** 01642 //*************************************************** 01643 01644 // dbopl.h 01645 01646 // - near-pure data 01647 READ_POD( &chip, chip ); 01648 01649 01650 01651 01652 // - reloc ptr (!!!) 01653 READ_POD( &volhandler_idx, volhandler_idx ); 01654 READ_POD( &wavebase_idx, wavebase_idx ); 01655 READ_POD( &synthhandler_idx, synthhandler_idx ); 01656 01657 //*************************************************** 01658 //*************************************************** 01659 //*************************************************** 01660 01661 for( int lcv1=0; lcv1<18; lcv1++ ) { 01662 for( int lcv2=0; lcv2<2; lcv2++ ) { 01663 chip.chan[lcv1].op[lcv2].volHandler = VolumeHandlerTable[ volhandler_idx[lcv1][lcv2] ]; 01664 01665 chip.chan[lcv1].op[lcv2].waveBase = (Bit16s *) ((Bitu) wavebase_idx[lcv1][lcv2] + (Bitu) &WaveTable); 01666 } 01667 01668 01669 switch( synthhandler_idx[lcv1] ) { 01670 case 0x00: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMFM >; break; 01671 case 0x01: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMFM >; break; 01672 case 0x02: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMAM >; break; 01673 case 0x03: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMAM >; break; 01674 case 0x04: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AM >; break; 01675 case 0x05: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FM >; break; 01676 case 0x06: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2AM >; break; 01677 case 0x07: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2FM >; break; 01678 case 0x08: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3Percussion >; break; 01679 case 0x09: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2Percussion >; break; 01680 } 01681 } 01682 } 01683 } //Namespace DBOPL