3 * Copyright (C) 1998-2001 Ken Silverman
4 * Ken Silverman's official web site: "http://www.advsys.net/ken"
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 This file is a digital Adlib emulator for OPL2 and possibly OPL3
24 Features that could be added in a future version:
25 - Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit)
26 - Global Keyboard Split Number Bit (need to research this one some more)
27 - 2nd Adlib chip for OPL3 (simply need to make my cell array bigger)
28 - Advanced connection modes of OPL3 (Just need to add more "docell" cases)
29 - L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo)
31 Features that aren't worth supporting:
32 - Anything related to adlib timers&interrupts (Sorry - I always used IRQ0)
33 - Composite sine wave mode (CSM) (Supported only on ancient cards)
35 I'm not sure about a few things in my code:
36 - Attack curve. What function is this anyway? I chose to use an order-3
37 polynomial to approximate but this doesn't seem right.
38 - Attack/Decay/Release constants - my constants may not be exact
39 - What should ADJUSTSPEED be?
40 - Haven't verified that Global Keyboard Split Number Bit works yet
41 - Some of the drums don't always sound right. It's pretty hard to guess
42 the exact waveform of drums when you look at random data which is
43 slightly randomized due to digital ADC recording.
44 - Adlib seems to have a lot more treble than my emulator does. I'm not
45 sure if this is simply unfixable due to the sound blaster's different
46 filtering on FM and digital playback or if it's a serious bug in my
53 #if !defined(max) && !defined(__cplusplus)
54 #define max(a,b) (((a) > (b)) ? (a) : (b))
56 #if !defined(min) && !defined(__cplusplus)
57 #define min(a,b) (((a) < (b)) ? (a) : (b))
60 #define PI 3.141592653589793
64 static float AMPSCALE=(8192.0);
65 #define FRQSCALE (49716/512.0)
67 //Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!)
68 #define MODFACTOR 4.0 //How much of modulator cell goes into carrier
69 #define MFBFACTOR 1.0 //How much feedback goes back into modulator
70 #define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state
72 //Constants for Ken's Awe64G, on a P-133
73 //#define MODFACTOR 4.25 //How much of modulator cell goes into carrier
74 //#define MFBFACTOR 0.5 //How much feedback goes back into modulator
75 //#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state
79 float val, t, tinc, vol, sustain, amp, mfb;
80 float a0, a1, a2, a3, decaymul, releasemul;
83 void (*cellfunc)(void *, float);
84 unsigned char flags, dum0, dum1, dum2;
87 static long numspeakers, bytespersample;
88 static float recipsamp;
89 static celltype cell[MAXCELLS];
90 static signed short wavtable[WAVPREC*3];
91 static float kslmul[4] = {0.0,0.5,0.25,1.0};
92 static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16];
93 static unsigned char adlibreg[256], ksl[8][16];
94 static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18};
95 static unsigned char odrumstat = 0;
96 static unsigned char base2cell[22] = {0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8};
98 float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker
99 float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker
100 long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker
101 long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker
103 long nlvol[9], nrvol[9];
104 long nlplc[9], nrplc[9];
107 static float *rptr[9], *nrptr[9];
108 static float rbuf[9][FIFOSIZ*2];
109 static float snd[FIFOSIZ*2];
116 static _inline void ftol (float f, long *a)
122 fistp dword ptr [eax]
126 static void ftol(float f, long *a) {
131 #define ctc ((celltype *)c) //A rare attempt to make code easier to read!
132 void docell4 (void *c, float modulator) { }
133 void docell3 (void *c, float modulator)
137 ftol(ctc->t+modulator,&i);
139 ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
141 void docell2 (void *c, float modulator)
145 ftol(ctc->t+modulator,&i);
147 if (*(long *)&ctc->amp <= 0x37800000)
150 ctc->cellfunc = docell4;
152 ctc->amp *= ctc->releasemul;
155 ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
157 void docell1 (void *c, float modulator)
161 ftol(ctc->t+modulator,&i);
163 if ((*(long *)&ctc->amp) <= (*(long *)&ctc->sustain))
167 ctc->amp = ctc->sustain;
168 ctc->cellfunc = docell3;
171 ctc->cellfunc = docell2;
174 ctc->amp *= ctc->decaymul;
177 ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
179 void docell0 (void *c, float modulator)
183 ftol(ctc->t+modulator,&i);
185 ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0;
186 if ((*(long *)&ctc->amp) > 0x3f800000)
189 ctc->cellfunc = docell1;
193 ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
197 static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1};
198 static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1};
199 static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3};
200 static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
201 static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
202 void cellon (long i, long j, celltype *c, unsigned char iscarrier)
207 frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
208 oct = ((((long)adlibreg[i+0xb0])>>2)&7);
209 toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1)));
210 if (!(adlibreg[j+0x20]&16)) toff >>= 2;
212 f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp;
213 c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f;
214 f = -7.4493*decrelconst[toff&3]*recipsamp;
215 c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2)));
216 c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2)));
217 c->wavemask = wavemask[adlibreg[j+0xe0]&7];
218 c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]];
219 if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC];
220 c->t = wavestart[adlibreg[j+0xe0]&7];
221 c->flags = adlibreg[j+0x20];
222 c->cellfunc = docell0;
223 c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
224 c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
225 (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
226 c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5);
227 if (!iscarrier) c->amp = 0;
228 c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR;
229 if (!(adlibreg[i+0xc0]&14)) c->mfb = 0;
233 //This function (and bug fix) written by Chris Moeller
234 void cellfreq (signed long i, signed long j, celltype *c)
238 frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
239 oct = ((((long)adlibreg[i+0xb0])>>2)&7);
241 c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
242 c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
243 (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
246 static long initfirstime = 0;
247 void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample)
251 memset((void *)adlibreg,0,sizeof(adlibreg));
252 memset((void *)cell,0,sizeof(celltype)*MAXCELLS);
253 memset((void *)rbuf,0,sizeof(rbuf));
254 rend = 0; odrumstat = 0;
256 for(i=0;i<MAXCELLS;i++)
258 cell[i].cellfunc = docell4;
263 cell[i].wavemask = 0;
264 cell[i].waveform = &wavtable[WAVPREC];
267 numspeakers = danumspeakers;
268 bytespersample = dabytespersample;
270 recipsamp = 1.0 / (float)dasamplerate;
271 for(i=15;i>=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0);
277 for(i=0;i<(WAVPREC>>1);i++)
280 wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC));
281 wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC));
283 for(i=0;i<(WAVPREC>>3);i++)
285 wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384;
286 wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384;
289 //[table in book]*8/3
290 ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37;
291 ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47;
292 ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41;
296 oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0;
297 ksl[j][i] = (unsigned char)oct;
304 frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
305 oct = ((((long)adlibreg[i+0xb0])>>2)&7);
306 cell[i].tinc = (float)(frn<<oct)*nfrqmul[adlibreg[modulatorbase[i]+0x20]&15];
311 void adlib0 (long i, long v)
313 unsigned char tmp = adlibreg[i];
318 if ((v&16) > (odrumstat&16)) //BassDrum
320 cellon(6,16,&cell[6],0);
321 cellon(6,19,&cell[15],1);
324 if ((v&8) > (odrumstat&8)) //Snare
326 cellon(16,20,&cell[16],0);
327 cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]);
328 if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0;
331 if ((v&4) > (odrumstat&4)) //TomTom
333 cellon(8,18,&cell[8],0);
336 if ((v&2) > (odrumstat&2)) //Cymbal
338 cellon(17,21,&cell[17],0);
340 cell[17].wavemask = wavemask[5];
341 cell[17].waveform = &wavtable[waveform[5]];
342 cell[17].tinc *= 16; cell[17].vol *= 2;
344 //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0;
345 //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6))
346 // cell[17].waveform = &wavtable[(WAVPREC*7)>>2];
347 //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3))
348 // cell[17].waveform = &wavtable[(WAVPREC*5)>>2];
350 if ((v&1) > (odrumstat&1)) //Hihat
352 cellon(7,17,&cell[7],0);
353 if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) ||
354 ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0;
355 if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; }
360 else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6))
362 if ((i&7) < 3) // Modulator
363 cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]);
365 cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]);
367 else if ((unsigned)(i-0xa0) < (unsigned)9)
369 cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]);
370 cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]);
372 else if ((unsigned)(i-0xb0) < (unsigned)9)
374 if ((v&32) > (tmp&32))
376 cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0);
377 cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1);
379 else if ((v&32) < (tmp&32))
380 cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2;
381 cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]);
382 cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]);
390 static float fakeadd = 8388608.0+128.0;
391 static _inline void clipit8 (float f, long a)
397 fadd dword ptr fakeadd
398 fstp dword ptr fpuasm
404 skipit: mov byte ptr [edi], al
408 static _inline void clipit16 (float f, long a)
415 cmp word ptr [eax], 0x8000
417 fst dword ptr [fpuasm]
418 cmp fpuasm, 0x80000000
419 sbb word ptr [eax], 0
424 static void clipit8(float f,unsigned char *a) {
428 else if (f<0.5) *a=0;
432 static void clipit16(float f,short *a) {
433 if (f>32766.5) *a=32767;
434 else if (f<-32767.5) *a=-32768;
439 void adlibsetvolume(int i) {
443 void adlibgetsample (unsigned char *sndptr, long numbytes)
445 long i, j, k=0, ns, endsamples, rptrs, numsamples;
448 short *sndptr2=(short *)sndptr;
450 numsamples = (numbytes>>(numspeakers+bytespersample-2));
452 if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE;
453 if (numspeakers == 1)
455 nlvol[0] = lvol[0]*f;
456 for(i=0;i<9;i++) rptr[i] = &rbuf[0][0];
464 if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) ||
465 (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1]))
467 nlvol[rptrs] = lvol[i]*f;
468 nrvol[rptrs] = rvol[i]*f;
469 nlplc[rptrs] = rend-min(max(lplc[i],0),FIFOSIZ);
470 nrplc[rptrs] = rend-min(max(rplc[i],0),FIFOSIZ);
473 rptr[i] = &rbuf[rptrs-1][0];
478 //CPU time used to be somewhat less when emulator was only mono!
479 // Because of no delay fifos!
481 for(ns=0;ns<numsamples;ns+=endsamples)
483 endsamples = min(FIFOSIZ*2-rend,FIFOSIZ);
484 endsamples = min(endsamples,numsamples-ns);
487 nrptr[i] = &rptr[i][rend];
489 memset((void *)&rbuf[i][rend],0,endsamples*sizeof(float));
491 if (adlibreg[0xbd]&0x20)
494 if (cell[15].cellfunc != docell4)
496 if (adlibreg[0xc6]&1)
498 for(i=0;i<endsamples;i++)
500 (cell[15].cellfunc)((void *)&cell[15],0.0);
501 nrptr[6][i] += cell[15].val;
506 for(i=0;i<endsamples;i++)
508 (cell[6].cellfunc)((void *)&cell[6],cell[6].val*cell[6].mfb);
509 (cell[15].cellfunc)((void *)&cell[15],cell[6].val*WAVPREC*MODFACTOR);
510 nrptr[6][i] += cell[15].val;
515 //Snare/Hihat (j=7), Cymbal/TomTom (j=8)
516 if ((cell[7].cellfunc != docell4) || (cell[8].cellfunc != docell4) || (cell[16].cellfunc != docell4) || (cell[17].cellfunc != docell4))
518 for(i=0;i<endsamples;i++)
520 k = k*1664525+1013904223;
521 (cell[16].cellfunc)((void *)&cell[16],k&((WAVPREC>>1)-1)); //Snare
522 (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat
523 (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal
524 (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom
525 nrptr[7][i] += cell[7].val + cell[16].val;
526 nrptr[8][i] += cell[8].val + cell[17].val;
532 if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue;
534 cptr = &cell[j]; k = j;
535 if (adlibreg[0xc0+k]&1)
537 if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue;
538 for(i=0;i<endsamples;i++)
540 (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
541 (cptr->cellfunc)((void *)&cptr[9],0);
542 nrptr[j][i] += cptr[9].val + cptr->val;
547 if (cptr[9].cellfunc == docell4) continue;
548 for(i=0;i<endsamples;i++)
550 (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
551 (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR);
552 nrptr[j][i] += cptr[9].val;
557 if (numspeakers == 1)
559 if (bytespersample == 1)
561 for(i=endsamples-1;i>=0;i--)
562 clipit8(nrptr[0][i]*nlvol[0],sndptr+1);
566 for(i=endsamples-1;i>=0;i--)
567 clipit16(nrptr[0][i]*nlvol[0],sndptr2+i);
572 memset((void *)snd,0,endsamples*sizeof(float)*2);
575 for(i=0;i<endsamples;i++)
577 snd[(i<<1) ] += rbuf[j][(nlplc[j]+i)&(FIFOSIZ*2-1)]*nlvol[j];
578 snd[(i<<1)+1] += rbuf[j][(nrplc[j]+i)&(FIFOSIZ*2-1)]*nrvol[j];
580 nlplc[j] += endsamples;
581 nrplc[j] += endsamples;
584 if (bytespersample == 1)
586 for(i=(endsamples<<1)-1;i>=0;i--)
587 clipit8(snd[i],sndptr+i);
591 for(i=(endsamples<<1)-1;i>=0;i--)
592 clipit16(snd[i],sndptr2+i);
596 sndptr = sndptr+(numspeakers*endsamples);
597 sndptr2 = sndptr2+(numspeakers*endsamples);
598 rend = ((rend+endsamples)&(FIFOSIZ*2-1));