some movies fixed
[fceu.git] / mappers / fmopl.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 1999,2000 Tatsuyuki Satoh
5  *  Copyright (C) 2001,2002 Ben Parnell
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
20  */
21
22 /* This file has been heavily modified from the original(mostly unused
23    code was removed).  If you want to use it for anything other than
24    VRC7 sound emulation, you should get the original from the AdPlug
25    source distribution or the MAME(version 0.37b16) source distribution
26    (but be careful about the different licenses).
27         - Xodnizel
28 */
29    
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdarg.h>
34 #include <math.h>
35 #include "mapinc.h"
36 #include "fmopl.h"
37
38 #ifndef PI
39 #define PI 3.14159265358979323846
40 #endif
41
42 /* -------------------- preliminary define section --------------------- */
43 /* attack/decay rate time rate */
44 #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
45 #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
46
47 #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
48
49 #define FREQ_BITS 24                    /* frequency turn          */
50
51 /* counter bits = 20 , octerve 7 */
52 #define FREQ_RATE   (1<<(FREQ_BITS-20))
53 #define TL_BITS    (FREQ_BITS+2)
54
55 /* final output shift , limit minimum and maximum */
56 #define OPL_OUTSB   (TL_BITS+3-16)              /* OPL output final shift 16bit */
57 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB<<3)
58 #define OPL_MINOUT (-0x8000<<OPL_OUTSB<<3)
59
60 /* -------------------- quality selection --------------------- */
61
62 /* sinwave entries */
63 /* used static memory = SIN_ENT * 4 (byte) */
64 #define SIN_ENT 2048
65
66 /* output level entries (envelope,sinwave) */
67 /* envelope counter lower bits */
68 #define ENV_BITS 16
69 /* envelope output entries */
70 #define EG_ENT   4096
71 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
72 /* used static  memory = EG_ENT*4 (byte)                     */
73
74 #define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
75 #define EG_DED   EG_OFF
76 #define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
77 #define EG_AED   EG_DST
78 #define EG_AST   0                       /* ATTACK START */
79
80 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
81
82 /* LFO table entries */
83 #define VIB_ENT 512
84 #define VIB_SHIFT (32-9)
85 #define AMS_ENT 512
86 #define AMS_SHIFT (32-9)
87
88 #define VIB_RATE 256
89
90 /* -------------------- local defines , macros --------------------- */
91
92 /* register number to channel number , slot offset */
93 #define SLOT1 0
94 #define SLOT2 1
95
96 /* envelope phase */
97 #define ENV_MOD_RR  0x00
98 #define ENV_MOD_DR  0x01
99 #define ENV_MOD_AR  0x02
100
101 /* -------------------- tables --------------------- */
102 static const int slot_array[32]=
103 {
104          0, 2, 4, 1, 3, 5,-1,-1,
105          6, 8,10, 7, 9,11,-1,-1,
106         12,14,16,13,15,17,-1,-1,
107         -1,-1,-1,-1,-1,-1,-1,-1
108 };
109
110 /* key scale level */
111 /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
112 #define DV (EG_STEP/2)
113 static const UINT32 KSL_TABLE[8*16]=
114 {
115         /* OCT 0 */
116          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
117          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
118          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
119          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
120         /* OCT 1 */
121          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
122          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
123          0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
124          1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
125         /* OCT 2 */
126          0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
127          0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
128          3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
129          4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
130         /* OCT 3 */
131          0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
132          3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
133          6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
134          7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
135         /* OCT 4 */
136          0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
137          6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
138          9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
139         10.875/DV,11.250/DV,11.625/DV,12.000/DV,
140         /* OCT 5 */
141          0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
142          9.000/DV,10.125/DV,10.875/DV,11.625/DV,
143         12.000/DV,12.750/DV,13.125/DV,13.500/DV,
144         13.875/DV,14.250/DV,14.625/DV,15.000/DV,
145         /* OCT 6 */
146          0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
147         12.000/DV,13.125/DV,13.875/DV,14.625/DV,
148         15.000/DV,15.750/DV,16.125/DV,16.500/DV,
149         16.875/DV,17.250/DV,17.625/DV,18.000/DV,
150         /* OCT 7 */
151          0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
152         15.000/DV,16.125/DV,16.875/DV,17.625/DV,
153         18.000/DV,18.750/DV,19.125/DV,19.500/DV,
154         19.875/DV,20.250/DV,20.625/DV,21.000/DV
155 };
156 #undef DV
157
158 /* sustain lebel table (3db per step) */
159 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
160 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
161 static const INT32 SL_TABLE[16]={
162  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
163  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
164 };
165 #undef SC
166
167 #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
168 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
169 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
170 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
171 static INT32 *TL_TABLE;
172
173 /* pointers to TL_TABLE with sinwave output offset */
174 static INT32 **SIN_TABLE;
175
176 /* LFO table */
177 static INT32 *AMS_TABLE;
178 static INT32 *VIB_TABLE;
179
180 /* envelope output curve table */
181 /* attack + decay + OFF */
182 static INT32 ENV_CURVE[2*EG_ENT+1];
183
184 /* multiple table */
185 #define ML 2
186 static const UINT32 MUL_TABLE[16]= {
187 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
188    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
189    8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
190 };
191 #undef ML
192
193 /* dummy attack / decay rate ( when rate == 0 ) */
194 static INT32 RATE_0[16]=
195 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
196
197 /* -------------------- static state --------------------- */
198
199 /* lock level of common table */
200 static int num_lock = 0;
201
202 /* work table */
203 static void *cur_chip = NULL;   /* current chip point */
204 /* currenct chip state */
205 /* static OPLSAMPLE  *bufL,*bufR; */
206 static OPL_CH *S_CH;
207 static OPL_CH *E_CH;
208 OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
209
210 static INT32 outd[1];
211 static INT32 ams;
212 static INT32 vib;
213 INT32  *ams_table;
214 INT32  *vib_table;
215 static INT32 amsIncr;
216 static INT32 vibIncr;
217 static INT32 feedback2;         /* connect for SLOT 2 */
218
219 /* --------------------- subroutines  --------------------- */
220
221 INLINE int Limit( int val, int max, int min ) {
222         if ( val > max )
223                 val = max;
224         else if ( val < min )
225                 val = min;
226
227         return val;
228 }
229
230 /* ----- key on  ----- */
231 INLINE void OPL_KEYON(OPL_SLOT *SLOT)
232 {
233         /* sin wave restart */
234         SLOT->Cnt = 0;
235         /* set attack */
236         SLOT->evm = ENV_MOD_AR;
237         SLOT->evs = SLOT->evsa;
238         SLOT->evc = EG_AST;
239         SLOT->eve = EG_AED;
240 }
241 /* ----- key off ----- */
242 INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
243 {
244         if( SLOT->evm > ENV_MOD_RR)
245         {
246                 /* set envelope counter from envleope output */
247                 SLOT->evm = ENV_MOD_RR;
248                 if( !(SLOT->evc&EG_DST) )
249                         //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
250                         SLOT->evc = EG_DST;
251                 SLOT->eve = EG_DED;
252                 SLOT->evs = SLOT->evsr;
253         }
254 }
255
256 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
257 /* return : envelope output */
258 INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
259 {
260         /* calcrate envelope generator */
261         if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
262         {
263                 switch( SLOT->evm ){
264                 case ENV_MOD_AR: /* ATTACK -> DECAY1 */
265                         /* next DR */
266                         SLOT->evm = ENV_MOD_DR;
267                         SLOT->evc = EG_DST;
268                         SLOT->eve = SLOT->SL;
269                         SLOT->evs = SLOT->evsd;
270                         break;
271                 case ENV_MOD_DR: /* DECAY -> SL or RR */
272                         SLOT->evc = SLOT->SL;
273                         SLOT->eve = EG_DED;
274                         if(SLOT->eg_typ)
275                         {
276                                 SLOT->evs = 0;
277                         }
278                         else
279                         {
280                                 SLOT->evm = ENV_MOD_RR;
281                                 SLOT->evs = SLOT->evsr;
282                         }
283                         break;
284                 case ENV_MOD_RR: /* RR -> OFF */
285                         SLOT->evc = EG_OFF;
286                         SLOT->eve = EG_OFF+1;
287                         SLOT->evs = 0;
288                         break;
289                 }
290         }
291         /* calcrate envelope */
292         return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
293 }
294
295 /* set algorythm connection */
296 static void set_algorythm( OPL_CH *CH)
297 {
298         INT32 *carrier = &outd[0];
299         CH->connect1 = CH->CON ? carrier : &feedback2;
300         CH->connect2 = carrier;
301 }
302
303 /* ---------- frequency counter for operater update ---------- */
304 INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
305 {
306         int ksr;
307
308         /* frequency step counter */
309         SLOT->Incr = CH->fc * SLOT->mul;
310         ksr = CH->kcode >> SLOT->KSR;
311
312         if( SLOT->ksr != ksr )
313         {
314                 SLOT->ksr = ksr;
315                 /* attack , decay rate recalcration */
316                 SLOT->evsa = SLOT->AR[ksr];
317                 SLOT->evsd = SLOT->DR[ksr];
318                 SLOT->evsr = SLOT->RR[ksr];
319         }
320         SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
321 }
322
323 /* set multi,am,vib,EG-TYP,KSR,mul */
324 INLINE void set_mul(FM_OPL *OPL,int slot,int v)
325 {
326         OPL_CH   *CH   = &OPL->P_CH[slot/2];
327         OPL_SLOT *SLOT = &CH->SLOT[slot&1];
328
329         SLOT->mul    = MUL_TABLE[v&0x0f];
330         SLOT->KSR    = (v&0x10) ? 0 : 2;
331         SLOT->eg_typ = (v&0x20)>>5;
332         SLOT->vib    = (v&0x40);
333         SLOT->ams    = (v&0x80);
334         CALC_FCSLOT(CH,SLOT);
335 }
336
337 /* set ksl & tl */
338 INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
339 {
340         OPL_CH   *CH   = &OPL->P_CH[slot/2];
341         OPL_SLOT *SLOT = &CH->SLOT[slot&1];
342         int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
343
344 //      if(slot&1) 
345 //         if(ksl) {sprintf(errmsg,"doh");howlong=255;ksl=0;}
346
347         SLOT->ksl = ksl ? ksl : 31;
348 //      SLOT->ksl = ksl ? 3-ksl : 31;
349         SLOT->TL  = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
350
351         if( !(OPL->mode&0x80) )
352         {       /* not CSM latch total level */
353                 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
354         }
355 }
356
357 /* set attack rate & decay rate  */
358 INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
359 {
360         OPL_CH   *CH   = &OPL->P_CH[slot/2];
361         OPL_SLOT *SLOT = &CH->SLOT[slot&1];
362         int ar = v>>4;
363         int dr = v&0x0f;
364
365         SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
366         SLOT->evsa = SLOT->AR[SLOT->ksr];
367         if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
368
369         SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
370         SLOT->evsd = SLOT->DR[SLOT->ksr];
371         if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
372 }
373
374 /* set sustain level & release rate */
375 INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
376 {
377         OPL_CH   *CH   = &OPL->P_CH[slot/2];
378         OPL_SLOT *SLOT = &CH->SLOT[slot&1];
379         int sl = v>>4;
380         int rr = v & 0x0f;
381
382         SLOT->SL = SL_TABLE[sl];
383         if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
384         SLOT->RR = &OPL->DR_TABLE[rr<<2];
385         SLOT->evsr = SLOT->RR[SLOT->ksr];
386         if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
387 }
388
389 /* operator output calcrator */
390 #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
391 /* ---------- calcrate one of channel ---------- */
392 INLINE void OPL_CALC_CH( OPL_CH *CH )
393 {
394         UINT32 env_out;
395         OPL_SLOT *SLOT;
396
397         feedback2 = 0;
398         /* SLOT 1 */
399         SLOT = &CH->SLOT[SLOT1];
400         env_out=OPL_CALC_SLOT(SLOT);
401         if( env_out < EG_ENT-1 )
402         {
403                 /* PG */
404                 if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
405                 else          SLOT->Cnt += SLOT->Incr;
406                 /* connectoion */
407                 if(CH->FB)
408                 {
409                         int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
410                         CH->op1_out[1] = CH->op1_out[0];
411                         *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
412                 }
413                 else
414                 {
415                         *CH->connect1 += OP_OUT(SLOT,env_out,0);
416                 }
417         }else
418         {
419                 CH->op1_out[1] = CH->op1_out[0];
420                 CH->op1_out[0] = 0;
421         }
422         /* SLOT 2 */
423         SLOT = &CH->SLOT[SLOT2];
424         env_out=OPL_CALC_SLOT(SLOT);
425         if( env_out < EG_ENT-1 )
426         {
427                 /* PG */
428                 if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
429                 else          SLOT->Cnt += SLOT->Incr;
430                 /* connectoion */
431                 outd[0] += OP_OUT(SLOT,env_out, feedback2);
432         }
433 }
434
435 /* ----------- initialize time tabls ----------- */
436 static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
437 {
438         int i;
439         double rate;
440
441         /* make attack rate & decay rate tables */
442         for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
443         for (i = 4;i <= 60;i++){
444                 rate  = OPL->freqbase;                                          /* frequency rate */
445                 if( i < 60 ) rate *= 1.0+(i&3)*0.25;            /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
446                 rate *= 1<<((i>>2)-1);                                          /* b2-5 : shift bit */
447                 rate *= (double)(EG_ENT<<ENV_BITS);
448                 OPL->AR_TABLE[i] = rate / ARRATE;
449                 OPL->DR_TABLE[i] = rate / DRRATE;
450         }
451         for (i = 60;i < 76;i++)
452         {
453                 OPL->AR_TABLE[i] = EG_AED-1;
454                 OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
455         }
456 }
457
458 /* ---------- generic table initialize ---------- */
459 static int OPLOpenTable( void )
460 {
461         int s,t;
462         double rate;
463         int i,j;
464         double pom;
465
466         /* allocate dynamic tables */
467         if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
468                 return 0;
469         if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
470         {
471                 free(TL_TABLE);
472                 return 0;
473         }
474         if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
475         {
476                 free(TL_TABLE);
477                 free(SIN_TABLE);
478                 return 0;
479         }
480         if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
481         {
482                 free(TL_TABLE);
483                 free(SIN_TABLE);
484                 free(AMS_TABLE);
485                 return 0;
486         }
487         /* make total level table */
488         for (t = 0;t < EG_ENT-1 ;t++){
489                 rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);   /* dB -> voltage */
490                 TL_TABLE[       t] =  (int)rate;
491                 TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
492
493         }
494         /* fill volume off area */
495         for ( t = EG_ENT-1; t < TL_MAX ;t++){
496                 TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
497         }
498
499         /* make sinwave table (total level offet) */
500         /* degree 0 = degree 180                   = off */
501         SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]         = &TL_TABLE[EG_ENT-1];
502         for (s = 1;s <= SIN_ENT/4;s++){
503                 pom = sin(2*PI*s/SIN_ENT); /* sin     */
504                 pom = 20*log10(1/pom);     /* decibel */
505                 j = pom / EG_STEP;         /* TL_TABLE steps */
506
507         /* degree 0   -  90    , degree 180 -  90 : plus section */
508                 SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
509         /* degree 180 - 270    , degree 360 - 270 : minus section */
510                 SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
511
512         }
513         for (s = 0;s < SIN_ENT;s++)
514         {
515                 SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
516                 SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
517                 SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
518         }
519
520         /* envelope counter -> envelope output table */
521         for (i=0; i<EG_ENT; i++)
522         {
523                 /* ATTACK curve */
524                 pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
525                 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
526                 ENV_CURVE[i] = (int)pom;
527                 /* DECAY ,RELEASE curve */
528                 ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
529         }
530         /* off */
531         ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
532         /* make LFO ams table */
533         for (i=0; i<AMS_ENT; i++)
534         {
535                 pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
536                 AMS_TABLE[i]         = (1.0/EG_STEP)*pom; /* 1dB   */
537                 AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
538         }
539         /* make LFO vibrate table */
540         for (i=0; i<VIB_ENT; i++)
541         {
542                 /* 100cent = 1seminote = 6% ?? */
543                 pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
544                 VIB_TABLE[i]         = VIB_RATE + (pom*0.07); /* +- 7cent */
545                 VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
546         }
547         return 1;
548 }
549
550
551 static void OPLCloseTable( void )
552 {
553         free(TL_TABLE);
554         free(SIN_TABLE);
555         free(AMS_TABLE);
556         free(VIB_TABLE);
557 }
558
559 /* CSM Key Controll */
560 INLINE void CSMKeyControll(OPL_CH *CH)
561 {
562         OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
563         OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
564         /* all key off */
565         OPL_KEYOFF(slot1);
566         OPL_KEYOFF(slot2);
567         /* total level latch */
568         slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
569         slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
570         /* key on */
571         CH->op1_out[0] = CH->op1_out[1] = 0;
572         OPL_KEYON(slot1);
573         OPL_KEYON(slot2);
574 }
575
576 /* ---------- opl initialize ---------- */
577 static void OPL_initalize(FM_OPL *OPL)
578 {
579         int fn;
580
581         /* frequency base */
582         OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72  : 0;
583         /* make time tables */
584         init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
585         /* make fnumber -> increment counter table */
586         for( fn=0 ; fn < 1024 ; fn++ )
587         {
588                 OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
589         }
590         /* LFO freq.table */
591         OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
592         OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
593 }
594
595 /* ---------- write a OPL registers ---------- */
596 static void OPLWriteReg(FM_OPL *OPL, int r, int v)
597 {
598         OPL_CH *CH;
599         int slot;
600         int block_fnum;
601
602         switch(r&0xe0)
603         {
604         case 0x00: /* 00-1f:controll */
605                 switch(r&0x1f)
606                 {
607                 case 0x01:
608                         /* wave selector enable */
609                         if(OPL->type&OPL_TYPE_WAVESEL)
610                         {
611                                 OPL->wavesel = v&0x20;
612                                 if(!OPL->wavesel)
613                                 {
614                                         /* preset compatible mode */
615                                         int c;
616                                         for(c=0;c<OPL->max_ch;c++)
617                                         {
618                                                 OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
619                                                 OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
620                                         }
621                                 }
622                         }
623                         return;
624                 }
625                 break;
626         case 0x20:      /* am,vib,ksr,eg type,mul */
627                 slot = slot_array[r&0x1f];
628                 if(slot == -1) return;
629                 set_mul(OPL,slot,v);
630                 return;
631         case 0x40:
632                 slot = slot_array[r&0x1f];
633                 if(slot == -1) return;
634                 set_ksl_tl(OPL,slot,v);
635                 return;
636         case 0x60:
637                 slot = slot_array[r&0x1f];
638                 if(slot == -1) return;
639                 set_ar_dr(OPL,slot,v);
640                 return;
641         case 0x80:
642                 slot = slot_array[r&0x1f];
643                 if(slot == -1) return;
644                 set_sl_rr(OPL,slot,v);
645                 return;
646         case 0xa0:
647                 switch(r)
648                 {
649                 case 0xbd:
650                         /* amsep,vibdep,r,bd,sd,tom,tc,hh */
651                         {
652                         OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
653                         OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
654                         }
655                         return;
656                 }
657                 /* keyon,block,fnum */
658                 if( (r&0x0f) > 8) return;
659                 CH = &OPL->P_CH[r&0x0f];
660                 if(!(r&0x10))
661                 {       /* a0-a8 */
662                         block_fnum  = (CH->block_fnum&0x1f00) | v;
663                 }
664                 else
665                 {       /* b0-b8 */
666                         int keyon = (v>>5)&1;
667                         block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
668                         if(CH->keyon != keyon)
669                         {
670                                 if( (CH->keyon=keyon) )
671                                 {
672                                         CH->op1_out[0] = CH->op1_out[1] = 0;
673                                         OPL_KEYON(&CH->SLOT[SLOT1]);
674                                         OPL_KEYON(&CH->SLOT[SLOT2]);
675                                 }
676                                 else
677                                 {
678                                         OPL_KEYOFF(&CH->SLOT[SLOT1]);
679                                         OPL_KEYOFF(&CH->SLOT[SLOT2]);
680                                 }
681                         }
682                 }
683                 /* update */
684                 if(CH->block_fnum != block_fnum)
685                 {
686                         int blockRv = 7-(block_fnum>>10);
687                         int fnum   = block_fnum&0x3ff;
688                         CH->block_fnum = block_fnum;
689
690                         CH->ksl_base = KSL_TABLE[block_fnum>>6];
691                         CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
692                         CH->kcode = CH->block_fnum>>9;
693                         if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
694                         CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
695                         CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
696                 }
697                 return;
698         case 0xc0:
699                 /* FB,C */
700                 if( (r&0x0f) > 8) return;
701                 CH = &OPL->P_CH[r&0x0f];
702                 {
703                 int feedback = (v>>1)&7;
704                 CH->FB   = feedback ? (8+1) - feedback : 0;
705                 CH->CON = v&1;
706                 set_algorythm(CH);
707                 }
708                 return;
709         case 0xe0: /* wave type */
710                 slot = slot_array[r&0x1f];
711                 if(slot == -1) return;
712                 CH = &OPL->P_CH[slot/2];
713                 if(OPL->wavesel)
714                 {
715                         CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
716                 }
717                 return;
718         }
719 }
720
721 /* lock/unlock for common table */
722 static int OPL_LockTable(void)
723 {
724         num_lock++;
725         if(num_lock>1) return 0;
726         /* first time */
727         cur_chip = NULL;
728         /* allocate total level table (128kb space) */
729         if( !OPLOpenTable() )
730         {
731                 num_lock--;
732                 return -1;
733         }
734         return 0;
735 }
736
737 static void OPL_UnLockTable(void)
738 {
739         if(num_lock) num_lock--;
740         if(num_lock) return;
741         /* last time */
742         cur_chip = NULL;
743         OPLCloseTable();
744 }
745
746 /*******************************************************************************/
747 /*              YM3812 local section                                                   */
748 /*******************************************************************************/
749
750 /* ---------- update one of chip ----------- */
751 void YM3812UpdateOne(FM_OPL *OPL, UINT32 *buffer, int length)
752 {
753     int i;
754         UINT32 *buf = buffer;
755         UINT32 amsCnt  = OPL->amsCnt;
756         UINT32 vibCnt  = OPL->vibCnt;
757         OPL_CH *CH,*R_CH;
758
759         if( (void *)OPL != cur_chip ){
760                 cur_chip = (void *)OPL;
761                 /* channel pointers */
762                 S_CH = OPL->P_CH;
763                 E_CH = &S_CH[6];
764                 /* LFO state */
765                 amsIncr = OPL->amsIncr;
766                 vibIncr = OPL->vibIncr;
767                 ams_table = OPL->ams_table;
768                 vib_table = OPL->vib_table;
769         }
770         R_CH = E_CH;
771     for( i=0; i < length ; i++ )
772         {
773                 /*            channel A         channel B         channel C      */
774                 /* LFO */
775                 ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
776                 vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
777                 outd[0] = 0;
778                 /* FM part */
779                 for(CH=S_CH ; CH < R_CH ; CH++)
780                         OPL_CALC_CH(CH);
781                 /* limit check */
782                 //data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
783                 /* store to sound buffer */
784                 {
785                  int32 d=outd[0]>>OPL_OUTSB;
786                  if(d<-32768) d=-32768;
787                  d+=32768;
788                  buf[i] += d;
789                 }
790         }
791
792         OPL->amsCnt = amsCnt;
793         OPL->vibCnt = vibCnt;
794 }
795
796 /* ---------- reset one of chip ---------- */
797 void OPLResetChip(FM_OPL *OPL)
798 {
799         int c,s;
800         int i;
801
802         /* reset chip */
803         OPL->mode   = 0;        /* normal mode */
804
805         /* reset with register write */
806         OPLWriteReg(OPL,0x01,0); /* wabesel disable */
807         for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
808         /* reset OPerator paramater */
809         for( c = 0 ; c < OPL->max_ch ; c++ )
810         {
811                 OPL_CH *CH = &OPL->P_CH[c];
812                 /* OPL->P_CH[c].PAN = OPN_CENTER; */
813                 for(s = 0 ; s < 2 ; s++ )
814                 {
815                         /* wave table */
816                         CH->SLOT[s].wavetable = &SIN_TABLE[0];
817                         /* CH->SLOT[s].evm = ENV_MOD_RR; */
818                         CH->SLOT[s].evc = EG_OFF;
819                         CH->SLOT[s].eve = EG_OFF+1;
820                         CH->SLOT[s].evs = 0;
821                 }
822         }
823 }
824
825 /* ----------  Create one of vietual YM3812 ----------       */
826 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
827 FM_OPL *OPLCreate(int type, int clock, int rate)
828 {
829         char *ptr;
830         FM_OPL *OPL;
831         int state_size;
832         int max_ch = 9; /* normaly 9 channels */
833
834         if( OPL_LockTable() ==-1) return NULL;
835         /* allocate OPL state space */
836         state_size  = sizeof(FM_OPL);
837         state_size += sizeof(OPL_CH)*max_ch;
838
839         /* allocate memory block */
840         ptr = malloc(state_size);
841         if(ptr==NULL) return NULL;
842         /* clear */
843         memset(ptr,0,state_size);
844         OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
845         OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
846
847         /* set channel state pointer */
848         OPL->type  = type;
849         OPL->clock = clock;
850         OPL->rate  = rate;
851         OPL->max_ch = max_ch;
852         /* init grobal tables */
853         OPL_initalize(OPL);
854         /* reset chip */
855         OPLResetChip(OPL);
856
857         return OPL;
858 }
859
860 /* ----------  Destroy one of vietual YM3812 ----------       */
861 void OPLDestroy(FM_OPL *OPL)
862 {
863         OPL_UnLockTable();
864         free(OPL);
865 }
866
867 /* ---------- YM3812 I/O interface ---------- */
868 void OPLWrite(FM_OPL *OPL,UINT8 a,UINT8 v)
869 {
870         OPLWriteReg(OPL,a,v);
871 }