adlibemu.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /*
  2. * ADLIBEMU.C
  3. * Copyright (C) 1998-2001 Ken Silverman
  4. * Ken Silverman's official web site: "http://www.advsys.net/ken"
  5. *
  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.
  10. *
  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.
  15. *
  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
  19. */
  20. /*
  21. This file is a digital Adlib emulator for OPL2 and possibly OPL3
  22. Features that could be added in a future version:
  23. - Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit)
  24. - Global Keyboard Split Number Bit (need to research this one some more)
  25. - 2nd Adlib chip for OPL3 (simply need to make my cell array bigger)
  26. - Advanced connection modes of OPL3 (Just need to add more "docell" cases)
  27. - L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo)
  28. Features that aren't worth supporting:
  29. - Anything related to adlib timers&interrupts (Sorry - I always used IRQ0)
  30. - Composite sine wave mode (CSM) (Supported only on ancient cards)
  31. I'm not sure about a few things in my code:
  32. - Attack curve. What function is this anyway? I chose to use an order-3
  33. polynomial to approximate but this doesn't seem right.
  34. - Attack/Decay/Release constants - my constants may not be exact
  35. - What should ADJUSTSPEED be?
  36. - Haven't verified that Global Keyboard Split Number Bit works yet
  37. - Some of the drums don't always sound right. It's pretty hard to guess
  38. the exact waveform of drums when you look at random data which is
  39. slightly randomized due to digital ADC recording.
  40. - Adlib seems to have a lot more treble than my emulator does. I'm not
  41. sure if this is simply unfixable due to the sound blaster's different
  42. filtering on FM and digital playback or if it's a serious bug in my
  43. code.
  44. */
  45. #include <math.h>
  46. #include <string.h>
  47. #if !defined(max) && !defined(__cplusplus)
  48. #define max(a,b) (((a) > (b)) ? (a) : (b))
  49. #endif
  50. #if !defined(min) && !defined(__cplusplus)
  51. #define min(a,b) (((a) < (b)) ? (a) : (b))
  52. #endif
  53. #define PI 3.141592653589793
  54. #define MAXCELLS 18
  55. #define WAVPREC 2048
  56. static float AMPSCALE=(8192.0);
  57. #define FRQSCALE (49716/512.0)
  58. //Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!)
  59. #define MODFACTOR 4.0 //How much of modulator cell goes into carrier
  60. #define MFBFACTOR 1.0 //How much feedback goes back into modulator
  61. #define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state
  62. //Constants for Ken's Awe64G, on a P-133
  63. //#define MODFACTOR 4.25 //How much of modulator cell goes into carrier
  64. //#define MFBFACTOR 0.5 //How much feedback goes back into modulator
  65. //#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state
  66. typedef struct
  67. {
  68. float val, t, tinc, vol, sustain, amp, mfb;
  69. float a0, a1, a2, a3, decaymul, releasemul;
  70. short *waveform;
  71. long wavemask;
  72. void (*cellfunc)(void *, float);
  73. unsigned char flags, dum0, dum1, dum2;
  74. } celltype;
  75. static long numspeakers, bytespersample;
  76. static float recipsamp;
  77. static celltype cell[MAXCELLS];
  78. static signed short wavtable[WAVPREC*3];
  79. static float kslmul[4] = {0.0,0.5,0.25,1.0};
  80. static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16];
  81. static unsigned char adlibreg[256], ksl[8][16];
  82. static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18};
  83. static unsigned char odrumstat = 0;
  84. 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};
  85. float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker
  86. float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker
  87. long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker
  88. long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker
  89. long nlvol[9], nrvol[9];
  90. long nlplc[9], nrplc[9];
  91. long rend = 0;
  92. #define FIFOSIZ 256
  93. static float *rptr[9], *nrptr[9];
  94. static float rbuf[9][FIFOSIZ*2];
  95. static float snd[FIFOSIZ*2];
  96. #ifndef USING_ASM
  97. #define _inline
  98. #endif
  99. #ifdef USING_ASM
  100. static _inline void ftol (float f, long *a)
  101. {
  102. _asm
  103. {
  104. mov eax, a
  105. fld f
  106. fistp dword ptr [eax]
  107. }
  108. }
  109. #else
  110. static void ftol(float f, long *a) {
  111. *a=f;
  112. }
  113. #endif
  114. #define ctc ((celltype *)c) //A rare attempt to make code easier to read!
  115. void docell4 (void *c, float modulator) { }
  116. void docell3 (void *c, float modulator)
  117. {
  118. long i;
  119. ftol(ctc->t+modulator,&i);
  120. ctc->t += ctc->tinc;
  121. ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
  122. }
  123. void docell2 (void *c, float modulator)
  124. {
  125. long i;
  126. ftol(ctc->t+modulator,&i);
  127. if (*(long *)&ctc->amp <= 0x37800000)
  128. {
  129. ctc->amp = 0;
  130. ctc->cellfunc = docell4;
  131. }
  132. ctc->amp *= ctc->releasemul;
  133. ctc->t += ctc->tinc;
  134. ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
  135. }
  136. void docell1 (void *c, float modulator)
  137. {
  138. long i;
  139. ftol(ctc->t+modulator,&i);
  140. if ((*(long *)&ctc->amp) <= (*(long *)&ctc->sustain))
  141. {
  142. if (ctc->flags&32)
  143. {
  144. ctc->amp = ctc->sustain;
  145. ctc->cellfunc = docell3;
  146. }
  147. else
  148. ctc->cellfunc = docell2;
  149. }
  150. else
  151. ctc->amp *= ctc->decaymul;
  152. ctc->t += ctc->tinc;
  153. ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
  154. }
  155. void docell0 (void *c, float modulator)
  156. {
  157. long i;
  158. ftol(ctc->t+modulator,&i);
  159. ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0;
  160. if ((*(long *)&ctc->amp) > 0x3f800000)
  161. {
  162. ctc->amp = 1;
  163. ctc->cellfunc = docell1;
  164. }
  165. ctc->t += ctc->tinc;
  166. ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
  167. }
  168. static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1};
  169. static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1};
  170. static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3};
  171. static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
  172. static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
  173. void cellon (long i, long j, celltype *c, unsigned char iscarrier)
  174. {
  175. long frn, oct, toff;
  176. float f;
  177. frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
  178. oct = ((((long)adlibreg[i+0xb0])>>2)&7);
  179. toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1)));
  180. if (!(adlibreg[j+0x20]&16)) toff >>= 2;
  181. f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp;
  182. c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f;
  183. f = -7.4493*decrelconst[toff&3]*recipsamp;
  184. c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2)));
  185. c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2)));
  186. c->wavemask = wavemask[adlibreg[j+0xe0]&7];
  187. c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]];
  188. if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC];
  189. c->t = wavestart[adlibreg[j+0xe0]&7];
  190. c->flags = adlibreg[j+0x20];
  191. c->cellfunc = docell0;
  192. c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
  193. c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
  194. (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
  195. c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5);
  196. if (!iscarrier) c->amp = 0;
  197. c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR;
  198. if (!(adlibreg[i+0xc0]&14)) c->mfb = 0;
  199. c->val = 0;
  200. }
  201. //This function (and bug fix) written by Chris Moeller
  202. void cellfreq (signed long i, signed long j, celltype *c)
  203. {
  204. long frn, oct;
  205. frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
  206. oct = ((((long)adlibreg[i+0xb0])>>2)&7);
  207. c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
  208. c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
  209. (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
  210. }
  211. static long initfirstime = 0;
  212. void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample)
  213. {
  214. long i, j, frn, oct;
  215. memset((void *)adlibreg,0,sizeof(adlibreg));
  216. memset((void *)cell,0,sizeof(celltype)*MAXCELLS);
  217. memset((void *)rbuf,0,sizeof(rbuf));
  218. rend = 0; odrumstat = 0;
  219. for(i=0;i<MAXCELLS;i++)
  220. {
  221. cell[i].cellfunc = docell4;
  222. cell[i].amp = 0;
  223. cell[i].vol = 0;
  224. cell[i].t = 0;
  225. cell[i].tinc = 0;
  226. cell[i].wavemask = 0;
  227. cell[i].waveform = &wavtable[WAVPREC];
  228. }
  229. numspeakers = danumspeakers;
  230. bytespersample = dabytespersample;
  231. recipsamp = 1.0 / (float)dasamplerate;
  232. for(i=15;i>=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0);
  233. if (!initfirstime)
  234. {
  235. initfirstime = 1;
  236. for(i=0;i<(WAVPREC>>1);i++)
  237. {
  238. wavtable[i] =
  239. wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC));
  240. wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC));
  241. }
  242. for(i=0;i<(WAVPREC>>3);i++)
  243. {
  244. wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384;
  245. wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384;
  246. }
  247. //[table in book]*8/3
  248. ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37;
  249. ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47;
  250. ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41;
  251. for(j=6;j>=0;j--)
  252. for(i=0;i<16;i++)
  253. {
  254. oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0;
  255. ksl[j][i] = (unsigned char)oct;
  256. }
  257. }
  258. else
  259. {
  260. for(i=0;i<9;i++)
  261. {
  262. frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
  263. oct = ((((long)adlibreg[i+0xb0])>>2)&7);
  264. cell[i].tinc = (float)(frn<<oct)*nfrqmul[adlibreg[modulatorbase[i]+0x20]&15];
  265. }
  266. }
  267. }
  268. void adlib0 (long i, long v)
  269. {
  270. unsigned char tmp = adlibreg[i];
  271. adlibreg[i] = v;
  272. if (i == 0xbd)
  273. {
  274. if ((v&16) > (odrumstat&16)) //BassDrum
  275. {
  276. cellon(6,16,&cell[6],0);
  277. cellon(6,19,&cell[15],1);
  278. cell[15].vol *= 2;
  279. }
  280. if ((v&8) > (odrumstat&8)) //Snare
  281. {
  282. cellon(16,20,&cell[16],0);
  283. cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]);
  284. if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0;
  285. cell[16].vol *= 2;
  286. }
  287. if ((v&4) > (odrumstat&4)) //TomTom
  288. {
  289. cellon(8,18,&cell[8],0);
  290. cell[8].vol *= 2;
  291. }
  292. if ((v&2) > (odrumstat&2)) //Cymbal
  293. {
  294. cellon(17,21,&cell[17],0);
  295. cell[17].wavemask = wavemask[5];
  296. cell[17].waveform = &wavtable[waveform[5]];
  297. cell[17].tinc *= 16; cell[17].vol *= 2;
  298. //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0;
  299. //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6))
  300. // cell[17].waveform = &wavtable[(WAVPREC*7)>>2];
  301. //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3))
  302. // cell[17].waveform = &wavtable[(WAVPREC*5)>>2];
  303. }
  304. if ((v&1) > (odrumstat&1)) //Hihat
  305. {
  306. cellon(7,17,&cell[7],0);
  307. if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) ||
  308. ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0;
  309. if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; }
  310. }
  311. odrumstat = v;
  312. }
  313. else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6))
  314. {
  315. if ((i&7) < 3) // Modulator
  316. cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]);
  317. else // Carrier
  318. cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]);
  319. }
  320. else if ((unsigned)(i-0xa0) < (unsigned)9)
  321. {
  322. cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]);
  323. cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]);
  324. }
  325. else if ((unsigned)(i-0xb0) < (unsigned)9)
  326. {
  327. if ((v&32) > (tmp&32))
  328. {
  329. cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0);
  330. cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1);
  331. }
  332. else if ((v&32) < (tmp&32))
  333. cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2;
  334. cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]);
  335. cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]);
  336. }
  337. //outdata(i,v);
  338. }
  339. #ifdef USING_ASM
  340. static long fpuasm;
  341. static float fakeadd = 8388608.0+128.0;
  342. static _inline void clipit8 (float f, long a)
  343. {
  344. _asm
  345. {
  346. mov edi, a
  347. fld dword ptr f
  348. fadd dword ptr fakeadd
  349. fstp dword ptr fpuasm
  350. mov eax, fpuasm
  351. test eax, 0x007fff00
  352. jz short skipit
  353. shr eax, 16
  354. xor eax, -1
  355. skipit: mov byte ptr [edi], al
  356. }
  357. }
  358. static _inline void clipit16 (float f, long a)
  359. {
  360. _asm
  361. {
  362. mov eax, a
  363. fld dword ptr f
  364. fist word ptr [eax]
  365. cmp word ptr [eax], 0x8000
  366. jne short skipit2
  367. fst dword ptr [fpuasm]
  368. cmp fpuasm, 0x80000000
  369. sbb word ptr [eax], 0
  370. skipit2: fstp st
  371. }
  372. }
  373. #else
  374. static void clipit8(float f,unsigned char *a) {
  375. f/=256.0;
  376. f+=128.0;
  377. if (f>254.5) *a=255;
  378. else if (f<0.5) *a=0;
  379. else *a=f;
  380. }
  381. static void clipit16(float f,short *a) {
  382. if (f>32766.5) *a=32767;
  383. else if (f<-32767.5) *a=-32768;
  384. else *a=f;
  385. }
  386. #endif
  387. void adlibsetvolume(int i) {
  388. AMPSCALE=i;
  389. }
  390. void adlibgetsample (unsigned char *sndptr, long numbytes)
  391. {
  392. long i, j, k=0, ns, endsamples, rptrs, numsamples;
  393. celltype *cptr;
  394. float f;
  395. short *sndptr2=(short *)sndptr;
  396. numsamples = (numbytes>>(numspeakers+bytespersample-2));
  397. if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE;
  398. if (numspeakers == 1)
  399. {
  400. nlvol[0] = lvol[0]*f;
  401. for(i=0;i<9;i++) rptr[i] = &rbuf[0][0];
  402. rptrs = 1;
  403. }
  404. else
  405. {
  406. rptrs = 0;
  407. for(i=0;i<9;i++)
  408. {
  409. if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) ||
  410. (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1]))
  411. {
  412. nlvol[rptrs] = lvol[i]*f;
  413. nrvol[rptrs] = rvol[i]*f;
  414. nlplc[rptrs] = rend-min(max(lplc[i],0),FIFOSIZ);
  415. nrplc[rptrs] = rend-min(max(rplc[i],0),FIFOSIZ);
  416. rptrs++;
  417. }
  418. rptr[i] = &rbuf[rptrs-1][0];
  419. }
  420. }
  421. //CPU time used to be somewhat less when emulator was only mono!
  422. // Because of no delay fifos!
  423. for(ns=0;ns<numsamples;ns+=endsamples)
  424. {
  425. endsamples = min(FIFOSIZ*2-rend,FIFOSIZ);
  426. endsamples = min(endsamples,numsamples-ns);
  427. for(i=0;i<9;i++)
  428. nrptr[i] = &rptr[i][rend];
  429. for(i=0;i<rptrs;i++)
  430. memset((void *)&rbuf[i][rend],0,endsamples*sizeof(float));
  431. if (adlibreg[0xbd]&0x20)
  432. {
  433. //BassDrum (j=6)
  434. if (cell[15].cellfunc != docell4)
  435. {
  436. if (adlibreg[0xc6]&1)
  437. {
  438. for(i=0;i<endsamples;i++)
  439. {
  440. (cell[15].cellfunc)((void *)&cell[15],0.0);
  441. nrptr[6][i] += cell[15].val;
  442. }
  443. }
  444. else
  445. {
  446. for(i=0;i<endsamples;i++)
  447. {
  448. (cell[6].cellfunc)((void *)&cell[6],cell[6].val*cell[6].mfb);
  449. (cell[15].cellfunc)((void *)&cell[15],cell[6].val*WAVPREC*MODFACTOR);
  450. nrptr[6][i] += cell[15].val;
  451. }
  452. }
  453. }
  454. //Snare/Hihat (j=7), Cymbal/TomTom (j=8)
  455. if ((cell[7].cellfunc != docell4) || (cell[8].cellfunc != docell4) || (cell[16].cellfunc != docell4) || (cell[17].cellfunc != docell4))
  456. {
  457. for(i=0;i<endsamples;i++)
  458. {
  459. k = k*1664525+1013904223;
  460. (cell[16].cellfunc)((void *)&cell[16],k&((WAVPREC>>1)-1)); //Snare
  461. (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat
  462. (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal
  463. (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom
  464. nrptr[7][i] += cell[7].val + cell[16].val;
  465. nrptr[8][i] += cell[8].val + cell[17].val;
  466. }
  467. }
  468. }
  469. for(j=9-1;j>=0;j--)
  470. {
  471. if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue;
  472. cptr = &cell[j]; k = j;
  473. if (adlibreg[0xc0+k]&1)
  474. {
  475. if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue;
  476. for(i=0;i<endsamples;i++)
  477. {
  478. (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
  479. (cptr->cellfunc)((void *)&cptr[9],0);
  480. nrptr[j][i] += cptr[9].val + cptr->val;
  481. }
  482. }
  483. else
  484. {
  485. if (cptr[9].cellfunc == docell4) continue;
  486. for(i=0;i<endsamples;i++)
  487. {
  488. (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
  489. (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR);
  490. nrptr[j][i] += cptr[9].val;
  491. }
  492. }
  493. }
  494. if (numspeakers == 1)
  495. {
  496. if (bytespersample == 1)
  497. {
  498. for(i=endsamples-1;i>=0;i--)
  499. clipit8(nrptr[0][i]*nlvol[0],sndptr+1);
  500. }
  501. else
  502. {
  503. for(i=endsamples-1;i>=0;i--)
  504. clipit16(nrptr[0][i]*nlvol[0],sndptr2+i);
  505. }
  506. }
  507. else
  508. {
  509. memset((void *)snd,0,endsamples*sizeof(float)*2);
  510. for(j=0;j<rptrs;j++)
  511. {
  512. for(i=0;i<endsamples;i++)
  513. {
  514. snd[(i<<1) ] += rbuf[j][(nlplc[j]+i)&(FIFOSIZ*2-1)]*nlvol[j];
  515. snd[(i<<1)+1] += rbuf[j][(nrplc[j]+i)&(FIFOSIZ*2-1)]*nrvol[j];
  516. }
  517. nlplc[j] += endsamples;
  518. nrplc[j] += endsamples;
  519. }
  520. if (bytespersample == 1)
  521. {
  522. for(i=(endsamples<<1)-1;i>=0;i--)
  523. clipit8(snd[i],sndptr+i);
  524. }
  525. else
  526. {
  527. for(i=(endsamples<<1)-1;i>=0;i--)
  528. clipit16(snd[i],sndptr2+i);
  529. }
  530. }
  531. sndptr = sndptr+(numspeakers*endsamples);
  532. sndptr2 = sndptr2+(numspeakers*endsamples);
  533. rend = ((rend+endsamples)&(FIFOSIZ*2-1));
  534. }
  535. }