@@ -12,10 +12,10 @@ wmsx.OPL4AudioWave = function(opl4) {
1212 linearTable = tabs . getLinearTable12Bits ( ) ;
1313 expTable = tabs . getExpTable ( ) ;
1414 vibValues = tabs . getVIBValues ( ) ;
15- kslValues = tabs . getKSLValues ( ) ;
1615 rateAttackDurTable = tabs . getRateAttackDurations ( ) ;
1716 rateDecayDurTable = tabs . getRateDecayDurations ( ) ;
1817 envAttackCurve = tabs . getEnvAttackCurve ( ) ;
18+ panpotValues = tabs . getPanPotValues ( ) ;
1919 }
2020
2121 this . connect = function ( machine ) {
@@ -68,10 +68,10 @@ wmsx.OPL4AudioWave = function(opl4) {
6868
6969 // Dynamic values
7070
71- wmsx . Util . arrayFill ( volumeAtt , 0x7f << 4 ) ;
7271 wmsx . Util . arrayFill ( amAtt , 0 ) ;
7372 wmsx . Util . arrayFill ( envAtt , 0x100 << 4 ) ;
74- wmsx . Util . arrayFill ( totalAtt , 0x100 << 4 ) ;
73+ wmsx . Util . arrayFill ( totalAttL , 0x100 << 4 ) ;
74+ wmsx . Util . arrayFill ( totalAttR , 0x100 << 4 ) ;
7575 wmsx . Util . arrayFill ( envStep , IDLE ) ;
7676 wmsx . Util . arrayFill ( envStepLevelDur , 0 ) ;
7777 wmsx . Util . arrayFill ( envStepLevelIncClock , 0 ) ;
@@ -122,7 +122,7 @@ wmsx.OPL4AudioWave = function(opl4) {
122122
123123 this . nextSample = function ( ) {
124124 var phase , newPhase , delta ;
125- var sample = 0 ;
125+ var sample = 0 , sampleL = 0 , sampleR = 0 ;
126126
127127 for ( var cha = 23 ; cha >= 0 ; -- cha ) {
128128 if ( envStep [ cha ] === IDLE ) continue ;
@@ -133,17 +133,22 @@ wmsx.OPL4AudioWave = function(opl4) {
133133
134134 delta = ( newPhase >> 10 ) - ( phase >> 10 ) ;
135135
136- if ( delta > 0 )
137- sample += expTable [ advanceSample ( cha , delta ) + totalAtt [ cha ] ] ;
138- else
139- sample += expTable [ sampleValue [ cha ] + totalAtt [ cha ] ] ;
140-
141- // if (delta > 0) sample += advanceSample(cha, delta); else sample += sampleValue[cha];
136+ if ( delta > 0 ) {
137+ sample = advanceSample ( cha , delta ) ;
138+ sampleL += expTable [ sample + totalAttL [ cha ] ] ;
139+ sampleR += expTable [ sample + totalAttR [ cha ] ] ;
140+ } else {
141+ sampleL += expTable [ sampleValue [ cha ] + totalAttL [ cha ] ] ;
142+ sampleR += expTable [ sampleValue [ cha ] + totalAttR [ cha ] ] ;
143+ }
142144
143- // if (sample > (24 * 4096) || sample < (24 * -4096)) console.log("Wave overflow: " + sample);
145+ // if (delta > 0) sampleL += advanceSample(cha, delta); else sampleL += sampleValue[cha];
146+ // if (sampleL > (24 * 4096) || sampleL < (24 * -4096)) console.log("Wave overflow: " + sampleL);
144147 }
145148
146- return sample ;
149+ sampleResult [ 0 ] = sampleL ;
150+ sampleResult [ 1 ] = sampleR ;
151+ return sampleResult ;
147152 } ;
148153
149154 function readWaveHeader ( cha ) {
@@ -215,7 +220,7 @@ wmsx.OPL4AudioWave = function(opl4) {
215220 cha = reg - 0x50 ;
216221 if ( mod & 0xfe ) {
217222 volume [ cha ] = val >> 1 ; // TOTAL LEVEL
218- updateVolumeAttenuation ( cha ) ;
223+ updateTotalAttenuation ( cha ) ;
219224 }
220225 break ;
221226 case 0x68 : case 0x69 : case 0x6a : case 0x6b : case 0x6c : case 0x6d : case 0x6e : case 0x6f : case 0x70 : case 0x71 : case 0x72 : case 0x73 :
@@ -224,6 +229,11 @@ wmsx.OPL4AudioWave = function(opl4) {
224229 if ( mod & 0x80 ) setKeyOn ( cha , val >> 7 ) ; // KEY ON
225230 if ( mod & 0x40 )
226231 if ( val & 0x40 ) setEnvStep ( cha , DAMP_END ) ; // DAMP
232+ if ( mod & 0x0f ) {
233+ panpotL [ cha ] = panpotValues [ 0 ] [ val & 0x0f ] ; // PANPOT
234+ panpotR [ cha ] = panpotValues [ 1 ] [ val & 0x0f ] ;
235+ updateTotalAttenuation ( cha ) ;
236+ }
227237 break ;
228238 case 0x98 : case 0x99 : case 0x9a : case 0x9b : case 0x9c : case 0x9d : case 0x9e : case 0x9f : case 0xa0 : case 0xa1 : case 0xa2 : case 0xa3 :
229239 case 0xa4 : case 0xa5 : case 0xa6 : case 0xa7 : case 0xa8 : case 0xa9 : case 0xaa : case 0xab : case 0xac : case 0xad : case 0xae : case 0xaf :
@@ -477,20 +487,13 @@ wmsx.OPL4AudioWave = function(opl4) {
477487 }
478488
479489 function updateEnvAttenuation ( cha ) {
480- envAtt [ cha ] = ( envStep [ cha ] === ATTACK ? envAttackCurve [ envLevel [ cha ] ] : envLevel [ cha ] ) << 4 ;
481- updateTotalAttenuation ( cha ) ;
482- }
483-
484- function updateVolumeAttenuation ( cha ) {
485- volumeAtt [ cha ] = volume [ cha ] << 4 ;
490+ envAtt [ cha ] = envStep [ cha ] === ATTACK ? envAttackCurve [ envLevel [ cha ] ] : envLevel [ cha ] ;
486491 updateTotalAttenuation ( cha ) ;
487492 }
488493
489494 function updateTotalAttenuation ( cha ) {
490- totalAtt [ cha ] = amAtt [ cha ] + envAtt [ cha ] + volumeAtt [ cha ] ;
491-
492- // 0..208 + 0..1792 + 0..2048 + 0..2016
493- // max: 256 + 2048 + 4096 + 4096 = 10496 = 0x2900
495+ totalAttL [ cha ] = amAtt [ cha ] + ( envAtt [ cha ] << 4 ) + ( volume [ cha ] << 4 ) + ( panpotL [ cha ] << 7 ) ;
496+ totalAttR [ cha ] = amAtt [ cha ] + ( envAtt [ cha ] << 4 ) + ( volume [ cha ] << 4 ) + ( panpotR [ cha ] << 7 ) ;
494497 }
495498
496499
@@ -526,15 +529,17 @@ wmsx.OPL4AudioWave = function(opl4) {
526529 var rc = new Array ( 24 ) ;
527530 var rr = new Array ( 24 ) ;
528531
529- var am = new Array ( 24 ) ;
530- var vib = new Array ( 24 ) ;
531- var volume = new Array ( 24 ) ;
532+ var am = new Array ( 24 ) ;
533+ var vib = new Array ( 24 ) ;
534+ var volume = new Array ( 24 ) ;
535+ var panpotL = new Array ( 24 ) ;
536+ var panpotR = new Array ( 24 ) ;
532537
533538 // Dynamic values per Channel. May change as time passes without being set by software
534539 var amAtt = new Array ( 24 ) ;
535540 var envAtt = new Array ( 24 ) ;
536- var volumeAtt = new Array ( 24 ) ;
537- var totalAtt = new Array ( 24 ) ;
541+ var totalAttL = new Array ( 24 ) ;
542+ var totalAttR = new Array ( 24 ) ;
538543
539544 var envStep = new Array ( 24 ) ;
540545 var envStepLevelDur = new Array ( 24 ) ;
@@ -554,7 +559,8 @@ wmsx.OPL4AudioWave = function(opl4) {
554559
555560 // Pre calculated tables, factors, values
556561
557- var linearTable , expTable , vibValues , kslValues , rateAttackDurTable , rateDecayDurTable , envAttackCurve ;
562+ var linearTable , expTable , vibValues , rateAttackDurTable , rateDecayDurTable , envAttackCurve , panpotValues ;
563+ var sampleResult = [ 0 , 0 ] ;
558564
559565
560566 // Savestate -------------------------------------------
@@ -580,7 +586,8 @@ wmsx.OPL4AudioWave = function(opl4) {
580586
581587 amt : wmsx . Util . storeInt16BitArrayToStringBase64 ( amAtt ) ,
582588 evt : wmsx . Util . storeInt16BitArrayToStringBase64 ( envAtt ) ,
583- tot : wmsx . Util . storeInt16BitArrayToStringBase64 ( totalAtt ) ,
589+ totL : wmsx . Util . storeInt16BitArrayToStringBase64 ( totalAttL ) ,
590+ totR : wmsx . Util . storeInt16BitArrayToStringBase64 ( totalAttR ) ,
584591
585592 evs : wmsx . Util . storeInt8BitArrayToStringBase64 ( envStep ) ,
586593 evd : wmsx . Util . storeInt32BitArrayToStringBase64 ( envStepLevelDur ) ,
@@ -619,7 +626,8 @@ wmsx.OPL4AudioWave = function(opl4) {
619626
620627 amAtt = wmsx . Util . restoreStringBase64ToInt16BitArray ( s . amt , amAtt ) ;
621628 envAtt = wmsx . Util . restoreStringBase64ToInt16BitArray ( s . evt , envAtt ) ;
622- totalAtt = wmsx . Util . restoreStringBase64ToInt16BitArray ( s . tot , totalAtt ) ;
629+ totalAttL = wmsx . Util . restoreStringBase64ToInt16BitArray ( s . totL , totalAttL ) ;
630+ totalAttR = wmsx . Util . restoreStringBase64ToInt16BitArray ( s . totR , totalAttR ) ;
623631
624632 envStep = wmsx . Util . restoreStringBase64ToInt8BitArray ( s . evs , envStep ) ;
625633 envStepLevelDur = wmsx . Util . restoreStringBase64ToInt32BitArray ( s . evd ) ;
@@ -656,8 +664,8 @@ wmsx.OPL4AudioWave = function(opl4) {
656664
657665 this . envAtt = envAtt ;
658666 this . amAtt = amAtt ;
659- this . volumeAtt = volumeAtt ;
660- this . totalAtt = totalAtt ;
667+ this . totalAttL = totalAttL ;
668+ this . totalAttR = totalAttR ;
661669
662670 this . envStep = envStep ;
663671 this . envStepLevelDur = envStepLevelDur ;
0 commit comments