PCem

view src/dosbox/dbopl.cpp @ 154:d0d530adce12

Initial port to Linux (using Allegro). 64-bit fixes. Some changes to aid portability. A few other tweaks.
author TomW
date Thu Sep 04 21:07:24 2014 +0100
parents df66658b3f06
children
line source
1 /*
2 * Copyright (C) 2002-2010 The DOSBox Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
19 /*
20 DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
21 Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
22 Except for the table generation it's all integer math
23 Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
24 The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
25 MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
27 //TODO Don't delay first operator 1 sample in opl3 mode
28 //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
29 //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
30 //TODO Check if having the same accuracy in all frequency multipliers sounds better or not
32 //DUNNO Keyon in 4op, switch to 2op without keyoff.
33 */
35 /* $Id: dbopl.cpp,v 1.10 2009-06-10 19:54:51 harekiet Exp $ */
37 #include <math.h>
38 #include <stdlib.h>
39 #include <string.h>
40 //#include "dosbox.h"
41 #include "dbopl.h"
44 #ifndef PI
45 #define PI 3.14159265358979323846
46 #endif
48 namespace DBOPL {
50 #define OPLRATE ((double)(14318180.0 / 288.0))
51 #define TREMOLO_TABLE 52
53 //Try to use most precision for frequencies
54 //Else try to keep different waves in synch
55 //#define WAVE_PRECISION 1
56 #ifndef WAVE_PRECISION
57 //Wave bits available in the top of the 32bit range
58 //Original adlib uses 10.10, we use 10.22
59 #define WAVE_BITS 10
60 #else
61 //Need some extra bits at the top to have room for octaves and frequency multiplier
62 //We support to 8 times lower rate
63 //128 * 15 * 8 = 15350, 2^13.9, so need 14 bits
64 #define WAVE_BITS 14
65 #endif
66 #define WAVE_SH ( 32 - WAVE_BITS )
67 #define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 )
69 //Use the same accuracy as the waves
70 #define LFO_SH ( WAVE_SH - 10 )
71 //LFO is controlled by our tremolo 256 sample limit
72 #define LFO_MAX ( 256 << ( LFO_SH ) )
75 //Maximum amount of attenuation bits
76 //Envelope goes to 511, 9 bits
77 #if (DBOPL_WAVE == WAVE_TABLEMUL )
78 //Uses the value directly
79 #define ENV_BITS ( 9 )
80 #else
81 //Add 3 bits here for more accuracy and would have to be shifted up either way
82 #define ENV_BITS ( 9 )
83 #endif
84 //Limits of the envelope with those bits and when the envelope goes silent
85 #define ENV_MIN 0
86 #define ENV_EXTRA ( ENV_BITS - 9 )
87 #define ENV_MAX ( 511 << ENV_EXTRA )
88 #define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
89 #define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT )
91 //Attack/decay/release rate counter shift
92 #define RATE_SH 24
93 #define RATE_MASK ( ( 1 << RATE_SH ) - 1 )
94 //Has to fit within 16bit lookuptable
95 #define MUL_SH 16
97 //Check some ranges
98 #if ENV_EXTRA > 3
99 #error Too many envelope bits
100 #endif
103 //How much to substract from the base value for the final attenuation
104 static const Bit8u KslCreateTable[16] = {
105 //0 will always be be lower than 7 * 8
106 64, 32, 24, 19,
107 16, 12, 11, 10,
108 8, 6, 5, 4,
109 3, 2, 1, 0,
110 };
112 #define M(_X_) ((Bit8u)( (_X_) * 2))
113 static const Bit8u FreqCreateTable[16] = {
114 M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ),
115 M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15)
116 };
117 #undef M
119 //We're not including the highest attack rate, that gets a special value
120 static const Bit8u AttackSamplesTable[13] = {
121 69, 55, 46, 40,
122 35, 29, 23, 20,
123 19, 15, 11, 10,
124 9
125 };
126 //On a real opl these values take 8 samples to reach and are based upon larger tables
127 static const Bit8u EnvelopeIncreaseTable[13] = {
128 4, 5, 6, 7,
129 8, 10, 12, 14,
130 16, 20, 24, 28,
131 32,
132 };
134 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
135 static Bit16u ExpTable[ 256 ];
136 #endif
138 #if ( DBOPL_WAVE == WAVE_HANDLER )
139 //PI table used by WAVEHANDLER
140 static Bit16u SinTable[ 512 ];
141 #endif
143 #if ( DBOPL_WAVE > WAVE_HANDLER )
144 //Layout of the waveform table in 512 entry intervals
145 //With overlapping waves we reduce the table to half it's size
147 // | |//\\|____|WAV7|//__|/\ |____|/\/\|
148 // |\\//| | |WAV7| | \/| | |
149 // |06 |0126|17 |7 |3 |4 |4 5 |5 |
151 //6 is just 0 shifted and masked
153 static Bit16s WaveTable[ 8 * 512 ];
154 //Distance into WaveTable the wave starts
155 static const Bit16u WaveBaseTable[8] = {
156 0x000, 0x200, 0x200, 0x800,
157 0xa00, 0xc00, 0x100, 0x400,
159 };
160 //Mask the counter with this
161 static const Bit16u WaveMaskTable[8] = {
162 1023, 1023, 511, 511,
163 1023, 1023, 512, 1023,
164 };
166 //Where to start the counter on at keyon
167 static const Bit16u WaveStartTable[8] = {
168 512, 0, 0, 0,
169 0, 512, 512, 256,
170 };
171 #endif
173 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
174 static Bit16u MulTable[ 384 ];
175 #endif
177 static Bit8u KslTable[ 8 * 16 ];
178 static Bit8u TremoloTable[ TREMOLO_TABLE ];
179 //Start of a channel behind the chip struct start
180 static Bit16u ChanOffsetTable[32];
181 //Start of an operator behind the chip struct start
182 static Bit16u OpOffsetTable[64];
184 //The lower bits are the shift of the operator vibrato value
185 //The highest bit is right shifted to generate -1 or 0 for negation
186 //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
187 static const Bit8s VibratoTable[ 8 ] = {
188 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00,
189 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80
190 };
192 //Shift strength for the ksl value determined by ksl strength
193 static const Bit8u KslShiftTable[4] = {
194 31,1,2,0
195 };
197 //Generate a table index and table shift value using input value from a selected rate
198 static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) {
199 if ( val < 13 * 4 ) { //Rate 0 - 12
200 shift = 12 - ( val >> 2 );
201 index = val & 3;
202 } else if ( val < 15 * 4 ) { //rate 13 - 14
203 shift = 0;
204 index = val - 12 * 4;
205 } else { //rate 15 and up
206 shift = 0;
207 index = 12;
208 }
209 }
211 #if ( DBOPL_WAVE == WAVE_HANDLER )
212 /*
213 Generate the different waveforms out of the sine/exponetial table using handlers
214 */
215 static inline Bits MakeVolume( Bitu wave, Bitu volume ) {
216 Bitu total = wave + volume;
217 Bitu index = total & 0xff;
218 Bitu sig = ExpTable[ index ];
219 Bitu exp = total >> 8;
220 #if 0
221 //Check if we overflow the 31 shift limit
222 if ( exp >= 32 ) {
223 LOG_MSG( "WTF %d %d", total, exp );
224 }
225 #endif
226 return (sig >> exp);
227 };
229 static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) {
230 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
231 Bitu wave = SinTable[i & 511];
232 return (MakeVolume( wave, volume ) ^ neg) - neg;
233 }
234 static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) {
235 Bit32u wave = SinTable[i & 511];
236 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
237 return MakeVolume( wave, volume );
238 }
239 static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) {
240 Bitu wave = SinTable[i & 511];
241 return MakeVolume( wave, volume );
242 }
243 static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) {
244 Bitu wave = SinTable[i & 255];
245 wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 );
246 return MakeVolume( wave, volume );
247 }
248 static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) {
249 //Twice as fast
250 i <<= 1;
251 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
252 Bitu wave = SinTable[i & 511];
253 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
254 return (MakeVolume( wave, volume ) ^ neg) - neg;
255 }
256 static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) {
257 //Twice as fast
258 i <<= 1;
259 Bitu wave = SinTable[i & 511];
260 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
261 return MakeVolume( wave, volume );
262 }
263 static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) {
264 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
265 return (MakeVolume( 0, volume ) ^ neg) - neg;
266 }
267 static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) {
268 //Negative is reversed here
269 Bits neg = (( i >> 9) & 1) - 1;
270 Bitu wave = (i << 3);
271 //When negative the volume also runs backwards
272 wave = ((wave ^ neg) - neg) & 4095;
273 return (MakeVolume( wave, volume ) ^ neg) - neg;
274 }
276 static const WaveHandler WaveHandlerTable[8] = {
277 WaveForm0, WaveForm1, WaveForm2, WaveForm3,
278 WaveForm4, WaveForm5, WaveForm6, WaveForm7
279 };
281 #endif
283 /*
284 Operator
285 */
287 //We zero out when rate == 0
288 inline void Operator::UpdateAttack( const Chip* chip ) {
289 Bit8u rate = reg60 >> 4;
290 if ( rate ) {
291 Bit8u val = (rate << 2) + ksr;
292 attackAdd = chip->attackRates[ val ];
293 rateZero &= ~(1 << ATTACK);
294 } else {
295 attackAdd = 0;
296 rateZero |= (1 << ATTACK);
297 }
298 }
299 inline void Operator::UpdateDecay( const Chip* chip ) {
300 Bit8u rate = reg60 & 0xf;
301 if ( rate ) {
302 Bit8u val = (rate << 2) + ksr;
303 decayAdd = chip->linearRates[ val ];
304 rateZero &= ~(1 << DECAY);
305 } else {
306 decayAdd = 0;
307 rateZero |= (1 << DECAY);
308 }
309 }
310 inline void Operator::UpdateRelease( const Chip* chip ) {
311 Bit8u rate = reg80 & 0xf;
312 if ( rate ) {
313 Bit8u val = (rate << 2) + ksr;
314 releaseAdd = chip->linearRates[ val ];
315 rateZero &= ~(1 << RELEASE);
316 if ( !(reg20 & MASK_SUSTAIN ) ) {
317 rateZero &= ~( 1 << SUSTAIN );
318 }
319 } else {
320 rateZero |= (1 << RELEASE);
321 releaseAdd = 0;
322 if ( !(reg20 & MASK_SUSTAIN ) ) {
323 rateZero |= ( 1 << SUSTAIN );
324 }
325 }
326 }
328 inline void Operator::UpdateAttenuation( ) {
329 Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff);
330 Bit32u tl = reg40 & 0x3f;
331 Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
332 //Make sure the attenuation goes to the right bits
333 totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max
334 totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift;
335 }
337 void Operator::UpdateFrequency( ) {
338 Bit32u freq = chanData & (( 1 << 10 ) - 1);
339 Bit32u block = (chanData >> 10) & 0xff;
340 #ifdef WAVE_PRECISION
341 block = 7 - block;
342 waveAdd = ( freq * freqMul ) >> block;
343 #else
344 waveAdd = ( freq << block ) * freqMul;
345 #endif
346 if ( reg20 & MASK_VIBRATO ) {
347 vibStrength = (Bit8u)(freq >> 7);
349 #ifdef WAVE_PRECISION
350 vibrato = ( vibStrength * freqMul ) >> block;
351 #else
352 vibrato = ( vibStrength << block ) * freqMul;
353 #endif
354 } else {
355 vibStrength = 0;
356 vibrato = 0;
357 }
358 }
360 void Operator::UpdateRates( const Chip* chip ) {
361 //Mame seems to reverse this where enabling ksr actually lowers
362 //the rate, but pdf manuals says otherwise?
363 Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff);
364 if ( !( reg20 & MASK_KSR ) ) {
365 newKsr >>= 2;
366 }
367 if ( ksr == newKsr )
368 return;
369 ksr = newKsr;
370 UpdateAttack( chip );
371 UpdateDecay( chip );
372 UpdateRelease( chip );
373 }
375 INLINE Bit32s Operator::RateForward( Bit32u add ) {
376 rateIndex += add;
377 Bit32s ret = rateIndex >> RATE_SH;
378 rateIndex = rateIndex & RATE_MASK;
379 return ret;
380 }
382 template< Operator::State yes>
383 Bits Operator::TemplateVolume( ) {
384 Bit32s vol = volume;
385 Bit32s change;
386 switch ( yes ) {
387 case OFF:
388 return ENV_MAX;
389 case ATTACK:
390 change = RateForward( attackAdd );
391 if ( !change )
392 return vol;
393 vol += ( (~vol) * change ) >> 3;
394 if ( vol < ENV_MIN ) {
395 volume = ENV_MIN;
396 rateIndex = 0;
397 SetState( DECAY );
398 return ENV_MIN;
399 }
400 break;
401 case DECAY:
402 vol += RateForward( decayAdd );
403 if ( GCC_UNLIKELY(vol >= sustainLevel) ) {
404 //Check if we didn't overshoot max attenuation, then just go off
405 if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
406 volume = ENV_MAX;
407 SetState( OFF );
408 return ENV_MAX;
409 }
410 //Continue as sustain
411 rateIndex = 0;
412 SetState( SUSTAIN );
413 }
414 break;
415 case SUSTAIN:
416 if ( reg20 & MASK_SUSTAIN ) {
417 return vol;
418 }
419 //In sustain phase, but not sustaining, do regular release
420 case RELEASE:
421 vol += RateForward( releaseAdd );;
422 if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
423 volume = ENV_MAX;
424 SetState( OFF );
425 return ENV_MAX;
426 }
427 break;
428 }
429 volume = vol;
430 return vol;
431 }
433 static const VolumeHandler VolumeHandlerTable[5] = {
434 &Operator::TemplateVolume< Operator::OFF >,
435 &Operator::TemplateVolume< Operator::RELEASE >,
436 &Operator::TemplateVolume< Operator::SUSTAIN >,
437 &Operator::TemplateVolume< Operator::DECAY >,
438 &Operator::TemplateVolume< Operator::ATTACK >
439 };
441 INLINE Bitu Operator::ForwardVolume() {
442 return currentLevel + (this->*volHandler)();
443 }
446 INLINE Bitu Operator::ForwardWave() {
447 waveIndex += waveCurrent;
448 return waveIndex >> WAVE_SH;
449 }
451 void Operator::Write20( const Chip* chip, Bit8u val ) {
452 Bit8u change = (reg20 ^ val );
453 if ( !change )
454 return;
455 reg20 = val;
456 //Shift the tremolo bit over the entire register, saved a branch, YES!
457 tremoloMask = (Bit8s)(val) >> 7;
458 tremoloMask &= ~(( 1 << ENV_EXTRA ) -1);
459 //Update specific features based on changes
460 if ( change & MASK_KSR ) {
461 UpdateRates( chip );
462 }
463 //With sustain enable the volume doesn't change
464 if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) {
465 rateZero |= ( 1 << SUSTAIN );
466 } else {
467 rateZero &= ~( 1 << SUSTAIN );
468 }
469 //Frequency multiplier or vibrato changed
470 if ( change & (0xf | MASK_VIBRATO) ) {
471 freqMul = chip->freqMul[ val & 0xf ];
472 UpdateFrequency();
473 }
474 }
476 void Operator::Write40( const Chip* /*chip*/, Bit8u val ) {
477 if (!(reg40 ^ val ))
478 return;
479 reg40 = val;
480 UpdateAttenuation( );
481 }
483 void Operator::Write60( const Chip* chip, Bit8u val ) {
484 Bit8u change = reg60 ^ val;
485 reg60 = val;
486 if ( change & 0x0f ) {
487 UpdateDecay( chip );
488 }
489 if ( change & 0xf0 ) {
490 UpdateAttack( chip );
491 }
492 }
494 void Operator::Write80( const Chip* chip, Bit8u val ) {
495 Bit8u change = (reg80 ^ val );
496 if ( !change )
497 return;
498 reg80 = val;
499 Bit8u sustain = val >> 4;
500 //Turn 0xf into 0x1f
501 sustain |= ( sustain + 1) & 0x10;
502 sustainLevel = sustain << ( ENV_BITS - 5 );
503 if ( change & 0x0f ) {
504 UpdateRelease( chip );
505 }
506 }
508 void Operator::WriteE0( const Chip* chip, Bit8u val ) {
509 if ( !(regE0 ^ val) )
510 return;
511 //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
512 Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) );
513 regE0 = val;
514 #if ( DBOPL_WAVE == WAVE_HANDLER )
515 waveHandler = WaveHandlerTable[ waveForm ];
516 #else
517 waveBase = WaveTable + WaveBaseTable[ waveForm ];
518 waveStart = WaveStartTable[ waveForm ] << WAVE_SH;
519 waveMask = WaveMaskTable[ waveForm ];
520 #endif
521 }
523 INLINE void Operator::SetState( Bit8u s ) {
524 state = s;
525 volHandler = VolumeHandlerTable[ s ];
526 }
528 INLINE bool Operator::Silent() const {
529 if ( !ENV_SILENT( totalLevel + volume ) )
530 return false;
531 if ( !(rateZero & ( 1 << state ) ) )
532 return false;
533 return true;
534 }
536 INLINE void Operator::Prepare( const Chip* chip ) {
537 currentLevel = totalLevel + (chip->tremoloValue & tremoloMask);
538 waveCurrent = waveAdd;
539 if ( vibStrength >> chip->vibratoShift ) {
540 Bit32s add = vibrato >> chip->vibratoShift;
541 //Sign extend over the shift value
542 Bit32s neg = chip->vibratoSign;
543 //Negate the add with -1 or 0
544 add = ( add ^ neg ) - neg;
545 waveCurrent += add;
546 }
547 }
549 void Operator::KeyOn( Bit8u mask ) {
550 if ( !keyOn ) {
551 //Restart the frequency generator
552 #if ( DBOPL_WAVE > WAVE_HANDLER )
553 waveIndex = waveStart;
554 #else
555 waveIndex = 0;
556 #endif
557 rateIndex = 0;
558 SetState( ATTACK );
559 }
560 keyOn |= mask;
561 }
563 void Operator::KeyOff( Bit8u mask ) {
564 keyOn &= ~mask;
565 if ( !keyOn ) {
566 if ( state != OFF ) {
567 SetState( RELEASE );
568 }
569 }
570 }
572 INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) {
573 #if ( DBOPL_WAVE == WAVE_HANDLER )
574 return waveHandler( index, vol << ( 3 - ENV_EXTRA ) );
575 #elif ( DBOPL_WAVE == WAVE_TABLEMUL )
576 return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
577 #elif ( DBOPL_WAVE == WAVE_TABLELOG )
578 Bit32s wave = waveBase[ index & waveMask ];
579 Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA );
580 Bit32s sig = ExpTable[ total & 0xff ];
581 Bit32u exp = total >> 8;
582 Bit32s neg = wave >> 16;
583 return ((sig ^ neg) - neg) >> exp;
584 #else
585 #error "No valid wave routine"
586 #endif
587 }
589 Bits INLINE Operator::GetSample( Bits modulation ) {
590 Bitu vol = ForwardVolume();
591 if ( ENV_SILENT( vol ) ) {
592 //Simply forward the wave
593 waveIndex += waveCurrent;
594 return 0;
595 } else {
596 Bitu index = ForwardWave();
597 index += modulation;
598 return GetWave( index, vol );
599 }
600 }
602 Operator::Operator() {
603 chanData = 0;
604 freqMul = 0;
605 waveIndex = 0;
606 waveAdd = 0;
607 waveCurrent = 0;
608 keyOn = 0;
609 ksr = 0;
610 reg20 = 0;
611 reg40 = 0;
612 reg60 = 0;
613 reg80 = 0;
614 regE0 = 0;
615 SetState( OFF );
616 rateZero = (1 << OFF);
617 sustainLevel = ENV_MAX;
618 currentLevel = ENV_MAX;
619 totalLevel = ENV_MAX;
620 volume = ENV_MAX;
621 releaseAdd = 0;
622 }
624 /*
625 Channel
626 */
628 Channel::Channel() {
629 old[0] = old[1] = 0;
630 chanData = 0;
631 regB0 = 0;
632 regC0 = 0;
633 maskLeft = -1;
634 maskRight = -1;
635 feedback = 31;
636 fourMask = 0;
637 synthHandler = &Channel::BlockTemplate< sm2FM >;
638 };
640 void Channel::SetChanData( const Chip* chip, Bit32u data ) {
641 Bit32u change = chanData ^ data;
642 chanData = data;
643 Op( 0 )->chanData = data;
644 Op( 1 )->chanData = data;
645 //Since a frequency update triggered this, always update frequency
646 Op( 0 )->UpdateFrequency();
647 Op( 1 )->UpdateFrequency();
648 if ( change & ( 0xff << SHIFT_KSLBASE ) ) {
649 Op( 0 )->UpdateAttenuation();
650 Op( 1 )->UpdateAttenuation();
651 }
652 if ( change & ( 0xff << SHIFT_KEYCODE ) ) {
653 Op( 0 )->UpdateRates( chip );
654 Op( 1 )->UpdateRates( chip );
655 }
656 }
658 void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) {
659 //Extrace the frequency bits
660 Bit32u data = chanData & 0xffff;
661 Bit32u kslBase = KslTable[ data >> 6 ];
662 Bit32u keyCode = ( data & 0x1c00) >> 9;
663 if ( chip->reg08 & 0x40 ) {
664 keyCode |= ( data & 0x100)>>8; /* notesel == 1 */
665 } else {
666 keyCode |= ( data & 0x200)>>9; /* notesel == 0 */
667 }
668 //Add the keycode and ksl into the highest bits of chanData
669 data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE );
670 ( this + 0 )->SetChanData( chip, data );
671 if ( fourOp & 0x3f ) {
672 ( this + 1 )->SetChanData( chip, data );
673 }
674 }
676 void Channel::WriteA0( const Chip* chip, Bit8u val ) {
677 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
678 //Don't handle writes to silent fourop channels
679 if ( fourOp > 0x80 )
680 return;
681 Bit32u change = (chanData ^ val ) & 0xff;
682 if ( change ) {
683 chanData ^= change;
684 UpdateFrequency( chip, fourOp );
685 }
686 }
688 void Channel::WriteB0( const Chip* chip, Bit8u val ) {
689 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
690 //Don't handle writes to silent fourop channels
691 if ( fourOp > 0x80 )
692 return;
693 Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00;
694 if ( change ) {
695 chanData ^= change;
696 UpdateFrequency( chip, fourOp );
697 }
698 //Check for a change in the keyon/off state
699 if ( !(( val ^ regB0) & 0x20))
700 return;
701 regB0 = val;
702 if ( val & 0x20 ) {
703 Op(0)->KeyOn( 0x1 );
704 Op(1)->KeyOn( 0x1 );
705 if ( fourOp & 0x3f ) {
706 ( this + 1 )->Op(0)->KeyOn( 1 );
707 ( this + 1 )->Op(1)->KeyOn( 1 );
708 }
709 } else {
710 Op(0)->KeyOff( 0x1 );
711 Op(1)->KeyOff( 0x1 );
712 if ( fourOp & 0x3f ) {
713 ( this + 1 )->Op(0)->KeyOff( 1 );
714 ( this + 1 )->Op(1)->KeyOff( 1 );
715 }
716 }
717 }
719 void Channel::WriteC0( const Chip* chip, Bit8u val ) {
720 Bit8u change = val ^ regC0;
721 if ( !change )
722 return;
723 regC0 = val;
724 feedback = ( val >> 1 ) & 7;
725 if ( feedback ) {
726 //We shift the input to the right 10 bit wave index value
727 feedback = 9 - feedback;
728 } else {
729 feedback = 31;
730 }
731 //Select the new synth mode
732 if ( chip->opl3Active ) {
733 //4-op mode enabled for this channel
734 if ( (chip->reg104 & fourMask) & 0x3f ) {
735 Channel* chan0, *chan1;
736 //Check if it's the 2nd channel in a 4-op
737 if ( !(fourMask & 0x80 ) ) {
738 chan0 = this;
739 chan1 = this + 1;
740 } else {
741 chan0 = this - 1;
742 chan1 = this;
743 }
745 Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 );
746 switch ( synth ) {
747 case 0:
748 chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
749 break;
750 case 1:
751 chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
752 break;
753 case 2:
754 chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
755 break;
756 case 3:
757 chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
758 break;
759 }
760 //Disable updating percussion channels
761 } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) {
763 //Regular dual op, am or fm
764 } else if ( val & 1 ) {
765 synthHandler = &Channel::BlockTemplate< sm3AM >;
766 } else {
767 synthHandler = &Channel::BlockTemplate< sm3FM >;
768 }
769 maskLeft = ( val & 0x10 ) ? -1 : 0;
770 maskRight = ( val & 0x20 ) ? -1 : 0;
771 //opl2 active
772 } else {
773 //Disable updating percussion channels
774 if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) {
776 //Regular dual op, am or fm
777 } else if ( val & 1 ) {
778 synthHandler = &Channel::BlockTemplate< sm2AM >;
779 } else {
780 synthHandler = &Channel::BlockTemplate< sm2FM >;
781 }
782 }
783 }
785 void Channel::ResetC0( const Chip* chip ) {
786 Bit8u val = regC0;
787 regC0 ^= 0xff;
788 WriteC0( chip, val );
789 };
791 template< bool opl3Mode>
792 INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
793 Channel* chan = this;
795 //BassDrum
796 Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
797 old[0] = old[1];
798 old[1] = Op(0)->GetSample( mod );
800 //When bassdrum is in AM mode first operator is ignoed
801 if ( chan->regC0 & 1 ) {
802 mod = 0;
803 } else {
804 mod = old[0];
805 }
806 Bit32s sample = Op(1)->GetSample( mod );
809 //Precalculate stuff used by other outputs
810 Bit32u noiseBit = chip->ForwardNoise() & 0x1;
811 Bit32u c2 = Op(2)->ForwardWave();
812 Bit32u c5 = Op(5)->ForwardWave();
813 Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
815 //Hi-Hat
816 Bit32u hhVol = Op(2)->ForwardVolume();
817 if ( !ENV_SILENT( hhVol ) ) {
818 Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 )));
819 sample += Op(2)->GetWave( hhIndex, hhVol );
820 }
821 //Snare Drum
822 Bit32u sdVol = Op(3)->ForwardVolume();
823 if ( !ENV_SILENT( sdVol ) ) {
824 Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 );
825 sample += Op(3)->GetWave( sdIndex, sdVol );
826 }
827 //Tom-tom
828 sample += Op(4)->GetSample( 0 );
830 //Top-Cymbal
831 Bit32u tcVol = Op(5)->ForwardVolume();
832 if ( !ENV_SILENT( tcVol ) ) {
833 Bit32u tcIndex = (1 + phaseBit) << 8;
834 sample += Op(5)->GetWave( tcIndex, tcVol );
835 }
836 sample <<= 1;
837 if ( opl3Mode ) {
838 output[0] += sample;
839 output[1] += sample;
840 } else {
841 output[0] += sample;
842 }
843 }
845 template<SynthMode mode>
846 Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) {
847 switch( mode ) {
848 case sm2AM:
849 case sm3AM:
850 if ( Op(0)->Silent() && Op(1)->Silent() ) {
851 old[0] = old[1] = 0;
852 return (this + 1);
853 }
854 break;
855 case sm2FM:
856 case sm3FM:
857 if ( Op(1)->Silent() ) {
858 old[0] = old[1] = 0;
859 return (this + 1);
860 }
861 break;
862 case sm3FMFM:
863 if ( Op(3)->Silent() ) {
864 old[0] = old[1] = 0;
865 return (this + 2);
866 }
867 break;
868 case sm3AMFM:
869 if ( Op(0)->Silent() && Op(3)->Silent() ) {
870 old[0] = old[1] = 0;
871 return (this + 2);
872 }
873 break;
874 case sm3FMAM:
875 if ( Op(1)->Silent() && Op(3)->Silent() ) {
876 old[0] = old[1] = 0;
877 return (this + 2);
878 }
879 break;
880 case sm3AMAM:
881 if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) {
882 old[0] = old[1] = 0;
883 return (this + 2);
884 }
885 break;
886 }
887 //Init the operators with the the current vibrato and tremolo values
888 Op( 0 )->Prepare( chip );
889 Op( 1 )->Prepare( chip );
890 if ( mode > sm4Start ) {
891 Op( 2 )->Prepare( chip );
892 Op( 3 )->Prepare( chip );
893 }
894 if ( mode > sm6Start ) {
895 Op( 4 )->Prepare( chip );
896 Op( 5 )->Prepare( chip );
897 }
898 for ( Bitu i = 0; i < samples; i++ ) {
899 //Early out for percussion handlers
900 if ( mode == sm2Percussion ) {
901 GeneratePercussion<false>( chip, output + i );
902 continue; //Prevent some unitialized value bitching
903 } else if ( mode == sm3Percussion ) {
904 GeneratePercussion<true>( chip, output + i * 2 );
905 continue; //Prevent some unitialized value bitching
906 }
908 //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
909 Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
910 old[0] = old[1];
911 old[1] = Op(0)->GetSample( mod );
912 Bit32s sample;
913 Bit32s out0 = old[0];
914 if ( mode == sm2AM || mode == sm3AM ) {
915 sample = out0 + Op(1)->GetSample( 0 );
916 } else if ( mode == sm2FM || mode == sm3FM ) {
917 sample = Op(1)->GetSample( out0 );
918 } else if ( mode == sm3FMFM ) {
919 Bits next = Op(1)->GetSample( out0 );
920 next = Op(2)->GetSample( next );
921 sample = Op(3)->GetSample( next );
922 } else if ( mode == sm3AMFM ) {
923 sample = out0;
924 Bits next = Op(1)->GetSample( 0 );
925 next = Op(2)->GetSample( next );
926 sample += Op(3)->GetSample( next );
927 } else if ( mode == sm3FMAM ) {
928 sample = Op(1)->GetSample( out0 );
929 Bits next = Op(2)->GetSample( 0 );
930 sample += Op(3)->GetSample( next );
931 } else if ( mode == sm3AMAM ) {
932 sample = out0;
933 Bits next = Op(1)->GetSample( 0 );
934 sample += Op(2)->GetSample( next );
935 sample += Op(3)->GetSample( 0 );
936 }
937 switch( mode ) {
938 case sm2AM:
939 case sm2FM:
940 if (chip->is_opl3)
941 {
942 output[ i * 2 + 0 ] += sample;
943 output[ i * 2 + 1 ] += sample;
944 }
945 else
946 output[ i ] += sample;
947 break;
948 case sm3AM:
949 case sm3FM:
950 case sm3FMFM:
951 case sm3AMFM:
952 case sm3FMAM:
953 case sm3AMAM:
954 output[ i * 2 + 0 ] += sample & maskLeft;
955 output[ i * 2 + 1 ] += sample & maskRight;
956 break;
957 }
958 }
959 switch( mode ) {
960 case sm2AM:
961 case sm2FM:
962 case sm3AM:
963 case sm3FM:
964 return ( this + 1 );
965 case sm3FMFM:
966 case sm3AMFM:
967 case sm3FMAM:
968 case sm3AMAM:
969 return( this + 2 );
970 case sm2Percussion:
971 case sm3Percussion:
972 return( this + 3 );
973 }
974 return 0;
975 }
977 /*
978 Chip
979 */
981 Chip::Chip() {
982 reg08 = 0;
983 reg04 = 0;
984 regBD = 0;
985 reg104 = 0;
986 opl3Active = 0;
987 }
989 INLINE Bit32u Chip::ForwardNoise() {
990 noiseCounter += noiseAdd;
991 Bitu count = noiseCounter >> LFO_SH;
992 noiseCounter &= WAVE_MASK;
993 for ( ; count > 0; --count ) {
994 //Noise calculation from mame
995 noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) );
996 noiseValue >>= 1;
997 }
998 return noiseValue;
999 }
1001 INLINE Bit32u Chip::ForwardLFO( Bit32u samples ) {
1002 //Current vibrato value, runs 4x slower than tremolo
1003 vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7;
1004 vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength;
1005 tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength;
1007 //Check hom many samples there can be done before the value changes
1008 Bit32u todo = LFO_MAX - lfoCounter;
1009 Bit32u count = (todo + lfoAdd - 1) / lfoAdd;
1010 if ( count > samples ) {
1011 count = samples;
1012 lfoCounter += count * lfoAdd;
1013 } else {
1014 lfoCounter += count * lfoAdd;
1015 lfoCounter &= (LFO_MAX - 1);
1016 //Maximum of 7 vibrato value * 4
1017 vibratoIndex = ( vibratoIndex + 1 ) & 31;
1018 //Clip tremolo to the the table size
1019 if ( tremoloIndex + 1 < TREMOLO_TABLE )
1020 ++tremoloIndex;
1021 else
1022 tremoloIndex = 0;
1024 return count;
1028 void Chip::WriteBD( Bit8u val ) {
1029 Bit8u change = regBD ^ val;
1030 if ( !change )
1031 return;
1032 regBD = val;
1033 //TODO could do this with shift and xor?
1034 vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
1035 tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
1036 if ( val & 0x20 ) {
1037 //Drum was just enabled, make sure channel 6 has the right synth
1038 if ( change & 0x20 ) {
1039 if ( opl3Active ) {
1040 chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >;
1041 } else {
1042 chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >;
1045 //Bass Drum
1046 if ( val & 0x10 ) {
1047 chan[6].op[0].KeyOn( 0x2 );
1048 chan[6].op[1].KeyOn( 0x2 );
1049 } else {
1050 chan[6].op[0].KeyOff( 0x2 );
1051 chan[6].op[1].KeyOff( 0x2 );
1053 //Hi-Hat
1054 if ( val & 0x1 ) {
1055 chan[7].op[0].KeyOn( 0x2 );
1056 } else {
1057 chan[7].op[0].KeyOff( 0x2 );
1059 //Snare
1060 if ( val & 0x8 ) {
1061 chan[7].op[1].KeyOn( 0x2 );
1062 } else {
1063 chan[7].op[1].KeyOff( 0x2 );
1065 //Tom-Tom
1066 if ( val & 0x4 ) {
1067 chan[8].op[0].KeyOn( 0x2 );
1068 } else {
1069 chan[8].op[0].KeyOff( 0x2 );
1071 //Top Cymbal
1072 if ( val & 0x2 ) {
1073 chan[8].op[1].KeyOn( 0x2 );
1074 } else {
1075 chan[8].op[1].KeyOff( 0x2 );
1077 //Toggle keyoffs when we turn off the percussion
1078 } else if ( change & 0x20 ) {
1079 //Trigger a reset to setup the original synth handler
1080 chan[6].ResetC0( this );
1081 chan[6].op[0].KeyOff( 0x2 );
1082 chan[6].op[1].KeyOff( 0x2 );
1083 chan[7].op[0].KeyOff( 0x2 );
1084 chan[7].op[1].KeyOff( 0x2 );
1085 chan[8].op[0].KeyOff( 0x2 );
1086 chan[8].op[1].KeyOff( 0x2 );
1091 #define REGOP( _FUNC_ ) \
1092 index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \
1093 if ( OpOffsetTable[ index ] ) { \
1094 Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \
1095 regOp->_FUNC_( this, val ); \
1098 #define REGCHAN( _FUNC_ ) \
1099 index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \
1100 if ( ChanOffsetTable[ index ] ) { \
1101 Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \
1102 regChan->_FUNC_( this, val ); \
1105 void Chip::WriteReg( Bit32u reg, Bit8u val ) {
1106 Bitu index;
1107 switch ( (reg & 0xf0) >> 4 ) {
1108 case 0x00 >> 4:
1109 if ( reg == 0x01 ) {
1110 waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0;
1111 } else if ( reg == 0x104 ) {
1112 //Only detect changes in lowest 6 bits
1113 if ( !((reg104 ^ val) & 0x3f) )
1114 return;
1115 //Always keep the highest bit enabled, for checking > 0x80
1116 reg104 = 0x80 | ( val & 0x3f );
1117 } else if ( reg == 0x105 ) {
1118 //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
1119 if ( !((opl3Active ^ val) & 1 ) )
1120 return;
1121 opl3Active = ( val & 1 ) ? 0xff : 0;
1122 //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
1123 for ( int i = 0; i < 18;i++ ) {
1124 chan[i].ResetC0( this );
1126 } else if ( reg == 0x08 ) {
1127 reg08 = val;
1129 case 0x10 >> 4:
1130 break;
1131 case 0x20 >> 4:
1132 case 0x30 >> 4:
1133 REGOP( Write20 );
1134 break;
1135 case 0x40 >> 4:
1136 case 0x50 >> 4:
1137 REGOP( Write40 );
1138 break;
1139 case 0x60 >> 4:
1140 case 0x70 >> 4:
1141 REGOP( Write60 );
1142 break;
1143 case 0x80 >> 4:
1144 case 0x90 >> 4:
1145 REGOP( Write80 );
1146 break;
1147 case 0xa0 >> 4:
1148 REGCHAN( WriteA0 );
1149 break;
1150 case 0xb0 >> 4:
1151 if ( reg == 0xbd ) {
1152 WriteBD( val );
1153 } else {
1154 REGCHAN( WriteB0 );
1156 break;
1157 case 0xc0 >> 4:
1158 REGCHAN( WriteC0 );
1159 case 0xd0 >> 4:
1160 break;
1161 case 0xe0 >> 4:
1162 case 0xf0 >> 4:
1163 REGOP( WriteE0 );
1164 break;
1169 Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
1170 switch ( port & 3 ) {
1171 case 0:
1172 return val;
1173 case 2:
1174 if ( opl3Active || (val == 0x05) )
1175 return 0x100 | val;
1176 else
1177 return val;
1179 return 0;
1182 void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
1183 while ( total > 0 ) {
1184 Bit32u samples = ForwardLFO( total );
1185 memset(output, 0, sizeof(Bit32s) * samples);
1186 int count = 0;
1187 for( Channel* ch = chan; ch < chan + 9; ) {
1188 count++;
1189 ch = (ch->*(ch->synthHandler))( this, samples, output );
1191 total -= samples;
1192 output += samples;
1196 void Chip::GenerateBlock3( Bitu total, Bit32s* output ) {
1197 while ( total > 0 ) {
1198 Bit32u samples = ForwardLFO( total );
1199 memset(output, 0, sizeof(Bit32s) * samples *2);
1200 int count = 0;
1201 for( Channel* ch = chan; ch < chan + 18; ) {
1202 count++;
1203 ch = (ch->*(ch->synthHandler))( this, samples, output );
1205 total -= samples;
1206 output += samples * 2;
1210 void Chip::Setup( Bit32u rate, int chip_is_opl3 ) {
1211 double original = OPLRATE;
1212 // double original = rate;
1213 double scale = original / (double)rate;
1215 is_opl3 = chip_is_opl3;
1217 //Noise counter is run at the same precision as general waves
1218 noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
1219 noiseCounter = 0;
1220 noiseValue = 1; //Make sure it triggers the noise xor the first time
1221 //The low frequency oscillation counter
1222 //Every time his overflows vibrato and tremoloindex are increased
1223 lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
1224 lfoCounter = 0;
1225 vibratoIndex = 0;
1226 tremoloIndex = 0;
1228 //With higher octave this gets shifted up
1229 //-1 since the freqCreateTable = *2
1230 #ifdef WAVE_PRECISION
1231 double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10));
1232 for ( int i = 0; i < 16; i++ ) {
1233 freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] );
1235 #else
1236 Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10)));
1237 for ( int i = 0; i < 16; i++ ) {
1238 freqMul[i] = freqScale * FreqCreateTable[ i ];
1240 #endif
1242 //-3 since the real envelope takes 8 steps to reach the single value we supply
1243 for ( Bit8u i = 0; i < 76; i++ ) {
1244 Bit8u index, shift;
1245 EnvelopeSelect( i, index, shift );
1246 linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
1248 //Generate the best matching attack rate
1249 for ( Bit8u i = 0; i < 62; i++ ) {
1250 Bit8u index, shift;
1251 EnvelopeSelect( i, index, shift );
1252 //Original amount of samples the attack would take
1253 Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale);
1255 Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 )));
1256 Bit32s bestAdd = guessAdd;
1257 Bit32u bestDiff = 1 << 30;
1258 for( Bit32u passes = 0; passes < 16; passes ++ ) {
1259 Bit32s volume = ENV_MAX;
1260 Bit32s samples = 0;
1261 Bit32u count = 0;
1262 while ( volume > 0 && samples < original * 2 ) {
1263 count += guessAdd;
1264 Bit32s change = count >> RATE_SH;
1265 count &= RATE_MASK;
1266 if ( GCC_UNLIKELY(change) ) { // less than 1 %
1267 volume += ( ~volume * change ) >> 3;
1269 samples++;
1272 Bit32s diff = original - samples;
1273 Bit32u lDiff = labs( diff );
1274 //Init last on first pass
1275 if ( lDiff < bestDiff ) {
1276 bestDiff = lDiff;
1277 bestAdd = guessAdd;
1278 if ( !bestDiff )
1279 break;
1281 //Below our target
1282 if ( diff < 0 ) {
1283 //Better than the last time
1284 Bit32s mul = ((original - diff) << 12) / original;
1285 guessAdd = ((guessAdd * mul) >> 12);
1286 guessAdd++;
1287 } else if ( diff > 0 ) {
1288 Bit32s mul = ((original - diff) << 12) / original;
1289 guessAdd = (guessAdd * mul) >> 12;
1290 guessAdd--;
1293 attackRates[i] = bestAdd;
1295 for ( Bit8u i = 62; i < 76; i++ ) {
1296 //This should provide instant volume maximizing
1297 attackRates[i] = 8 << RATE_SH;
1299 //Setup the channels with the correct four op flags
1300 //Channels are accessed through a table so they appear linear here
1301 chan[ 0].fourMask = 0x00 | ( 1 << 0 );
1302 chan[ 1].fourMask = 0x80 | ( 1 << 0 );
1303 chan[ 2].fourMask = 0x00 | ( 1 << 1 );
1304 chan[ 3].fourMask = 0x80 | ( 1 << 1 );
1305 chan[ 4].fourMask = 0x00 | ( 1 << 2 );
1306 chan[ 5].fourMask = 0x80 | ( 1 << 2 );
1308 chan[ 9].fourMask = 0x00 | ( 1 << 3 );
1309 chan[10].fourMask = 0x80 | ( 1 << 3 );
1310 chan[11].fourMask = 0x00 | ( 1 << 4 );
1311 chan[12].fourMask = 0x80 | ( 1 << 4 );
1312 chan[13].fourMask = 0x00 | ( 1 << 5 );
1313 chan[14].fourMask = 0x80 | ( 1 << 5 );
1315 //mark the percussion channels
1316 chan[ 6].fourMask = 0x40;
1317 chan[ 7].fourMask = 0x40;
1318 chan[ 8].fourMask = 0x40;
1320 //Clear Everything in opl3 mode
1321 WriteReg( 0x105, 0x1 );
1322 for ( int i = 0; i < 512; i++ ) {
1323 if ( i == 0x105 )
1324 continue;
1325 WriteReg( i, 0xff );
1326 WriteReg( i, 0x0 );
1328 WriteReg( 0x105, 0x0 );
1329 //Clear everything in opl2 mode
1330 for ( int i = 0; i < 255; i++ ) {
1331 WriteReg( i, 0xff );
1332 WriteReg( i, 0x0 );
1336 static bool doneTables = false;
1337 void InitTables( void ) {
1338 if ( doneTables )
1339 return;
1340 doneTables = true;
1341 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
1342 //Exponential volume table, same as the real adlib
1343 for ( int i = 0; i < 256; i++ ) {
1344 //Save them in reverse
1345 ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 );
1346 ExpTable[i] += 1024; //or remove the -1 oh well :)
1347 //Preshift to the left once so the final volume can shift to the right
1348 ExpTable[i] *= 2;
1350 #endif
1351 #if ( DBOPL_WAVE == WAVE_HANDLER )
1352 //Add 0.5 for the trunc rounding of the integer cast
1353 //Do a PI sinetable instead of the original 0.5 PI
1354 for ( int i = 0; i < 512; i++ ) {
1355 SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
1357 #endif
1358 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
1359 //Multiplication based tables
1360 for ( int i = 0; i < 384; i++ ) {
1361 int s = i * 8;
1362 //TODO maybe keep some of the precision errors of the original table?
1363 double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
1364 MulTable[i] = (Bit16u)(val);
1367 //Sine Wave Base
1368 for ( int i = 0; i < 512; i++ ) {
1369 WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084);
1370 WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
1372 //Exponential wave
1373 for ( int i = 0; i < 256; i++ ) {
1374 WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
1375 WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
1377 #endif
1378 #if ( DBOPL_WAVE == WAVE_TABLELOG )
1379 //Sine Wave Base
1380 for ( int i = 0; i < 512; i++ ) {
1381 WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
1382 WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
1384 //Exponential wave
1385 for ( int i = 0; i < 256; i++ ) {
1386 WaveTable[ 0x700 + i ] = i * 8;
1387 WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
1389 #endif
1391 // | |//\\|____|WAV7|//__|/\ |____|/\/\|
1392 // |\\//| | |WAV7| | \/| | |
1393 // |06 |0126|27 |7 |3 |4 |4 5 |5 |
1395 #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
1396 for ( int i = 0; i < 256; i++ ) {
1397 //Fill silence gaps
1398 WaveTable[ 0x400 + i ] = WaveTable[0];
1399 WaveTable[ 0x500 + i ] = WaveTable[0];
1400 WaveTable[ 0x900 + i ] = WaveTable[0];
1401 WaveTable[ 0xc00 + i ] = WaveTable[0];
1402 WaveTable[ 0xd00 + i ] = WaveTable[0];
1403 //Replicate sines in other pieces
1404 WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
1405 //double speed sines
1406 WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
1407 WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
1408 WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
1409 WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
1411 #endif
1413 //Create the ksl table
1414 for ( int oct = 0; oct < 8; oct++ ) {
1415 int base = oct * 8;
1416 for ( int i = 0; i < 16; i++ ) {
1417 int val = base - KslCreateTable[i];
1418 if ( val < 0 )
1419 val = 0;
1420 //*4 for the final range to match attenuation range
1421 KslTable[ oct * 16 + i ] = val * 4;
1424 //Create the Tremolo table, just increase and decrease a triangle wave
1425 for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) {
1426 Bit8u val = i << ENV_EXTRA;
1427 TremoloTable[i] = val;
1428 TremoloTable[TREMOLO_TABLE - 1 - i] = val;
1430 //Create a table with offsets of the channels from the start of the chip
1431 DBOPL::Chip* chip = 0;
1432 for ( Bitu i = 0; i < 32; i++ ) {
1433 Bitu index = i & 0xf;
1434 if ( index >= 9 ) {
1435 ChanOffsetTable[i] = 0;
1436 continue;
1438 //Make sure the four op channels follow eachother
1439 if ( index < 6 ) {
1440 index = (index % 3) * 2 + ( index / 3 );
1442 //Add back the bits for highest ones
1443 if ( i >= 16 )
1444 index += 9;
1445 intptr_t blah = reinterpret_cast<intptr_t>( &(chip->chan[ index ]) );
1446 ChanOffsetTable[i] = blah;
1448 //Same for operators
1449 for ( Bitu i = 0; i < 64; i++ ) {
1450 if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) {
1451 OpOffsetTable[i] = 0;
1452 continue;
1454 Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
1455 //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
1456 if ( chNum >= 12 )
1457 chNum += 16 - 12;
1458 Bitu opNum = ( i % 8 ) / 3;
1459 DBOPL::Channel* chan = 0;
1460 intptr_t blah = reinterpret_cast<intptr_t>( &(chan->op[opNum]) );
1461 OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah;
1463 #if 0
1464 //Stupid checks if table's are correct
1465 for ( Bitu i = 0; i < 18; i++ ) {
1466 Bit32u find = (Bit16u)( &(chip->chan[ i ]) );
1467 for ( Bitu c = 0; c < 32; c++ ) {
1468 if ( ChanOffsetTable[c] == find ) {
1469 find = 0;
1470 break;
1473 if ( find ) {
1474 find = find;
1477 for ( Bitu i = 0; i < 36; i++ ) {
1478 Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) );
1479 for ( Bitu c = 0; c < 64; c++ ) {
1480 if ( OpOffsetTable[c] == find ) {
1481 find = 0;
1482 break;
1485 if ( find ) {
1486 find = find;
1489 #endif
1492 /*Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) {
1493 return chip.WriteAddr( port, val );
1496 void Handler::WriteReg( Bit32u addr, Bit8u val ) {
1497 chip.WriteReg( addr, val );
1500 void Handler::Generate( MixerChannel* chan, Bitu samples ) {
1501 Bit32s buffer[ 512 * 2 ];
1502 if ( GCC_UNLIKELY(samples > 512) )
1503 samples = 512;
1504 if ( !chip.opl3Active ) {
1505 chip.GenerateBlock2( samples, buffer );
1506 chan->AddSamples_m32( samples, buffer );
1507 } else {
1508 chip.GenerateBlock3( samples, buffer );
1509 chan->AddSamples_s32( samples, buffer );
1513 void Handler::Init( Bitu rate ) {
1514 InitTables();
1515 chip.Setup( rate );
1516 }*/
1519 }; //Namespace DBOPL