Ticket #9010: dosbox_adlib_v4.patch

File dosbox_adlib_v4.patch, 195.9 KB (added by lordhoto, 11 years ago)

Patch against r40184.

Line 
1Index: sound/module.mk
2===================================================================
3--- sound/module.mk (revision 40181)
4+++ sound/module.mk (working copy)
5@@ -30,6 +30,9 @@
6 mods/rjp1.o \
7 mods/soundfx.o \
8 softsynth/adlib.o \
9+ softsynth/adlib/dbopl.o \
10+ softsynth/adlib/dosbox.o \
11+ softsynth/adlib/mame.o \
12 softsynth/ym2612.o \
13 softsynth/fluidsynth.o \
14 softsynth/mt32.o \
15Index: sound/fmopl.h
16===================================================================
17--- sound/fmopl.h 2009-04-28 18:36:54.319782168 +0200
18+++ sound/fmopl.h 2009-04-28 18:38:31.171943036 +0200
19@@ -8,166 +8,64 @@
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
23-
24+ *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29-
30+ *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 *
35- * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.h $
36- * $Id: fmopl.h 38211 2009-02-15 10:07:50Z sev $
37- *
38- * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
39- * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
40+ * $URL$
41+ * $Id$
42 */
43
44-
45 #ifndef SOUND_FMOPL_H
46 #define SOUND_FMOPL_H
47
48 #include "common/scummsys.h"
49-#include "common/util.h"
50
51-enum {
52- FMOPL_ENV_BITS_HQ = 16,
53- FMOPL_ENV_BITS_MQ = 8,
54- FMOPL_ENV_BITS_LQ = 8,
55- FMOPL_EG_ENT_HQ = 4096,
56- FMOPL_EG_ENT_MQ = 1024,
57- FMOPL_EG_ENT_LQ = 128
58-};
59+namespace AdLib {
60+
61+// TODO: Documentation
62+class AdLib {
63+public:
64+ virtual ~AdLib() {}
65
66+ enum kOplType {
67+ kOpl2 = 0
68+ };
69
70-typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
71-typedef void (*OPL_IRQHANDLER)(int param,int irq);
72-typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
73-
74-#define OPL_TYPE_WAVESEL 0x01 /* waveform select */
75-
76-/* Saving is necessary for member of the 'R' mark for suspend/resume */
77-/* ---------- OPL one of slot ---------- */
78-typedef struct fm_opl_slot {
79- int TL; /* total level :TL << 8 */
80- int TLL; /* adjusted now TL */
81- uint8 KSR; /* key scale rate :(shift down bit) */
82- int *AR; /* attack rate :&AR_TABLE[AR<<2] */
83- int *DR; /* decay rate :&DR_TABLE[DR<<2] */
84- int SL; /* sustain level :SL_TABLE[SL] */
85- int *RR; /* release rate :&DR_TABLE[RR<<2] */
86- uint8 ksl; /* keyscale level :(shift down bits) */
87- uint8 ksr; /* key scale rate :kcode>>KSR */
88- uint mul; /* multiple :ML_TABLE[ML] */
89- uint Cnt; /* frequency count */
90- uint Incr; /* frequency step */
91-
92- /* envelope generator state */
93- uint8 eg_typ;/* envelope type flag */
94- uint8 evm; /* envelope phase */
95- int evc; /* envelope counter */
96- int eve; /* envelope counter end point */
97- int evs; /* envelope counter step */
98- int evsa; /* envelope step for AR :AR[ksr] */
99- int evsd; /* envelope step for DR :DR[ksr] */
100- int evsr; /* envelope step for RR :RR[ksr] */
101-
102- /* LFO */
103- uint8 ams; /* ams flag */
104- uint8 vib; /* vibrate flag */
105- /* wave selector */
106- int **wavetable;
107-} OPL_SLOT;
108-
109-/* ---------- OPL one of channel ---------- */
110-typedef struct fm_opl_channel {
111- OPL_SLOT SLOT[2];
112- uint8 CON; /* connection type */
113- uint8 FB; /* feed back :(shift down bit)*/
114- int *connect1; /* slot1 output pointer */
115- int *connect2; /* slot2 output pointer */
116- int op1_out[2]; /* slot1 output for selfeedback */
117-
118- /* phase generator state */
119- uint block_fnum; /* block+fnum */
120- uint8 kcode; /* key code : KeyScaleCode */
121- uint fc; /* Freq. Increment base */
122- uint ksl_base; /* KeyScaleLevel Base step */
123- uint8 keyon; /* key on/off flag */
124-} OPL_CH;
125-
126-/* OPL state */
127-typedef struct fm_opl_f {
128- uint8 type; /* chip type */
129- int clock; /* master clock (Hz) */
130- int rate; /* sampling rate (Hz) */
131- double freqbase; /* frequency base */
132- double TimerBase; /* Timer base time (==sampling time) */
133- uint8 address; /* address register */
134- uint8 status; /* status flag */
135- uint8 statusmask; /* status mask */
136- uint mode; /* Reg.08 : CSM , notesel,etc. */
137-
138- /* Timer */
139- int T[2]; /* timer counter */
140- uint8 st[2]; /* timer enable */
141-
142- /* FM channel slots */
143- OPL_CH *P_CH; /* pointer of CH */
144- int max_ch; /* maximum channel */
145-
146- /* Rythm sention */
147- uint8 rythm; /* Rythm mode , key flag */
148-
149- /* time tables */
150- int AR_TABLE[76]; /* atttack rate tables */
151- int DR_TABLE[76]; /* decay rate tables */
152- uint FN_TABLE[1024];/* fnumber -> increment counter */
153-
154- /* LFO */
155- int *ams_table;
156- int *vib_table;
157- int amsCnt;
158- int amsIncr;
159- int vibCnt;
160- int vibIncr;
161-
162- /* wave selector enable flag */
163- uint8 wavesel;
164-
165- /* external event callback handler */
166- OPL_TIMERHANDLER TimerHandler; /* TIMER handler */
167- int TimerParam; /* TIMER parameter */
168- OPL_IRQHANDLER IRQHandler; /* IRQ handler */
169- int IRQParam; /* IRQ parameter */
170- OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */
171- int UpdateParam; /* stream update parameter */
172-
173- Common::RandomSource rnd;
174-} FM_OPL;
175-
176-/* ---------- Generic interface section ---------- */
177-#define OPL_TYPE_YM3526 (0)
178-#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
179+ virtual void init(int rate, kOplType type = kOpl2) = 0;
180+ virtual void reset() = 0;
181
182-void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);
183+ virtual void write(int a, int v) = 0;
184+ virtual byte read(int a) = 0;
185+
186+ virtual void writeReg(int r, int v) = 0;
187+
188+ virtual void readBuffer(int16 *buffer, int length) = 0;
189+
190+ static AdLib *createInstance();
191+};
192+
193+} // end of namespace AdLib
194+
195+// Legacy API
196+typedef AdLib::AdLib FM_OPL;
197
198-FM_OPL *OPLCreate(int type, int clock, int rate);
199 void OPLDestroy(FM_OPL *OPL);
200-void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset);
201-void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param);
202-void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param);
203
204 void OPLResetChip(FM_OPL *OPL);
205-int OPLWrite(FM_OPL *OPL, int a, int v);
206+void OPLWrite(FM_OPL *OPL, int a, int v);
207 unsigned char OPLRead(FM_OPL *OPL, int a);
208-int OPLTimerOver(FM_OPL *OPL, int c);
209 void OPLWriteReg(FM_OPL *OPL, int r, int v);
210-void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave = 0);
211+void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length);
212
213 // Factory method
214 FM_OPL *makeAdlibOPL(int rate);
215
216 #endif
217+
218Index: sound/fmopl.cpp
219===================================================================
220--- sound/fmopl.cpp 2009-04-28 18:38:05.947781895 +0200
221+++ sound/fmopl.cpp 2009-04-28 18:38:21.552408141 +0200
222@@ -8,1184 +8,63 @@
223 * modify it under the terms of the GNU General Public License
224 * as published by the Free Software Foundation; either version 2
225 * of the License, or (at your option) any later version.
226-
227+ *
228 * This program is distributed in the hope that it will be useful,
229 * but WITHOUT ANY WARRANTY; without even the implied warranty of
230 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
231 * GNU General Public License for more details.
232-
233+ *
234 * You should have received a copy of the GNU General Public License
235 * along with this program; if not, write to the Free Software
236 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
237 *
238- * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.cpp $
239- * $Id: fmopl.cpp 38211 2009-02-15 10:07:50Z sev $
240- *
241- * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
242- * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
243+ * $URL$
244+ * $Id$
245 */
246
247-#include <stdio.h>
248-#include <stdlib.h>
249-#include <string.h>
250-#include <stdarg.h>
251-#include <math.h>
252-
253 #include "sound/fmopl.h"
254
255-#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__)
256-#include "common/config-manager.h"
257-#endif
258-
259-/* -------------------- preliminary define section --------------------- */
260-/* attack/decay rate time rate */
261-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
262-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
263-
264-#define FREQ_BITS 24 /* frequency turn */
265-
266-/* counter bits = 20 , octerve 7 */
267-#define FREQ_RATE (1<<(FREQ_BITS-20))
268-#define TL_BITS (FREQ_BITS+2)
269-
270-/* final output shift , limit minimum and maximum */
271-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
272-#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
273-#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
274-
275-/* -------------------- quality selection --------------------- */
276-
277-/* sinwave entries */
278-/* used static memory = SIN_ENT * 4 (byte) */
279-#ifdef __DS__
280-#include "dsmain.h"
281-#define SIN_ENT_SHIFT 8
282-#else
283-#define SIN_ENT_SHIFT 11
284-#endif
285-#define SIN_ENT (1<<SIN_ENT_SHIFT)
286-
287-/* output level entries (envelope,sinwave) */
288-/* envelope counter lower bits */
289-int ENV_BITS;
290-/* envelope output entries */
291-int EG_ENT;
292-
293-/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
294-/* used static memory = EG_ENT*4 (byte) */
295-int EG_OFF; /* OFF */
296-int EG_DED;
297-int EG_DST; /* DECAY START */
298-int EG_AED;
299-#define EG_AST 0 /* ATTACK START */
300-
301-#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
302-
303-/* LFO table entries */
304-#define VIB_ENT 512
305-#define VIB_SHIFT (32-9)
306-#define AMS_ENT 512
307-#define AMS_SHIFT (32-9)
308-
309-#define VIB_RATE_SHIFT 8
310-#define VIB_RATE (1<<VIB_RATE_SHIFT)
311-
312-/* -------------------- local defines , macros --------------------- */
313-
314-/* register number to channel number , slot offset */
315-#define SLOT1 0
316-#define SLOT2 1
317-
318-/* envelope phase */
319-#define ENV_MOD_RR 0x00
320-#define ENV_MOD_DR 0x01
321-#define ENV_MOD_AR 0x02
322-
323-/* -------------------- tables --------------------- */
324-static const int slot_array[32] = {
325- 0, 2, 4, 1, 3, 5,-1,-1,
326- 6, 8,10, 7, 9,11,-1,-1,
327- 12,14,16,13,15,17,-1,-1,
328- -1,-1,-1,-1,-1,-1,-1,-1
329-};
330-
331-static uint KSL_TABLE[8 * 16];
332-
333-static const double KSL_TABLE_SEED[8 * 16] = {
334- /* OCT 0 */
335- 0.000, 0.000, 0.000, 0.000,
336- 0.000, 0.000, 0.000, 0.000,
337- 0.000, 0.000, 0.000, 0.000,
338- 0.000, 0.000, 0.000, 0.000,
339- /* OCT 1 */
340- 0.000, 0.000, 0.000, 0.000,
341- 0.000, 0.000, 0.000, 0.000,
342- 0.000, 0.750, 1.125, 1.500,
343- 1.875, 2.250, 2.625, 3.000,
344- /* OCT 2 */
345- 0.000, 0.000, 0.000, 0.000,
346- 0.000, 1.125, 1.875, 2.625,
347- 3.000, 3.750, 4.125, 4.500,
348- 4.875, 5.250, 5.625, 6.000,
349- /* OCT 3 */
350- 0.000, 0.000, 0.000, 1.875,
351- 3.000, 4.125, 4.875, 5.625,
352- 6.000, 6.750, 7.125, 7.500,
353- 7.875, 8.250, 8.625, 9.000,
354- /* OCT 4 */
355- 0.000, 0.000, 3.000, 4.875,
356- 6.000, 7.125, 7.875, 8.625,
357- 9.000, 9.750, 10.125, 10.500,
358- 10.875, 11.250, 11.625, 12.000,
359- /* OCT 5 */
360- 0.000, 3.000, 6.000, 7.875,
361- 9.000, 10.125, 10.875, 11.625,
362- 12.000, 12.750, 13.125, 13.500,
363- 13.875, 14.250, 14.625, 15.000,
364- /* OCT 6 */
365- 0.000, 6.000, 9.000, 10.875,
366- 12.000, 13.125, 13.875, 14.625,
367- 15.000, 15.750, 16.125, 16.500,
368- 16.875, 17.250, 17.625, 18.000,
369- /* OCT 7 */
370- 0.000, 9.000, 12.000, 13.875,
371- 15.000, 16.125, 16.875, 17.625,
372- 18.000, 18.750, 19.125, 19.500,
373- 19.875, 20.250, 20.625, 21.000
374-};
375-
376-/* sustain level table (3db per step) */
377-/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
378-
379-static int SL_TABLE[16];
380-
381-static const uint SL_TABLE_SEED[16] = {
382- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31
383-};
384-
385-#define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
386-/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
387-/* TL_TABLE[ 0 to TL_MAX ] : plus section */
388-/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
389-static int *TL_TABLE;
390-
391-/* pointers to TL_TABLE with sinwave output offset */
392-static int **SIN_TABLE;
393-
394-/* LFO table */
395-static int *AMS_TABLE;
396-static int *VIB_TABLE;
397-
398-/* envelope output curve table */
399-/* attack + decay + OFF */
400-//static int ENV_CURVE[2*EG_ENT+1];
401-//static int ENV_CURVE[2 * 4096 + 1]; // to keep it static ...
402-static int *ENV_CURVE;
403-
404-
405-/* multiple table */
406-#define ML(a) (int)(a * 2)
407-static const uint MUL_TABLE[16]= {
408-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
409- ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
410- ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
411-};
412-#undef ML
413-
414-/* dummy attack / decay rate ( when rate == 0 ) */
415-static int RATE_0[16]=
416-{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
417-
418-/* -------------------- static state --------------------- */
419-
420-/* lock level of common table */
421-static int num_lock = 0;
422-
423-/* work table */
424-static void *cur_chip = NULL; /* current chip point */
425-/* currenct chip state */
426-/* static OPLSAMPLE *bufL,*bufR; */
427-static OPL_CH *S_CH;
428-static OPL_CH *E_CH;
429-OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
430-
431-static int outd[1];
432-static int ams;
433-static int vib;
434-int *ams_table;
435-int *vib_table;
436-static int amsIncr;
437-static int vibIncr;
438-static int feedback2; /* connect for SLOT 2 */
439-
440-/* --------------------- rebuild tables ------------------- */
441-
442-#define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2)))
443-#define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
444-
445-void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
446- int i;
447-
448- ENV_BITS = ENV_BITS_PARAM;
449- EG_ENT = EG_ENT_PARAM;
450- EG_OFF = ((2 * EG_ENT)<<ENV_BITS); /* OFF */
451- EG_DED = EG_OFF;
452- EG_DST = (EG_ENT << ENV_BITS); /* DECAY START */
453- EG_AED = EG_DST;
454- //EG_STEP = (96.0/EG_ENT);
455-
456- for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++)
457- KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
458-
459- for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++)
460- SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
461-}
462-
463-#undef SC_KSL
464-#undef SC_SL
465-
466-/* --------------------- subroutines --------------------- */
467-
468-/* status set and IRQ handling */
469-inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
470- /* set status flag */
471- OPL->status |= flag;
472- if(!(OPL->status & 0x80)) {
473- if(OPL->status & OPL->statusmask) { /* IRQ on */
474- OPL->status |= 0x80;
475- /* callback user interrupt handler (IRQ is OFF to ON) */
476- if(OPL->IRQHandler)
477- (OPL->IRQHandler)(OPL->IRQParam,1);
478- }
479- }
480-}
481-
482-/* status reset and IRQ handling */
483-inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
484- /* reset status flag */
485- OPL->status &= ~flag;
486- if((OPL->status & 0x80)) {
487- if (!(OPL->status & OPL->statusmask)) {
488- OPL->status &= 0x7f;
489- /* callback user interrupt handler (IRQ is ON to OFF) */
490- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
491- }
492- }
493-}
494-
495-/* IRQ mask set */
496-inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
497- OPL->statusmask = flag;
498- /* IRQ handling check */
499- OPL_STATUS_SET(OPL,0);
500- OPL_STATUS_RESET(OPL,0);
501-}
502-
503-/* ----- key on ----- */
504-inline void OPL_KEYON(OPL_SLOT *SLOT) {
505- /* sin wave restart */
506- SLOT->Cnt = 0;
507- /* set attack */
508- SLOT->evm = ENV_MOD_AR;
509- SLOT->evs = SLOT->evsa;
510- SLOT->evc = EG_AST;
511- SLOT->eve = EG_AED;
512-}
513-
514-/* ----- key off ----- */
515-inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
516- if( SLOT->evm > ENV_MOD_RR) {
517- /* set envelope counter from envleope output */
518-
519- // WORKAROUND: The Kyra engine does something very strange when
520- // starting a new song. For each channel:
521- //
522- // * The release rate is set to "fastest".
523- // * Any note is keyed off.
524- // * A very low-frequency note is keyed on.
525- //
526- // Usually, what happens next is that the real notes is keyed
527- // on immediately, in which case there's no problem.
528- //
529- // However, if the note is again keyed off (because the channel
530- // begins on a rest rather than a note), the envelope counter
531- // was moved from the very lowest point on the attack curve to
532- // the very highest point on the release curve.
533- //
534- // Again, this might not be a problem, if the release rate is
535- // still set to "fastest". But in many cases, it had already
536- // been increased. And, possibly because of inaccuracies in the
537- // envelope generator, that would cause the note to "fade out"
538- // for quite a long time.
539- //
540- // What we really need is a way to find the correct starting
541- // point for the envelope counter, and that may be what the
542- // commented-out line below is meant to do. For now, simply
543- // handle the pathological case.
544-
545- if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
546- SLOT->evc = EG_DED;
547- else if( !(SLOT->evc & EG_DST) )
548- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
549- SLOT->evc = EG_DST;
550- SLOT->eve = EG_DED;
551- SLOT->evs = SLOT->evsr;
552- SLOT->evm = ENV_MOD_RR;
553- }
554-}
555-
556-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
557-
558-/* return : envelope output */
559-inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
560- /* calcrate envelope generator */
561- if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
562- switch( SLOT->evm ) {
563- case ENV_MOD_AR: /* ATTACK -> DECAY1 */
564- /* next DR */
565- SLOT->evm = ENV_MOD_DR;
566- SLOT->evc = EG_DST;
567- SLOT->eve = SLOT->SL;
568- SLOT->evs = SLOT->evsd;
569- break;
570- case ENV_MOD_DR: /* DECAY -> SL or RR */
571- SLOT->evc = SLOT->SL;
572- SLOT->eve = EG_DED;
573- if(SLOT->eg_typ) {
574- SLOT->evs = 0;
575- } else {
576- SLOT->evm = ENV_MOD_RR;
577- SLOT->evs = SLOT->evsr;
578- }
579- break;
580- case ENV_MOD_RR: /* RR -> OFF */
581- SLOT->evc = EG_OFF;
582- SLOT->eve = EG_OFF + 1;
583- SLOT->evs = 0;
584- break;
585- }
586- }
587- /* calcrate envelope */
588- return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
589-}
590-
591-/* set algorythm connection */
592-static void set_algorythm(OPL_CH *CH) {
593- int *carrier = &outd[0];
594- CH->connect1 = CH->CON ? carrier : &feedback2;
595- CH->connect2 = carrier;
596-}
597-
598-/* ---------- frequency counter for operater update ---------- */
599-inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
600- int ksr;
601-
602- /* frequency step counter */
603- SLOT->Incr = CH->fc * SLOT->mul;
604- ksr = CH->kcode >> SLOT->KSR;
605-
606- if( SLOT->ksr != ksr ) {
607- SLOT->ksr = ksr;
608- /* attack , decay rate recalcration */
609- SLOT->evsa = SLOT->AR[ksr];
610- SLOT->evsd = SLOT->DR[ksr];
611- SLOT->evsr = SLOT->RR[ksr];
612- }
613- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
614-}
615-
616-/* set multi,am,vib,EG-TYP,KSR,mul */
617-inline void set_mul(FM_OPL *OPL, int slot, int v) {
618- OPL_CH *CH = &OPL->P_CH[slot>>1];
619- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
620-
621- SLOT->mul = MUL_TABLE[v & 0x0f];
622- SLOT->KSR = (v & 0x10) ? 0 : 2;
623- SLOT->eg_typ = (v & 0x20) >> 5;
624- SLOT->vib = (v & 0x40);
625- SLOT->ams = (v & 0x80);
626- CALC_FCSLOT(CH, SLOT);
627-}
628-
629-/* set ksl & tl */
630-inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
631- OPL_CH *CH = &OPL->P_CH[slot>>1];
632- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
633- int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
634-
635- SLOT->ksl = ksl ? 3-ksl : 31;
636- SLOT->TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
637-
638- if(!(OPL->mode & 0x80)) { /* not CSM latch total level */
639- SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
640- }
641-}
642-
643-/* set attack rate & decay rate */
644-inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
645- OPL_CH *CH = &OPL->P_CH[slot>>1];
646- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
647- int ar = v >> 4;
648- int dr = v & 0x0f;
649-
650- SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
651- SLOT->evsa = SLOT->AR[SLOT->ksr];
652- if(SLOT->evm == ENV_MOD_AR)
653- SLOT->evs = SLOT->evsa;
654-
655- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
656- SLOT->evsd = SLOT->DR[SLOT->ksr];
657- if(SLOT->evm == ENV_MOD_DR)
658- SLOT->evs = SLOT->evsd;
659-}
660+#include "sound/softsynth/adlib/dosbox.h"
661+#include "sound/softsynth/adlib/mame.h"
662
663-/* set sustain level & release rate */
664-inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
665- OPL_CH *CH = &OPL->P_CH[slot>>1];
666- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
667- int sl = v >> 4;
668- int rr = v & 0x0f;
669+namespace AdLib {
670
671- SLOT->SL = SL_TABLE[sl];
672- if(SLOT->evm == ENV_MOD_DR)
673- SLOT->eve = SLOT->SL;
674- SLOT->RR = &OPL->DR_TABLE[rr<<2];
675- SLOT->evsr = SLOT->RR[SLOT->ksr];
676- if(SLOT->evm == ENV_MOD_RR)
677- SLOT->evs = SLOT->evsr;
678+AdLib *AdLib::createInstance() {
679+// return new MAME::AdLib_MAME();
680+ return new DOSBox::AdLib_DOSBox();
681 }
682
683-/* operator output calcrator */
684-
685-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env]
686-/* ---------- calcrate one of channel ---------- */
687-inline void OPL_CALC_CH(OPL_CH *CH) {
688- uint env_out;
689- OPL_SLOT *SLOT;
690-
691- feedback2 = 0;
692- /* SLOT 1 */
693- SLOT = &CH->SLOT[SLOT1];
694- env_out=OPL_CALC_SLOT(SLOT);
695- if(env_out < (uint)(EG_ENT - 1)) {
696- /* PG */
697- if(SLOT->vib)
698- SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
699- else
700- SLOT->Cnt += SLOT->Incr;
701- /* connection */
702- if(CH->FB) {
703- int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
704- CH->op1_out[1] = CH->op1_out[0];
705- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
706- } else {
707- *CH->connect1 += OP_OUT(SLOT, env_out, 0);
708- }
709- } else {
710- CH->op1_out[1] = CH->op1_out[0];
711- CH->op1_out[0] = 0;
712- }
713- /* SLOT 2 */
714- SLOT = &CH->SLOT[SLOT2];
715- env_out=OPL_CALC_SLOT(SLOT);
716- if(env_out < (uint)(EG_ENT - 1)) {
717- /* PG */
718- if(SLOT->vib)
719- SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
720- else
721- SLOT->Cnt += SLOT->Incr;
722- /* connection */
723- outd[0] += OP_OUT(SLOT, env_out, feedback2);
724- }
725-}
726-
727-/* ---------- calcrate rythm block ---------- */
728-#define WHITE_NOISE_db 6.0
729-inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
730- uint env_tam, env_sd, env_top, env_hh;
731- // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
732- // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
733- // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
734- // or 128, so we can safely avoid any FP ops.
735- int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4);
736-
737- int tone8;
738-
739- OPL_SLOT *SLOT;
740- int env_out;
741-
742- /* BD : same as FM serial mode and output level is large */
743- feedback2 = 0;
744- /* SLOT 1 */
745- SLOT = &CH[6].SLOT[SLOT1];
746- env_out = OPL_CALC_SLOT(SLOT);
747- if(env_out < EG_ENT-1) {
748- /* PG */
749- if(SLOT->vib)
750- SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
751- else
752- SLOT->Cnt += SLOT->Incr;
753- /* connection */
754- if(CH[6].FB) {
755- int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
756- CH[6].op1_out[1] = CH[6].op1_out[0];
757- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
758- }
759- else {
760- feedback2 = OP_OUT(SLOT, env_out, 0);
761- }
762- } else {
763- feedback2 = 0;
764- CH[6].op1_out[1] = CH[6].op1_out[0];
765- CH[6].op1_out[0] = 0;
766- }
767- /* SLOT 2 */
768- SLOT = &CH[6].SLOT[SLOT2];
769- env_out = OPL_CALC_SLOT(SLOT);
770- if(env_out < EG_ENT-1) {
771- /* PG */
772- if(SLOT->vib)
773- SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
774- else
775- SLOT->Cnt += SLOT->Incr;
776- /* connection */
777- outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
778- }
779-
780- // SD (17) = mul14[fnum7] + white noise
781- // TAM (15) = mul15[fnum8]
782- // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
783- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
784- env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
785- env_tam =OPL_CALC_SLOT(SLOT8_1);
786- env_top = OPL_CALC_SLOT(SLOT8_2);
787- env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
788-
789- /* PG */
790- if(SLOT7_1->vib)
791- SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1);
792- else
793- SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
794- if(SLOT7_2->vib)
795- SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3);
796- else
797- SLOT7_2->Cnt += (CH[7].fc * 8);
798- if(SLOT8_1->vib)
799- SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;
800- else
801- SLOT8_1->Cnt += SLOT8_1->Incr;
802- if(SLOT8_2->vib)
803- SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4);
804- else
805- SLOT8_2->Cnt += (CH[8].fc * 48);
806-
807- tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
808-
809- /* SD */
810- if(env_sd < (uint)(EG_ENT - 1))
811- outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
812- /* TAM */
813- if(env_tam < (uint)(EG_ENT - 1))
814- outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
815- /* TOP-CY */
816- if(env_top < (uint)(EG_ENT - 1))
817- outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
818- /* HH */
819- if(env_hh < (uint)(EG_ENT-1))
820- outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
821-}
822-
823-/* ----------- initialize time tabls ----------- */
824-static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
825- int i;
826- double rate;
827-
828- /* make attack rate & decay rate tables */
829- for (i = 0; i < 4; i++)
830- OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
831- for (i = 4; i <= 60; i++) {
832- rate = OPL->freqbase; /* frequency rate */
833- if(i < 60)
834- rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
835- rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */
836- rate *= (double)(EG_ENT << ENV_BITS);
837- OPL->AR_TABLE[i] = (int)(rate / ARRATE);
838- OPL->DR_TABLE[i] = (int)(rate / DRRATE);
839- }
840- for (i = 60; i < 76; i++) {
841- OPL->AR_TABLE[i] = EG_AED-1;
842- OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
843- }
844-}
845-
846-/* ---------- generic table initialize ---------- */
847-static int OPLOpenTable(void) {
848- int s,t;
849- double rate;
850- int i,j;
851- double pom;
852-
853-#ifdef __DS__
854- DS::fastRamReset();
855-
856- TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *));
857- SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *));
858-#else
859-
860- /* allocate dynamic tables */
861- if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
862- return 0;
863-
864- if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
865- free(TL_TABLE);
866- return 0;
867- }
868-#endif
869-
870- if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
871- free(TL_TABLE);
872- free(SIN_TABLE);
873- return 0;
874- }
875-
876- if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
877- free(TL_TABLE);
878- free(SIN_TABLE);
879- free(AMS_TABLE);
880- return 0;
881- }
882- /* make total level table */
883- for (t = 0; t < EG_ENT - 1 ; t++) {
884- rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */
885- TL_TABLE[ t] = (int)rate;
886- TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
887- }
888- /* fill volume off area */
889- for (t = EG_ENT - 1; t < TL_MAX; t++) {
890- TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
891- }
892-
893- /* make sinwave table (total level offet) */
894- /* degree 0 = degree 180 = off */
895- SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
896- for (s = 1;s <= SIN_ENT / 4; s++) {
897- pom = sin(2 * PI * s / SIN_ENT); /* sin */
898- pom = 20 * log10(1 / pom); /* decibel */
899- j = int(pom / EG_STEP); /* TL_TABLE steps */
900-
901- /* degree 0 - 90 , degree 180 - 90 : plus section */
902- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
903- /* degree 180 - 270 , degree 360 - 270 : minus section */
904- SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
905- }
906- for (s = 0;s < SIN_ENT; s++) {
907- SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
908- SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
909- SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
910- }
911-
912-
913- ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1));
914-
915- /* envelope counter -> envelope output table */
916- for (i=0; i < EG_ENT; i++) {
917- /* ATTACK curve */
918- pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
919- /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
920- ENV_CURVE[i] = (int)pom;
921- /* DECAY ,RELEASE curve */
922- ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
923- }
924- /* off */
925- ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
926- /* make LFO ams table */
927- for (i=0; i < AMS_ENT; i++) {
928- pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
929- AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */
930- AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
931- }
932- /* make LFO vibrate table */
933- for (i=0; i < VIB_ENT; i++) {
934- /* 100cent = 1seminote = 6% ?? */
935- pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
936- VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
937- VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
938- }
939- return 1;
940-}
941-
942-static void OPLCloseTable(void) {
943- free(TL_TABLE);
944- free(SIN_TABLE);
945- free(AMS_TABLE);
946- free(VIB_TABLE);
947- free(ENV_CURVE);
948-}
949-
950-/* CSM Key Controll */
951-inline void CSMKeyControll(OPL_CH *CH) {
952- OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
953- OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
954- /* all key off */
955- OPL_KEYOFF(slot1);
956- OPL_KEYOFF(slot2);
957- /* total level latch */
958- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
959- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
960- /* key on */
961- CH->op1_out[0] = CH->op1_out[1] = 0;
962- OPL_KEYON(slot1);
963- OPL_KEYON(slot2);
964-}
965+} // end of namespace AdLib
966
967-/* ---------- opl initialize ---------- */
968-static void OPL_initalize(FM_OPL *OPL) {
969- int fn;
970-
971- /* frequency base */
972- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
973- /* Timer base time */
974- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
975- /* make time tables */
976- init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
977- /* make fnumber -> increment counter table */
978- for( fn=0; fn < 1024; fn++) {
979- OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
980- }
981- /* LFO freq.table */
982- OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0);
983- OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0);
984-}
985-
986-/* ---------- write a OPL registers ---------- */
987-void OPLWriteReg(FM_OPL *OPL, int r, int v) {
988- OPL_CH *CH;
989- int slot;
990- uint block_fnum;
991-
992- switch(r & 0xe0) {
993- case 0x00: /* 00-1f:controll */
994- switch(r & 0x1f) {
995- case 0x01:
996- /* wave selector enable */
997- if(OPL->type&OPL_TYPE_WAVESEL) {
998- OPL->wavesel = v & 0x20;
999- if(!OPL->wavesel) {
1000- /* preset compatible mode */
1001- int c;
1002- for(c=0; c<OPL->max_ch; c++) {
1003- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
1004- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
1005- }
1006- }
1007- }
1008- return;
1009- case 0x02: /* Timer 1 */
1010- OPL->T[0] = (256-v) * 4;
1011- break;
1012- case 0x03: /* Timer 2 */
1013- OPL->T[1] = (256-v) * 16;
1014- return;
1015- case 0x04: /* IRQ clear / mask and Timer enable */
1016- if(v & 0x80) { /* IRQ flag clear */
1017- OPL_STATUS_RESET(OPL, 0x7f);
1018- } else { /* set IRQ mask ,timer enable*/
1019- uint8 st1 = v & 1;
1020- uint8 st2 = (v >> 1) & 1;
1021- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
1022- OPL_STATUS_RESET(OPL, v & 0x78);
1023- OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
1024- /* timer 2 */
1025- if(OPL->st[1] != st2) {
1026- double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
1027- OPL->st[1] = st2;
1028- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
1029- }
1030- /* timer 1 */
1031- if(OPL->st[0] != st1) {
1032- double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
1033- OPL->st[0] = st1;
1034- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
1035- }
1036- }
1037- return;
1038- }
1039- break;
1040- case 0x20: /* am,vib,ksr,eg type,mul */
1041- slot = slot_array[r&0x1f];
1042- if(slot == -1)
1043- return;
1044- set_mul(OPL,slot,v);
1045- return;
1046- case 0x40:
1047- slot = slot_array[r&0x1f];
1048- if(slot == -1)
1049- return;
1050- set_ksl_tl(OPL,slot,v);
1051- return;
1052- case 0x60:
1053- slot = slot_array[r&0x1f];
1054- if(slot == -1)
1055- return;
1056- set_ar_dr(OPL,slot,v);
1057- return;
1058- case 0x80:
1059- slot = slot_array[r&0x1f];
1060- if(slot == -1)
1061- return;
1062- set_sl_rr(OPL,slot,v);
1063- return;
1064- case 0xa0:
1065- switch(r) {
1066- case 0xbd:
1067- /* amsep,vibdep,r,bd,sd,tom,tc,hh */
1068- {
1069- uint8 rkey = OPL->rythm ^ v;
1070- OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
1071- OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
1072- OPL->rythm = v & 0x3f;
1073- if(OPL->rythm & 0x20) {
1074- /* BD key on/off */
1075- if(rkey & 0x10) {
1076- if(v & 0x10) {
1077- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
1078- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
1079- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
1080- } else {
1081- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
1082- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
1083- }
1084- }
1085- /* SD key on/off */
1086- if(rkey & 0x08) {
1087- if(v & 0x08)
1088- OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
1089- else
1090- OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
1091- }/* TAM key on/off */
1092- if(rkey & 0x04) {
1093- if(v & 0x04)
1094- OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
1095- else
1096- OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
1097- }
1098- /* TOP-CY key on/off */
1099- if(rkey & 0x02) {
1100- if(v & 0x02)
1101- OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
1102- else
1103- OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
1104- }
1105- /* HH key on/off */
1106- if(rkey & 0x01) {
1107- if(v & 0x01)
1108- OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
1109- else
1110- OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
1111- }
1112- }
1113- }
1114- return;
1115-
1116- default:
1117- break;
1118- }
1119- /* keyon,block,fnum */
1120- if((r & 0x0f) > 8)
1121- return;
1122- CH = &OPL->P_CH[r & 0x0f];
1123- if(!(r&0x10)) { /* a0-a8 */
1124- block_fnum = (CH->block_fnum & 0x1f00) | v;
1125- } else { /* b0-b8 */
1126- int keyon = (v >> 5) & 1;
1127- block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
1128- if(CH->keyon != keyon) {
1129- if((CH->keyon=keyon)) {
1130- CH->op1_out[0] = CH->op1_out[1] = 0;
1131- OPL_KEYON(&CH->SLOT[SLOT1]);
1132- OPL_KEYON(&CH->SLOT[SLOT2]);
1133- } else {
1134- OPL_KEYOFF(&CH->SLOT[SLOT1]);
1135- OPL_KEYOFF(&CH->SLOT[SLOT2]);
1136- }
1137- }
1138- }
1139- /* update */
1140- if(CH->block_fnum != block_fnum) {
1141- int blockRv = 7 - (block_fnum >> 10);
1142- int fnum = block_fnum & 0x3ff;
1143- CH->block_fnum = block_fnum;
1144- CH->ksl_base = KSL_TABLE[block_fnum >> 6];
1145- CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
1146- CH->kcode = CH->block_fnum >> 9;
1147- if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
1148- CH->kcode |=1;
1149- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
1150- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
1151- }
1152- return;
1153- case 0xc0:
1154- /* FB,C */
1155- if((r & 0x0f) > 8)
1156- return;
1157- CH = &OPL->P_CH[r&0x0f];
1158- {
1159- int feedback = (v >> 1) & 7;
1160- CH->FB = feedback ? (8 + 1) - feedback : 0;
1161- CH->CON = v & 1;
1162- set_algorythm(CH);
1163- }
1164- return;
1165- case 0xe0: /* wave type */
1166- slot = slot_array[r & 0x1f];
1167- if(slot == -1)
1168- return;
1169- CH = &OPL->P_CH[slot>>1];
1170- if(OPL->wavesel) {
1171- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
1172- }
1173- return;
1174- }
1175-}
1176-
1177-/* lock/unlock for common table */
1178-static int OPL_LockTable(void) {
1179- num_lock++;
1180- if(num_lock>1)
1181- return 0;
1182- /* first time */
1183- cur_chip = NULL;
1184- /* allocate total level table (128kb space) */
1185- if(!OPLOpenTable()) {
1186- num_lock--;
1187- return -1;
1188- }
1189- return 0;
1190-}
1191-
1192-static void OPL_UnLockTable(void) {
1193- if(num_lock)
1194- num_lock--;
1195- if(num_lock)
1196- return;
1197- /* last time */
1198- cur_chip = NULL;
1199- OPLCloseTable();
1200-}
1201-
1202-/*******************************************************************************/
1203-/* YM3812 local section */
1204-/*******************************************************************************/
1205-
1206-/* ---------- update one of chip ----------- */
1207-void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave) {
1208- int i;
1209- int data;
1210- int16 *buf = buffer;
1211- uint amsCnt = OPL->amsCnt;
1212- uint vibCnt = OPL->vibCnt;
1213- uint8 rythm = OPL->rythm & 0x20;
1214- OPL_CH *CH, *R_CH;
1215-
1216-
1217- if((void *)OPL != cur_chip) {
1218- cur_chip = (void *)OPL;
1219- /* channel pointers */
1220- S_CH = OPL->P_CH;
1221- E_CH = &S_CH[9];
1222- /* rythm slot */
1223- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
1224- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
1225- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
1226- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
1227- /* LFO state */
1228- amsIncr = OPL->amsIncr;
1229- vibIncr = OPL->vibIncr;
1230- ams_table = OPL->ams_table;
1231- vib_table = OPL->vib_table;
1232- }
1233- R_CH = rythm ? &S_CH[6] : E_CH;
1234- for(i = 0; i < length; i++) {
1235- /* channel A channel B channel C */
1236- /* LFO */
1237- ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
1238- vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
1239- outd[0] = 0;
1240- /* FM part */
1241- for(CH=S_CH; CH < R_CH; CH++)
1242- OPL_CALC_CH(CH);
1243- /* Rythn part */
1244- if(rythm)
1245- OPL_CALC_RH(OPL, S_CH);
1246- /* limit check */
1247- data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT);
1248- /* store to sound buffer */
1249- buf[i << interleave] = data >> OPL_OUTSB;
1250- }
1251-
1252- OPL->amsCnt = amsCnt;
1253- OPL->vibCnt = vibCnt;
1254-}
1255-
1256-/* ---------- reset a chip ---------- */
1257-void OPLResetChip(FM_OPL *OPL) {
1258- int c,s;
1259- int i;
1260-
1261- /* reset chip */
1262- OPL->mode = 0; /* normal mode */
1263- OPL_STATUS_RESET(OPL, 0x7f);
1264- /* reset with register write */
1265- OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
1266- OPLWriteReg(OPL, 0x02,0); /* Timer1 */
1267- OPLWriteReg(OPL, 0x03,0); /* Timer2 */
1268- OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
1269- for(i = 0xff; i >= 0x20; i--)
1270- OPLWriteReg(OPL,i,0);
1271- /* reset OPerator parameter */
1272- for(c = 0; c < OPL->max_ch ;c++ ) {
1273- OPL_CH *CH = &OPL->P_CH[c];
1274- /* OPL->P_CH[c].PAN = OPN_CENTER; */
1275- for(s = 0; s < 2; s++ ) {
1276- /* wave table */
1277- CH->SLOT[s].wavetable = &SIN_TABLE[0];
1278- /* CH->SLOT[s].evm = ENV_MOD_RR; */
1279- CH->SLOT[s].evc = EG_OFF;
1280- CH->SLOT[s].eve = EG_OFF + 1;
1281- CH->SLOT[s].evs = 0;
1282- }
1283- }
1284-}
1285-
1286-/* ---------- Create a virtual YM3812 ---------- */
1287-/* 'rate' is sampling rate and 'bufsiz' is the size of the */
1288-FM_OPL *OPLCreate(int type, int clock, int rate) {
1289- char *ptr;
1290- FM_OPL *OPL;
1291- int state_size;
1292- int max_ch = 9; /* normaly 9 channels */
1293-
1294- if( OPL_LockTable() == -1)
1295- return NULL;
1296- /* allocate OPL state space */
1297- state_size = sizeof(FM_OPL);
1298- state_size += sizeof(OPL_CH) * max_ch;
1299-
1300- /* allocate memory block */
1301- ptr = (char *)calloc(state_size, 1);
1302- if(ptr == NULL)
1303- return NULL;
1304-
1305- /* clear */
1306- memset(ptr, 0, state_size);
1307- OPL = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
1308- OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
1309-
1310- /* set channel state pointer */
1311- OPL->type = type;
1312- OPL->clock = clock;
1313- OPL->rate = rate;
1314- OPL->max_ch = max_ch;
1315-
1316- /* init grobal tables */
1317- OPL_initalize(OPL);
1318-
1319- /* reset chip */
1320- OPLResetChip(OPL);
1321- return OPL;
1322-}
1323-
1324-/* ---------- Destroy one of vietual YM3812 ---------- */
1325 void OPLDestroy(FM_OPL *OPL) {
1326- OPL_UnLockTable();
1327- free(OPL);
1328-}
1329-
1330-/* ---------- Option handlers ---------- */
1331-void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
1332- OPL->TimerHandler = TimerHandler;
1333- OPL->TimerParam = channelOffset;
1334+ delete OPL;
1335 }
1336
1337-void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
1338- OPL->IRQHandler = IRQHandler;
1339- OPL->IRQParam = param;
1340+void OPLResetChip(FM_OPL *OPL) {
1341+ OPL->reset();
1342 }
1343
1344-void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
1345- OPL->UpdateHandler = UpdateHandler;
1346- OPL->UpdateParam = param;
1347+void OPLWrite(FM_OPL *OPL, int a, int v) {
1348+ OPL->write(a, v);
1349 }
1350
1351-/* ---------- YM3812 I/O interface ---------- */
1352-int OPLWrite(FM_OPL *OPL,int a,int v) {
1353- if(!(a & 1)) { /* address port */
1354- OPL->address = v & 0xff;
1355- } else { /* data port */
1356- if(OPL->UpdateHandler)
1357- OPL->UpdateHandler(OPL->UpdateParam,0);
1358- OPLWriteReg(OPL, OPL->address,v);
1359- }
1360- return OPL->status >> 7;
1361+unsigned char OPLRead(FM_OPL *OPL, int a) {
1362+ return OPL->read(a);
1363 }
1364
1365-unsigned char OPLRead(FM_OPL *OPL,int a) {
1366- if(!(a & 1)) { /* status port */
1367- return OPL->status & (OPL->statusmask | 0x80);
1368- }
1369- /* data port */
1370- switch(OPL->address) {
1371- case 0x05: /* KeyBoard IN */
1372- warning("OPL:read unmapped KEYBOARD port\n");
1373- return 0;
1374- case 0x19: /* I/O DATA */
1375- warning("OPL:read unmapped I/O port\n");
1376- return 0;
1377- case 0x1a: /* PCM-DATA */
1378- return 0;
1379- default:
1380- break;
1381- }
1382- return 0;
1383+void OPLWriteReg(FM_OPL *OPL, int r, int v) {
1384+ OPL->writeReg(r, v);
1385 }
1386
1387-int OPLTimerOver(FM_OPL *OPL, int c) {
1388- if(c) { /* Timer B */
1389- OPL_STATUS_SET(OPL, 0x20);
1390- } else { /* Timer A */
1391- OPL_STATUS_SET(OPL, 0x40);
1392- /* CSM mode key,TL controll */
1393- if(OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */
1394- int ch;
1395- if(OPL->UpdateHandler)
1396- OPL->UpdateHandler(OPL->UpdateParam,0);
1397- for(ch = 0; ch < 9; ch++)
1398- CSMKeyControll(&OPL->P_CH[ch]);
1399- }
1400- }
1401- /* reload timer */
1402- if (OPL->TimerHandler)
1403- (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);
1404- return OPL->status >> 7;
1405+void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
1406+ OPL->readBuffer(buffer, length);
1407 }
1408
1409+// Factory method
1410 FM_OPL *makeAdlibOPL(int rate) {
1411- // We need to emulate one YM3812 chip
1412- int env_bits = FMOPL_ENV_BITS_HQ;
1413- int eg_ent = FMOPL_EG_ENT_HQ;
1414-#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__)
1415- if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
1416- env_bits = FMOPL_ENV_BITS_HQ;
1417- eg_ent = FMOPL_EG_ENT_HQ;
1418- } else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) {
1419- env_bits = FMOPL_ENV_BITS_MQ;
1420- eg_ent = FMOPL_EG_ENT_MQ;
1421- } else {
1422- env_bits = FMOPL_ENV_BITS_LQ;
1423- eg_ent = FMOPL_EG_ENT_LQ;
1424- }
1425-#endif
1426-
1427- OPLBuildTables(env_bits, eg_ent);
1428- return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
1429+ FM_OPL *opl = AdLib::AdLib::createInstance();
1430+ if (opl)
1431+ opl->init(rate);
1432+ return opl;
1433 }
1434+
1435Index: sound/softsynth/adlib/dosbox.cpp
1436===================================================================
1437--- sound/softsynth/adlib/dosbox.cpp (revision 0)
1438+++ sound/softsynth/adlib/dosbox.cpp (revision 0)
1439@@ -0,0 +1,308 @@
1440+/* ScummVM - Graphic Adventure Engine
1441+ *
1442+ * ScummVM is the legal property of its developers, whose names
1443+ * are too numerous to list here. Please refer to the COPYRIGHT
1444+ * file distributed with this source distribution.
1445+ *
1446+ * This program is free software; you can redistribute it and/or
1447+ * modify it under the terms of the GNU General Public License
1448+ * as published by the Free Software Foundation; either version 2
1449+ * of the License, or (at your option) any later version.
1450+ *
1451+ * This program is distributed in the hope that it will be useful,
1452+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1453+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1454+ * GNU General Public License for more details.
1455+ *
1456+ * You should have received a copy of the GNU General Public License
1457+ * along with this program; if not, write to the Free Software
1458+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1459+ *
1460+ * $URL$
1461+ * $Id$
1462+ */
1463+
1464+/*
1465+ * Based on AdLib emulation code of DOSBox
1466+ * Copyright (C) 2002-2009 The DOSBox Team
1467+ * Licensed under GPLv2+
1468+ * http://www.dosbox.com
1469+ */
1470+
1471+#ifndef DISABLE_DOSBOX_ADLIB
1472+
1473+#include "dosbox.h"
1474+#include "dbopl.h"
1475+
1476+#include "common/system.h"
1477+
1478+#include <math.h>
1479+#include <string.h>
1480+
1481+namespace AdLib {
1482+namespace DOSBox {
1483+
1484+// TODO: The DOSBox AdLib code is only capable of *one* instance, we
1485+// would need to restructure the code to allow multiple instances.
1486+namespace DBOPL_FL {
1487+namespace OPL2 {
1488+#include "dbopl_fl.cpp"
1489+
1490+struct Handler : public DOSBox::Handler {
1491+ void writeReg(uint32 reg, uint8 val) {
1492+ adlib_write(reg, val);
1493+ }
1494+ uint32 writeAddr(uint32 port, uint8 val) {
1495+ return val;
1496+ }
1497+ void generate(int16 *chan, uint samples) {
1498+ adlib_getsample(chan, samples);
1499+ }
1500+ void init(uint rate) {
1501+ adlib_init(rate);
1502+ }
1503+};
1504+} // end of namespace OPL2
1505+} // end of namespace DBOPL_FL
1506+
1507+Timer::Timer() {
1508+ masked = false;
1509+ overflow = false;
1510+ enabled = false;
1511+ counter = 0;
1512+ delay = 0;
1513+}
1514+
1515+void Timer::update(double time) {
1516+ if (!enabled || !delay)
1517+ return;
1518+ double deltaStart = time - startTime;
1519+ // Only set the overflow flag when not masked
1520+ if (deltaStart >= 0 && !masked)
1521+ overflow = 1;
1522+}
1523+
1524+void Timer::reset(double time) {
1525+ overflow = false;
1526+ if (!delay || !enabled)
1527+ return;
1528+ double delta = (time - startTime);
1529+ double rem = fmod(delta, delay);
1530+ double next = delay - rem;
1531+ startTime = time + next;
1532+}
1533+
1534+void Timer::stop() {
1535+ enabled = false;
1536+}
1537+
1538+void Timer::start(double time, int scale) {
1539+ //Don't enable again
1540+ if (enabled)
1541+ return;
1542+ enabled = true;
1543+ delay = 0.001 * (256 - counter) * scale;
1544+ startTime = time + delay;
1545+}
1546+
1547+bool Chip::write(uint32 reg, uint8 val) {
1548+ switch (reg) {
1549+ case 0x02:
1550+ timer[0].counter = val;
1551+ return true;
1552+ case 0x03:
1553+ timer[1].counter = val;
1554+ return true;
1555+ case 0x04:
1556+ // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess
1557+ // it should be like this...
1558+ double time = g_system->getMillis() / 1000.0;
1559+
1560+ if (val & 0x80) {
1561+ timer[0].reset(time);
1562+ timer[1].reset(time);
1563+ } else {
1564+ timer[0].update(time);
1565+ timer[1].update(time);
1566+
1567+ if (val & 0x1)
1568+ timer[0].start(time, 80);
1569+ else
1570+ timer[0].stop();
1571+
1572+ timer[0].masked = (val & 0x40) > 0;
1573+
1574+ if (timer[0].masked)
1575+ timer[0].overflow = false;
1576+
1577+ if (val & 0x2)
1578+ timer[1].start(time, 320);
1579+ else
1580+ timer[1].stop();
1581+
1582+ timer[1].masked = (val & 0x20) > 0;
1583+
1584+ if (timer[1].masked)
1585+ timer[1].overflow = false;
1586+ }
1587+ return true;
1588+ }
1589+ return false;
1590+}
1591+
1592+uint8 Chip::read() {
1593+ // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess
1594+ // it should be like this...
1595+ double time = g_system->getMillis() / 1000.0;
1596+
1597+ timer[0].update(time);
1598+ timer[1].update(time);
1599+
1600+ uint8 ret = 0;
1601+ //Overflow won't be set if a channel is masked
1602+ if (timer[0].overflow) {
1603+ ret |= 0x40;
1604+ ret |= 0x80;
1605+ }
1606+ if (timer[1].overflow) {
1607+ ret |= 0x20;
1608+ ret |= 0x80;
1609+ }
1610+ return ret;
1611+}
1612+
1613+AdLib_DOSBox::AdLib_DOSBox() : _type(kOpl2), _rate(0), _handler(0) {
1614+}
1615+
1616+AdLib_DOSBox::~AdLib_DOSBox() {
1617+ free();
1618+}
1619+
1620+void AdLib_DOSBox::free() {
1621+ delete _handler;
1622+ _handler = 0;
1623+}
1624+
1625+void AdLib_DOSBox::init(int rate, kOplType type) {
1626+ free();
1627+
1628+ _reg.dual[0] = 0;
1629+ _reg.dual[1] = 0;
1630+ _reg.normal = 0;
1631+
1632+ memset(_chip, 0, sizeof(_chip));
1633+ _type = type;
1634+
1635+ switch (_type) {
1636+ case kOpl2:
1637+// _handler = new DBOPL_FL::OPL2::Handler();
1638+ _handler = new DBOPL::Handler();
1639+ break;
1640+ }
1641+
1642+ _handler->init(rate);
1643+ _rate = rate;
1644+}
1645+
1646+void AdLib_DOSBox::reset() {
1647+ // TODO: Find a nicer way to reset the emulator
1648+ init(_rate, _type);
1649+}
1650+
1651+void AdLib_DOSBox::write(int port, int val) {
1652+ if (port&1) {
1653+ switch (_type) {
1654+ case kOpl2:
1655+ //case kOpl3:
1656+ if (!_chip[0].write(_reg.normal, val))
1657+ _handler->writeReg(_reg.normal, val);
1658+ break;
1659+ /*case kDualOpl2:
1660+ // Not a 0x??8 port, then write to a specific port
1661+ if (!(port & 0x8)) {
1662+ byte index = (port & 2) >> 1;
1663+ dualWrite(index, _reg.dual[index], val);
1664+ } else {
1665+ //Write to both ports
1666+ dualWrite(0, _reg.dual[0], val);
1667+ dualWrite(1, _reg.dual[1], val);
1668+ }
1669+ break;*/
1670+ }
1671+ } else {
1672+ // Ask the handler to write the address
1673+ // Make sure to clip them in the right range
1674+ switch (_type) {
1675+ case kOpl2:
1676+ _reg.normal = _handler->writeAddr(port, val) & 0xff;
1677+ break;
1678+ /*case kOpl3:
1679+ _reg.normal = _handler->writeAddr(port, val) & 0x1ff;
1680+ break;
1681+ case kDualOpl2:
1682+ // Not a 0x?88 port, when write to a specific side
1683+ if (!(port & 0x8)) {
1684+ byte index = (port & 2) >> 1;
1685+ _reg.dual[index] = val & 0xff;
1686+ } else {
1687+ _reg.dual[0] = val & 0xff;
1688+ _reg.dual[1] = val & 0xff;
1689+ }
1690+ break;*/
1691+ }
1692+ }
1693+}
1694+
1695+byte AdLib_DOSBox::read(int port) {
1696+ switch (_type) {
1697+ case kOpl2:
1698+ if (!(port & 1))
1699+ //Make sure the low bits are 6 on opl2
1700+ return _chip[0].read() | 0x6;
1701+ break;
1702+ /*case kOpl3:
1703+ if (!(port & 1))
1704+ return _chip[0].read();
1705+ break;
1706+ case kDualOpl2:
1707+ // Only return for the lower ports
1708+ if (port & 1)
1709+ return 0xff;
1710+ // Make sure the low bits are 6 on opl2
1711+ return _chip[(port >> 1) & 1].read() | 0x6;*/
1712+ }
1713+ return 0;
1714+}
1715+
1716+void AdLib_DOSBox::writeReg(int r, int v) {
1717+ byte tempReg = 0;
1718+ switch (_type) {
1719+ case kOpl2:
1720+ //case kOpl3:
1721+ // We can't use _handler->writeReg here directly, since it would miss timer changes.
1722+
1723+ // Backup old setup register
1724+ tempReg = _reg.normal;
1725+
1726+ // We need to set the register we want to write to via port 0x388
1727+ write(0x388, r);
1728+ // Do the real writing to the register
1729+ write(0x389, v);
1730+ // Restore the old register
1731+ write(0x388, tempReg);
1732+ break;
1733+
1734+ //case kDualOpl2:
1735+ // error("Can't use AdLib_DOSBox::writeReg on Dual OPL2");
1736+ // break;
1737+ };
1738+}
1739+
1740+void AdLib_DOSBox::readBuffer(int16 *buffer, int length) {
1741+ _handler->generate(buffer, length);
1742+}
1743+
1744+} // end of namespace DOSBox
1745+} // end of namespace AdLib
1746+
1747+#endif // !DISABLE_DOSBOX_ADLIB
1748Index: sound/softsynth/adlib/mame.cpp
1749===================================================================
1750--- sound/softsynth/adlib/mame.cpp (revision 0)
1751+++ sound/softsynth/adlib/mame.cpp (revision 0)
1752@@ -0,0 +1,1230 @@
1753+/* ScummVM - Graphic Adventure Engine
1754+ *
1755+ * ScummVM is the legal property of its developers, whose names
1756+ * are too numerous to list here. Please refer to the COPYRIGHT
1757+ * file distributed with this source distribution.
1758+ *
1759+ * This program is free software; you can redistribute it and/or
1760+ * modify it under the terms of the GNU General Public License
1761+ * as published by the Free Software Foundation; either version 2
1762+ * of the License, or (at your option) any later version.
1763+
1764+ * This program is distributed in the hope that it will be useful,
1765+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1766+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1767+ * GNU General Public License for more details.
1768+
1769+ * You should have received a copy of the GNU General Public License
1770+ * along with this program; if not, write to the Free Software
1771+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1772+ *
1773+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.cpp $
1774+ * $Id: fmopl.cpp 38211 2009-02-15 10:07:50Z sev $
1775+ *
1776+ * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
1777+ * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
1778+ */
1779+
1780+#include <stdio.h>
1781+#include <stdlib.h>
1782+#include <string.h>
1783+#include <stdarg.h>
1784+#include <math.h>
1785+
1786+#include "mame.h"
1787+
1788+#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__)
1789+#include "common/config-manager.h"
1790+#endif
1791+
1792+namespace AdLib {
1793+namespace MAME {
1794+
1795+AdLib_MAME::~AdLib_MAME() {
1796+ MAME::OPLDestroy(_opl);
1797+ _opl = 0;
1798+}
1799+
1800+void AdLib_MAME::init(int rate, kOplType type) {
1801+ if (_opl)
1802+ MAME::OPLDestroy(_opl);
1803+
1804+ _opl = MAME::makeAdlibOPL(rate);
1805+}
1806+
1807+void AdLib_MAME::reset() {
1808+ MAME::OPLResetChip(_opl);
1809+}
1810+
1811+void AdLib_MAME::write(int a, int v) {
1812+ MAME::OPLWrite(_opl, a, v);
1813+}
1814+
1815+byte AdLib_MAME::read(int a) {
1816+ return MAME::OPLRead(_opl, a);
1817+}
1818+
1819+void AdLib_MAME::writeReg(int r, int v) {
1820+ MAME::OPLWriteReg(_opl, r, v);
1821+}
1822+
1823+void AdLib_MAME::readBuffer(int16 *buffer, int length) {
1824+ MAME::YM3812UpdateOne(_opl, buffer, length);
1825+}
1826+
1827+/* -------------------- preliminary define section --------------------- */
1828+/* attack/decay rate time rate */
1829+#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
1830+#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
1831+
1832+#define FREQ_BITS 24 /* frequency turn */
1833+
1834+/* counter bits = 20 , octerve 7 */
1835+#define FREQ_RATE (1<<(FREQ_BITS-20))
1836+#define TL_BITS (FREQ_BITS+2)
1837+
1838+/* final output shift , limit minimum and maximum */
1839+#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
1840+#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
1841+#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
1842+
1843+/* -------------------- quality selection --------------------- */
1844+
1845+/* sinwave entries */
1846+/* used static memory = SIN_ENT * 4 (byte) */
1847+#ifdef __DS__
1848+#include "dsmain.h"
1849+#define SIN_ENT_SHIFT 8
1850+#else
1851+#define SIN_ENT_SHIFT 11
1852+#endif
1853+#define SIN_ENT (1<<SIN_ENT_SHIFT)
1854+
1855+/* output level entries (envelope,sinwave) */
1856+/* envelope counter lower bits */
1857+int ENV_BITS;
1858+/* envelope output entries */
1859+int EG_ENT;
1860+
1861+/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
1862+/* used static memory = EG_ENT*4 (byte) */
1863+int EG_OFF; /* OFF */
1864+int EG_DED;
1865+int EG_DST; /* DECAY START */
1866+int EG_AED;
1867+#define EG_AST 0 /* ATTACK START */
1868+
1869+#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
1870+
1871+/* LFO table entries */
1872+#define VIB_ENT 512
1873+#define VIB_SHIFT (32-9)
1874+#define AMS_ENT 512
1875+#define AMS_SHIFT (32-9)
1876+
1877+#define VIB_RATE_SHIFT 8
1878+#define VIB_RATE (1<<VIB_RATE_SHIFT)
1879+
1880+/* -------------------- local defines , macros --------------------- */
1881+
1882+/* register number to channel number , slot offset */
1883+#define SLOT1 0
1884+#define SLOT2 1
1885+
1886+/* envelope phase */
1887+#define ENV_MOD_RR 0x00
1888+#define ENV_MOD_DR 0x01
1889+#define ENV_MOD_AR 0x02
1890+
1891+/* -------------------- tables --------------------- */
1892+static const int slot_array[32] = {
1893+ 0, 2, 4, 1, 3, 5,-1,-1,
1894+ 6, 8,10, 7, 9,11,-1,-1,
1895+ 12,14,16,13,15,17,-1,-1,
1896+ -1,-1,-1,-1,-1,-1,-1,-1
1897+};
1898+
1899+static uint KSL_TABLE[8 * 16];
1900+
1901+static const double KSL_TABLE_SEED[8 * 16] = {
1902+ /* OCT 0 */
1903+ 0.000, 0.000, 0.000, 0.000,
1904+ 0.000, 0.000, 0.000, 0.000,
1905+ 0.000, 0.000, 0.000, 0.000,
1906+ 0.000, 0.000, 0.000, 0.000,
1907+ /* OCT 1 */
1908+ 0.000, 0.000, 0.000, 0.000,
1909+ 0.000, 0.000, 0.000, 0.000,
1910+ 0.000, 0.750, 1.125, 1.500,
1911+ 1.875, 2.250, 2.625, 3.000,
1912+ /* OCT 2 */
1913+ 0.000, 0.000, 0.000, 0.000,
1914+ 0.000, 1.125, 1.875, 2.625,
1915+ 3.000, 3.750, 4.125, 4.500,
1916+ 4.875, 5.250, 5.625, 6.000,
1917+ /* OCT 3 */
1918+ 0.000, 0.000, 0.000, 1.875,
1919+ 3.000, 4.125, 4.875, 5.625,
1920+ 6.000, 6.750, 7.125, 7.500,
1921+ 7.875, 8.250, 8.625, 9.000,
1922+ /* OCT 4 */
1923+ 0.000, 0.000, 3.000, 4.875,
1924+ 6.000, 7.125, 7.875, 8.625,
1925+ 9.000, 9.750, 10.125, 10.500,
1926+ 10.875, 11.250, 11.625, 12.000,
1927+ /* OCT 5 */
1928+ 0.000, 3.000, 6.000, 7.875,
1929+ 9.000, 10.125, 10.875, 11.625,
1930+ 12.000, 12.750, 13.125, 13.500,
1931+ 13.875, 14.250, 14.625, 15.000,
1932+ /* OCT 6 */
1933+ 0.000, 6.000, 9.000, 10.875,
1934+ 12.000, 13.125, 13.875, 14.625,
1935+ 15.000, 15.750, 16.125, 16.500,
1936+ 16.875, 17.250, 17.625, 18.000,
1937+ /* OCT 7 */
1938+ 0.000, 9.000, 12.000, 13.875,
1939+ 15.000, 16.125, 16.875, 17.625,
1940+ 18.000, 18.750, 19.125, 19.500,
1941+ 19.875, 20.250, 20.625, 21.000
1942+};
1943+
1944+/* sustain level table (3db per step) */
1945+/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
1946+
1947+static int SL_TABLE[16];
1948+
1949+static const uint SL_TABLE_SEED[16] = {
1950+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31
1951+};
1952+
1953+#define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
1954+/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
1955+/* TL_TABLE[ 0 to TL_MAX ] : plus section */
1956+/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
1957+static int *TL_TABLE;
1958+
1959+/* pointers to TL_TABLE with sinwave output offset */
1960+static int **SIN_TABLE;
1961+
1962+/* LFO table */
1963+static int *AMS_TABLE;
1964+static int *VIB_TABLE;
1965+
1966+/* envelope output curve table */
1967+/* attack + decay + OFF */
1968+//static int ENV_CURVE[2*EG_ENT+1];
1969+//static int ENV_CURVE[2 * 4096 + 1]; // to keep it static ...
1970+static int *ENV_CURVE;
1971+
1972+
1973+/* multiple table */
1974+#define ML(a) (int)(a * 2)
1975+static const uint MUL_TABLE[16]= {
1976+/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
1977+ ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
1978+ ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
1979+};
1980+#undef ML
1981+
1982+/* dummy attack / decay rate ( when rate == 0 ) */
1983+static int RATE_0[16]=
1984+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1985+
1986+/* -------------------- static state --------------------- */
1987+
1988+/* lock level of common table */
1989+static int num_lock = 0;
1990+
1991+/* work table */
1992+static void *cur_chip = NULL; /* current chip point */
1993+/* currenct chip state */
1994+/* static OPLSAMPLE *bufL,*bufR; */
1995+static OPL_CH *S_CH;
1996+static OPL_CH *E_CH;
1997+OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
1998+
1999+static int outd[1];
2000+static int ams;
2001+static int vib;
2002+int *ams_table;
2003+int *vib_table;
2004+static int amsIncr;
2005+static int vibIncr;
2006+static int feedback2; /* connect for SLOT 2 */
2007+
2008+/* --------------------- rebuild tables ------------------- */
2009+
2010+#define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2)))
2011+#define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
2012+
2013+void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
2014+ int i;
2015+
2016+ ENV_BITS = ENV_BITS_PARAM;
2017+ EG_ENT = EG_ENT_PARAM;
2018+ EG_OFF = ((2 * EG_ENT)<<ENV_BITS); /* OFF */
2019+ EG_DED = EG_OFF;
2020+ EG_DST = (EG_ENT << ENV_BITS); /* DECAY START */
2021+ EG_AED = EG_DST;
2022+ //EG_STEP = (96.0/EG_ENT);
2023+
2024+ for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++)
2025+ KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
2026+
2027+ for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++)
2028+ SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
2029+}
2030+
2031+#undef SC_KSL
2032+#undef SC_SL
2033+
2034+/* --------------------- subroutines --------------------- */
2035+
2036+/* status set and IRQ handling */
2037+inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
2038+ /* set status flag */
2039+ OPL->status |= flag;
2040+ if(!(OPL->status & 0x80)) {
2041+ if(OPL->status & OPL->statusmask) { /* IRQ on */
2042+ OPL->status |= 0x80;
2043+ /* callback user interrupt handler (IRQ is OFF to ON) */
2044+ if(OPL->IRQHandler)
2045+ (OPL->IRQHandler)(OPL->IRQParam,1);
2046+ }
2047+ }
2048+}
2049+
2050+/* status reset and IRQ handling */
2051+inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
2052+ /* reset status flag */
2053+ OPL->status &= ~flag;
2054+ if((OPL->status & 0x80)) {
2055+ if (!(OPL->status & OPL->statusmask)) {
2056+ OPL->status &= 0x7f;
2057+ /* callback user interrupt handler (IRQ is ON to OFF) */
2058+ if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
2059+ }
2060+ }
2061+}
2062+
2063+/* IRQ mask set */
2064+inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
2065+ OPL->statusmask = flag;
2066+ /* IRQ handling check */
2067+ OPL_STATUS_SET(OPL,0);
2068+ OPL_STATUS_RESET(OPL,0);
2069+}
2070+
2071+/* ----- key on ----- */
2072+inline void OPL_KEYON(OPL_SLOT *SLOT) {
2073+ /* sin wave restart */
2074+ SLOT->Cnt = 0;
2075+ /* set attack */
2076+ SLOT->evm = ENV_MOD_AR;
2077+ SLOT->evs = SLOT->evsa;
2078+ SLOT->evc = EG_AST;
2079+ SLOT->eve = EG_AED;
2080+}
2081+
2082+/* ----- key off ----- */
2083+inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
2084+ if( SLOT->evm > ENV_MOD_RR) {
2085+ /* set envelope counter from envleope output */
2086+
2087+ // WORKAROUND: The Kyra engine does something very strange when
2088+ // starting a new song. For each channel:
2089+ //
2090+ // * The release rate is set to "fastest".
2091+ // * Any note is keyed off.
2092+ // * A very low-frequency note is keyed on.
2093+ //
2094+ // Usually, what happens next is that the real notes is keyed
2095+ // on immediately, in which case there's no problem.
2096+ //
2097+ // However, if the note is again keyed off (because the channel
2098+ // begins on a rest rather than a note), the envelope counter
2099+ // was moved from the very lowest point on the attack curve to
2100+ // the very highest point on the release curve.
2101+ //
2102+ // Again, this might not be a problem, if the release rate is
2103+ // still set to "fastest". But in many cases, it had already
2104+ // been increased. And, possibly because of inaccuracies in the
2105+ // envelope generator, that would cause the note to "fade out"
2106+ // for quite a long time.
2107+ //
2108+ // What we really need is a way to find the correct starting
2109+ // point for the envelope counter, and that may be what the
2110+ // commented-out line below is meant to do. For now, simply
2111+ // handle the pathological case.
2112+
2113+ if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
2114+ SLOT->evc = EG_DED;
2115+ else if( !(SLOT->evc & EG_DST) )
2116+ //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
2117+ SLOT->evc = EG_DST;
2118+ SLOT->eve = EG_DED;
2119+ SLOT->evs = SLOT->evsr;
2120+ SLOT->evm = ENV_MOD_RR;
2121+ }
2122+}
2123+
2124+/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
2125+
2126+/* return : envelope output */
2127+inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
2128+ /* calcrate envelope generator */
2129+ if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
2130+ switch( SLOT->evm ) {
2131+ case ENV_MOD_AR: /* ATTACK -> DECAY1 */
2132+ /* next DR */
2133+ SLOT->evm = ENV_MOD_DR;
2134+ SLOT->evc = EG_DST;
2135+ SLOT->eve = SLOT->SL;
2136+ SLOT->evs = SLOT->evsd;
2137+ break;
2138+ case ENV_MOD_DR: /* DECAY -> SL or RR */
2139+ SLOT->evc = SLOT->SL;
2140+ SLOT->eve = EG_DED;
2141+ if(SLOT->eg_typ) {
2142+ SLOT->evs = 0;
2143+ } else {
2144+ SLOT->evm = ENV_MOD_RR;
2145+ SLOT->evs = SLOT->evsr;
2146+ }
2147+ break;
2148+ case ENV_MOD_RR: /* RR -> OFF */
2149+ SLOT->evc = EG_OFF;
2150+ SLOT->eve = EG_OFF + 1;
2151+ SLOT->evs = 0;
2152+ break;
2153+ }
2154+ }
2155+ /* calcrate envelope */
2156+ return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
2157+}
2158+
2159+/* set algorythm connection */
2160+static void set_algorythm(OPL_CH *CH) {
2161+ int *carrier = &outd[0];
2162+ CH->connect1 = CH->CON ? carrier : &feedback2;
2163+ CH->connect2 = carrier;
2164+}
2165+
2166+/* ---------- frequency counter for operater update ---------- */
2167+inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
2168+ int ksr;
2169+
2170+ /* frequency step counter */
2171+ SLOT->Incr = CH->fc * SLOT->mul;
2172+ ksr = CH->kcode >> SLOT->KSR;
2173+
2174+ if( SLOT->ksr != ksr ) {
2175+ SLOT->ksr = ksr;
2176+ /* attack , decay rate recalcration */
2177+ SLOT->evsa = SLOT->AR[ksr];
2178+ SLOT->evsd = SLOT->DR[ksr];
2179+ SLOT->evsr = SLOT->RR[ksr];
2180+ }
2181+ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
2182+}
2183+
2184+/* set multi,am,vib,EG-TYP,KSR,mul */
2185+inline void set_mul(FM_OPL *OPL, int slot, int v) {
2186+ OPL_CH *CH = &OPL->P_CH[slot>>1];
2187+ OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
2188+
2189+ SLOT->mul = MUL_TABLE[v & 0x0f];
2190+ SLOT->KSR = (v & 0x10) ? 0 : 2;
2191+ SLOT->eg_typ = (v & 0x20) >> 5;
2192+ SLOT->vib = (v & 0x40);
2193+ SLOT->ams = (v & 0x80);
2194+ CALC_FCSLOT(CH, SLOT);
2195+}
2196+
2197+/* set ksl & tl */
2198+inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
2199+ OPL_CH *CH = &OPL->P_CH[slot>>1];
2200+ OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
2201+ int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
2202+
2203+ SLOT->ksl = ksl ? 3-ksl : 31;
2204+ SLOT->TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
2205+
2206+ if(!(OPL->mode & 0x80)) { /* not CSM latch total level */
2207+ SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
2208+ }
2209+}
2210+
2211+/* set attack rate & decay rate */
2212+inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
2213+ OPL_CH *CH = &OPL->P_CH[slot>>1];
2214+ OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
2215+ int ar = v >> 4;
2216+ int dr = v & 0x0f;
2217+
2218+ SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
2219+ SLOT->evsa = SLOT->AR[SLOT->ksr];
2220+ if(SLOT->evm == ENV_MOD_AR)
2221+ SLOT->evs = SLOT->evsa;
2222+
2223+ SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
2224+ SLOT->evsd = SLOT->DR[SLOT->ksr];
2225+ if(SLOT->evm == ENV_MOD_DR)
2226+ SLOT->evs = SLOT->evsd;
2227+}
2228+
2229+/* set sustain level & release rate */
2230+inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
2231+ OPL_CH *CH = &OPL->P_CH[slot>>1];
2232+ OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
2233+ int sl = v >> 4;
2234+ int rr = v & 0x0f;
2235+
2236+ SLOT->SL = SL_TABLE[sl];
2237+ if(SLOT->evm == ENV_MOD_DR)
2238+ SLOT->eve = SLOT->SL;
2239+ SLOT->RR = &OPL->DR_TABLE[rr<<2];
2240+ SLOT->evsr = SLOT->RR[SLOT->ksr];
2241+ if(SLOT->evm == ENV_MOD_RR)
2242+ SLOT->evs = SLOT->evsr;
2243+}
2244+
2245+/* operator output calcrator */
2246+
2247+#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env]
2248+/* ---------- calcrate one of channel ---------- */
2249+inline void OPL_CALC_CH(OPL_CH *CH) {
2250+ uint env_out;
2251+ OPL_SLOT *SLOT;
2252+
2253+ feedback2 = 0;
2254+ /* SLOT 1 */
2255+ SLOT = &CH->SLOT[SLOT1];
2256+ env_out=OPL_CALC_SLOT(SLOT);
2257+ if(env_out < (uint)(EG_ENT - 1)) {
2258+ /* PG */
2259+ if(SLOT->vib)
2260+ SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
2261+ else
2262+ SLOT->Cnt += SLOT->Incr;
2263+ /* connection */
2264+ if(CH->FB) {
2265+ int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
2266+ CH->op1_out[1] = CH->op1_out[0];
2267+ *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
2268+ } else {
2269+ *CH->connect1 += OP_OUT(SLOT, env_out, 0);
2270+ }
2271+ } else {
2272+ CH->op1_out[1] = CH->op1_out[0];
2273+ CH->op1_out[0] = 0;
2274+ }
2275+ /* SLOT 2 */
2276+ SLOT = &CH->SLOT[SLOT2];
2277+ env_out=OPL_CALC_SLOT(SLOT);
2278+ if(env_out < (uint)(EG_ENT - 1)) {
2279+ /* PG */
2280+ if(SLOT->vib)
2281+ SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
2282+ else
2283+ SLOT->Cnt += SLOT->Incr;
2284+ /* connection */
2285+ outd[0] += OP_OUT(SLOT, env_out, feedback2);
2286+ }
2287+}
2288+
2289+/* ---------- calcrate rythm block ---------- */
2290+#define WHITE_NOISE_db 6.0
2291+inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
2292+ uint env_tam, env_sd, env_top, env_hh;
2293+ // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
2294+ // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
2295+ // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
2296+ // or 128, so we can safely avoid any FP ops.
2297+ int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4);
2298+
2299+ int tone8;
2300+
2301+ OPL_SLOT *SLOT;
2302+ int env_out;
2303+
2304+ /* BD : same as FM serial mode and output level is large */
2305+ feedback2 = 0;
2306+ /* SLOT 1 */
2307+ SLOT = &CH[6].SLOT[SLOT1];
2308+ env_out = OPL_CALC_SLOT(SLOT);
2309+ if(env_out < EG_ENT-1) {
2310+ /* PG */
2311+ if(SLOT->vib)
2312+ SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
2313+ else
2314+ SLOT->Cnt += SLOT->Incr;
2315+ /* connection */
2316+ if(CH[6].FB) {
2317+ int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
2318+ CH[6].op1_out[1] = CH[6].op1_out[0];
2319+ feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
2320+ }
2321+ else {
2322+ feedback2 = OP_OUT(SLOT, env_out, 0);
2323+ }
2324+ } else {
2325+ feedback2 = 0;
2326+ CH[6].op1_out[1] = CH[6].op1_out[0];
2327+ CH[6].op1_out[0] = 0;
2328+ }
2329+ /* SLOT 2 */
2330+ SLOT = &CH[6].SLOT[SLOT2];
2331+ env_out = OPL_CALC_SLOT(SLOT);
2332+ if(env_out < EG_ENT-1) {
2333+ /* PG */
2334+ if(SLOT->vib)
2335+ SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
2336+ else
2337+ SLOT->Cnt += SLOT->Incr;
2338+ /* connection */
2339+ outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
2340+ }
2341+
2342+ // SD (17) = mul14[fnum7] + white noise
2343+ // TAM (15) = mul15[fnum8]
2344+ // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
2345+ // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
2346+ env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
2347+ env_tam =OPL_CALC_SLOT(SLOT8_1);
2348+ env_top = OPL_CALC_SLOT(SLOT8_2);
2349+ env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
2350+
2351+ /* PG */
2352+ if(SLOT7_1->vib)
2353+ SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1);
2354+ else
2355+ SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
2356+ if(SLOT7_2->vib)
2357+ SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3);
2358+ else
2359+ SLOT7_2->Cnt += (CH[7].fc * 8);
2360+ if(SLOT8_1->vib)
2361+ SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;
2362+ else
2363+ SLOT8_1->Cnt += SLOT8_1->Incr;
2364+ if(SLOT8_2->vib)
2365+ SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4);
2366+ else
2367+ SLOT8_2->Cnt += (CH[8].fc * 48);
2368+
2369+ tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
2370+
2371+ /* SD */
2372+ if(env_sd < (uint)(EG_ENT - 1))
2373+ outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
2374+ /* TAM */
2375+ if(env_tam < (uint)(EG_ENT - 1))
2376+ outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
2377+ /* TOP-CY */
2378+ if(env_top < (uint)(EG_ENT - 1))
2379+ outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
2380+ /* HH */
2381+ if(env_hh < (uint)(EG_ENT-1))
2382+ outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
2383+}
2384+
2385+/* ----------- initialize time tabls ----------- */
2386+static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
2387+ int i;
2388+ double rate;
2389+
2390+ /* make attack rate & decay rate tables */
2391+ for (i = 0; i < 4; i++)
2392+ OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
2393+ for (i = 4; i <= 60; i++) {
2394+ rate = OPL->freqbase; /* frequency rate */
2395+ if(i < 60)
2396+ rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
2397+ rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */
2398+ rate *= (double)(EG_ENT << ENV_BITS);
2399+ OPL->AR_TABLE[i] = (int)(rate / ARRATE);
2400+ OPL->DR_TABLE[i] = (int)(rate / DRRATE);
2401+ }
2402+ for (i = 60; i < 76; i++) {
2403+ OPL->AR_TABLE[i] = EG_AED-1;
2404+ OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
2405+ }
2406+}
2407+
2408+/* ---------- generic table initialize ---------- */
2409+static int OPLOpenTable(void) {
2410+ int s,t;
2411+ double rate;
2412+ int i,j;
2413+ double pom;
2414+
2415+#ifdef __DS__
2416+ DS::fastRamReset();
2417+
2418+ TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *));
2419+ SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *));
2420+#else
2421+
2422+ /* allocate dynamic tables */
2423+ if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
2424+ return 0;
2425+
2426+ if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
2427+ free(TL_TABLE);
2428+ return 0;
2429+ }
2430+#endif
2431+
2432+ if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
2433+ free(TL_TABLE);
2434+ free(SIN_TABLE);
2435+ return 0;
2436+ }
2437+
2438+ if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
2439+ free(TL_TABLE);
2440+ free(SIN_TABLE);
2441+ free(AMS_TABLE);
2442+ return 0;
2443+ }
2444+ /* make total level table */
2445+ for (t = 0; t < EG_ENT - 1 ; t++) {
2446+ rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */
2447+ TL_TABLE[ t] = (int)rate;
2448+ TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
2449+ }
2450+ /* fill volume off area */
2451+ for (t = EG_ENT - 1; t < TL_MAX; t++) {
2452+ TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
2453+ }
2454+
2455+ /* make sinwave table (total level offet) */
2456+ /* degree 0 = degree 180 = off */
2457+ SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
2458+ for (s = 1;s <= SIN_ENT / 4; s++) {
2459+ pom = sin(2 * PI * s / SIN_ENT); /* sin */
2460+ pom = 20 * log10(1 / pom); /* decibel */
2461+ j = int(pom / EG_STEP); /* TL_TABLE steps */
2462+
2463+ /* degree 0 - 90 , degree 180 - 90 : plus section */
2464+ SIN_TABLE[ s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
2465+ /* degree 180 - 270 , degree 360 - 270 : minus section */
2466+ SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
2467+ }
2468+ for (s = 0;s < SIN_ENT; s++) {
2469+ SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
2470+ SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
2471+ SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
2472+ }
2473+
2474+
2475+ ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1));
2476+
2477+ /* envelope counter -> envelope output table */
2478+ for (i=0; i < EG_ENT; i++) {
2479+ /* ATTACK curve */
2480+ pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
2481+ /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
2482+ ENV_CURVE[i] = (int)pom;
2483+ /* DECAY ,RELEASE curve */
2484+ ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
2485+ }
2486+ /* off */
2487+ ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
2488+ /* make LFO ams table */
2489+ for (i=0; i < AMS_ENT; i++) {
2490+ pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
2491+ AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */
2492+ AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
2493+ }
2494+ /* make LFO vibrate table */
2495+ for (i=0; i < VIB_ENT; i++) {
2496+ /* 100cent = 1seminote = 6% ?? */
2497+ pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
2498+ VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
2499+ VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
2500+ }
2501+ return 1;
2502+}
2503+
2504+static void OPLCloseTable(void) {
2505+ free(TL_TABLE);
2506+ free(SIN_TABLE);
2507+ free(AMS_TABLE);
2508+ free(VIB_TABLE);
2509+ free(ENV_CURVE);
2510+}
2511+
2512+/* CSM Key Controll */
2513+inline void CSMKeyControll(OPL_CH *CH) {
2514+ OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
2515+ OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
2516+ /* all key off */
2517+ OPL_KEYOFF(slot1);
2518+ OPL_KEYOFF(slot2);
2519+ /* total level latch */
2520+ slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
2521+ slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
2522+ /* key on */
2523+ CH->op1_out[0] = CH->op1_out[1] = 0;
2524+ OPL_KEYON(slot1);
2525+ OPL_KEYON(slot2);
2526+}
2527+
2528+/* ---------- opl initialize ---------- */
2529+static void OPL_initalize(FM_OPL *OPL) {
2530+ int fn;
2531+
2532+ /* frequency base */
2533+ OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
2534+ /* Timer base time */
2535+ OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
2536+ /* make time tables */
2537+ init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
2538+ /* make fnumber -> increment counter table */
2539+ for( fn=0; fn < 1024; fn++) {
2540+ OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
2541+ }
2542+ /* LFO freq.table */
2543+ OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0);
2544+ OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0);
2545+}
2546+
2547+/* ---------- write a OPL registers ---------- */
2548+void OPLWriteReg(FM_OPL *OPL, int r, int v) {
2549+ OPL_CH *CH;
2550+ int slot;
2551+ uint block_fnum;
2552+
2553+ switch(r & 0xe0) {
2554+ case 0x00: /* 00-1f:controll */
2555+ switch(r & 0x1f) {
2556+ case 0x01:
2557+ /* wave selector enable */
2558+ if(OPL->type&OPL_TYPE_WAVESEL) {
2559+ OPL->wavesel = v & 0x20;
2560+ if(!OPL->wavesel) {
2561+ /* preset compatible mode */
2562+ int c;
2563+ for(c=0; c<OPL->max_ch; c++) {
2564+ OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
2565+ OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
2566+ }
2567+ }
2568+ }
2569+ return;
2570+ case 0x02: /* Timer 1 */
2571+ OPL->T[0] = (256-v) * 4;
2572+ break;
2573+ case 0x03: /* Timer 2 */
2574+ OPL->T[1] = (256-v) * 16;
2575+ return;
2576+ case 0x04: /* IRQ clear / mask and Timer enable */
2577+ if(v & 0x80) { /* IRQ flag clear */
2578+ OPL_STATUS_RESET(OPL, 0x7f);
2579+ } else { /* set IRQ mask ,timer enable*/
2580+ uint8 st1 = v & 1;
2581+ uint8 st2 = (v >> 1) & 1;
2582+ /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
2583+ OPL_STATUS_RESET(OPL, v & 0x78);
2584+ OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
2585+ /* timer 2 */
2586+ if(OPL->st[1] != st2) {
2587+ double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
2588+ OPL->st[1] = st2;
2589+ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
2590+ }
2591+ /* timer 1 */
2592+ if(OPL->st[0] != st1) {
2593+ double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
2594+ OPL->st[0] = st1;
2595+ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
2596+ }
2597+ }
2598+ return;
2599+ }
2600+ break;
2601+ case 0x20: /* am,vib,ksr,eg type,mul */
2602+ slot = slot_array[r&0x1f];
2603+ if(slot == -1)
2604+ return;
2605+ set_mul(OPL,slot,v);
2606+ return;
2607+ case 0x40:
2608+ slot = slot_array[r&0x1f];
2609+ if(slot == -1)
2610+ return;
2611+ set_ksl_tl(OPL,slot,v);
2612+ return;
2613+ case 0x60:
2614+ slot = slot_array[r&0x1f];
2615+ if(slot == -1)
2616+ return;
2617+ set_ar_dr(OPL,slot,v);
2618+ return;
2619+ case 0x80:
2620+ slot = slot_array[r&0x1f];
2621+ if(slot == -1)
2622+ return;
2623+ set_sl_rr(OPL,slot,v);
2624+ return;
2625+ case 0xa0:
2626+ switch(r) {
2627+ case 0xbd:
2628+ /* amsep,vibdep,r,bd,sd,tom,tc,hh */
2629+ {
2630+ uint8 rkey = OPL->rythm ^ v;
2631+ OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
2632+ OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
2633+ OPL->rythm = v & 0x3f;
2634+ if(OPL->rythm & 0x20) {
2635+ /* BD key on/off */
2636+ if(rkey & 0x10) {
2637+ if(v & 0x10) {
2638+ OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
2639+ OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
2640+ OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
2641+ } else {
2642+ OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
2643+ OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
2644+ }
2645+ }
2646+ /* SD key on/off */
2647+ if(rkey & 0x08) {
2648+ if(v & 0x08)
2649+ OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
2650+ else
2651+ OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
2652+ }/* TAM key on/off */
2653+ if(rkey & 0x04) {
2654+ if(v & 0x04)
2655+ OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
2656+ else
2657+ OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
2658+ }
2659+ /* TOP-CY key on/off */
2660+ if(rkey & 0x02) {
2661+ if(v & 0x02)
2662+ OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
2663+ else
2664+ OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
2665+ }
2666+ /* HH key on/off */
2667+ if(rkey & 0x01) {
2668+ if(v & 0x01)
2669+ OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
2670+ else
2671+ OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
2672+ }
2673+ }
2674+ }
2675+ return;
2676+
2677+ default:
2678+ break;
2679+ }
2680+ /* keyon,block,fnum */
2681+ if((r & 0x0f) > 8)
2682+ return;
2683+ CH = &OPL->P_CH[r & 0x0f];
2684+ if(!(r&0x10)) { /* a0-a8 */
2685+ block_fnum = (CH->block_fnum & 0x1f00) | v;
2686+ } else { /* b0-b8 */
2687+ int keyon = (v >> 5) & 1;
2688+ block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
2689+ if(CH->keyon != keyon) {
2690+ if((CH->keyon=keyon)) {
2691+ CH->op1_out[0] = CH->op1_out[1] = 0;
2692+ OPL_KEYON(&CH->SLOT[SLOT1]);
2693+ OPL_KEYON(&CH->SLOT[SLOT2]);
2694+ } else {
2695+ OPL_KEYOFF(&CH->SLOT[SLOT1]);
2696+ OPL_KEYOFF(&CH->SLOT[SLOT2]);
2697+ }
2698+ }
2699+ }
2700+ /* update */
2701+ if(CH->block_fnum != block_fnum) {
2702+ int blockRv = 7 - (block_fnum >> 10);
2703+ int fnum = block_fnum & 0x3ff;
2704+ CH->block_fnum = block_fnum;
2705+ CH->ksl_base = KSL_TABLE[block_fnum >> 6];
2706+ CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
2707+ CH->kcode = CH->block_fnum >> 9;
2708+ if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
2709+ CH->kcode |=1;
2710+ CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
2711+ CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
2712+ }
2713+ return;
2714+ case 0xc0:
2715+ /* FB,C */
2716+ if((r & 0x0f) > 8)
2717+ return;
2718+ CH = &OPL->P_CH[r&0x0f];
2719+ {
2720+ int feedback = (v >> 1) & 7;
2721+ CH->FB = feedback ? (8 + 1) - feedback : 0;
2722+ CH->CON = v & 1;
2723+ set_algorythm(CH);
2724+ }
2725+ return;
2726+ case 0xe0: /* wave type */
2727+ slot = slot_array[r & 0x1f];
2728+ if(slot == -1)
2729+ return;
2730+ CH = &OPL->P_CH[slot>>1];
2731+ if(OPL->wavesel) {
2732+ CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
2733+ }
2734+ return;
2735+ }
2736+}
2737+
2738+/* lock/unlock for common table */
2739+static int OPL_LockTable(void) {
2740+ num_lock++;
2741+ if(num_lock>1)
2742+ return 0;
2743+ /* first time */
2744+ cur_chip = NULL;
2745+ /* allocate total level table (128kb space) */
2746+ if(!OPLOpenTable()) {
2747+ num_lock--;
2748+ return -1;
2749+ }
2750+ return 0;
2751+}
2752+
2753+static void OPL_UnLockTable(void) {
2754+ if(num_lock)
2755+ num_lock--;
2756+ if(num_lock)
2757+ return;
2758+ /* last time */
2759+ cur_chip = NULL;
2760+ OPLCloseTable();
2761+}
2762+
2763+/*******************************************************************************/
2764+/* YM3812 local section */
2765+/*******************************************************************************/
2766+
2767+/* ---------- update one of chip ----------- */
2768+void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave) {
2769+ int i;
2770+ int data;
2771+ int16 *buf = buffer;
2772+ uint amsCnt = OPL->amsCnt;
2773+ uint vibCnt = OPL->vibCnt;
2774+ uint8 rythm = OPL->rythm & 0x20;
2775+ OPL_CH *CH, *R_CH;
2776+
2777+
2778+ if((void *)OPL != cur_chip) {
2779+ cur_chip = (void *)OPL;
2780+ /* channel pointers */
2781+ S_CH = OPL->P_CH;
2782+ E_CH = &S_CH[9];
2783+ /* rythm slot */
2784+ SLOT7_1 = &S_CH[7].SLOT[SLOT1];
2785+ SLOT7_2 = &S_CH[7].SLOT[SLOT2];
2786+ SLOT8_1 = &S_CH[8].SLOT[SLOT1];
2787+ SLOT8_2 = &S_CH[8].SLOT[SLOT2];
2788+ /* LFO state */
2789+ amsIncr = OPL->amsIncr;
2790+ vibIncr = OPL->vibIncr;
2791+ ams_table = OPL->ams_table;
2792+ vib_table = OPL->vib_table;
2793+ }
2794+ R_CH = rythm ? &S_CH[6] : E_CH;
2795+ for(i = 0; i < length; i++) {
2796+ /* channel A channel B channel C */
2797+ /* LFO */
2798+ ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
2799+ vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
2800+ outd[0] = 0;
2801+ /* FM part */
2802+ for(CH=S_CH; CH < R_CH; CH++)
2803+ OPL_CALC_CH(CH);
2804+ /* Rythn part */
2805+ if(rythm)
2806+ OPL_CALC_RH(OPL, S_CH);
2807+ /* limit check */
2808+ data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT);
2809+ /* store to sound buffer */
2810+ buf[i << interleave] = data >> OPL_OUTSB;
2811+ }
2812+
2813+ OPL->amsCnt = amsCnt;
2814+ OPL->vibCnt = vibCnt;
2815+}
2816+
2817+/* ---------- reset a chip ---------- */
2818+void OPLResetChip(FM_OPL *OPL) {
2819+ int c,s;
2820+ int i;
2821+
2822+ /* reset chip */
2823+ OPL->mode = 0; /* normal mode */
2824+ OPL_STATUS_RESET(OPL, 0x7f);
2825+ /* reset with register write */
2826+ OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
2827+ OPLWriteReg(OPL, 0x02,0); /* Timer1 */
2828+ OPLWriteReg(OPL, 0x03,0); /* Timer2 */
2829+ OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
2830+ for(i = 0xff; i >= 0x20; i--)
2831+ OPLWriteReg(OPL,i,0);
2832+ /* reset OPerator parameter */
2833+ for(c = 0; c < OPL->max_ch ;c++ ) {
2834+ OPL_CH *CH = &OPL->P_CH[c];
2835+ /* OPL->P_CH[c].PAN = OPN_CENTER; */
2836+ for(s = 0; s < 2; s++ ) {
2837+ /* wave table */
2838+ CH->SLOT[s].wavetable = &SIN_TABLE[0];
2839+ /* CH->SLOT[s].evm = ENV_MOD_RR; */
2840+ CH->SLOT[s].evc = EG_OFF;
2841+ CH->SLOT[s].eve = EG_OFF + 1;
2842+ CH->SLOT[s].evs = 0;
2843+ }
2844+ }
2845+}
2846+
2847+/* ---------- Create a virtual YM3812 ---------- */
2848+/* 'rate' is sampling rate and 'bufsiz' is the size of the */
2849+FM_OPL *OPLCreate(int type, int clock, int rate) {
2850+ char *ptr;
2851+ FM_OPL *OPL;
2852+ int state_size;
2853+ int max_ch = 9; /* normaly 9 channels */
2854+
2855+ if( OPL_LockTable() == -1)
2856+ return NULL;
2857+ /* allocate OPL state space */
2858+ state_size = sizeof(FM_OPL);
2859+ state_size += sizeof(OPL_CH) * max_ch;
2860+
2861+ /* allocate memory block */
2862+ ptr = (char *)calloc(state_size, 1);
2863+ if(ptr == NULL)
2864+ return NULL;
2865+
2866+ /* clear */
2867+ memset(ptr, 0, state_size);
2868+ OPL = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
2869+ OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
2870+
2871+ /* set channel state pointer */
2872+ OPL->type = type;
2873+ OPL->clock = clock;
2874+ OPL->rate = rate;
2875+ OPL->max_ch = max_ch;
2876+
2877+ /* init grobal tables */
2878+ OPL_initalize(OPL);
2879+
2880+ /* reset chip */
2881+ OPLResetChip(OPL);
2882+ return OPL;
2883+}
2884+
2885+/* ---------- Destroy one of vietual YM3812 ---------- */
2886+void OPLDestroy(FM_OPL *OPL) {
2887+ OPL_UnLockTable();
2888+ free(OPL);
2889+}
2890+
2891+/* ---------- Option handlers ---------- */
2892+void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
2893+ OPL->TimerHandler = TimerHandler;
2894+ OPL->TimerParam = channelOffset;
2895+}
2896+
2897+void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
2898+ OPL->IRQHandler = IRQHandler;
2899+ OPL->IRQParam = param;
2900+}
2901+
2902+void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
2903+ OPL->UpdateHandler = UpdateHandler;
2904+ OPL->UpdateParam = param;
2905+}
2906+
2907+/* ---------- YM3812 I/O interface ---------- */
2908+int OPLWrite(FM_OPL *OPL,int a,int v) {
2909+ if(!(a & 1)) { /* address port */
2910+ OPL->address = v & 0xff;
2911+ } else { /* data port */
2912+ if(OPL->UpdateHandler)
2913+ OPL->UpdateHandler(OPL->UpdateParam,0);
2914+ OPLWriteReg(OPL, OPL->address,v);
2915+ }
2916+ return OPL->status >> 7;
2917+}
2918+
2919+unsigned char OPLRead(FM_OPL *OPL,int a) {
2920+ if(!(a & 1)) { /* status port */
2921+ return OPL->status & (OPL->statusmask | 0x80);
2922+ }
2923+ /* data port */
2924+ switch(OPL->address) {
2925+ case 0x05: /* KeyBoard IN */
2926+ warning("OPL:read unmapped KEYBOARD port\n");
2927+ return 0;
2928+ case 0x19: /* I/O DATA */
2929+ warning("OPL:read unmapped I/O port\n");
2930+ return 0;
2931+ case 0x1a: /* PCM-DATA */
2932+ return 0;
2933+ default:
2934+ break;
2935+ }
2936+ return 0;
2937+}
2938+
2939+int OPLTimerOver(FM_OPL *OPL, int c) {
2940+ if(c) { /* Timer B */
2941+ OPL_STATUS_SET(OPL, 0x20);
2942+ } else { /* Timer A */
2943+ OPL_STATUS_SET(OPL, 0x40);
2944+ /* CSM mode key,TL controll */
2945+ if(OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */
2946+ int ch;
2947+ if(OPL->UpdateHandler)
2948+ OPL->UpdateHandler(OPL->UpdateParam,0);
2949+ for(ch = 0; ch < 9; ch++)
2950+ CSMKeyControll(&OPL->P_CH[ch]);
2951+ }
2952+ }
2953+ /* reload timer */
2954+ if (OPL->TimerHandler)
2955+ (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);
2956+ return OPL->status >> 7;
2957+}
2958+
2959+FM_OPL *makeAdlibOPL(int rate) {
2960+ // We need to emulate one YM3812 chip
2961+ int env_bits = FMOPL_ENV_BITS_HQ;
2962+ int eg_ent = FMOPL_EG_ENT_HQ;
2963+#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__)
2964+ if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
2965+ env_bits = FMOPL_ENV_BITS_HQ;
2966+ eg_ent = FMOPL_EG_ENT_HQ;
2967+ } else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) {
2968+ env_bits = FMOPL_ENV_BITS_MQ;
2969+ eg_ent = FMOPL_EG_ENT_MQ;
2970+ } else {
2971+ env_bits = FMOPL_ENV_BITS_LQ;
2972+ eg_ent = FMOPL_EG_ENT_LQ;
2973+ }
2974+#endif
2975+
2976+ OPLBuildTables(env_bits, eg_ent);
2977+ return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
2978+}
2979+
2980+} // end of namespace MAME
2981+} // end of namespace AdLib
2982+
2983Index: sound/softsynth/adlib/dbopl.cpp
2984===================================================================
2985--- sound/softsynth/adlib/dbopl.cpp (revision 0)
2986+++ sound/softsynth/adlib/dbopl.cpp (revision 0)
2987@@ -0,0 +1,1468 @@
2988+/*
2989+ * Copyright (C) 2002-2009 The DOSBox Team
2990+ *
2991+ * This program is free software; you can redistribute it and/or modify
2992+ * it under the terms of the GNU General Public License as published by
2993+ * the Free Software Foundation; either version 2 of the License, or
2994+ * (at your option) any later version.
2995+ *
2996+ * This program is distributed in the hope that it will be useful,
2997+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2998+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2999+ * GNU General Public License for more details.
3000+ *
3001+ * You should have received a copy of the GNU General Public License
3002+ * along with this program; if not, write to the Free Software
3003+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3004+ */
3005+
3006+/*
3007+ DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
3008+ Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
3009+ Except for the table generation it's all integer math
3010+ Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
3011+ The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
3012+ MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
3013+
3014+ //TODO Don't delay first operator 1 sample in opl3 mode
3015+ //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
3016+ //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
3017+ //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample
3018+ //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree
3019+
3020+ //DUNNO Keyon in 4op, switch to 2op without keyoff.
3021+*/
3022+
3023+#ifndef DISABLE_DOSBOX_ADLIB
3024+
3025+#include "dbopl.h"
3026+#include <stddef.h> // for ptrdiff_t
3027+
3028+#ifndef PI
3029+#define PI 3.14159265358979323846
3030+#endif
3031+
3032+#ifndef INLINE
3033+#define INLINE
3034+#endif
3035+
3036+#define OFFS(type,item) (((ptrdiff_t)(&((type*)42)->type::item))-42)
3037+
3038+namespace AdLib {
3039+namespace DOSBox {
3040+namespace DBOPL {
3041+
3042+#define MAX_SAMPLES 256
3043+#define OPLRATE ((double)(14318180.0 / 288.0))
3044+
3045+//Only need 4 valid bits at the top for vibrato
3046+#define VIBRATO_SH ( 32 - 4 )
3047+//Need 6 bits of accuracy
3048+#define TREMOLO_SH ( 32 - 6 )
3049+#define TREMOLO_TABLE 52
3050+
3051+//Wave bits available in the top of the 32bit range
3052+//Original adlib uses 10.10, we use 12.20
3053+//Have to keep some bits in the top to allow for freqmul 0.5
3054+#define WAVE_BITS 12
3055+#define WAVE_SH ( 32 - WAVE_BITS )
3056+#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 )
3057+
3058+//Maximum amount of attenuation bits
3059+//Envelope goes to 511, 9 bits
3060+#if (DBOPL_WAVE == WAVE_TABLEMUL )
3061+//Uses the value directly
3062+#define ENV_BITS ( 9 )
3063+#else
3064+//Add 3 bits here for more accuracy and would have to be shifted up either way
3065+#define ENV_BITS ( 9 )
3066+#endif
3067+//Limits of the envelope with those bits and when the envelope goes silent
3068+#define ENV_MIN 0
3069+#define ENV_EXTRA ( ENV_BITS - 9 )
3070+#define ENV_MAX ( 511 << ENV_EXTRA )
3071+#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
3072+#define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT )
3073+
3074+//Attack/decay/release rate counter shift
3075+#define RATE_SH 24
3076+#define RATE_MASK ( ( 1 << RATE_SH ) - 1 )
3077+//Has to fit within 16bit lookuptable
3078+#define MUL_SH 16
3079+
3080+//Check some ranges
3081+#if ENV_EXTRA > 3
3082+#error Too many envelope bits
3083+#endif
3084+
3085+
3086+//How much to substract from the base value for the final attenuation
3087+static const Bit8u KslCreateTable[16] = {
3088+ //0 will always be be lower than 7 * 8
3089+ 64, 32, 24, 19,
3090+ 16, 12, 11, 10,
3091+ 8, 6, 5, 4,
3092+ 3, 2, 1, 0,
3093+};
3094+
3095+#define M(_X_) ((Bit8u)( (_X_) * 2))
3096+static const Bit8u FreqCreateTable[16] = {
3097+ M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ),
3098+ M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15)
3099+};
3100+#undef M
3101+
3102+//We're not including the highest attack rate, that gets a special value
3103+static const Bit8u AttackSamplesTable[13] = {
3104+ 69, 55, 46, 40,
3105+ 35, 29, 23, 20,
3106+ 19, 15, 11, 10,
3107+ 9
3108+};
3109+//On a real opl these values take 8 samples to reach and are based upon larger tables
3110+static const Bit8u EnvelopeIncreaseTable[13] = {
3111+ 4, 5, 6, 7,
3112+ 8, 10, 12, 14,
3113+ 16, 20, 24, 28,
3114+ 32,
3115+};
3116+
3117+#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
3118+static Bit16u ExpTable[ 256 ];
3119+#endif
3120+
3121+#if ( DBOPL_WAVE == WAVE_HANDLER )
3122+//PI table used by WAVEHANDLER
3123+static Bit16u SinTable[ 512 ];
3124+#endif
3125+
3126+#if ( DBOPL_WAVE > WAVE_HANDLER )
3127+//Layout of the waveform table in 512 entry intervals
3128+//With overlapping waves we reduce the table to half it's size
3129+
3130+// | |//\\|____|WAV7|//__|/\ |____|/\/\|
3131+// |\\//| | |WAV7| | \/| | |
3132+// |06 |0126|17 |7 |3 |4 |4 5 |5 |
3133+
3134+//6 is just 0 shifted and masked
3135+
3136+static Bit16s WaveTable[ 8 * 512 ];
3137+//Distance into WaveTable the wave starts
3138+static const Bit16u WaveBaseTable[8] = {
3139+ 0x000, 0x200, 0x200, 0x800,
3140+ 0xa00, 0xc00, 0x100, 0x400,
3141+
3142+};
3143+//Mask the counter with this
3144+static const Bit16u WaveMaskTable[8] = {
3145+ 1023, 1023, 511, 511,
3146+ 1023, 1023, 512, 1023,
3147+};
3148+
3149+//Where to start the counter on at keyon
3150+static const Bit16u WaveStartTable[8] = {
3151+ 512, 0, 0, 0,
3152+ 0, 512, 512, 256,
3153+};
3154+#endif
3155+
3156+#if ( DBOPL_WAVE == WAVE_TABLEMUL )
3157+static Bit16u MulTable[ 384 ];
3158+#endif
3159+
3160+static Bit8u KslTable[ 8 * 16 ];
3161+static Bit8u TremoloTable[ TREMOLO_TABLE ];
3162+//Start of a channel behind the chip struct start
3163+static Bit16u ChanOffsetTable[32];
3164+//Start of an operator behind the chip struct start
3165+static Bit16u OpOffsetTable[64];
3166+
3167+//The lower bits are the shift of the operator vibrato value
3168+//The highest bit is right shifted to generate -1 or 0 for negation
3169+//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
3170+static const Bit8s VibratoTable[ 8 ] = {
3171+ 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00,
3172+ 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80
3173+};
3174+
3175+//Shift strength for the ksl value determined by ksl strength
3176+static const Bit8u KslShiftTable[4] = {
3177+ 31,1,2,0
3178+};
3179+
3180+//Generate a table index and table shift value using input value from a selected rate
3181+static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) {
3182+ if ( val < 13 * 4 ) { //Rate 0 - 12
3183+ shift = 12 - ( val >> 2 );
3184+ index = val & 3;
3185+ } else if ( val < 15 * 4 ) { //rate 13 - 14
3186+ shift = 0;
3187+ index = val - 12 * 4;
3188+ } else { //rate 15 and up
3189+ shift = 0;
3190+ index = 12;
3191+ }
3192+}
3193+
3194+#if ( DBOPL_WAVE == WAVE_HANDLER )
3195+/*
3196+ Generate the different waveforms out of the sine/exponetial table using handlers
3197+*/
3198+static inline Bits MakeVolume( Bitu wave, Bitu volume ) {
3199+ Bitu total = wave + volume;
3200+ Bitu index = total & 0xff;
3201+ Bitu sig = ExpTable[ index ];
3202+ Bitu exp = total >> 8;
3203+#if 0
3204+ //Check if we overflow the 31 shift limit
3205+ if ( exp >= 32 ) {
3206+ LOG_MSG( "WTF %d %d", total, exp );
3207+ }
3208+#endif
3209+ return (sig >> exp);
3210+};
3211+
3212+static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) {
3213+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
3214+ Bitu wave = SinTable[i & 511];
3215+ return (MakeVolume( wave, volume ) ^ neg) - neg;
3216+}
3217+static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) {
3218+ Bit32u wave = SinTable[i & 511];
3219+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
3220+ return MakeVolume( wave, volume );
3221+}
3222+static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) {
3223+ Bitu wave = SinTable[i & 511];
3224+ return MakeVolume( wave, volume );
3225+}
3226+static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) {
3227+ Bitu wave = SinTable[i & 255];
3228+ wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 );
3229+ return MakeVolume( wave, volume );
3230+}
3231+static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) {
3232+ //Twice as fast
3233+ i <<= 1;
3234+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
3235+ Bitu wave = SinTable[i & 511];
3236+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
3237+ return (MakeVolume( wave, volume ) ^ neg) - neg;
3238+}
3239+static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) {
3240+ //Twice as fast
3241+ i <<= 1;
3242+ Bitu wave = SinTable[i & 511];
3243+ wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
3244+ return MakeVolume( wave, volume );
3245+}
3246+static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) {
3247+ Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
3248+ return (MakeVolume( 0, volume ) ^ neg) - neg;
3249+}
3250+static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) {
3251+ //Negative is reversed here
3252+ Bits neg = (( i >> 9) & 1) - 1;
3253+ Bitu wave = (i << 3);
3254+ //When negative the volume also runs backwards
3255+ wave = ((wave ^ neg) - neg) & 4095;
3256+ return (MakeVolume( wave, volume ) ^ neg) - neg;
3257+}
3258+
3259+static const WaveHandler WaveHandlerTable[8] = {
3260+ WaveForm0, WaveForm1, WaveForm2, WaveForm3,
3261+ WaveForm4, WaveForm5, WaveForm6, WaveForm7
3262+};
3263+
3264+#endif
3265+
3266+//Structto hold the data everything well yeh works with
3267+static struct {
3268+ Bitu samples;
3269+ Bits vibrato;
3270+ Bits tremolo;
3271+ inline void SetVibrato( Bit8s vib ) {
3272+ vibrato = vib;
3273+ vibrato &= ~0x80;
3274+ }
3275+ Bit32s output[MAX_SAMPLES * 2];
3276+ //Could intermix the vib/trem table for slightly better cache hits
3277+ Bit8s vibTable[MAX_SAMPLES];
3278+ Bit8s tremTable[MAX_SAMPLES];
3279+} Work;
3280+
3281+/*
3282+ Operator
3283+*/
3284+
3285+//We zero out when rate == 0
3286+inline void Operator::UpdateAttack( const Chip* chip ) {
3287+ Bit8u rate = reg60 >> 4;
3288+ if ( rate ) {
3289+ Bit8u val = (rate << 2) + ksr;
3290+ attackAdd = chip->attackRates[ val ];
3291+ rateZero &= ~(1 << ATTACK);
3292+ } else {
3293+ attackAdd = 0;
3294+ rateZero |= (1 << ATTACK);
3295+ }
3296+}
3297+inline void Operator::UpdateDecay( const Chip* chip ) {
3298+ Bit8u rate = reg60 & 0xf;
3299+ if ( rate ) {
3300+ Bit8u val = (rate << 2) + ksr;
3301+ decayAdd = chip->linearRates[ val ];
3302+ rateZero &= ~(1 << DECAY);
3303+ } else {
3304+ decayAdd = 0;
3305+ rateZero |= (1 << DECAY);
3306+ }
3307+}
3308+inline void Operator::UpdateRelease( const Chip* chip ) {
3309+ Bit8u rate = reg80 & 0xf;
3310+ if ( rate ) {
3311+ Bit8u val = (rate << 2) + ksr;
3312+ releaseAdd = chip->linearRates[ val ];
3313+ rateZero &= ~(1 << RELEASE);
3314+ if ( !(reg20 & MASK_SUSTAIN ) ) {
3315+ rateZero &= ~( 1 << SUSTAIN );
3316+ }
3317+ } else {
3318+ rateZero |= (1 << RELEASE);
3319+ releaseAdd = 0;
3320+ if ( !(reg20 & MASK_SUSTAIN ) ) {
3321+ rateZero |= ( 1 << SUSTAIN );
3322+ }
3323+ }
3324+}
3325+
3326+inline void Operator::UpdateAttenuation( ) {
3327+ Bit8u kslBase = (chanData >> SHIFT_KSLBASE) & 0xff;
3328+ Bit32u tl = reg40 & 0x3f;
3329+ Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
3330+ //Make sure the attenuation goes to the right bits
3331+ totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max
3332+ totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift;
3333+}
3334+
3335+void Operator::UpdateFrequency( ) {
3336+ Bit32u freq = chanData & (( 1 << 10 ) - 1);
3337+ Bit32u block = (chanData >> 10) & 0xff;
3338+
3339+ waveAdd = (freq << block) * freqMul;
3340+ if ( reg20 & MASK_VIBRATO ) {
3341+ vibStrength = (Bit8u)(freq >> 7);
3342+ vibrato = ( vibStrength << block ) * freqMul;
3343+ } else {
3344+ vibStrength = 0;
3345+ vibrato = 0;
3346+ }
3347+}
3348+
3349+void Operator::UpdateRates( const Chip* chip ) {
3350+ //Mame seems to reverse this where enabling ksr actually lowers
3351+ //the rate, but pdf manuals says otherwise?
3352+ Bit8u newKsr = (chanData >> SHIFT_KEYCODE) & 0xff;
3353+ if ( !( reg20 & MASK_KSR ) ) {
3354+ newKsr >>= 2;
3355+ }
3356+ if ( ksr == newKsr )
3357+ return;
3358+ ksr = newKsr;
3359+ UpdateAttack( chip );
3360+ UpdateDecay( chip );
3361+ UpdateRelease( chip );
3362+}
3363+
3364+INLINE Bit32s Operator::RateForward( Bit32u add ) {
3365+ rateIndex += add;
3366+ Bit32s ret = rateIndex >> RATE_SH;
3367+ rateIndex = rateIndex & RATE_MASK;
3368+ return ret;
3369+}
3370+
3371+template< Operator::State yes>
3372+Bits Operator::TemplateVolume( ) {
3373+ Bit32s vol = activeLevel;
3374+ Bit32s change;
3375+ switch ( yes ) {
3376+ case OFF:
3377+ return ENV_MAX;
3378+ case ATTACK:
3379+ change = RateForward( attackAdd );
3380+ if ( !change )
3381+ return vol;
3382+ vol += ( (~vol) * change ) >> 3;
3383+ if ( vol < ENV_MIN ) {
3384+ activeLevel = ENV_MIN;
3385+ rateIndex = 0;
3386+ SetState( DECAY );
3387+ return ENV_MIN;
3388+ }
3389+ break;
3390+ case DECAY:
3391+ vol += RateForward( decayAdd );
3392+ if ( vol >= sustainLevel ) {
3393+ //Check if we didn't overshoot max attenuation, then just go off
3394+ if ( vol >= ENV_MAX ) {
3395+ activeLevel = ENV_MAX;
3396+ SetState( OFF );
3397+ return ENV_MAX;
3398+ }
3399+ //Continue as sustain
3400+ rateIndex = 0;
3401+ SetState( SUSTAIN );
3402+ }
3403+ break;
3404+ case SUSTAIN:
3405+ if ( reg20 & MASK_SUSTAIN ) {
3406+ return vol;
3407+ }
3408+ //In sustain phase, but not sustaining, do regular release
3409+ case RELEASE:
3410+ vol += RateForward( releaseAdd );;
3411+ if ( vol >= ENV_MAX ) {
3412+ activeLevel = ENV_MAX;
3413+ SetState( OFF );
3414+ return ENV_MAX;
3415+ }
3416+ break;
3417+ }
3418+ activeLevel = vol;
3419+ return vol;
3420+}
3421+
3422+static const VolumeHandler VolumeHandlerTable[5] = {
3423+ &Operator::TemplateVolume< Operator::OFF >,
3424+ &Operator::TemplateVolume< Operator::RELEASE >,
3425+ &Operator::TemplateVolume< Operator::SUSTAIN >,
3426+ &Operator::TemplateVolume< Operator::DECAY >,
3427+ &Operator::TemplateVolume< Operator::ATTACK >
3428+};
3429+
3430+INLINE Bitu Operator::ForwardVolume() {
3431+ return totalLevel + (this->*volHandler)()
3432+#if defined ( DBOPL_TREMOLO )
3433+ + (Work.tremolo & tremoloMask)
3434+#endif
3435+ ;
3436+}
3437+
3438+
3439+INLINE Bitu Operator::ForwardWave() {
3440+#if defined ( DBOPL_VIBRATO )
3441+ if ( vibStrength >> (Bit8u)(Work.vibrato) ) {
3442+ Bit32s add = vibrato >> (Bit8u)(Work.vibrato);
3443+ //Sign extend over the shift value
3444+ Bit32s neg = Work.vibrato >> 16;
3445+ //Negate the add with -1 or 0
3446+ add = ( add ^ neg ) - neg;
3447+ waveIndex += add + waveAdd;
3448+ return waveIndex >> WAVE_SH;
3449+ }
3450+#endif
3451+ waveIndex += waveAdd;
3452+ return waveIndex >> WAVE_SH;
3453+}
3454+
3455+
3456+void Operator::Write20( const Chip* chip, Bit8u val ) {
3457+ Bit8u change = (reg20 ^ val );
3458+ if ( !change )
3459+ return;
3460+ reg20 = val;
3461+ //Shift the tremolo bit over the entire register, saved a branch, YES!
3462+ tremoloMask = (Bit8s)(val) >> 7;
3463+ tremoloMask &= ~(( 1 << ENV_EXTRA ) -1);
3464+ //Update specific features based on changes
3465+ if ( change & MASK_KSR ) {
3466+ UpdateRates( chip );
3467+ }
3468+ //With sustain enable the volume doesn't change
3469+ if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) {
3470+ rateZero |= ( 1 << SUSTAIN );
3471+ } else {
3472+ rateZero &= ~( 1 << SUSTAIN );
3473+ }
3474+ //Frequency multiplier or vibrato changed
3475+ if ( change & (0xf | MASK_VIBRATO) ) {
3476+ freqMul = chip->freqMul[ val & 0xf ];
3477+ UpdateFrequency();
3478+ }
3479+}
3480+
3481+void Operator::Write40( const Chip* chip, Bit8u val ) {
3482+ if (!(reg40 ^ val ))
3483+ return;
3484+ reg40 = val;
3485+ UpdateAttenuation( );
3486+}
3487+
3488+void Operator::Write60( const Chip* chip, Bit8u val ) {
3489+ Bit8u change = reg60 ^ val;
3490+ reg60 = val;
3491+ if ( change & 0x0f ) {
3492+ UpdateDecay( chip );
3493+ }
3494+ if ( change & 0xf0 ) {
3495+ UpdateAttack( chip );
3496+ }
3497+}
3498+
3499+void Operator::Write80( const Chip* chip, Bit8u val ) {
3500+ Bit8u change = (reg80 ^ val );
3501+ if ( !change )
3502+ return;
3503+ reg80 = val;
3504+ Bit8u sustain = val >> 4;
3505+ //Turn 0xf into 0x1f
3506+ sustain |= ( sustain + 1) & 0x10;
3507+ sustainLevel = sustain << ( ENV_BITS - 5 );
3508+ if ( change & 0x0f ) {
3509+ UpdateRelease( chip );
3510+ }
3511+}
3512+
3513+void Operator::WriteE0( const Chip* chip, Bit8u val ) {
3514+ if ( !(regE0 ^ val) )
3515+ return;
3516+ //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
3517+ Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) );
3518+ regE0 = val;
3519+#if ( DBOPL_WAVE == WAVE_HANDLER )
3520+ waveHandler = WaveHandlerTable[ waveForm ];
3521+#else
3522+ waveBase = WaveTable + WaveBaseTable[ waveForm ];
3523+ waveStart = WaveStartTable[ waveForm ] << WAVE_SH;
3524+ waveMask = WaveMaskTable[ waveForm ];
3525+#endif
3526+}
3527+
3528+INLINE void Operator::SetState( Bit8u s ) {
3529+ state = s;
3530+ volHandler = VolumeHandlerTable[ s ];
3531+}
3532+
3533+INLINE bool Operator::Silent() const {
3534+ if ( !ENV_SILENT( totalLevel + activeLevel ) )
3535+ return false;
3536+ if ( !(rateZero & ( 1 << state ) ) )
3537+ return false;
3538+ return true;
3539+}
3540+
3541+void Operator::KeyOn( Bit8u mask ) {
3542+ if ( !keyOn ) {
3543+ //Restart the frequency generator
3544+#if ( DBOPL_WAVE > WAVE_HANDLER )
3545+ waveIndex = waveStart;
3546+#else
3547+ waveIndex = 0;
3548+#endif
3549+ rateIndex = 0;
3550+ SetState( ATTACK );
3551+ }
3552+ keyOn |= mask;
3553+}
3554+
3555+void Operator::KeyOff( Bit8u mask ) {
3556+ keyOn &= ~mask;
3557+ if ( !keyOn ) {
3558+ if ( state != OFF ) {
3559+ SetState( RELEASE );
3560+ }
3561+ }
3562+}
3563+
3564+INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) {
3565+#if ( DBOPL_WAVE == WAVE_HANDLER )
3566+ return waveHandler( index, vol << ( 3 - ENV_EXTRA ) );
3567+#elif ( DBOPL_WAVE == WAVE_TABLEMUL )
3568+ return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
3569+#elif ( DBOPL_WAVE == WAVE_TABLELOG )
3570+ Bit32s wave = waveBase[ index & waveMask ];
3571+ Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA );
3572+ Bit32s sig = ExpTable[ total & 0xff ];
3573+ Bit32u exp = total >> 8;
3574+ Bit32s neg = wave >> 16;
3575+ return ((sig ^ neg) - neg) >> exp;
3576+#else
3577+#error "No valid wave routine"
3578+#endif
3579+}
3580+
3581+Bits INLINE Operator::GetSample( Bits modulation ) {
3582+ Bitu vol = ForwardVolume();
3583+ if ( ENV_SILENT( vol ) ) {
3584+ //Simply forward the wave
3585+ waveIndex += waveAdd;
3586+ return 0;
3587+ } else {
3588+ Bitu index = ForwardWave();
3589+ index += modulation;
3590+ return GetWave( index, vol );
3591+ }
3592+}
3593+
3594+Operator::Operator() {
3595+ chanData = 0;
3596+ freqMul = 0;
3597+ waveIndex = 0;
3598+ waveAdd = 0;
3599+ keyOn = 0;
3600+ ksr = 0;
3601+ reg20 = 0;
3602+ reg40 = 0;
3603+ reg60 = 0;
3604+ reg80 = 0;
3605+ regE0 = 0;
3606+ SetState( OFF );
3607+ rateZero = (1 << OFF);
3608+ sustainLevel = ENV_MAX;
3609+ activeLevel = ENV_MAX;
3610+ totalLevel = ENV_MAX;
3611+}
3612+
3613+/*
3614+ Channel
3615+*/
3616+
3617+Channel::Channel() {
3618+ old[0] = old[1] = 0;
3619+ chanData = 0;
3620+ regB0 = 0;
3621+ regC0 = 0;
3622+ maskLeft = -1;
3623+ maskRight = -1;
3624+ feedback = 31;
3625+ fourMask = 0;
3626+ synthHandler = &Channel::BlockTemplate< sm2FM >;
3627+}
3628+
3629+void Channel::SetChanData( const Chip* chip, Bit32u data ) {
3630+ Bit32u change = chanData ^ data;
3631+ chanData = data;
3632+ Op( 0 )->chanData = data;
3633+ Op( 1 )->chanData = data;
3634+ //Since a frequency update triggered this, always update frequency
3635+ Op( 0 )->UpdateFrequency();
3636+ Op( 1 )->UpdateFrequency();
3637+ if ( change & ( 0xff << SHIFT_KSLBASE ) ) {
3638+ Op( 0 )->UpdateAttenuation();
3639+ Op( 1 )->UpdateAttenuation();
3640+ }
3641+ if ( change & ( 0xff << SHIFT_KEYCODE ) ) {
3642+ Op( 0 )->UpdateRates( chip );
3643+ Op( 1 )->UpdateRates( chip );
3644+ }
3645+}
3646+
3647+void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) {
3648+ //Extrace the frequency bits
3649+ Bit32u data = chanData & 0xffff;
3650+ Bit32u kslBase = KslTable[ data >> 6 ];
3651+ Bit32u keyCode = ( data & 0x1c00) >> 9;
3652+ if ( chip->reg08 & 0x40 ) {
3653+ keyCode |= ( data & 0x100)>>8; /* notesel == 1 */
3654+ } else {
3655+ keyCode |= ( data & 0x200)>>9; /* notesel == 0 */
3656+ }
3657+ //Add the keycode and ksl into the highest bits of chanData
3658+ data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE );
3659+ ( this + 0 )->SetChanData( chip, data );
3660+ if ( fourOp & 0x3f ) {
3661+ ( this + 1 )->SetChanData( chip, data );
3662+ }
3663+}
3664+
3665+void Channel::WriteA0( const Chip* chip, Bit8u val ) {
3666+ Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
3667+ //Don't handle writes to silent fourop channels
3668+ if ( fourOp > 0x80 )
3669+ return;
3670+ Bit32u change = (chanData ^ val ) & 0xff;
3671+ if ( change ) {
3672+ chanData ^= change;
3673+ UpdateFrequency( chip, fourOp );
3674+ }
3675+}
3676+
3677+void Channel::WriteB0( const Chip* chip, Bit8u val ) {
3678+ Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
3679+ //Don't handle writes to silent fourop channels
3680+ if ( fourOp > 0x80 )
3681+ return;
3682+ Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00;
3683+ if ( change ) {
3684+ chanData ^= change;
3685+ UpdateFrequency( chip, fourOp );
3686+ }
3687+ //Check for a change in the keyon/off state
3688+ if ( !(( val ^ regB0) & 0x20))
3689+ return;
3690+ regB0 = val;
3691+ if ( val & 0x20 ) {
3692+ Op(0)->KeyOn( 0x1 );
3693+ Op(1)->KeyOn( 0x1 );
3694+ if ( fourOp & 0x3f ) {
3695+ ( this + 1 )->Op(0)->KeyOn( 1 );
3696+ ( this + 1 )->Op(1)->KeyOn( 1 );
3697+ }
3698+ } else {
3699+ Op(0)->KeyOff( 0x1 );
3700+ Op(1)->KeyOff( 0x1 );
3701+ if ( fourOp & 0x3f ) {
3702+ ( this + 1 )->Op(0)->KeyOff( 1 );
3703+ ( this + 1 )->Op(1)->KeyOff( 1 );
3704+ }
3705+ }
3706+}
3707+
3708+void Channel::WriteC0( const Chip* chip, Bit8u val ) {
3709+ Bit8u change = val ^ regC0;
3710+ if ( !change )
3711+ return;
3712+ regC0 = val;
3713+ feedback = ( val >> 1 ) & 7;
3714+ if ( feedback ) {
3715+ //We shift the input to the right 10 bit wave index value
3716+ feedback = 9 - feedback;
3717+ } else {
3718+ feedback = 31;
3719+ }
3720+ //Select the new synth mode
3721+ if ( chip->opl3Active ) {
3722+ //4-op mode enabled for this channel
3723+ if ( (chip->reg104 & fourMask) & 0x3f ) {
3724+ Channel* chan0, *chan1;
3725+ //Check if it's the 2nd channel in a 4-op
3726+ if ( !(fourMask & 0x80 ) ) {
3727+ chan0 = this;
3728+ chan1 = this + 1;
3729+ } else {
3730+ chan0 = this - 1;
3731+ chan1 = this;
3732+ }
3733+
3734+ Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 );
3735+ switch ( synth ) {
3736+ case 0:
3737+ chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
3738+ break;
3739+ case 1:
3740+ chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
3741+ break;
3742+ case 2:
3743+ chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
3744+ break;
3745+ case 3:
3746+ chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
3747+ break;
3748+ }
3749+ //Disable updating percussion channels
3750+ } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) {
3751+
3752+ //Regular dual op, am or fm
3753+ } else if ( val & 1 ) {
3754+ synthHandler = &Channel::BlockTemplate< sm3AM >;
3755+ } else {
3756+ synthHandler = &Channel::BlockTemplate< sm3FM >;
3757+ }
3758+ maskLeft = ( val & 0x10 ) ? -1 : 0;
3759+ maskRight = ( val & 0x20 ) ? -1 : 0;
3760+ //opl2 active
3761+ } else {
3762+ //Disable updating percussion channels
3763+ if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) {
3764+
3765+ //Regular dual op, am or fm
3766+ } else if ( val & 1 ) {
3767+ synthHandler = &Channel::BlockTemplate< sm2AM >;
3768+ } else {
3769+ synthHandler = &Channel::BlockTemplate< sm2FM >;
3770+ }
3771+ }
3772+}
3773+
3774+void Channel::ResetC0( const Chip* chip ) {
3775+ Bit8u val = regC0;
3776+ regC0 ^= 0xff;
3777+ WriteC0( chip, val );
3778+}
3779+
3780+template< bool opl3Mode>
3781+void Channel::GeneratePercussion( Bit32s* output ) {
3782+ Channel* chan = this;
3783+
3784+ //BassDrum
3785+ Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
3786+ old[0] = old[1];
3787+ old[1] = Op(0)->GetSample( mod );
3788+
3789+ //When bassdrum is in AM mode first operator is ignoed
3790+ if ( chan->regC0 & 1 ) {
3791+ mod = 0;
3792+ } else {
3793+ mod = old[0];
3794+ }
3795+ Bit32s sample = Op(1)->GetSample( mod );
3796+
3797+ Operator* op2 = ( this + 1 )->Op(0);
3798+ Operator* op4 = ( this + 2 )->Op(0);
3799+
3800+ //Precalculate stuff used by other oupts
3801+ Bit32u noiseBit = rand() & 0x2;
3802+ Bit32u c2 = op2->ForwardWave();
3803+ //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1
3804+ Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 );
3805+ Bit32u c4 = op4->ForwardWave();
3806+ //bit 5 ^ bit 3 to bit 1
3807+ Bit32u gateBit = ( c4 >> 4 ) ^ ( c4 >> 3 );
3808+ phaseBit = (phaseBit | gateBit) & 0x2;
3809+
3810+ //Hi-Hat
3811+ Bit32u hhVol = op2->ForwardVolume();
3812+ if ( !ENV_SILENT( hhVol ) ) {
3813+ /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
3814+ /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
3815+ Bit32u hhIndex = ( phaseBit << 8 ) | ( 0xd0 >> ( phaseBit ^ noiseBit ) );
3816+ sample += op2->GetWave( hhIndex, hhVol );
3817+ }
3818+ //Snare Drum
3819+ Operator* op3 = ( this + 1 )->Op(1);
3820+ Bit32u sdVol = op3->ForwardVolume();
3821+ if ( !ENV_SILENT( sdVol ) ) {
3822+ Bit32u sdBits = 0x100 + (c2 & 0x100);
3823+ Bit32u sdIndex = sdBits ^ ( noiseBit << 7 );
3824+ sample += op3->GetWave( sdIndex, sdVol );
3825+ }
3826+ //Tom-tom
3827+ sample += op4->GetSample( 0 );
3828+ //Top-Cymbal
3829+ Operator* op5 = ( this + 2 )->Op(1);
3830+ Bit32u tcVol = op5->ForwardVolume();
3831+ if ( !ENV_SILENT( tcVol ) ) {
3832+ Bit32u tcIndex = (1 + phaseBit) << 8;
3833+ sample += op5->GetWave( tcIndex, tcVol );
3834+ }
3835+ sample <<= 1;
3836+ if ( opl3Mode ) {
3837+ output[0] += sample;
3838+ output[1] += sample;
3839+ } else {
3840+ output[0] += sample;
3841+ }
3842+}
3843+
3844+template<SynthMode mode>
3845+Channel* Channel::BlockTemplate( ) {
3846+ switch( mode ) {
3847+ case sm2AM:
3848+ case sm3AM:
3849+ if ( Op(0)->Silent() && Op(1)->Silent() ) {
3850+ old[0] = old[1] = 0;
3851+ return (this + 1);
3852+ }
3853+ break;
3854+ case sm2FM:
3855+ case sm3FM:
3856+ if ( Op(1)->Silent() ) {
3857+ old[0] = old[1] = 0;
3858+ return (this + 1);
3859+ }
3860+ break;
3861+ case sm3FMFM:
3862+ if ( Op(3)->Silent() ) {
3863+ old[0] = old[1] = 0;
3864+ return (this + 2);
3865+ }
3866+ break;
3867+ case sm3AMFM:
3868+ if ( Op(0)->Silent() && Op(3)->Silent() ) {
3869+ old[0] = old[1] = 0;
3870+ return (this + 2);
3871+ }
3872+ break;
3873+ case sm3FMAM:
3874+ if ( Op(1)->Silent() && Op(3)->Silent() ) {
3875+ old[0] = old[1] = 0;
3876+ return (this + 2);
3877+ }
3878+ break;
3879+ case sm3AMAM:
3880+ if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) {
3881+ old[0] = old[1] = 0;
3882+ return (this + 2);
3883+ }
3884+ break;
3885+ // TODO: Check this
3886+ default:
3887+ break;
3888+ }
3889+ for ( Bitu i = 0; i < Work.samples; i++ ) {
3890+ Work.vibrato = Work.vibTable[i];
3891+ Work.tremolo = Work.tremTable[i];
3892+
3893+ //Early out for percussion handlers
3894+ if ( mode == sm2Percussion ) {
3895+ GeneratePercussion<false>( Work.output + i );
3896+ continue; //Prevent some unitialized value bitching
3897+ } else if ( mode == sm3Percussion ) {
3898+ GeneratePercussion<true>( Work.output + i * 2 );
3899+ continue; //Prevent some unitialized value bitching
3900+ }
3901+
3902+ //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
3903+ Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback;
3904+ old[0] = old[1];
3905+ old[1] = Op(0)->GetSample( mod );
3906+ Bit32s sample;
3907+ Bit32s out0 = old[0];
3908+ if ( mode == sm2AM || mode == sm3AM ) {
3909+ sample = out0 + Op(1)->GetSample( 0 );
3910+ } else if ( mode == sm2FM || mode == sm3FM ) {
3911+ sample = Op(1)->GetSample( out0 );
3912+ } else if ( mode == sm3FMFM ) {
3913+ Bits next = Op(1)->GetSample( out0 );
3914+ next = Op(2)->GetSample( next );
3915+ sample = Op(3)->GetSample( next );
3916+ } else if ( mode == sm3AMFM ) {
3917+ sample = out0;
3918+ Bits next = Op(1)->GetSample( 0 );
3919+ next = Op(2)->GetSample( next );
3920+ sample += Op(3)->GetSample( next );
3921+ } else if ( mode == sm3FMAM ) {
3922+ sample = Op(1)->GetSample( out0 );
3923+ Bits next = Op(2)->GetSample( 0 );
3924+ sample += Op(3)->GetSample( next );
3925+ } else if ( mode == sm3AMAM ) {
3926+ sample = out0;
3927+ Bits next = Op(1)->GetSample( 0 );
3928+ sample += Op(2)->GetSample( next );
3929+ sample += Op(3)->GetSample( 0 );
3930+ }
3931+ switch( mode ) {
3932+ case sm2AM:
3933+ case sm2FM:
3934+ Work.output[ i ] += sample;
3935+ break;
3936+ case sm3AM:
3937+ case sm3FM:
3938+ case sm3FMFM:
3939+ case sm3AMFM:
3940+ case sm3FMAM:
3941+ case sm3AMAM:
3942+ Work.output[ i * 2 + 0 ] += sample & maskLeft;
3943+ Work.output[ i * 2 + 1 ] += sample & maskRight;
3944+ break;
3945+ // TODO: Check this
3946+ default:
3947+ break;
3948+ }
3949+ }
3950+ switch( mode ) {
3951+ case sm2AM:
3952+ case sm2FM:
3953+ case sm3AM:
3954+ case sm3FM:
3955+ return ( this + 1 );
3956+ case sm3FMFM:
3957+ case sm3AMFM:
3958+ case sm3FMAM:
3959+ case sm3AMAM:
3960+ return( this + 2 );
3961+ case sm2Percussion:
3962+ case sm3Percussion:
3963+ return( this + 3 );
3964+ }
3965+ return 0;
3966+}
3967+
3968+/*
3969+ Chip
3970+*/
3971+
3972+Chip::Chip() {
3973+ reg08 = 0;
3974+ reg04 = 0;
3975+ regBD = 0;
3976+ reg104 = 0;
3977+ opl3Active = 0;
3978+}
3979+
3980+
3981+Bit8u Chip::ForwardTremolo( ) {
3982+ tremoloCounter += tremoloAdd;
3983+ if ( tremoloCounter >= (uint)(TREMOLO_TABLE << TREMOLO_SH) ) {
3984+ tremoloCounter -= TREMOLO_TABLE << TREMOLO_SH;
3985+ }
3986+ Bitu index = tremoloCounter >> TREMOLO_SH;
3987+ return TremoloTable[ index ] >> tremoloShift;
3988+}
3989+
3990+Bit8s Chip::ForwardVibrato( ) {
3991+ vibratoCounter += vibratoAdd;
3992+ Bitu index = vibratoCounter >> VIBRATO_SH;
3993+ //Vibrato shift, basically makes the shift greater reducing the actual final value
3994+ return VibratoTable[index & 7] + vibratoShift;
3995+}
3996+
3997+void Chip::WriteBD( Bit8u val ) {
3998+ Bit8u change = regBD ^ val;
3999+ if ( !change )
4000+ return;
4001+ regBD = val;
4002+ //TODO could do this with shift and xor?
4003+ vibratoShift = (val & 0x40) ? 0x00 : 0x01;
4004+ tremoloShift = (val & 0x80) ? 0x00 : 0x02;
4005+ if ( val & 0x20 ) {
4006+ //Drum was just enabled, make sure channel 6 has the right synth
4007+ if ( change & 0x20 ) {
4008+ if ( opl3Active ) {
4009+ chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >;
4010+ } else {
4011+ chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >;
4012+ }
4013+ }
4014+ //Bass Drum
4015+ if ( val & 0x10 ) {
4016+ chan[6].op[0].KeyOn( 0x2 );
4017+ chan[6].op[1].KeyOn( 0x2 );
4018+ } else {
4019+ chan[6].op[0].KeyOff( 0x2 );
4020+ chan[6].op[1].KeyOff( 0x2 );
4021+ }
4022+ //Hi-Hat
4023+ if ( val & 0x1 ) {
4024+ chan[7].op[0].KeyOn( 0x2 );
4025+ } else {
4026+ chan[7].op[0].KeyOff( 0x2 );
4027+ }
4028+ //Snare
4029+ if ( val & 0x8 ) {
4030+ chan[7].op[1].KeyOn( 0x2 );
4031+ } else {
4032+ chan[7].op[1].KeyOff( 0x2 );
4033+ }
4034+ //Tom-Tom
4035+ if ( val & 0x4 ) {
4036+ chan[8].op[0].KeyOn( 0x2 );
4037+ } else {
4038+ chan[8].op[0].KeyOff( 0x2 );
4039+ }
4040+ //Top Cymbal
4041+ if ( val & 0x2 ) {
4042+ chan[8].op[1].KeyOn( 0x2 );
4043+ } else {
4044+ chan[8].op[1].KeyOff( 0x2 );
4045+ }
4046+ //Toggle keyoffs when we turn off the percussion
4047+ } else if ( change & 0x20 ) {
4048+ //Trigger a reset to setup the original synth handler
4049+ chan[6].ResetC0( this );
4050+ chan[6].op[0].KeyOff( 0x2 );
4051+ chan[6].op[1].KeyOff( 0x2 );
4052+ chan[7].op[0].KeyOff( 0x2 );
4053+ chan[7].op[1].KeyOff( 0x2 );
4054+ chan[8].op[0].KeyOff( 0x2 );
4055+ chan[8].op[1].KeyOff( 0x2 );
4056+ }
4057+}
4058+
4059+
4060+#define REGOP( _FUNC_ ) \
4061+ index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \
4062+ if ( OpOffsetTable[ index ] ) { \
4063+ Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \
4064+ regOp->_FUNC_( this, val ); \
4065+ }
4066+
4067+#define REGCHAN( _FUNC_ ) \
4068+ index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \
4069+ if ( ChanOffsetTable[ index ] ) { \
4070+ Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \
4071+ regChan->_FUNC_( this, val ); \
4072+ }
4073+
4074+void Chip::WriteReg( Bit32u reg, Bit8u val ) {
4075+ Bitu index;
4076+ switch ( (reg & 0xf0) >> 4 ) {
4077+ case 0x00 >> 4:
4078+ if ( reg == 0x01 ) {
4079+ waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0;
4080+ } else if ( reg == 0x104 ) {
4081+ //Only detect changes in lowest 6 bits
4082+ if ( !((reg104 ^ val) & 0x3f) )
4083+ return;
4084+ //Always keep the highest bit enabled, for checking > 0x80
4085+ reg104 = 0x80 | ( val & 0x3f );
4086+ } else if ( reg == 0x105 ) {
4087+ //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
4088+ if ( !((opl3Active ^ val) & 1 ) )
4089+ return;
4090+ opl3Active = ( val & 1 ) ? 0xff : 0;
4091+ //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
4092+ for ( int i = 0; i < 18;i++ ) {
4093+ chan[i].ResetC0( this );
4094+ }
4095+ } else if ( reg == 0x08 ) {
4096+ reg08 = val;
4097+ }
4098+ case 0x10 >> 4:
4099+ break;
4100+ case 0x20 >> 4:
4101+ case 0x30 >> 4:
4102+ REGOP( Write20 );
4103+ break;
4104+ case 0x40 >> 4:
4105+ case 0x50 >> 4:
4106+ REGOP( Write40 );
4107+ break;
4108+ case 0x60 >> 4:
4109+ case 0x70 >> 4:
4110+ REGOP( Write60 );
4111+ break;
4112+ case 0x80 >> 4:
4113+ case 0x90 >> 4:
4114+ REGOP( Write80 );
4115+ break;
4116+ case 0xa0 >> 4:
4117+ REGCHAN( WriteA0 );
4118+ break;
4119+ case 0xb0 >> 4:
4120+ if ( reg == 0xbd ) {
4121+ WriteBD( val );
4122+ } else {
4123+ REGCHAN( WriteB0 );
4124+ }
4125+ break;
4126+ case 0xc0 >> 4:
4127+ REGCHAN( WriteC0 );
4128+ case 0xd0 >> 4:
4129+ break;
4130+ case 0xe0 >> 4:
4131+ case 0xf0 >> 4:
4132+ REGOP( WriteE0 );
4133+ break;
4134+ }
4135+}
4136+
4137+
4138+Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
4139+ switch ( port & 3 ) {
4140+ case 0:
4141+ return val;
4142+ case 2:
4143+ if ( opl3Active || (val == 0x05) )
4144+ return 0x100 | val;
4145+ else
4146+ return val;
4147+ }
4148+ return 0;
4149+}
4150+
4151+void Chip::GenerateBlock2( Bitu samples ) {
4152+ Work.samples = samples;
4153+ for ( Bitu i = 0; i < Work.samples; i++ ) {
4154+ Work.vibTable[i] = ForwardVibrato();
4155+ Work.tremTable[i] = ForwardTremolo();
4156+ Work.output[i] = 0;
4157+ }
4158+ int count = 0;
4159+ for( Channel* ch = chan; ch < chan + 9; ) {
4160+ count++;
4161+ ch = (ch->*(ch->synthHandler))();
4162+ }
4163+}
4164+
4165+void Chip::GenerateBlock3( Bitu samples ) {
4166+ Work.samples = samples;
4167+ for ( Bitu i = 0; i < Work.samples; i++ ) {
4168+ Work.vibTable[i] = ForwardVibrato();
4169+ Work.tremTable[i] = ForwardTremolo();
4170+ Work.output[i*2 + 0] = 0;
4171+ Work.output[i*2 + 1] = 0;
4172+ }
4173+ int count = 0;
4174+ for( Channel* ch = chan; ch < chan + 18; ) {
4175+ count++;
4176+ ch = (ch->*(ch->synthHandler))();
4177+ }
4178+}
4179+
4180+void Chip::Setup( Bit32u rate ) {
4181+ //Vibrato forwards every 1024 samples
4182+ vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE);
4183+ vibratoCounter = 0;
4184+ //tremolo forwards every 64 samples
4185+ //We use a 52 entry table, real is 210, so repeat each sample an extra 4 times
4186+ tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE);
4187+ tremoloCounter = 0;
4188+ //10 bits of frequency counter
4189+ //With higher octave this gets shifted up
4190+ //-1 since the freqCreateTable = *2
4191+ double scale = (OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate;
4192+ for ( int i = 0; i < 16; i++ ) {
4193+ //Use rounding with 0.5
4194+ freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] );
4195+ }
4196+
4197+ scale = OPLRATE / rate;
4198+ //-3 since the real envelope takes 8 steps to reach the single value we supply
4199+ for ( Bit8u i = 0; i < 76; i++ ) {
4200+ Bit8u index, shift;
4201+ EnvelopeSelect( i, index, shift );
4202+ linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
4203+ }
4204+ //Generate the best matching attack rate
4205+ for ( Bit8u i = 0; i < 62; i++ ) {
4206+ Bit8u index, shift;
4207+ EnvelopeSelect( i, index, shift );
4208+ //Original amount of samples the attack would take
4209+ Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale);
4210+
4211+ Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 )));
4212+ Bit32s bestAdd;
4213+ Bit32u bestDiff = 1 << 30;
4214+ for( Bit32u passes = 0; passes < 16; passes ++ ) {
4215+ Bit32s volume = ENV_MAX;
4216+ Bit32s samples = 0;
4217+ Bit32u count = 0;
4218+ while ( volume > 0 && samples < original * 2 ) {
4219+ count += guessAdd;
4220+ Bit32s change = count >> RATE_SH;
4221+ count &= RATE_MASK;
4222+ if ( change ) {
4223+ volume += ( ~volume * change ) >> 3;
4224+ }
4225+ samples++;
4226+
4227+ }
4228+ Bit32s diff = original - samples;
4229+ Bit32u lDiff = labs( diff );
4230+ //Init last on first pass
4231+ if ( lDiff < bestDiff ) {
4232+ bestDiff = lDiff;
4233+ bestAdd = guessAdd;
4234+ if ( !bestDiff )
4235+ break;
4236+ }
4237+ //Below our target
4238+ if ( diff < 0 ) {
4239+ //Better than the last time
4240+ Bit32s mul = ((original - diff) << 12) / original;
4241+ guessAdd = ((guessAdd * mul) >> 12);
4242+ guessAdd++;
4243+ } else if ( diff > 0 ) {
4244+ Bit32s mul = ((original - diff) << 12) / original;
4245+ guessAdd = (guessAdd * mul) >> 12;
4246+ guessAdd--;
4247+ }
4248+ }
4249+ attackRates[i] = bestAdd;
4250+ }
4251+ for ( Bit8u i = 62; i < 76; i++ ) {
4252+ //This should provide instant volume maximizing
4253+ attackRates[i] = 8 << RATE_SH;
4254+ }
4255+ //Setup the channels with the correct four op flags
4256+ //Channels are accessed through a table so they appear linear here
4257+ chan[ 0].fourMask = 0x00 | ( 1 << 0 );
4258+ chan[ 1].fourMask = 0x80 | ( 1 << 0 );
4259+ chan[ 2].fourMask = 0x00 | ( 1 << 1 );
4260+ chan[ 3].fourMask = 0x80 | ( 1 << 1 );
4261+ chan[ 4].fourMask = 0x00 | ( 1 << 2 );
4262+ chan[ 5].fourMask = 0x80 | ( 1 << 2 );
4263+
4264+ chan[ 9].fourMask = 0x00 | ( 1 << 3 );
4265+ chan[10].fourMask = 0x80 | ( 1 << 3 );
4266+ chan[11].fourMask = 0x00 | ( 1 << 4 );
4267+ chan[12].fourMask = 0x80 | ( 1 << 4 );
4268+ chan[13].fourMask = 0x00 | ( 1 << 5 );
4269+ chan[14].fourMask = 0x80 | ( 1 << 5 );
4270+
4271+ //mark the percussion channels
4272+ chan[ 6].fourMask = 0x40;
4273+ chan[ 7].fourMask = 0x40;
4274+ chan[ 8].fourMask = 0x40;
4275+
4276+ //Clear Everything in opl3 mode
4277+ WriteReg( 0x105, 0x1 );
4278+ for ( int i = 0; i < 512; i++ ) {
4279+ if ( i == 0x105 )
4280+ continue;
4281+ WriteReg( i, 0xff );
4282+ WriteReg( i, 0x0 );
4283+ }
4284+ WriteReg( 0x105, 0x0 );
4285+ //Clear everything in opl2 mode
4286+ for ( int i = 0; i < 255; i++ ) {
4287+ WriteReg( i, 0xff );
4288+ WriteReg( i, 0x0 );
4289+ }
4290+}
4291+
4292+static bool doneTables = false;
4293+void InitTables( void ) {
4294+ if ( doneTables )
4295+ return;
4296+ doneTables = true;
4297+#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
4298+ //Exponential volume table, same as the real adlib
4299+ for ( int i = 0; i < 256; i++ ) {
4300+ //Save them in reverse
4301+ ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 );
4302+ ExpTable[i] += 1024; //or remove the -1 oh well :)
4303+ //Preshift to the left once so the final volume can shift to the right
4304+ ExpTable[i] *= 2;
4305+ }
4306+#endif
4307+#if ( DBOPL_WAVE == WAVE_HANDLER )
4308+ //Add 0.5 for the trunc rounding of the integer cast
4309+ //Do a PI sinetable instead of the original 0.5 PI
4310+ for ( int i = 0; i < 512; i++ ) {
4311+ SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
4312+ }
4313+#endif
4314+#if ( DBOPL_WAVE == WAVE_TABLEMUL )
4315+ //Multiplication based tables
4316+ for ( int i = 0; i < 384; i++ ) {
4317+ int s = i * 8;
4318+ //TODO maybe keep some of the precision errors of the original table?
4319+ double val = ( 0.5 + ( pow(2, -1 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
4320+ MulTable[i] = (Bit16u)(val);
4321+ }
4322+
4323+ //Sine Wave Base
4324+ for ( int i = 0; i < 512; i++ ) {
4325+ WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084);
4326+ WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
4327+ }
4328+ //Exponential wave
4329+ for ( int i = 0; i < 256; i++ ) {
4330+ WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2, -1 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
4331+ WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
4332+ }
4333+#endif
4334+#if ( DBOPL_WAVE == WAVE_TABLELOG )
4335+ //Sine Wave Base
4336+ for ( int i = 0; i < 512; i++ ) {
4337+ WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
4338+ WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
4339+ }
4340+ //Exponential wave
4341+ for ( int i = 0; i < 256; i++ ) {
4342+ WaveTable[ 0x700 + i ] = i * 8;
4343+ WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
4344+ }
4345+#endif
4346+
4347+ // | |//\\|____|WAV7|//__|/\ |____|/\/\|
4348+ // |\\//| | |WAV7| | \/| | |
4349+ // |06 |0126|27 |7 |3 |4 |4 5 |5 |
4350+
4351+#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
4352+ for ( int i = 0; i < 256; i++ ) {
4353+ //Fill silence gaps
4354+ WaveTable[ 0x400 + i ] = WaveTable[0];
4355+ WaveTable[ 0x500 + i ] = WaveTable[0];
4356+ WaveTable[ 0x900 + i ] = WaveTable[0];
4357+ WaveTable[ 0xc00 + i ] = WaveTable[0];
4358+ WaveTable[ 0xd00 + i ] = WaveTable[0];
4359+ //Replicate sines in other pieces
4360+ WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
4361+ //double speed sines
4362+ WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
4363+ WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
4364+ WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
4365+ WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
4366+ }
4367+#endif
4368+
4369+ //Create the ksl table
4370+ for ( int oct = 0; oct < 8; oct++ ) {
4371+ int base = oct * 8;
4372+ for ( int i = 0; i < 16; i++ ) {
4373+ int val = base - KslCreateTable[i];
4374+ if ( val < 0 )
4375+ val = 0;
4376+ //*4 for the final range to match attenuation range
4377+ KslTable[ oct * 16 + i ] = val * 4;
4378+ }
4379+ }
4380+ //Create the Tremolo table, just increase and decrease a triangle wave
4381+ for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) {
4382+ Bit8u val = i << ENV_EXTRA;
4383+ TremoloTable[i] = val;
4384+ TremoloTable[TREMOLO_TABLE - 1 - i] = val;
4385+ }
4386+ //Create a table with offsets of the channels from the start of the chip
4387+ for ( Bitu i = 0; i < 32; i++ ) {
4388+ Bitu index = i & 0xf;
4389+ if ( index >= 9 ) {
4390+ ChanOffsetTable[i] = 0;
4391+ continue;
4392+ }
4393+ //Make sure the four op channels follow eachother
4394+ if ( index < 6 ) {
4395+ index = (index % 3) * 2 + ( index / 3 );
4396+ }
4397+ //Add back the bits for highest ones
4398+ if ( i >= 16 )
4399+ index += 9;
4400+ ChanOffsetTable[i] = OFFS(Chip, chan) + index * sizeof(Channel);
4401+ }
4402+ //Same for operators
4403+ for ( Bitu i = 0; i < 64; i++ ) {
4404+ if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) {
4405+ OpOffsetTable[i] = 0;
4406+ continue;
4407+ }
4408+ Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
4409+ //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
4410+ if ( chNum >= 12 )
4411+ chNum += 16 - 12;
4412+ Bitu opNum = ( i % 8 ) / 3;
4413+ OpOffsetTable[i] = ChanOffsetTable[ chNum ] + OFFS(Channel, op) + opNum * sizeof(Operator);
4414+ }
4415+}
4416+
4417+Bit32u Handler::writeAddr( Bit32u port, Bit8u val ) {
4418+ return chip.WriteAddr( port, val );
4419+
4420+}
4421+void Handler::writeReg( Bit32u addr, Bit8u val ) {
4422+ chip.WriteReg( addr, val );
4423+}
4424+
4425+void Handler::generate( Bit16s *chan, Bitu samples ) {
4426+ // Opl3 is stereo thus we half the number of samples here.
4427+
4428+ while (samples > 0) {
4429+ Bitu todo = samples > MAX_SAMPLES ? MAX_SAMPLES : samples;
4430+ samples -= todo;
4431+ if ( !chip.opl3Active ) {
4432+ chip.GenerateBlock2( todo );
4433+ for (uint i = 0; i < todo; ++i)
4434+ chan[i] = Work.output[i];
4435+ chan += todo;
4436+ } else {
4437+ chip.GenerateBlock3( samples );
4438+ for (uint i = 0; i < (todo << 1); ++i)
4439+ chan[i] = Work.output[i];
4440+ chan += (todo << 1);
4441+ }
4442+ }
4443+}
4444+
4445+void Handler::init( Bitu rate ) {
4446+ InitTables();
4447+ chip.Setup( rate );
4448+}
4449+
4450+} // end of namespace DBOPL
4451+} // end of namespace DOSBox
4452+} // end of namespace AdLib
4453+
4454+#endif
4455+
4456Index: sound/softsynth/adlib/dbopl_fl.cpp
4457===================================================================
4458--- sound/softsynth/adlib/dbopl_fl.cpp (revision 0)
4459+++ sound/softsynth/adlib/dbopl_fl.cpp (revision 0)
4460@@ -0,0 +1,1449 @@
4461+/*
4462+ * Copyright (C) 2002-2009 The DOSBox Team
4463+ * OPL2/OPL3 emulation library
4464+ *
4465+ * This library is free software; you can redistribute it and/or
4466+ * modify it under the terms of the GNU Lesser General Public
4467+ * License as published by the Free Software Foundation; either
4468+ * version 2.1 of the License, or (at your option) any later version.
4469+ *
4470+ * This library is distributed in the hope that it will be useful,
4471+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4472+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4473+ * Lesser General Public License for more details.
4474+ *
4475+ * You should have received a copy of the GNU Lesser General Public
4476+ * License along with this library; if not, write to the Free Software
4477+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4478+ */
4479+
4480+
4481+/*
4482+ * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman
4483+ * Copyright (C) 1998-2001 Ken Silverman
4484+ * Ken Silverman's official web site: "http://www.advsys.net/ken"
4485+ */
4486+
4487+#include "dbopl_fl.h"
4488+
4489+#ifndef INLINE
4490+#define INLINE
4491+#endif
4492+
4493+
4494+static fltype recipsamp; // inverse of sampling rate
4495+static Bit16s wavtable[WAVEPREC*3]; // wave form table
4496+
4497+// vibrato/tremolo tables
4498+static Bit32s vib_table[VIBTAB_SIZE];
4499+static Bit32s trem_table[TREMTAB_SIZE*2];
4500+
4501+static Bit32s vibval_const[BLOCKBUF_SIZE];
4502+static Bit32s tremval_const[BLOCKBUF_SIZE];
4503+
4504+// vibrato value tables (used per-operator)
4505+static Bit32s vibval_var1[BLOCKBUF_SIZE];
4506+static Bit32s vibval_var2[BLOCKBUF_SIZE];
4507+
4508+// vibrato/trmolo value table pointers
4509+static Bit32s *vibval1, *vibval2, *vibval3, *vibval4;
4510+static Bit32s *tremval1, *tremval2, *tremval3, *tremval4;
4511+
4512+
4513+// key scale level lookup table
4514+static const fltype kslmul[4] = {
4515+ 0.0, 0.5, 0.25, 1.0 // -> 0, 3, 1.5, 6 dB/oct
4516+};
4517+
4518+// frequency multiplicator lookup table
4519+static const fltype frqmul_tab[16] = {
4520+ 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15
4521+};
4522+// calculated frequency multiplication values (depend on sampling rate)
4523+static float frqmul[16];
4524+
4525+// key scale levels
4526+static Bit8u kslev[8][16];
4527+
4528+// map a channel number to the register offset of the modulator (=register base)
4529+static const Bit8u modulatorbase[9] = {
4530+ 0,1,2,
4531+ 8,9,10,
4532+ 16,17,18
4533+};
4534+
4535+// map a register base to a modulator operator number or operator number
4536+#if defined(OPLTYPE_IS_OPL3)
4537+static const Bit8u regbase2modop[44] = {
4538+ 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8, // first set
4539+ 18,19,20,18,19,20,0,0,21,22,23,21,22,23,0,0,24,25,26,24,25,26 // second set
4540+};
4541+static const Bit8u regbase2op[44] = {
4542+ 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17, // first set
4543+ 18,19,20,27,28,29,0,0,21,22,23,30,31,32,0,0,24,25,26,33,34,35 // second set
4544+};
4545+#else
4546+static const Bit8u regbase2modop[22] = {
4547+ 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8
4548+};
4549+static const Bit8u regbase2op[22] = {
4550+ 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17
4551+};
4552+#endif
4553+
4554+
4555+// start of the waveform
4556+static Bit32u waveform[8] = {
4557+ WAVEPREC,
4558+ WAVEPREC>>1,
4559+ WAVEPREC,
4560+ (WAVEPREC*3)>>2,
4561+ 0,
4562+ 0,
4563+ (WAVEPREC*5)>>2,
4564+ WAVEPREC<<1
4565+};
4566+
4567+// length of the waveform as mask
4568+static Bit32u wavemask[8] = {
4569+ WAVEPREC-1,
4570+ WAVEPREC-1,
4571+ (WAVEPREC>>1)-1,
4572+ (WAVEPREC>>1)-1,
4573+ WAVEPREC-1,
4574+ ((WAVEPREC*3)>>2)-1,
4575+ WAVEPREC>>1,
4576+ WAVEPREC-1
4577+};
4578+
4579+// where the first entry resides
4580+static Bit32u wavestart[8] = {
4581+ 0,
4582+ WAVEPREC>>1,
4583+ 0,
4584+ WAVEPREC>>2,
4585+ 0,
4586+ 0,
4587+ 0,
4588+ WAVEPREC>>3
4589+};
4590+
4591+// envelope generator function constants
4592+static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
4593+static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
4594+
4595+
4596+void operator_advance(op_type* op_pt, Bit32s vib) {
4597+ op_pt->wfpos = op_pt->tcount; // waveform position
4598+
4599+ // advance waveform time
4600+ op_pt->tcount += op_pt->tinc;
4601+ op_pt->tcount += (Bit32s)(op_pt->tinc)*vib/FIXEDPT;
4602+
4603+ op_pt->generator_pos += generator_add;
4604+}
4605+
4606+void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) {
4607+ Bit32u c1 = op_pt1->tcount/FIXEDPT;
4608+ Bit32u c3 = op_pt3->tcount/FIXEDPT;
4609+ Bit32u phasebit = (((c1 & 0x88) ^ ((c1<<5) & 0x80)) | ((c3 ^ (c3<<2)) & 0x20)) ? 0x02 : 0x00;
4610+
4611+ Bit32u noisebit = rand()&1;
4612+
4613+ Bit32u snare_phase_bit = (((Bitu)((op_pt1->tcount/FIXEDPT) / 0x100))&1);
4614+
4615+ //Hihat
4616+ Bit32u inttm = (phasebit<<8) | (0x34<<(phasebit ^ (noisebit<<1)));
4617+ op_pt1->wfpos = inttm*FIXEDPT; // waveform position
4618+ // advance waveform time
4619+ op_pt1->tcount += op_pt1->tinc;
4620+ op_pt1->tcount += (Bit32s)(op_pt1->tinc)*vib1/FIXEDPT;
4621+ op_pt1->generator_pos += generator_add;
4622+
4623+ //Snare
4624+ inttm = ((1+snare_phase_bit) ^ noisebit)<<8;
4625+ op_pt2->wfpos = inttm*FIXEDPT; // waveform position
4626+ // advance waveform time
4627+ op_pt2->tcount += op_pt2->tinc;
4628+ op_pt2->tcount += (Bit32s)(op_pt2->tinc)*vib2/FIXEDPT;
4629+ op_pt2->generator_pos += generator_add;
4630+
4631+ //Cymbal
4632+ inttm = (1+phasebit)<<8;
4633+ op_pt3->wfpos = inttm*FIXEDPT; // waveform position
4634+ // advance waveform time
4635+ op_pt3->tcount += op_pt3->tinc;
4636+ op_pt3->tcount += (Bit32s)(op_pt3->tinc)*vib3/FIXEDPT;
4637+ op_pt3->generator_pos += generator_add;
4638+}
4639+
4640+
4641+// output level is sustained, mode changes only when operator is turned off (->release)
4642+// or when the keep-sustained bit is turned off (->sustain_nokeep)
4643+void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) {
4644+ if (op_pt->op_state != OF_TYPE_OFF) {
4645+ op_pt->lastcval = op_pt->cval;
4646+ Bit32u i = (Bit32u)((op_pt->wfpos+modulator)/FIXEDPT);
4647+
4648+ // wform: -16384 to 16383 (0x4000)
4649+ // trem : 32768 to 65535 (0x10000)
4650+ // step_amp: 0.0 to 1.0
4651+ // vol : 1/2^14 to 1/2^29 (/0x4000; /1../0x8000)
4652+
4653+ op_pt->cval = (Bit32s)(op_pt->step_amp*op_pt->vol*op_pt->cur_wform[i&op_pt->cur_wmask]*trem/16.0);
4654+ }
4655+}
4656+
4657+
4658+// no action, operator is off
4659+void operator_off(op_type* /*op_pt*/) {
4660+}
4661+
4662+// output level is sustained, mode changes only when operator is turned off (->release)
4663+// or when the keep-sustained bit is turned off (->sustain_nokeep)
4664+void operator_sustain(op_type* op_pt) {
4665+ Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples
4666+ for (Bit32u ct=0; ct<num_steps_add; ct++) {
4667+ op_pt->cur_env_step++;
4668+ }
4669+ op_pt->generator_pos -= num_steps_add*FIXEDPT;
4670+}
4671+
4672+// operator in release mode, if output level reaches zero the operator is turned off
4673+void operator_release(op_type* op_pt) {
4674+ // ??? boundary?
4675+ if (op_pt->amp > 0.00000001) {
4676+ // release phase
4677+ op_pt->amp *= op_pt->releasemul;
4678+ }
4679+
4680+ Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples
4681+ for (Bit32u ct=0; ct<num_steps_add; ct++) {
4682+ op_pt->cur_env_step++; // sample counter
4683+ if ((op_pt->cur_env_step & op_pt->env_step_r)==0) {
4684+ if (op_pt->amp <= 0.00000001) {
4685+ // release phase finished, turn off this operator
4686+ op_pt->amp = 0.0;
4687+ if (op_pt->op_state == OF_TYPE_REL) {
4688+ op_pt->op_state = OF_TYPE_OFF;
4689+ }
4690+ }
4691+ op_pt->step_amp = op_pt->amp;
4692+ }
4693+ }
4694+ op_pt->generator_pos -= num_steps_add*FIXEDPT;
4695+}
4696+
4697+// operator in decay mode, if sustain level is reached the output level is either
4698+// kept (sustain level keep enabled) or the operator is switched into release mode
4699+void operator_decay(op_type* op_pt) {
4700+ if (op_pt->amp > op_pt->sustain_level) {
4701+ // decay phase
4702+ op_pt->amp *= op_pt->decaymul;
4703+ }
4704+
4705+ Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples
4706+ for (Bit32u ct=0; ct<num_steps_add; ct++) {
4707+ op_pt->cur_env_step++;
4708+ if ((op_pt->cur_env_step & op_pt->env_step_d)==0) {
4709+ if (op_pt->amp <= op_pt->sustain_level) {
4710+ // decay phase finished, sustain level reached
4711+ if (op_pt->sus_keep) {
4712+ // keep sustain level (until turned off)
4713+ op_pt->op_state = OF_TYPE_SUS;
4714+ op_pt->amp = op_pt->sustain_level;
4715+ } else {
4716+ // next: release phase
4717+ op_pt->op_state = OF_TYPE_SUS_NOKEEP;
4718+ }
4719+ }
4720+ op_pt->step_amp = op_pt->amp;
4721+ }
4722+ }
4723+ op_pt->generator_pos -= num_steps_add*FIXEDPT;
4724+}
4725+
4726+// operator in attack mode, if full output level is reached,
4727+// the operator is switched into decay mode
4728+void operator_attack(op_type* op_pt) {
4729+ op_pt->amp = ((op_pt->a3*op_pt->amp + op_pt->a2)*op_pt->amp + op_pt->a1)*op_pt->amp + op_pt->a0;
4730+
4731+ Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples
4732+ for (Bit32u ct=0; ct<num_steps_add; ct++) {
4733+ op_pt->cur_env_step++; // next sample
4734+ if ((op_pt->cur_env_step & op_pt->env_step_a)==0) { // check if next step already reached
4735+ if (op_pt->amp > 1.0) {
4736+ // attack phase finished, next: decay
4737+ op_pt->op_state = OF_TYPE_DEC;
4738+ op_pt->amp = 1.0;
4739+ op_pt->step_amp = 1.0;
4740+ }
4741+ op_pt->step_skip_pos <<= 1;
4742+ if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1;
4743+ if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step
4744+ op_pt->step_amp = op_pt->amp;
4745+ }
4746+ }
4747+ }
4748+ op_pt->generator_pos -= num_steps_add*FIXEDPT;
4749+}
4750+
4751+
4752+typedef void (*optype_fptr)(op_type*);
4753+
4754+optype_fptr opfuncs[6] = {
4755+ operator_attack,
4756+ operator_decay,
4757+ operator_release,
4758+ operator_sustain, // sustain phase (keeping level)
4759+ operator_release, // sustain_nokeep phase (release-style)
4760+ operator_off
4761+};
4762+
4763+void change_attackrate(Bitu regbase, op_type* op_pt) {
4764+ Bits attackrate = adlibreg[ARC_ATTR_DECR+regbase]>>4;
4765+ if (attackrate) {
4766+ fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*recipsamp);
4767+ // attack rate coefficients
4768+ op_pt->a0 = (fltype)(0.0377*f);
4769+ op_pt->a1 = (fltype)(10.73*f+1);
4770+ op_pt->a2 = (fltype)(-17.57*f);
4771+ op_pt->a3 = (fltype)(7.42*f);
4772+
4773+ Bits step_skip = attackrate*4 + op_pt->toff;
4774+ Bits steps = step_skip >> 2;
4775+ op_pt->env_step_a = (1<<(steps<=12?12-steps:0))-1;
4776+
4777+ Bits step_num = (step_skip<=48)?(4-(step_skip&3)):0;
4778+ static Bit8u step_skip_mask[5] = {0xff, 0xfe, 0xee, 0xba, 0xaa};
4779+ op_pt->env_step_skip_a = step_skip_mask[step_num];
4780+
4781+#if defined(OPLTYPE_IS_OPL3)
4782+ if (step_skip>=60) {
4783+#else
4784+ if (step_skip>=62) {
4785+#endif
4786+ op_pt->a0 = (fltype)(2.0); // something that triggers an immediate transition to amp:=1.0
4787+ op_pt->a1 = (fltype)(0.0);
4788+ op_pt->a2 = (fltype)(0.0);
4789+ op_pt->a3 = (fltype)(0.0);
4790+ }
4791+ } else {
4792+ // attack disabled
4793+ op_pt->a0 = 0.0;
4794+ op_pt->a1 = 1.0;
4795+ op_pt->a2 = 0.0;
4796+ op_pt->a3 = 0.0;
4797+ op_pt->env_step_a = 0;
4798+ op_pt->env_step_skip_a = 0;
4799+ }
4800+}
4801+
4802+void change_decayrate(Bitu regbase, op_type* op_pt) {
4803+ Bits decayrate = adlibreg[ARC_ATTR_DECR+regbase]&15;
4804+ // decaymul should be 1.0 when decayrate==0
4805+ if (decayrate) {
4806+ fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp);
4807+ op_pt->decaymul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(decayrate+(op_pt->toff>>2)))));
4808+ Bits steps = (decayrate*4 + op_pt->toff) >> 2;
4809+ op_pt->env_step_d = (1<<(steps<=12?12-steps:0))-1;
4810+ } else {
4811+ op_pt->decaymul = 1.0;
4812+ op_pt->env_step_d = 0;
4813+ }
4814+}
4815+
4816+void change_releaserate(Bitu regbase, op_type* op_pt) {
4817+ Bits releaserate = adlibreg[ARC_SUSL_RELR+regbase]&15;
4818+ // releasemul should be 1.0 when releaserate==0
4819+ if (releaserate) {
4820+ fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp);
4821+ op_pt->releasemul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(releaserate+(op_pt->toff>>2)))));
4822+ Bits steps = (releaserate*4 + op_pt->toff) >> 2;
4823+ op_pt->env_step_r = (1<<(steps<=12?12-steps:0))-1;
4824+ } else {
4825+ op_pt->releasemul = 1.0;
4826+ op_pt->env_step_r = 0;
4827+ }
4828+}
4829+
4830+void change_sustainlevel(Bitu regbase, op_type* op_pt) {
4831+ Bits sustainlevel = adlibreg[ARC_SUSL_RELR+regbase]>>4;
4832+ // sustainlevel should be 0.0 when sustainlevel==15 (max)
4833+ if (sustainlevel<15) {
4834+ op_pt->sustain_level = (fltype)(pow(FL2,(fltype)sustainlevel * (-FL05)));
4835+ } else {
4836+ op_pt->sustain_level = 0.0;
4837+ }
4838+}
4839+
4840+void change_waveform(Bitu regbase, op_type* op_pt) {
4841+#if defined(OPLTYPE_IS_OPL3)
4842+ if (regbase>=ARC_SECONDSET) regbase -= (ARC_SECONDSET-22); // second set starts at 22
4843+#endif
4844+ // waveform selection
4845+ op_pt->cur_wmask = wavemask[wave_sel[regbase]];
4846+ op_pt->cur_wform = &wavtable[waveform[wave_sel[regbase]]];
4847+ // (might need to be adapted to waveform type here...)
4848+}
4849+
4850+void change_keepsustain(Bitu regbase, op_type* op_pt) {
4851+ op_pt->sus_keep = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x20)>0;
4852+ if (op_pt->op_state==OF_TYPE_SUS) {
4853+ if (!op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS_NOKEEP;
4854+ } else if (op_pt->op_state==OF_TYPE_SUS_NOKEEP) {
4855+ if (op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS;
4856+ }
4857+}
4858+
4859+// enable/disable vibrato/tremolo LFO effects
4860+void change_vibrato(Bitu regbase, op_type* op_pt) {
4861+ op_pt->vibrato = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x40)!=0;
4862+ op_pt->tremolo = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x80)!=0;
4863+}
4864+
4865+// change amount of self-feedback
4866+void change_feedback(Bitu chanbase, op_type* op_pt) {
4867+ Bits feedback = adlibreg[ARC_FEEDBACK+chanbase]&14;
4868+ if (feedback) op_pt->mfbi = (Bit32s)(pow(FL2,(fltype)((feedback>>1)+8)));
4869+ else op_pt->mfbi = 0;
4870+}
4871+
4872+void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt) {
4873+ // frequency
4874+ Bit32u frn = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)adlibreg[ARC_FREQ_NUM+chanbase];
4875+ // block number/octave
4876+ Bit32u oct = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])>>2)&7);
4877+ op_pt->freq_high = (Bit32s)((frn>>7)&7);
4878+
4879+ // keysplit
4880+ Bit32u note_sel = (adlibreg[8]>>6)&1;
4881+ op_pt->toff = ((frn>>9)&(note_sel^1)) | ((frn>>8)&note_sel);
4882+ op_pt->toff += (oct<<1);
4883+
4884+ // envelope scaling (KSR)
4885+ if (!(adlibreg[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2;
4886+
4887+ // 20+a0+b0:
4888+ op_pt->tinc = (Bit32u)((((fltype)(frn<<oct))*frqmul[adlibreg[ARC_TVS_KSR_MUL+regbase]&15]));
4889+ // 40+a0+b0:
4890+ fltype vol_in = (fltype)((fltype)(adlibreg[ARC_KSL_OUTLEV+regbase]&63) +
4891+ kslmul[adlibreg[ARC_KSL_OUTLEV+regbase]>>6]*kslev[oct][frn>>6]);
4892+ op_pt->vol = (fltype)(pow(FL2,(fltype)(vol_in * -0.125 - 14)));
4893+
4894+ // operator frequency changed, care about features that depend on it
4895+ change_attackrate(regbase,op_pt);
4896+ change_decayrate(regbase,op_pt);
4897+ change_releaserate(regbase,op_pt);
4898+}
4899+
4900+void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) {
4901+ // check if this is really an off-on transition
4902+ if (op_pt->act_state == OP_ACT_OFF) {
4903+ Bits wselbase = regbase;
4904+ if (wselbase>=ARC_SECONDSET) wselbase -= (ARC_SECONDSET-22); // second set starts at 22
4905+
4906+ op_pt->tcount = wavestart[wave_sel[wselbase]]*FIXEDPT;
4907+
4908+ // start with attack mode
4909+ op_pt->op_state = OF_TYPE_ATT;
4910+ op_pt->act_state |= act_type;
4911+ }
4912+}
4913+
4914+void disable_operator(op_type* op_pt, Bit32u act_type) {
4915+ // check if this is really an on-off transition
4916+ if (op_pt->act_state != OP_ACT_OFF) {
4917+ op_pt->act_state &= (~act_type);
4918+ if (op_pt->act_state == OP_ACT_OFF) {
4919+ if (op_pt->op_state != OF_TYPE_OFF) op_pt->op_state = OF_TYPE_REL;
4920+ }
4921+ }
4922+}
4923+
4924+void adlib_init(Bit32u samplerate) {
4925+ Bits i, j, oct;
4926+
4927+ int_samplerate = samplerate;
4928+
4929+ generator_add = (Bit32u)(INTFREQU*FIXEDPT/int_samplerate);
4930+
4931+
4932+ memset((void *)adlibreg,0,sizeof(adlibreg));
4933+ memset((void *)op,0,sizeof(op_type)*MAXOPERATORS);
4934+ memset((void *)wave_sel,0,sizeof(wave_sel));
4935+
4936+ for (i=0;i<MAXOPERATORS;i++) {
4937+ op[i].op_state = OF_TYPE_OFF;
4938+ op[i].act_state = OP_ACT_OFF;
4939+ op[i].amp = 0.0;
4940+ op[i].step_amp = 0.0;
4941+ op[i].vol = 0.0;
4942+ op[i].tcount = 0;
4943+ op[i].tinc = 0;
4944+ op[i].toff = 0;
4945+ op[i].cur_wmask = wavemask[0];
4946+ op[i].cur_wform = &wavtable[waveform[0]];
4947+ op[i].freq_high = 0;
4948+
4949+ op[i].generator_pos = 0;
4950+ op[i].cur_env_step = 0;
4951+ op[i].env_step_a = 0;
4952+ op[i].env_step_d = 0;
4953+ op[i].env_step_r = 0;
4954+ op[i].step_skip_pos = 0;
4955+ op[i].env_step_skip_a = 0;
4956+
4957+#if defined(OPLTYPE_IS_OPL3)
4958+ op[i].is_4op = false;
4959+ op[i].is_4op_attached = false;
4960+ op[i].left_pan = 2;
4961+ op[i].right_pan = 2;
4962+#endif
4963+ }
4964+
4965+ recipsamp = 1.0 / (fltype)int_samplerate;
4966+ for (i=15;i>=0;i--) {
4967+ frqmul[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*recipsamp);
4968+ }
4969+
4970+ status = 0;
4971+ index = 0;
4972+
4973+
4974+ // create vibrato table
4975+ vib_table[0] = 8;
4976+ vib_table[1] = 4;
4977+ vib_table[2] = 0;
4978+ vib_table[3] = -4;
4979+ for (i=4; i<VIBTAB_SIZE; i++) vib_table[i] = vib_table[i-4]*-1;
4980+
4981+ // vibrato at ~6.1 ?? (opl3 docs say 6.1, opl4 docs say 6.0, y8950 docs say 6.4)
4982+ vibtab_add = static_cast<Bit32u>(VIBTAB_SIZE*FIXEDPT_LFO/8192*INTFREQU/int_samplerate);
4983+ vibtab_pos = 0;
4984+
4985+ for (i=0; i<BLOCKBUF_SIZE; i++) vibval_const[i] = 0;
4986+
4987+
4988+ // create tremolo table
4989+ Bit32s trem_table_int[TREMTAB_SIZE];
4990+ for (i=0; i<14; i++) trem_table_int[i] = i-13; // upwards (13 to 26 -> -0.5/6 to 0)
4991+ for (i=14; i<41; i++) trem_table_int[i] = -i+14; // downwards (26 to 0 -> 0 to -1/6)
4992+ for (i=41; i<53; i++) trem_table_int[i] = i-40-26; // upwards (1 to 12 -> -1/6 to -0.5/6)
4993+
4994+ for (i=0; i<TREMTAB_SIZE; i++) {
4995+ // 0.0 .. -26/26*4.8/6 == [0.0 .. -0.8], 4/53 steps == [1 .. 0.57]
4996+ fltype trem_val1=(fltype)(((fltype)trem_table_int[i])*4.8/26.0/6.0); // 4.8db
4997+ fltype trem_val2=(fltype)((fltype)((Bit32s)(trem_table_int[i]/4))*1.2/6.0/6.0); // 1.2db (larger stepping)
4998+
4999+ trem_table[i] = (Bit32s)(pow(FL2,trem_val1)*FIXEDPT);
5000+ trem_table[TREMTAB_SIZE+i] = (Bit32s)(pow(FL2,trem_val2)*FIXEDPT);
5001+ }
5002+
5003+ // tremolo at 3.7hz
5004+ tremtab_add = (Bit32u)((fltype)TREMTAB_SIZE * TREM_FREQ * FIXEDPT_LFO / (fltype)int_samplerate);
5005+ tremtab_pos = 0;
5006+
5007+ for (i=0; i<BLOCKBUF_SIZE; i++) tremval_const[i] = FIXEDPT;
5008+
5009+
5010+ static Bitu initfirstime = 0;
5011+ if (!initfirstime) {
5012+ initfirstime = 1;
5013+
5014+ // create waveform tables
5015+ for (i=0;i<(WAVEPREC>>1);i++) {
5016+ wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC));
5017+ wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC));
5018+ wavtable[i] = wavtable[(i<<1) +WAVEPREC];
5019+ // table to be verified, alternative: (zero-less)
5020+/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC));
5021+ wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC));
5022+ wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */
5023+ }
5024+ for (i=0;i<(WAVEPREC>>3);i++) {
5025+ wavtable[i+(WAVEPREC<<1)] = wavtable[i+(WAVEPREC>>3)]-16384;
5026+ wavtable[i+((WAVEPREC*17)>>3)] = wavtable[i+(WAVEPREC>>2)]+16384;
5027+ }
5028+
5029+ // key scale level table verified ([table in book]*8/3)
5030+ kslev[7][0] = 0; kslev[7][1] = 24; kslev[7][2] = 32; kslev[7][3] = 37;
5031+ kslev[7][4] = 40; kslev[7][5] = 43; kslev[7][6] = 45; kslev[7][7] = 47;
5032+ kslev[7][8] = 48;
5033+ for (i=9;i<16;i++) kslev[7][i] = (Bit8u)(i+41);
5034+ for (j=6;j>=0;j--) {
5035+ for (i=0;i<16;i++) {
5036+ oct = (Bits)kslev[j+1][i]-8;
5037+ if (oct < 0) oct = 0;
5038+ kslev[j][i] = (Bit8u)oct;
5039+ }
5040+ }
5041+ }
5042+
5043+}
5044+
5045+
5046+
5047+void adlib_write(Bitu idx, Bit8u val) {
5048+ Bit32u second_set = idx&0x100;
5049+ adlibreg[idx] = val;
5050+
5051+ switch (idx&0xf0) {
5052+ case ARC_CONTROL:
5053+ // here we check for the second set registers, too:
5054+ switch (idx) {
5055+ case 0x02: // timer1 counter
5056+ case 0x03: // timer2 counter
5057+ break;
5058+ case 0x04:
5059+ // IRQ reset, timer mask/start
5060+ if (val&0x80) {
5061+ // clear IRQ bits in status register
5062+ status &= ~0x60;
5063+ } else {
5064+ status = 0;
5065+ }
5066+ break;
5067+#if defined(OPLTYPE_IS_OPL3)
5068+ case 0x04|ARC_SECONDSET:
5069+ // 4op enable/disable switches for each possible channel
5070+ op[0].is_4op = (val&1)>0;
5071+ op[3].is_4op_attached = op[0].is_4op;
5072+ op[1].is_4op = (val&2)>0;
5073+ op[4].is_4op_attached = op[1].is_4op;
5074+ op[2].is_4op = (val&4)>0;
5075+ op[5].is_4op_attached = op[2].is_4op;
5076+ op[18].is_4op = (val&8)>0;
5077+ op[21].is_4op_attached = op[18].is_4op;
5078+ op[19].is_4op = (val&16)>0;
5079+ op[22].is_4op_attached = op[19].is_4op;
5080+ op[20].is_4op = (val&32)>0;
5081+ op[23].is_4op_attached = op[20].is_4op;
5082+ break;
5083+ case 0x05|ARC_SECONDSET:
5084+ break;
5085+#endif
5086+ case 0x08:
5087+ // CSW, note select
5088+ break;
5089+ default:
5090+ break;
5091+ }
5092+ break;
5093+ case ARC_TVS_KSR_MUL:
5094+ case ARC_TVS_KSR_MUL+0x10: {
5095+ // tremolo/vibrato/sustain keeping enabled; key scale rate; frequency multiplication
5096+ int num = idx&7;
5097+ Bitu base = (idx-ARC_TVS_KSR_MUL)&0xff;
5098+ if ((num<6) && (base<22)) {
5099+ Bitu modop = regbase2modop[second_set?(base+22):base];
5100+ Bitu regbase = base+second_set;
5101+ Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop;
5102+
5103+ // change tremolo/vibrato and sustain keeping of this operator
5104+ op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)];
5105+ change_keepsustain(regbase,op_ptr);
5106+ change_vibrato(regbase,op_ptr);
5107+
5108+ // change frequency calculations of this operator as
5109+ // key scale rate and frequency multiplicator can be changed
5110+#if defined(OPLTYPE_IS_OPL3)
5111+ if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) {
5112+ // operator uses frequency of channel
5113+ change_frequency(chanbase-3,regbase,op_ptr);
5114+ } else {
5115+ change_frequency(chanbase,regbase,op_ptr);
5116+ }
5117+#else
5118+ change_frequency(chanbase,base,op_ptr);
5119+#endif
5120+ }
5121+ }
5122+ break;
5123+ case ARC_KSL_OUTLEV:
5124+ case ARC_KSL_OUTLEV+0x10: {
5125+ // key scale level; output rate
5126+ int num = idx&7;
5127+ Bitu base = (idx-ARC_KSL_OUTLEV)&0xff;
5128+ if ((num<6) && (base<22)) {
5129+ Bitu modop = regbase2modop[second_set?(base+22):base];
5130+ Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop;
5131+
5132+ // change frequency calculations of this operator as
5133+ // key scale level and output rate can be changed
5134+ op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)];
5135+#if defined(OPLTYPE_IS_OPL3)
5136+ Bitu regbase = base+second_set;
5137+ if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) {
5138+ // operator uses frequency of channel
5139+ change_frequency(chanbase-3,regbase,op_ptr);
5140+ } else {
5141+ change_frequency(chanbase,regbase,op_ptr);
5142+ }
5143+#else
5144+ change_frequency(chanbase,base,op_ptr);
5145+#endif
5146+ }
5147+ }
5148+ break;
5149+ case ARC_ATTR_DECR:
5150+ case ARC_ATTR_DECR+0x10: {
5151+ // attack/decay rates
5152+ int num = idx&7;
5153+ Bitu base = (idx-ARC_ATTR_DECR)&0xff;
5154+ if ((num<6) && (base<22)) {
5155+ Bitu regbase = base+second_set;
5156+
5157+ // change attack rate and decay rate of this operator
5158+ op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]];
5159+ change_attackrate(regbase,op_ptr);
5160+ change_decayrate(regbase,op_ptr);
5161+ }
5162+ }
5163+ break;
5164+ case ARC_SUSL_RELR:
5165+ case ARC_SUSL_RELR+0x10: {
5166+ // sustain level; release rate
5167+ int num = idx&7;
5168+ Bitu base = (idx-ARC_SUSL_RELR)&0xff;
5169+ if ((num<6) && (base<22)) {
5170+ Bitu regbase = base+second_set;
5171+
5172+ // change sustain level and release rate of this operator
5173+ op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]];
5174+ change_releaserate(regbase,op_ptr);
5175+ change_sustainlevel(regbase,op_ptr);
5176+ }
5177+ }
5178+ break;
5179+ case ARC_FREQ_NUM: {
5180+ // 0xa0-0xa8 low8 frequency
5181+ Bitu base = (idx-ARC_FREQ_NUM)&0xff;
5182+ if (base<9) {
5183+ Bits opbase = second_set?(base+18):base;
5184+#if defined(OPLTYPE_IS_OPL3)
5185+ if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break;
5186+#endif
5187+ // regbase of modulator:
5188+ Bits modbase = modulatorbase[base]+second_set;
5189+
5190+ Bitu chanbase = base+second_set;
5191+
5192+ change_frequency(chanbase,modbase,&op[opbase]);
5193+ change_frequency(chanbase,modbase+3,&op[opbase+9]);
5194+#if defined(OPLTYPE_IS_OPL3)
5195+ // for 4op channels all four operators are modified to the frequency of the channel
5196+ if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) {
5197+ change_frequency(chanbase,modbase+8,&op[opbase+3]);
5198+ change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]);
5199+ }
5200+#endif
5201+ }
5202+ }
5203+ break;
5204+ case ARC_KON_BNUM: {
5205+ if (idx == ARC_PERC_MODE) {
5206+#if defined(OPLTYPE_IS_OPL3)
5207+ if (second_set) return;
5208+#endif
5209+
5210+ if ((val&0x30) == 0x30) { // BassDrum active
5211+ enable_operator(16,&op[6],OP_ACT_PERC);
5212+ change_frequency(6,16,&op[6]);
5213+ enable_operator(16+3,&op[6+9],OP_ACT_PERC);
5214+ change_frequency(6,16+3,&op[6+9]);
5215+ } else {
5216+ disable_operator(&op[6],OP_ACT_PERC);
5217+ disable_operator(&op[6+9],OP_ACT_PERC);
5218+ }
5219+ if ((val&0x28) == 0x28) { // Snare active
5220+ enable_operator(17+3,&op[16],OP_ACT_PERC);
5221+ change_frequency(7,17+3,&op[16]);
5222+ } else {
5223+ disable_operator(&op[16],OP_ACT_PERC);
5224+ }
5225+ if ((val&0x24) == 0x24) { // TomTom active
5226+ enable_operator(18,&op[8],OP_ACT_PERC);
5227+ change_frequency(8,18,&op[8]);
5228+ } else {
5229+ disable_operator(&op[8],OP_ACT_PERC);
5230+ }
5231+ if ((val&0x22) == 0x22) { // Cymbal active
5232+ enable_operator(18+3,&op[8+9],OP_ACT_PERC);
5233+ change_frequency(8,18+3,&op[8+9]);
5234+ } else {
5235+ disable_operator(&op[8+9],OP_ACT_PERC);
5236+ }
5237+ if ((val&0x21) == 0x21) { // Hihat active
5238+ enable_operator(17,&op[7],OP_ACT_PERC);
5239+ change_frequency(7,17,&op[7]);
5240+ } else {
5241+ disable_operator(&op[7],OP_ACT_PERC);
5242+ }
5243+
5244+ break;
5245+ }
5246+ // regular 0xb0-0xb8
5247+ Bitu base = (idx-ARC_KON_BNUM)&0xff;
5248+ if (base<9) {
5249+ Bits opbase = second_set?(base+18):base;
5250+#if defined(OPLTYPE_IS_OPL3)
5251+ if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break;
5252+#endif
5253+ // regbase of modulator:
5254+ Bits modbase = modulatorbase[base]+second_set;
5255+
5256+ if (val&32) {
5257+ // operator switched on
5258+ enable_operator(modbase,&op[opbase],OP_ACT_NORMAL); // modulator (if 2op)
5259+ enable_operator(modbase+3,&op[opbase+9],OP_ACT_NORMAL); // carrier (if 2op)
5260+#if defined(OPLTYPE_IS_OPL3)
5261+ // for 4op channels all four operators are switched on
5262+ if ((adlibreg[0x105]&1) && op[opbase].is_4op) {
5263+ // turn on chan+3 operators as well
5264+ enable_operator(modbase+8,&op[opbase+3],OP_ACT_NORMAL);
5265+ enable_operator(modbase+3+8,&op[opbase+3+9],OP_ACT_NORMAL);
5266+ }
5267+#endif
5268+ } else {
5269+ // operator switched off
5270+ disable_operator(&op[opbase],OP_ACT_NORMAL);
5271+ disable_operator(&op[opbase+9],OP_ACT_NORMAL);
5272+#if defined(OPLTYPE_IS_OPL3)
5273+ // for 4op channels all four operators are switched off
5274+ if ((adlibreg[0x105]&1) && op[opbase].is_4op) {
5275+ // turn off chan+3 operators as well
5276+ disable_operator(&op[opbase+3],OP_ACT_NORMAL);
5277+ disable_operator(&op[opbase+3+9],OP_ACT_NORMAL);
5278+ }
5279+#endif
5280+ }
5281+
5282+ Bitu chanbase = base+second_set;
5283+
5284+ // change frequency calculations of modulator and carrier (2op) as
5285+ // the frequency of the channel has changed
5286+ change_frequency(chanbase,modbase,&op[opbase]);
5287+ change_frequency(chanbase,modbase+3,&op[opbase+9]);
5288+#if defined(OPLTYPE_IS_OPL3)
5289+ // for 4op channels all four operators are modified to the frequency of the channel
5290+ if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) {
5291+ // change frequency calculations of chan+3 operators as well
5292+ change_frequency(chanbase,modbase+8,&op[opbase+3]);
5293+ change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]);
5294+ }
5295+#endif
5296+ }
5297+ }
5298+ break;
5299+ case ARC_FEEDBACK: {
5300+ // 0xc0-0xc8 feedback/modulation type (AM/FM)
5301+ Bitu base = (idx-ARC_FEEDBACK)&0xff;
5302+ if (base<9) {
5303+ Bits opbase = second_set?(base+18):base;
5304+ Bitu chanbase = base+second_set;
5305+ change_feedback(chanbase,&op[opbase]);
5306+#if defined(OPLTYPE_IS_OPL3)
5307+ // OPL3 panning
5308+ op[opbase].left_pan = ((val&0x10)>>4)+((val&0x40)>>6);
5309+ op[opbase].right_pan = ((val&0x20)>>5)+((val&0x80)>>7);
5310+#endif
5311+ }
5312+ }
5313+ break;
5314+ case ARC_WAVE_SEL:
5315+ case ARC_WAVE_SEL+0x10: {
5316+ int num = idx&7;
5317+ Bitu base = (idx-ARC_WAVE_SEL)&0xff;
5318+ if ((num<6) && (base<22)) {
5319+#if defined(OPLTYPE_IS_OPL3)
5320+ Bits wselbase = second_set?(base+22):base; // for easier mapping onto wave_sel[]
5321+ // change waveform
5322+ if (adlibreg[0x105]&1) wave_sel[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible
5323+ else wave_sel[wselbase] = val&3;
5324+ op_type* op_ptr = &op[regbase2modop[wselbase]+((num<3) ? 0 : 9)];
5325+ change_waveform(wselbase,op_ptr);
5326+#else
5327+ if (adlibreg[0x01]&0x20) {
5328+ // wave selection enabled, change waveform
5329+ wave_sel[base] = val&3;
5330+ op_type* op_ptr = &op[regbase2modop[base]+((num<3) ? 0 : 9)];
5331+ change_waveform(base,op_ptr);
5332+ }
5333+#endif
5334+ }
5335+ }
5336+ break;
5337+ default:
5338+ break;
5339+ }
5340+}
5341+
5342+
5343+Bitu adlib_reg_read(Bitu port) {
5344+#if defined(OPLTYPE_IS_OPL3)
5345+ // opl3-detection routines require ret&6 to be zero
5346+ if ((port&1)==0) {
5347+ return status;
5348+ }
5349+ return 0x00;
5350+#else
5351+ // opl2-detection routines require ret&6 to be 6
5352+ if ((port&1)==0) {
5353+ return status|6;
5354+ }
5355+ return 0xff;
5356+#endif
5357+}
5358+
5359+void adlib_write_index(Bitu port, Bit8u val) {
5360+ index = val;
5361+#if defined(OPLTYPE_IS_OPL3)
5362+ if ((port&3)!=0) {
5363+ // possibly second set
5364+ if (((adlibreg[0x105]&1)!=0) || (index==5)) index |= ARC_SECONDSET;
5365+ }
5366+#endif
5367+}
5368+
5369+static void INLINE clipit16(Bit32s ival, Bit16s* outval) {
5370+ if (ival<32768) {
5371+ if (ival>-32769) {
5372+ *outval=(Bit16s)ival;
5373+ } else {
5374+ *outval = -32768;
5375+ }
5376+ } else {
5377+ *outval = 32767;
5378+ }
5379+}
5380+
5381+
5382+
5383+// be careful with this
5384+// uses cptr and chanval, outputs into outbufl(/outbufr)
5385+// for opl3 check if opl3-mode is enabled (which uses stereo panning)
5386+#undef CHANVAL_OUT
5387+#if defined(OPLTYPE_IS_OPL3)
5388+#define CHANVAL_OUT \
5389+ if (adlibreg[0x105]&1) { \
5390+ outbufl[i] += chanval*cptr[0].left_pan; \
5391+ outbufr[i] += chanval*cptr[0].right_pan; \
5392+ } else { \
5393+ outbufl[i] += chanval*2; \
5394+ }
5395+#else
5396+#define CHANVAL_OUT \
5397+ outbufl[i] += chanval;
5398+#endif
5399+
5400+void adlib_getsample(Bit16s* sndptr, Bits numsamples) {
5401+ Bits i, endsamples;
5402+ op_type* cptr;
5403+
5404+ Bit32s outbufl[BLOCKBUF_SIZE];
5405+#if defined(OPLTYPE_IS_OPL3)
5406+ // second output buffer (right channel for opl3 stereo)
5407+ Bit32s outbufr[BLOCKBUF_SIZE];
5408+#endif
5409+
5410+ // vibrato/tremolo lookup tables (global, to possibly be used by all operators)
5411+ Bit32s vib_lut[BLOCKBUF_SIZE];
5412+ Bit32s trem_lut[BLOCKBUF_SIZE];
5413+
5414+ Bits samples_to_process = numsamples;
5415+
5416+ for (Bits cursmp=0; cursmp<samples_to_process; cursmp+=endsamples) {
5417+ endsamples = samples_to_process-cursmp;
5418+ if (endsamples>BLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE;
5419+
5420+ memset((void*)&outbufl,0,endsamples*sizeof(Bit32s));
5421+#if defined(OPLTYPE_IS_OPL3)
5422+ // clear second output buffer (opl3 stereo)
5423+ if (adlibreg[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s));
5424+#endif
5425+
5426+ // calculate vibrato/tremolo lookup tables
5427+ Bit32s vib_tshift = ((adlibreg[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching
5428+ for (i=0;i<endsamples;i++) {
5429+ // cycle through vibrato table
5430+ vibtab_pos += vibtab_add;
5431+ if (vibtab_pos/FIXEDPT_LFO>=VIBTAB_SIZE) vibtab_pos-=VIBTAB_SIZE*FIXEDPT_LFO;
5432+ vib_lut[i] = vib_table[vibtab_pos/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents
5433+
5434+ // cycle through tremolo table
5435+ tremtab_pos += tremtab_add;
5436+ if (tremtab_pos/FIXEDPT_LFO>=TREMTAB_SIZE) tremtab_pos-=TREMTAB_SIZE*FIXEDPT_LFO;
5437+ if (adlibreg[ARC_PERC_MODE]&0x80) trem_lut[i] = trem_table[tremtab_pos/FIXEDPT_LFO];
5438+ else trem_lut[i] = trem_table[TREMTAB_SIZE+tremtab_pos/FIXEDPT_LFO];
5439+ }
5440+
5441+ if (adlibreg[ARC_PERC_MODE]&0x20) {
5442+ //BassDrum
5443+ cptr = &op[6];
5444+ if (adlibreg[ARC_FEEDBACK+6]&1) {
5445+ // additive synthesis
5446+ if (cptr[9].op_state != OF_TYPE_OFF) {
5447+ if (cptr[9].vibrato) {
5448+ vibval1 = vibval_var1;
5449+ for (i=0;i<endsamples;i++)
5450+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5451+ } else vibval1 = vibval_const;
5452+ if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5453+ else tremval1 = tremval_const;
5454+
5455+ // calculate channel output
5456+ for (i=0;i<endsamples;i++) {
5457+ operator_advance(&cptr[9],vibval1[i]);
5458+ opfuncs[cptr[9].op_state](&cptr[9]);
5459+ operator_output(&cptr[9],0,tremval1[i]);
5460+
5461+ Bit32s chanval = cptr[9].cval*2;
5462+ CHANVAL_OUT
5463+ }
5464+ }
5465+ } else {
5466+ // frequency modulation
5467+ if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[0].op_state != OF_TYPE_OFF)) {
5468+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5469+ vibval1 = vibval_var1;
5470+ for (i=0;i<endsamples;i++)
5471+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5472+ } else vibval1 = vibval_const;
5473+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5474+ vibval2 = vibval_var2;
5475+ for (i=0;i<endsamples;i++)
5476+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5477+ } else vibval2 = vibval_const;
5478+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5479+ else tremval1 = tremval_const;
5480+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5481+ else tremval2 = tremval_const;
5482+
5483+ // calculate channel output
5484+ for (i=0;i<endsamples;i++) {
5485+ operator_advance(&cptr[0],vibval1[i]);
5486+ opfuncs[cptr[0].op_state](&cptr[0]);
5487+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5488+
5489+ operator_advance(&cptr[9],vibval2[i]);
5490+ opfuncs[cptr[9].op_state](&cptr[9]);
5491+ operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]);
5492+
5493+ Bit32s chanval = cptr[9].cval*2;
5494+ CHANVAL_OUT
5495+ }
5496+ }
5497+ }
5498+
5499+ //TomTom (j=8)
5500+ if (op[8].op_state != OF_TYPE_OFF) {
5501+ cptr = &op[8];
5502+ if (cptr[0].vibrato) {
5503+ vibval3 = vibval_var1;
5504+ for (i=0;i<endsamples;i++)
5505+ vibval3[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5506+ } else vibval3 = vibval_const;
5507+
5508+ if (cptr[0].tremolo) tremval3 = trem_lut; // tremolo enabled, use table
5509+ else tremval3 = tremval_const;
5510+
5511+ // calculate channel output
5512+ for (i=0;i<endsamples;i++) {
5513+ operator_advance(&cptr[0],vibval3[i]);
5514+ opfuncs[cptr[0].op_state](&cptr[0]); //TomTom
5515+ operator_output(&cptr[0],0,tremval3[i]);
5516+ Bit32s chanval = cptr[0].cval*2;
5517+ CHANVAL_OUT
5518+ }
5519+ }
5520+
5521+ //Snare/Hihat (j=7), Cymbal (j=8)
5522+ if ((op[7].op_state != OF_TYPE_OFF) || (op[16].op_state != OF_TYPE_OFF) ||
5523+ (op[17].op_state != OF_TYPE_OFF)) {
5524+ cptr = &op[7];
5525+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5526+ vibval1 = vibval_var1;
5527+ for (i=0;i<endsamples;i++)
5528+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5529+ } else vibval1 = vibval_const;
5530+ if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) {
5531+ vibval2 = vibval_var2;
5532+ for (i=0;i<endsamples;i++)
5533+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5534+ } else vibval2 = vibval_const;
5535+
5536+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5537+ else tremval1 = tremval_const;
5538+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5539+ else tremval2 = tremval_const;
5540+
5541+ cptr = &op[8];
5542+ if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) {
5543+ vibval4 = vibval_var2;
5544+ for (i=0;i<endsamples;i++)
5545+ vibval4[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5546+ } else vibval4 = vibval_const;
5547+
5548+ if (cptr[9].tremolo) tremval4 = trem_lut; // tremolo enabled, use table
5549+ else tremval4 = tremval_const;
5550+
5551+ // calculate channel output
5552+ for (i=0;i<endsamples;i++) {
5553+ operator_advance_drums(&op[7],vibval1[i],&op[7+9],vibval2[i],&op[8+9],vibval4[i]);
5554+
5555+ opfuncs[op[7].op_state](&op[7]); //Hihat
5556+ operator_output(&op[7],0,tremval1[i]);
5557+
5558+ opfuncs[op[7+9].op_state](&op[7+9]); //Snare
5559+ operator_output(&op[7+9],0,tremval2[i]);
5560+
5561+ opfuncs[op[8+9].op_state](&op[8+9]); //Cymbal
5562+ operator_output(&op[8+9],0,tremval4[i]);
5563+
5564+ Bit32s chanval = (op[7].cval + op[7+9].cval + op[8+9].cval)*2;
5565+ CHANVAL_OUT
5566+ }
5567+ }
5568+ }
5569+
5570+ Bitu max_channel = NUM_CHANNELS;
5571+#if defined(OPLTYPE_IS_OPL3)
5572+ if ((adlibreg[0x105]&1)==0) max_channel = NUM_CHANNELS/2;
5573+#endif
5574+ for (Bits cur_ch=max_channel-1; cur_ch>=0; cur_ch--) {
5575+ // skip drum/percussion operators
5576+ if ((adlibreg[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue;
5577+
5578+ Bitu k = cur_ch;
5579+#if defined(OPLTYPE_IS_OPL3)
5580+ if (cur_ch < 9) {
5581+ cptr = &op[cur_ch];
5582+ } else {
5583+ cptr = &op[cur_ch+9]; // second set is operator18-operator35
5584+ k += (-9+256); // second set uses registers 0x100 onwards
5585+ }
5586+ // check if this operator is part of a 4-op
5587+ if ((adlibreg[0x105]&1) && cptr->is_4op_attached) continue;
5588+#else
5589+ cptr = &op[cur_ch];
5590+#endif
5591+
5592+ // check for FM/AM
5593+ if (adlibreg[ARC_FEEDBACK+k]&1) {
5594+#if defined(OPLTYPE_IS_OPL3)
5595+ if ((adlibreg[0x105]&1) && cptr->is_4op) {
5596+ if (adlibreg[ARC_FEEDBACK+k+3]&1) {
5597+ // AM-AM-style synthesis (op1[fb] + (op2 * op3) + op4)
5598+ if (cptr[0].op_state != OF_TYPE_OFF) {
5599+ if (cptr[0].vibrato) {
5600+ vibval1 = vibval_var1;
5601+ for (i=0;i<endsamples;i++)
5602+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5603+ } else vibval1 = vibval_const;
5604+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5605+ else tremval1 = tremval_const;
5606+
5607+ // calculate channel output
5608+ for (i=0;i<endsamples;i++) {
5609+ operator_advance(&cptr[0],vibval1[i]);
5610+ opfuncs[cptr[0].op_state](&cptr[0]);
5611+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5612+
5613+ Bit32s chanval = cptr[0].cval;
5614+ CHANVAL_OUT
5615+ }
5616+ }
5617+
5618+ if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) {
5619+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5620+ vibval1 = vibval_var1;
5621+ for (i=0;i<endsamples;i++)
5622+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5623+ } else vibval1 = vibval_const;
5624+ if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5625+ else tremval1 = tremval_const;
5626+ if (cptr[3].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5627+ else tremval2 = tremval_const;
5628+
5629+ // calculate channel output
5630+ for (i=0;i<endsamples;i++) {
5631+ operator_advance(&cptr[9],vibval1[i]);
5632+ opfuncs[cptr[9].op_state](&cptr[9]);
5633+ operator_output(&cptr[9],0,tremval1[i]);
5634+
5635+ operator_advance(&cptr[3],0);
5636+ opfuncs[cptr[3].op_state](&cptr[3]);
5637+ operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]);
5638+
5639+ Bit32s chanval = cptr[3].cval;
5640+ CHANVAL_OUT
5641+ }
5642+ }
5643+
5644+ if (cptr[3+9].op_state != OF_TYPE_OFF) {
5645+ if (cptr[3+9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5646+ else tremval1 = tremval_const;
5647+
5648+ // calculate channel output
5649+ for (i=0;i<endsamples;i++) {
5650+ operator_advance(&cptr[3+9],0);
5651+ opfuncs[cptr[3+9].op_state](&cptr[3+9]);
5652+ operator_output(&cptr[3+9],0,tremval1[i]);
5653+
5654+ Bit32s chanval = cptr[3+9].cval;
5655+ CHANVAL_OUT
5656+ }
5657+ }
5658+ } else {
5659+ // AM-FM-style synthesis (op1[fb] + (op2 * op3 * op4))
5660+ if (cptr[0].op_state != OF_TYPE_OFF) {
5661+ if (cptr[0].vibrato) {
5662+ vibval1 = vibval_var1;
5663+ for (i=0;i<endsamples;i++)
5664+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5665+ } else vibval1 = vibval_const;
5666+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5667+ else tremval1 = tremval_const;
5668+
5669+ // calculate channel output
5670+ for (i=0;i<endsamples;i++) {
5671+ operator_advance(&cptr[0],vibval1[i]);
5672+ opfuncs[cptr[0].op_state](&cptr[0]);
5673+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5674+
5675+ Bit32s chanval = cptr[0].cval;
5676+ CHANVAL_OUT
5677+ }
5678+ }
5679+
5680+ if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) {
5681+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5682+ vibval1 = vibval_var1;
5683+ for (i=0;i<endsamples;i++)
5684+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5685+ } else vibval1 = vibval_const;
5686+ if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5687+ else tremval1 = tremval_const;
5688+ if (cptr[3].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5689+ else tremval2 = tremval_const;
5690+ if (cptr[3+9].tremolo) tremval3 = trem_lut; // tremolo enabled, use table
5691+ else tremval3 = tremval_const;
5692+
5693+ // calculate channel output
5694+ for (i=0;i<endsamples;i++) {
5695+ operator_advance(&cptr[9],vibval1[i]);
5696+ opfuncs[cptr[9].op_state](&cptr[9]);
5697+ operator_output(&cptr[9],0,tremval1[i]);
5698+
5699+ operator_advance(&cptr[3],0);
5700+ opfuncs[cptr[3].op_state](&cptr[3]);
5701+ operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]);
5702+
5703+ operator_advance(&cptr[3+9],0);
5704+ opfuncs[cptr[3+9].op_state](&cptr[3+9]);
5705+ operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval3[i]);
5706+
5707+ Bit32s chanval = cptr[3+9].cval;
5708+ CHANVAL_OUT
5709+ }
5710+ }
5711+ }
5712+ continue;
5713+ }
5714+#endif
5715+ // 2op additive synthesis
5716+ if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue;
5717+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5718+ vibval1 = vibval_var1;
5719+ for (i=0;i<endsamples;i++)
5720+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5721+ } else vibval1 = vibval_const;
5722+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5723+ vibval2 = vibval_var2;
5724+ for (i=0;i<endsamples;i++)
5725+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5726+ } else vibval2 = vibval_const;
5727+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5728+ else tremval1 = tremval_const;
5729+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5730+ else tremval2 = tremval_const;
5731+
5732+ // calculate channel output
5733+ for (i=0;i<endsamples;i++) {
5734+ // carrier1
5735+ operator_advance(&cptr[0],vibval1[i]);
5736+ opfuncs[cptr[0].op_state](&cptr[0]);
5737+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5738+
5739+ // carrier2
5740+ operator_advance(&cptr[9],vibval2[i]);
5741+ opfuncs[cptr[9].op_state](&cptr[9]);
5742+ operator_output(&cptr[9],0,tremval2[i]);
5743+
5744+ Bit32s chanval = cptr[9].cval + cptr[0].cval;
5745+ CHANVAL_OUT
5746+ }
5747+ } else {
5748+#if defined(OPLTYPE_IS_OPL3)
5749+ if ((adlibreg[0x105]&1) && cptr->is_4op) {
5750+ if (adlibreg[ARC_FEEDBACK+k+3]&1) {
5751+ // FM-AM-style synthesis ((op1[fb] * op2) + (op3 * op4))
5752+ if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) {
5753+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5754+ vibval1 = vibval_var1;
5755+ for (i=0;i<endsamples;i++)
5756+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5757+ } else vibval1 = vibval_const;
5758+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5759+ vibval2 = vibval_var2;
5760+ for (i=0;i<endsamples;i++)
5761+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5762+ } else vibval2 = vibval_const;
5763+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5764+ else tremval1 = tremval_const;
5765+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5766+ else tremval2 = tremval_const;
5767+
5768+ // calculate channel output
5769+ for (i=0;i<endsamples;i++) {
5770+ operator_advance(&cptr[0],vibval1[i]);
5771+ opfuncs[cptr[0].op_state](&cptr[0]);
5772+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5773+
5774+ operator_advance(&cptr[9],vibval2[i]);
5775+ opfuncs[cptr[9].op_state](&cptr[9]);
5776+ operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]);
5777+
5778+ Bit32s chanval = cptr[9].cval;
5779+ CHANVAL_OUT
5780+ }
5781+ }
5782+
5783+ if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) {
5784+ if (cptr[3].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5785+ else tremval1 = tremval_const;
5786+ if (cptr[3+9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5787+ else tremval2 = tremval_const;
5788+
5789+ // calculate channel output
5790+ for (i=0;i<endsamples;i++) {
5791+ operator_advance(&cptr[3],0);
5792+ opfuncs[cptr[3].op_state](&cptr[3]);
5793+ operator_output(&cptr[3],0,tremval1[i]);
5794+
5795+ operator_advance(&cptr[3+9],0);
5796+ opfuncs[cptr[3+9].op_state](&cptr[3+9]);
5797+ operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval2[i]);
5798+
5799+ Bit32s chanval = cptr[3+9].cval;
5800+ CHANVAL_OUT
5801+ }
5802+ }
5803+
5804+ } else {
5805+ // FM-FM-style synthesis (op1[fb] * op2 * op3 * op4)
5806+ if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF) ||
5807+ (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) {
5808+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5809+ vibval1 = vibval_var1;
5810+ for (i=0;i<endsamples;i++)
5811+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5812+ } else vibval1 = vibval_const;
5813+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5814+ vibval2 = vibval_var2;
5815+ for (i=0;i<endsamples;i++)
5816+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5817+ } else vibval2 = vibval_const;
5818+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5819+ else tremval1 = tremval_const;
5820+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5821+ else tremval2 = tremval_const;
5822+ if (cptr[3].tremolo) tremval3 = trem_lut; // tremolo enabled, use table
5823+ else tremval3 = tremval_const;
5824+ if (cptr[3+9].tremolo) tremval4 = trem_lut; // tremolo enabled, use table
5825+ else tremval4 = tremval_const;
5826+
5827+ // calculate channel output
5828+ for (i=0;i<endsamples;i++) {
5829+ operator_advance(&cptr[0],vibval1[i]);
5830+ opfuncs[cptr[0].op_state](&cptr[0]);
5831+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5832+
5833+ operator_advance(&cptr[9],vibval2[i]);
5834+ opfuncs[cptr[9].op_state](&cptr[9]);
5835+ operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]);
5836+
5837+ operator_advance(&cptr[3],0);
5838+ opfuncs[cptr[3].op_state](&cptr[3]);
5839+ operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval3[i]);
5840+
5841+ operator_advance(&cptr[3+9],0);
5842+ opfuncs[cptr[3+9].op_state](&cptr[3+9]);
5843+ operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval4[i]);
5844+
5845+ Bit32s chanval = cptr[3+9].cval;
5846+ CHANVAL_OUT
5847+ }
5848+ }
5849+ }
5850+ continue;
5851+ }
5852+#endif
5853+ // 2op frequency modulation
5854+ if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue;
5855+ if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) {
5856+ vibval1 = vibval_var1;
5857+ for (i=0;i<endsamples;i++)
5858+ vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC);
5859+ } else vibval1 = vibval_const;
5860+ if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) {
5861+ vibval2 = vibval_var2;
5862+ for (i=0;i<endsamples;i++)
5863+ vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC);
5864+ } else vibval2 = vibval_const;
5865+ if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table
5866+ else tremval1 = tremval_const;
5867+ if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table
5868+ else tremval2 = tremval_const;
5869+
5870+ // calculate channel output
5871+ for (i=0;i<endsamples;i++) {
5872+ // modulator
5873+ operator_advance(&cptr[0],vibval1[i]);
5874+ opfuncs[cptr[0].op_state](&cptr[0]);
5875+ operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]);
5876+
5877+ // carrier
5878+ operator_advance(&cptr[9],vibval2[i]);
5879+ opfuncs[cptr[9].op_state](&cptr[9]);
5880+ operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]);
5881+
5882+ Bit32s chanval = cptr[9].cval;
5883+ CHANVAL_OUT
5884+ }
5885+ }
5886+ }
5887+
5888+#if defined(OPLTYPE_IS_OPL3)
5889+ if (adlibreg[0x105]&1) {
5890+ // convert to 16bit samples (stereo)
5891+ for (i=0;i<endsamples;i++) {
5892+ clipit16(outbufl[i],sndptr++);
5893+ clipit16(outbufr[i],sndptr++);
5894+ }
5895+ } else {
5896+ // convert to 16bit samples (mono)
5897+ for (i=0;i<endsamples;i++) {
5898+ clipit16(outbufl[i],sndptr++);
5899+ clipit16(outbufl[i],sndptr++);
5900+ }
5901+ }
5902+#else
5903+ // convert to 16bit samples
5904+ for (i=0;i<endsamples;i++)
5905+ clipit16(outbufl[i],sndptr++);
5906+#endif
5907+
5908+ }
5909+}
5910Index: sound/softsynth/adlib/dosbox.h
5911===================================================================
5912--- sound/softsynth/adlib/dosbox.h (revision 0)
5913+++ sound/softsynth/adlib/dosbox.h (revision 0)
5914@@ -0,0 +1,120 @@
5915+/* ScummVM - Graphic Adventure Engine
5916+ *
5917+ * ScummVM is the legal property of its developers, whose names
5918+ * are too numerous to list here. Please refer to the COPYRIGHT
5919+ * file distributed with this source distribution.
5920+ *
5921+ * This program is free software; you can redistribute it and/or
5922+ * modify it under the terms of the GNU General Public License
5923+ * as published by the Free Software Foundation; either version 2
5924+ * of the License, or (at your option) any later version.
5925+ *
5926+ * This program is distributed in the hope that it will be useful,
5927+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5928+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5929+ * GNU General Public License for more details.
5930+ *
5931+ * You should have received a copy of the GNU General Public License
5932+ * along with this program; if not, write to the Free Software
5933+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
5934+ *
5935+ * $URL$
5936+ * $Id$
5937+ */
5938+
5939+/*
5940+ * Based on AdLib emulation code of DOSBox
5941+ * Copyright (C) 2002-2009 The DOSBox Team
5942+ * Licensed under GPLv2+
5943+ * http://www.dosbox.com
5944+ */
5945+
5946+#ifndef SOUND_SOFTSYNTH_ADLIB_DOSBOX_H
5947+#define SOUND_SOFTSYNTH_ADLIB_DOSBOX_H
5948+
5949+#ifndef DISABLE_DOSBOX_ADLIB
5950+
5951+#include "sound/fmopl.h"
5952+
5953+namespace AdLib {
5954+namespace DOSBox {
5955+
5956+class Handler;
5957+
5958+struct Timer {
5959+ double startTime;
5960+ double delay;
5961+ bool enabled, overflow, masked;
5962+ uint8 counter;
5963+
5964+ Timer();
5965+
5966+ //Call update before making any further changes
5967+ void update(double time);
5968+
5969+ //On a reset make sure the start is in sync with the next cycle
5970+ void reset(double time);
5971+
5972+ void stop();
5973+
5974+ void start(double time, int scale);
5975+};
5976+
5977+struct Chip {
5978+ //Last selected register
5979+ Timer timer[2];
5980+ //Check for it being a write to the timer
5981+ bool write(uint32 addr, uint8 val);
5982+ //Read the current timer state, will use current double
5983+ uint8 read();
5984+};
5985+
5986+class Handler {
5987+public:
5988+ virtual ~Handler() {}
5989+
5990+ // Write an address to a chip, returns the address the chip sets
5991+ virtual uint32 writeAddr(uint32 port, uint8 val) = 0;
5992+ // Write to a specific register in the chip
5993+ virtual void writeReg(uint32 addr, uint8 val) = 0;
5994+ // Generate a certain amount of samples
5995+ virtual void generate(int16 *chan, uint samples) = 0;
5996+ // Initialize at a specific sample rate and mode
5997+ virtual void init(uint rate) = 0;
5998+};
5999+
6000+class AdLib_DOSBox : public AdLib {
6001+private:
6002+ kOplType _type;
6003+ uint _rate;
6004+
6005+ Handler *_handler;
6006+ Chip _chip[2];
6007+ union {
6008+ uint16 normal;
6009+ uint8 dual[2];
6010+ } _reg;
6011+
6012+ void free();
6013+public:
6014+ AdLib_DOSBox();
6015+ ~AdLib_DOSBox();
6016+
6017+ void init(int rate, kOplType type);
6018+ void reset();
6019+
6020+ void write(int a, int v);
6021+ byte read(int a);
6022+
6023+ void writeReg(int r, int v);
6024+
6025+ void readBuffer(int16 *buffer, int length);
6026+};
6027+
6028+} // end of namespace DOSBox
6029+} // end of namespace AdLib
6030+
6031+#endif // !DISABLE_DOSBOX_ADLIB
6032+
6033+#endif
6034+
6035Index: sound/softsynth/adlib/mame.h
6036===================================================================
6037--- sound/softsynth/adlib/mame.h (revision 0)
6038+++ sound/softsynth/adlib/mame.h (revision 0)
6039@@ -0,0 +1,200 @@
6040+/* ScummVM - Graphic Adventure Engine
6041+ *
6042+ * ScummVM is the legal property of its developers, whose names
6043+ * are too numerous to list here. Please refer to the COPYRIGHT
6044+ * file distributed with this source distribution.
6045+ *
6046+ * This program is free software; you can redistribute it and/or
6047+ * modify it under the terms of the GNU General Public License
6048+ * as published by the Free Software Foundation; either version 2
6049+ * of the License, or (at your option) any later version.
6050+
6051+ * This program is distributed in the hope that it will be useful,
6052+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6053+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6054+ * GNU General Public License for more details.
6055+
6056+ * You should have received a copy of the GNU General Public License
6057+ * along with this program; if not, write to the Free Software
6058+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6059+ *
6060+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.h $
6061+ * $Id: fmopl.h 38211 2009-02-15 10:07:50Z sev $
6062+ *
6063+ * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
6064+ * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
6065+ */
6066+
6067+
6068+#ifndef SOUND_SOFTSYNTH_ADLIB_MAME_H
6069+#define SOUND_SOFTSYNTH_ADLIB_MAME_H
6070+
6071+#include "common/scummsys.h"
6072+#include "common/util.h"
6073+
6074+#include "sound/fmopl.h"
6075+
6076+namespace AdLib {
6077+namespace MAME {
6078+
6079+enum {
6080+ FMOPL_ENV_BITS_HQ = 16,
6081+ FMOPL_ENV_BITS_MQ = 8,
6082+ FMOPL_ENV_BITS_LQ = 8,
6083+ FMOPL_EG_ENT_HQ = 4096,
6084+ FMOPL_EG_ENT_MQ = 1024,
6085+ FMOPL_EG_ENT_LQ = 128
6086+};
6087+
6088+
6089+typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
6090+typedef void (*OPL_IRQHANDLER)(int param,int irq);
6091+typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
6092+
6093+#define OPL_TYPE_WAVESEL 0x01 /* waveform select */
6094+
6095+/* Saving is necessary for member of the 'R' mark for suspend/resume */
6096+/* ---------- OPL one of slot ---------- */
6097+typedef struct fm_opl_slot {
6098+ int TL; /* total level :TL << 8 */
6099+ int TLL; /* adjusted now TL */
6100+ uint8 KSR; /* key scale rate :(shift down bit) */
6101+ int *AR; /* attack rate :&AR_TABLE[AR<<2] */
6102+ int *DR; /* decay rate :&DR_TABLE[DR<<2] */
6103+ int SL; /* sustain level :SL_TABLE[SL] */
6104+ int *RR; /* release rate :&DR_TABLE[RR<<2] */
6105+ uint8 ksl; /* keyscale level :(shift down bits) */
6106+ uint8 ksr; /* key scale rate :kcode>>KSR */
6107+ uint mul; /* multiple :ML_TABLE[ML] */
6108+ uint Cnt; /* frequency count */
6109+ uint Incr; /* frequency step */
6110+
6111+ /* envelope generator state */
6112+ uint8 eg_typ;/* envelope type flag */
6113+ uint8 evm; /* envelope phase */
6114+ int evc; /* envelope counter */
6115+ int eve; /* envelope counter end point */
6116+ int evs; /* envelope counter step */
6117+ int evsa; /* envelope step for AR :AR[ksr] */
6118+ int evsd; /* envelope step for DR :DR[ksr] */
6119+ int evsr; /* envelope step for RR :RR[ksr] */
6120+
6121+ /* LFO */
6122+ uint8 ams; /* ams flag */
6123+ uint8 vib; /* vibrate flag */
6124+ /* wave selector */
6125+ int **wavetable;
6126+} OPL_SLOT;
6127+
6128+/* ---------- OPL one of channel ---------- */
6129+typedef struct fm_opl_channel {
6130+ OPL_SLOT SLOT[2];
6131+ uint8 CON; /* connection type */
6132+ uint8 FB; /* feed back :(shift down bit)*/
6133+ int *connect1; /* slot1 output pointer */
6134+ int *connect2; /* slot2 output pointer */
6135+ int op1_out[2]; /* slot1 output for selfeedback */
6136+
6137+ /* phase generator state */
6138+ uint block_fnum; /* block+fnum */
6139+ uint8 kcode; /* key code : KeyScaleCode */
6140+ uint fc; /* Freq. Increment base */
6141+ uint ksl_base; /* KeyScaleLevel Base step */
6142+ uint8 keyon; /* key on/off flag */
6143+} OPL_CH;
6144+
6145+/* OPL state */
6146+typedef struct fm_opl_f {
6147+ uint8 type; /* chip type */
6148+ int clock; /* master clock (Hz) */
6149+ int rate; /* sampling rate (Hz) */
6150+ double freqbase; /* frequency base */
6151+ double TimerBase; /* Timer base time (==sampling time) */
6152+ uint8 address; /* address register */
6153+ uint8 status; /* status flag */
6154+ uint8 statusmask; /* status mask */
6155+ uint mode; /* Reg.08 : CSM , notesel,etc. */
6156+
6157+ /* Timer */
6158+ int T[2]; /* timer counter */
6159+ uint8 st[2]; /* timer enable */
6160+
6161+ /* FM channel slots */
6162+ OPL_CH *P_CH; /* pointer of CH */
6163+ int max_ch; /* maximum channel */
6164+
6165+ /* Rythm sention */
6166+ uint8 rythm; /* Rythm mode , key flag */
6167+
6168+ /* time tables */
6169+ int AR_TABLE[76]; /* atttack rate tables */
6170+ int DR_TABLE[76]; /* decay rate tables */
6171+ uint FN_TABLE[1024];/* fnumber -> increment counter */
6172+
6173+ /* LFO */
6174+ int *ams_table;
6175+ int *vib_table;
6176+ int amsCnt;
6177+ int amsIncr;
6178+ int vibCnt;
6179+ int vibIncr;
6180+
6181+ /* wave selector enable flag */
6182+ uint8 wavesel;
6183+
6184+ /* external event callback handler */
6185+ OPL_TIMERHANDLER TimerHandler; /* TIMER handler */
6186+ int TimerParam; /* TIMER parameter */
6187+ OPL_IRQHANDLER IRQHandler; /* IRQ handler */
6188+ int IRQParam; /* IRQ parameter */
6189+ OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */
6190+ int UpdateParam; /* stream update parameter */
6191+
6192+ Common::RandomSource rnd;
6193+} FM_OPL;
6194+
6195+/* ---------- Generic interface section ---------- */
6196+#define OPL_TYPE_YM3526 (0)
6197+#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
6198+
6199+void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);
6200+
6201+FM_OPL *OPLCreate(int type, int clock, int rate);
6202+void OPLDestroy(FM_OPL *OPL);
6203+void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset);
6204+void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param);
6205+void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param);
6206+
6207+void OPLResetChip(FM_OPL *OPL);
6208+int OPLWrite(FM_OPL *OPL, int a, int v);
6209+unsigned char OPLRead(FM_OPL *OPL, int a);
6210+int OPLTimerOver(FM_OPL *OPL, int c);
6211+void OPLWriteReg(FM_OPL *OPL, int r, int v);
6212+void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave = 0);
6213+
6214+// Factory method
6215+FM_OPL *makeAdlibOPL(int rate);
6216+
6217+// AdLib API implementation
6218+class AdLib_MAME : public AdLib {
6219+private:
6220+ FM_OPL *_opl;
6221+public:
6222+ AdLib_MAME() : _opl(0) {}
6223+ ~AdLib_MAME();
6224+
6225+ void init(int rate, kOplType type);
6226+ void reset();
6227+
6228+ void write(int a, int v);
6229+ byte read(int a);
6230+
6231+ void writeReg(int r, int v);
6232+
6233+ void readBuffer(int16 *buffer, int length);
6234+};
6235+
6236+} // end of namespace MAME
6237+} // end of namespace AdLib
6238+
6239+#endif
6240Index: sound/softsynth/adlib/dbopl.h
6241===================================================================
6242--- sound/softsynth/adlib/dbopl.h (revision 0)
6243+++ sound/softsynth/adlib/dbopl.h (revision 0)
6244@@ -0,0 +1,284 @@
6245+/* ScummVM - Graphic Adventure Engine
6246+ *
6247+ * ScummVM is the legal property of its developers, whose names
6248+ * are too numerous to list here. Please refer to the COPYRIGHT
6249+ * file distributed with this source distribution.
6250+ *
6251+ * This program is free software; you can redistribute it and/or
6252+ * modify it under the terms of the GNU General Public License
6253+ * as published by the Free Software Foundation; either version 2
6254+ * of the License, or (at your option) any later version.
6255+ *
6256+ * This program is distributed in the hope that it will be useful,
6257+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6258+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6259+ * GNU General Public License for more details.
6260+ *
6261+ * You should have received a copy of the GNU General Public License
6262+ * along with this program; if not, write to the Free Software
6263+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6264+ *
6265+ * $URL$
6266+ * $Id$
6267+ */
6268+
6269+/*
6270+ * Based on AdLib emulation code of DOSBox
6271+ * Copyright (C) 2002-2009 The DOSBox Team
6272+ * Licensed under GPLv2+
6273+ * http://www.dosbox.com
6274+ */
6275+
6276+#ifndef DISABLE_DOSBOX_ADLIB
6277+
6278+#ifndef SOUND_SOFTSYNTH_ADLIB_DBOPL_H
6279+#define SOUND_SOFTSYNTH_ADLIB_DBOPL_H
6280+
6281+#include "common/scummsys.h"
6282+#include "dosbox.h"
6283+
6284+//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
6285+#define WAVE_HANDLER 10
6286+//Use a logarithmic wavetable with an exponential table for volume
6287+#define WAVE_TABLELOG 11
6288+//Use a linear wavetable with a multiply table for volume
6289+#define WAVE_TABLEMUL 12
6290+
6291+//Select the type of wave generator routine
6292+#define DBOPL_WAVE WAVE_TABLEMUL
6293+//Enable vibrato in the output
6294+#define DBOPL_VIBRATO
6295+//Enable tremolo in the output
6296+#define DBOPL_TREMOLO
6297+
6298+namespace AdLib {
6299+namespace DOSBox {
6300+namespace DBOPL {
6301+
6302+// Define types required by DOSBox code
6303+typedef int Bits;
6304+typedef uint Bitu;
6305+typedef int8 Bit8s;
6306+typedef uint8 Bit8u;
6307+typedef int16 Bit16s;
6308+typedef uint16 Bit16u;
6309+typedef int32 Bit32s;
6310+typedef uint32 Bit32u;
6311+
6312+struct Chip;
6313+struct Operator;
6314+struct Channel;
6315+
6316+#if (DBOPL_WAVE == WAVE_HANDLER)
6317+typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
6318+#endif
6319+
6320+typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
6321+typedef Channel* ( DBOPL::Channel::*SynthHandler) ( );
6322+
6323+//Different synth modes that can generate blocks of data
6324+enum SynthMode {
6325+ smNone,
6326+ sm2AM,
6327+ sm2FM,
6328+ sm2Percussion,
6329+ sm3AM,
6330+ sm3FM,
6331+ sm3FMFM,
6332+ sm3AMFM,
6333+ sm3FMAM,
6334+ sm3AMAM,
6335+ sm3Percussion
6336+};
6337+
6338+//Shifts for the values contained in chandata variable
6339+enum {
6340+ SHIFT_KSLBASE = 16,
6341+ SHIFT_KEYCODE = 24
6342+};
6343+
6344+struct Operator {
6345+public:
6346+ //Masks for operator 20 values
6347+ enum {
6348+ MASK_KSR = 0x10,
6349+ MASK_SUSTAIN = 0x20,
6350+ MASK_VIBRATO = 0x40,
6351+ MASK_TREMOLO = 0x80
6352+ };
6353+
6354+ enum State {
6355+ OFF,
6356+ RELEASE,
6357+ SUSTAIN,
6358+ DECAY,
6359+ ATTACK
6360+ };
6361+
6362+ VolumeHandler volHandler;
6363+
6364+#if (DBOPL_WAVE == WAVE_HANDLER)
6365+ WaveHandler waveHandler; //Routine that generate a wave
6366+#else
6367+ Bit16s* waveBase;
6368+ Bit32u waveMask;
6369+ Bit32u waveStart;
6370+#endif
6371+ Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
6372+ Bit32u waveAdd;
6373+
6374+ Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
6375+ Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
6376+ Bit32u vibrato; //Scaled up vibrato strength
6377+ Bit32s sustainLevel; //When stopping at sustain level stop here
6378+ Bit32s totalLevel; //totalLeve is added to every generated volume
6379+ Bit32s activeLevel; //The currently active volume
6380+
6381+ Bit32u attackAdd; //Timers for the different states of the envelope
6382+ Bit32u decayAdd;
6383+ Bit32u releaseAdd;
6384+ Bit32u rateIndex; //Current position of the evenlope
6385+
6386+ Bit8u rateZero; //Bits for the different states of the envelope having no changes
6387+ Bit8u keyOn; //Bitmask of different values that can generate keyon
6388+ //Registers, also used to check for changes
6389+ Bit8u reg20, reg40, reg60, reg80, regE0;
6390+ //Active part of the envelope we're in
6391+ Bit8u state;
6392+ //0xff when tremolo is enabled
6393+ Bit8u tremoloMask;
6394+ //Strength of the vibrato
6395+ Bit8u vibStrength;
6396+ //Keep track of the calculated KSR so we can check for changes
6397+ Bit8u ksr;
6398+private:
6399+ void SetState( Bit8u s );
6400+ void UpdateAttack( const Chip* chip );
6401+ void UpdateRelease( const Chip* chip );
6402+ void UpdateDecay( const Chip* chip );
6403+public:
6404+ void UpdateAttenuation();
6405+ void UpdateRates( const Chip* chip );
6406+ void UpdateFrequency( );
6407+
6408+ void Write20( const Chip* chip, Bit8u val );
6409+ void Write40( const Chip* chip, Bit8u val );
6410+ void Write60( const Chip* chip, Bit8u val );
6411+ void Write80( const Chip* chip, Bit8u val );
6412+ void WriteE0( const Chip* chip, Bit8u val );
6413+
6414+ bool Silent() const;
6415+ void KeyOn( Bit8u mask);
6416+ void KeyOff( Bit8u mask);
6417+
6418+ template< State state>
6419+ Bits TemplateVolume( );
6420+
6421+ Bit32s RateForward( Bit32u add );
6422+ Bitu ForwardWave();
6423+ Bitu ForwardVolume();
6424+
6425+ Bits GetSample( Bits modulation );
6426+ Bits GetWave( Bitu index, Bitu vol );
6427+public:
6428+ Operator();
6429+};
6430+
6431+struct Channel {
6432+ Operator op[2];
6433+ inline Operator* Op( Bitu index ) {
6434+ return &( ( this + (index >> 1) )->op[ index & 1 ]);
6435+ }
6436+ SynthHandler synthHandler;
6437+ Bit32u chanData; //Frequency/octave and derived values
6438+ Bit32s old[2]; //Old data for feedback
6439+
6440+ Bit8u feedback; //Feedback shift
6441+ Bit8u regB0; //Register values to check for changes
6442+ Bit8u regC0;
6443+ //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
6444+ Bit8u fourMask;
6445+ Bit8s maskLeft; //Sign extended values for both channel's panning
6446+ Bit8s maskRight;
6447+
6448+ //Forward the channel data to the operators of the channel
6449+ void SetChanData( const Chip* chip, Bit32u data );
6450+ //Change in the chandata, check for new values and if we have to forward to operators
6451+ void UpdateFrequency( const Chip* chip, Bit8u fourOp );
6452+ void WriteA0( const Chip* chip, Bit8u val );
6453+ void WriteB0( const Chip* chip, Bit8u val );
6454+ void WriteC0( const Chip* chip, Bit8u val );
6455+ void ResetC0( const Chip* chip );
6456+
6457+ //call this for the first channel
6458+ template< bool opl3Mode >
6459+ void GeneratePercussion( Bit32s* output );
6460+
6461+ //Generate blocks of data in specific modes
6462+ template<SynthMode mode>
6463+ Channel* BlockTemplate( );
6464+ Channel();
6465+};
6466+
6467+struct Chip {
6468+ //This is used as the base counter for vibrato and tremolo
6469+ Bit32u tremoloCounter;
6470+ Bit32u tremoloAdd;
6471+ Bit32u vibratoCounter;
6472+ Bit32u vibratoAdd;
6473+
6474+ //Frequency scales for the different multiplications
6475+ Bit32u freqMul[16];
6476+ //Rates for decay and release for rate of this chip
6477+ Bit32u linearRates[76];
6478+ //Best match attack rates for the rate of this chip
6479+ Bit32u attackRates[76];
6480+
6481+ //18 channels with 2 operators each
6482+ Channel chan[18];
6483+
6484+ Bit8u reg104;
6485+ Bit8u reg08;
6486+ Bit8u reg04;
6487+ Bit8u regBD;
6488+ Bit8u vibratoShift;
6489+ Bit8u tremoloShift;
6490+ //Mask for allowed wave forms
6491+ Bit8u waveFormMask;
6492+ //0 or -1 when enabled
6493+ Bit8s opl3Active;
6494+
6495+ Bit8u ForwardTremolo();
6496+ Bit8s ForwardVibrato();
6497+
6498+ void WriteBD( Bit8u val );
6499+ void WriteReg(Bit32u reg, Bit8u val );
6500+
6501+ Bit32u WriteAddr( Bit32u port, Bit8u val );
6502+
6503+ void GenerateBlock2( Bitu samples );
6504+ void GenerateBlock3( Bitu samples );
6505+
6506+ void Generate( Bit32u samples );
6507+ void Setup( Bit32u r );
6508+
6509+ Chip();
6510+};
6511+
6512+struct Handler : public DOSBox::Handler {
6513+ DBOPL::Chip chip;
6514+
6515+ virtual Bit32u writeAddr( Bit32u port, Bit8u val );
6516+ virtual void writeReg( Bit32u addr, Bit8u val );
6517+ virtual void generate( Bit16s *chan, Bitu samples );
6518+ virtual void init( Bitu rate );
6519+};
6520+
6521+} // end of namespace DBOPL
6522+} // end of namespace DOSBox
6523+} // end of namespace AdLib
6524+
6525+#endif
6526+
6527+#endif
6528+
6529Index: sound/softsynth/adlib/dbopl_fl.h
6530===================================================================
6531--- sound/softsynth/adlib/dbopl_fl.h (revision 0)
6532+++ sound/softsynth/adlib/dbopl_fl.h (revision 0)
6533@@ -0,0 +1,198 @@
6534+/*
6535+ * Copyright (C) 2002-2009 The DOSBox Team
6536+ * OPL2/OPL3 emulation library
6537+ *
6538+ * This library is free software; you can redistribute it and/or
6539+ * modify it under the terms of the GNU Lesser General Public
6540+ * License as published by the Free Software Foundation; either
6541+ * version 2.1 of the License, or (at your option) any later version.
6542+ *
6543+ * This library is distributed in the hope that it will be useful,
6544+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6545+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6546+ * Lesser General Public License for more details.
6547+ *
6548+ * You should have received a copy of the GNU Lesser General Public
6549+ * License along with this library; if not, write to the Free Software
6550+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6551+ */
6552+
6553+
6554+/*
6555+ * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman
6556+ * Copyright (C) 1998-2001 Ken Silverman
6557+ * Ken Silverman's official web site: "http://www.advsys.net/ken"
6558+ */
6559+
6560+
6561+#define fltype double
6562+
6563+/*
6564+ define Bits, Bitu, Bit32s, Bit32u, Bit16s, Bit16u, Bit8s, Bit8u here
6565+*/
6566+
6567+typedef uint Bitu;
6568+typedef int Bits;
6569+typedef uint32 Bit32u;
6570+typedef int32 Bit32s;
6571+typedef uint16 Bit16u;
6572+typedef int16 Bit16s;
6573+typedef uint8 Bit8u;
6574+typedef int8 Bit8s;
6575+
6576+
6577+#undef NUM_CHANNELS
6578+#if defined(OPLTYPE_IS_OPL3)
6579+#define NUM_CHANNELS 18
6580+#else
6581+#define NUM_CHANNELS 9
6582+#endif
6583+
6584+#define MAXOPERATORS (NUM_CHANNELS*2)
6585+
6586+
6587+#define FL05 ((fltype)0.5)
6588+#define FL2 ((fltype)2.0)
6589+
6590+#ifdef PI
6591+#undef PI
6592+#endif
6593+
6594+#define PI ((fltype)3.1415926535897932384626433832795)
6595+
6596+
6597+#define FIXEDPT 0x10000 // fixed-point calculations using 16+16
6598+#define FIXEDPT_LFO 0x1000000 // fixed-point calculations using 8+24
6599+
6600+#define WAVEPREC 1024 // waveform precision (10 bits)
6601+
6602+#define INTFREQU ((fltype)(14318180.0 / 288.0)) // clocking of the chip
6603+
6604+
6605+#define OF_TYPE_ATT 0
6606+#define OF_TYPE_DEC 1
6607+#define OF_TYPE_REL 2
6608+#define OF_TYPE_SUS 3
6609+#define OF_TYPE_SUS_NOKEEP 4
6610+#define OF_TYPE_OFF 5
6611+
6612+#define ARC_CONTROL 0x00
6613+#define ARC_TVS_KSR_MUL 0x20
6614+#define ARC_KSL_OUTLEV 0x40
6615+#define ARC_ATTR_DECR 0x60
6616+#define ARC_SUSL_RELR 0x80
6617+#define ARC_FREQ_NUM 0xa0
6618+#define ARC_KON_BNUM 0xb0
6619+#define ARC_PERC_MODE 0xbd
6620+#define ARC_FEEDBACK 0xc0
6621+#define ARC_WAVE_SEL 0xe0
6622+
6623+#define ARC_SECONDSET 0x100 // second operator set for OPL3
6624+
6625+
6626+#define OP_ACT_OFF 0x00
6627+#define OP_ACT_NORMAL 0x01 // regular channel activated (bitmasked)
6628+#define OP_ACT_PERC 0x02 // percussion channel activated (bitmasked)
6629+
6630+#define BLOCKBUF_SIZE 512
6631+
6632+
6633+// vibrato constants
6634+#define VIBTAB_SIZE 8
6635+#define VIBFAC 70/50000 // no braces, integer mul/div
6636+
6637+// tremolo constants and table
6638+#define TREMTAB_SIZE 53
6639+#define TREM_FREQ ((fltype)(3.7)) // tremolo at 3.7hz
6640+
6641+
6642+/* operator struct definition
6643+ For OPL2 all 9 channels consist of two operators each, carrier and modulator.
6644+ Channel x has operators x as modulator and operators (9+x) as carrier.
6645+ For OPL3 all 18 channels consist either of two operators (2op mode) or four
6646+ operators (4op mode) which is determined through register4 of the second
6647+ adlib register set.
6648+ Only the channels 0,1,2 (first set) and 9,10,11 (second set) can act as
6649+ 4op channels. The two additional operators for a channel y come from the
6650+ 2op channel y+3 so the operatorss y, (9+y), y+3, (9+y)+3 make up a 4op
6651+ channel.
6652+*/
6653+typedef struct operator_struct {
6654+ Bit32s cval, lastcval; // current output/last output (used for feedback)
6655+ Bit32u tcount, wfpos, tinc; // time (position in waveform) and time increment
6656+ fltype amp, step_amp; // and amplification (envelope)
6657+ fltype vol; // volume
6658+ fltype sustain_level; // sustain level
6659+ Bit32s mfbi; // feedback amount
6660+ fltype a0, a1, a2, a3; // attack rate function coefficients
6661+ fltype decaymul, releasemul; // decay/release rate functions
6662+ Bit32u op_state; // current state of operator (attack/decay/sustain/release/off)
6663+ Bit32u toff;
6664+ Bit32s freq_high; // highest three bits of the frequency, used for vibrato calculations
6665+ Bit16s* cur_wform; // start of selected waveform
6666+ Bit32u cur_wmask; // mask for selected waveform
6667+ Bit32u act_state; // activity state (regular, percussion)
6668+ bool sus_keep; // keep sustain level when decay finished
6669+ bool vibrato,tremolo; // vibrato/tremolo enable bits
6670+
6671+ // variables used to provide non-continuous envelopes
6672+ Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed
6673+ Bits cur_env_step; // current (standardized) sample position
6674+ Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode)
6675+ Bit8u step_skip_pos; // position of 8-cyclic step skipping (always 2^x to check against mask)
6676+ Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then)
6677+
6678+#if defined(OPLTYPE_IS_OPL3)
6679+ bool is_4op,is_4op_attached; // base of a 4op channel/part of a 4op channel
6680+ Bit32s left_pan,right_pan; // opl3 stereo panning amount
6681+#endif
6682+} op_type;
6683+
6684+// per-chip variables
6685+Bitu chip_num;
6686+op_type op[MAXOPERATORS];
6687+
6688+Bits int_samplerate;
6689+
6690+Bit8u status;
6691+Bit32u index;
6692+#if defined(OPLTYPE_IS_OPL3)
6693+Bit8u adlibreg[512]; // adlib register set (including second set)
6694+Bit8u wave_sel[44]; // waveform selection
6695+#else
6696+Bit8u adlibreg[256]; // adlib register set
6697+Bit8u wave_sel[22]; // waveform selection
6698+#endif
6699+
6700+
6701+// vibrato/tremolo increment/counter
6702+Bit32u vibtab_pos;
6703+Bit32u vibtab_add;
6704+Bit32u tremtab_pos;
6705+Bit32u tremtab_add;
6706+
6707+
6708+// enable an operator
6709+void enable_operator(Bitu regbase, op_type* op_pt);
6710+
6711+// functions to change parameters of an operator
6712+void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt);
6713+
6714+void change_attackrate(Bitu regbase, op_type* op_pt);
6715+void change_decayrate(Bitu regbase, op_type* op_pt);
6716+void change_releaserate(Bitu regbase, op_type* op_pt);
6717+void change_sustainlevel(Bitu regbase, op_type* op_pt);
6718+void change_waveform(Bitu regbase, op_type* op_pt);
6719+void change_keepsustain(Bitu regbase, op_type* op_pt);
6720+void change_vibrato(Bitu regbase, op_type* op_pt);
6721+void change_feedback(Bitu chanbase, op_type* op_pt);
6722+
6723+// general functions
6724+void adlib_init(Bit32u samplerate);
6725+void adlib_write(Bitu idx, Bit8u val);
6726+void adlib_getsample(Bit16s* sndptr, Bits numsamples);
6727+
6728+Bitu adlib_reg_read(Bitu port);
6729+void adlib_write_index(Bitu port, Bit8u val);
6730+
6731+static Bit32u generator_add; // should be a chip parameter
6732Index: engines/sci/sfx/softseq/opl2.cpp
6733===================================================================
6734--- engines/sci/sfx/softseq/opl2.cpp (revision 40181)
6735+++ engines/sci/sfx/softseq/opl2.cpp (working copy)
6736@@ -47,8 +47,12 @@
6737 #include "../softseq.h"
6738 #include "../adlib.h"
6739
6740-#include "sound/fmopl.h"
6741+// FIXME: This code seems to heavily rely on the MAME fmopl emulator,
6742+// thus we will use it directly.
6743+#include "sound/softsynth/adlib/mame.h"
6744
6745+using namespace AdLib::MAME;
6746+
6747 namespace Sci {
6748
6749 // FIXME: Instead of hardcoding SAMPLE_RATE we should call Mixer::getOutputRate()
6750@@ -119,8 +123,8 @@
6751 static uint8 oper_note[ADLIB_VOICES];
6752 static uint8 oper_chn[ADLIB_VOICES];
6753
6754-static FM_OPL *ym3812_L = NULL;
6755-static FM_OPL *ym3812_R = NULL;
6756+static AdLib::MAME::FM_OPL *ym3812_L = NULL;
6757+static AdLib::MAME::FM_OPL *ym3812_R = NULL;
6758
6759 static uint8 adlib_reg_L[256];
6760 static uint8 adlib_reg_R[256];
6761@@ -549,7 +553,7 @@
6762
6763
6764 static void opl2_exit(sfx_softseq_t *self) {
6765- FM_OPL *opl = ym3812_L;
6766+ AdLib::MAME::FM_OPL *opl = ym3812_L;
6767 ym3812_L = NULL;
6768 OPLDestroy(opl);
6769 opl = ym3812_R;