Ticket #9010: dosbox_adlib_v6.patch
File dosbox_adlib_v6.patch, 145.7 KB (added by , 15 years ago) |
---|
-
engines/sci/sfx/softseq/opl2.cpp
42 42 43 43 ***************************************************************************/ 44 44 45 #include "common/util.h" 46 45 47 #include "sci/tools.h" 46 48 #include "sci/sfx/iterator.h" 47 49 #include "../softseq.h" … … 79 81 #define ADLIB_LEFT 0 80 82 #define ADLIB_RIGHT 1 81 83 82 /* #define OPL_INTERNAL_FREQ 3600000 */83 #define OPL_INTERNAL_FREQ 357954584 85 84 static int ready = 0; 86 85 static int pcmout_stereo = STEREO; 87 86 … … 157 156 158 157 /* more shamelessly lifted from xmp and adplug. And altered. :) */ 159 158 160 static intopl_write_L(int a, int v) {159 static void opl_write_L(int a, int v) { 161 160 adlib_reg_L[a] = v; 162 161 OPLWrite(ym3812_L, 0x388, a); 163 returnOPLWrite(ym3812_L, 0x389, v);162 OPLWrite(ym3812_L, 0x389, v); 164 163 } 165 164 166 static intopl_write_R(int a, int v) {165 static void opl_write_R(int a, int v) { 167 166 adlib_reg_R[a] = v; 168 167 OPLWrite(ym3812_R, 0x388, a); 169 returnOPLWrite(ym3812_R, 0x389, v);168 OPLWrite(ym3812_R, 0x389, v); 170 169 } 171 170 172 static intopl_write(int a, int v) {171 static void opl_write(int a, int v) { 173 172 opl_write_L(a, v); 174 returnopl_write_R(a, v);173 opl_write_R(a, v); 175 174 } 176 175 177 176 /* … … 472 471 We assume 16-bit stereo frames (ie 4 bytes) 473 472 */ 474 473 static void opl2_poll(sfx_softseq_t *self, byte *dest, int count) { 475 int16 *buffer = (int16 *) dest; 476 int16 *ptr = buffer; 474 int16 *ptr = (int16 *)dest; 477 475 478 if (!ready) {476 if (!ready) 479 477 error("synth_mixer(): !ready \n"); 480 }481 478 482 if (! buffer) {479 if (!ptr) 483 480 error("synth_mixer(): !buffer \n"); 484 }485 481 486 482 #if 0 487 483 { … … 509 505 #endif 510 506 511 507 if (pcmout_stereo) { 512 YM3812UpdateOne(ym3812_L, ptr, count, 1); 513 YM3812UpdateOne(ym3812_R, ptr + 1, count, 1); 508 int16 buffer[512]; 509 510 while (count > 0) { 511 int process = count > ARRAYSIZE(buffer) ? ARRAYSIZE(buffer) : count; 512 count -= process; 513 514 YM3812UpdateOne(ym3812_L, buffer, process); 515 for (int i = 0; i < process; ++i) 516 ptr[(i << 1) + 0] = buffer[i]; 517 518 YM3812UpdateOne(ym3812_R, buffer, process); 519 for (int i = 0; i < process; ++i) 520 ptr[(i << 1) + 1] = buffer[i]; 521 522 ptr += (count << 1); 523 } 514 524 } else { 515 YM3812UpdateOne(ym3812_L, ptr, count , 0);525 YM3812UpdateOne(ym3812_L, ptr, count); 516 526 } 517 527 } 518 528 … … 533 543 for (i = 48; i < 96; i++) 534 544 make_sbi((adlib_def *)(data_ptr + 2 + (28 * i)), adlib_sbi[i]); 535 545 536 OPLBuildTables(FMOPL_ENV_BITS_HQ, FMOPL_EG_ENT_HQ); 537 538 if (!(ym3812_L = OPLCreate(OPL_TYPE_YM3812, OPL_INTERNAL_FREQ, SAMPLE_RATE)) || 539 !(ym3812_R = OPLCreate(OPL_TYPE_YM3812, OPL_INTERNAL_FREQ, SAMPLE_RATE))) { 546 if (!(ym3812_L = makeAdlibOPL(SAMPLE_RATE)) || !(ym3812_R = makeAdlibOPL(SAMPLE_RATE))) { 540 547 sciprintf("[sfx:seq:opl2] Failure: Emulator init failed!\n"); 541 548 return SFX_ERROR; 542 549 } … … 549 556 550 557 551 558 static void opl2_exit(sfx_softseq_t *self) { 552 FM_OPL *opl = ym3812_L;559 OPLDestroy(ym3812_L); 553 560 ym3812_L = NULL; 554 OPLDestroy(opl); 555 opl = ym3812_R; 561 OPLDestroy(ym3812_R); 556 562 ym3812_R = NULL; 557 OPLDestroy(opl);558 563 559 564 // XXX deregister with pcm layer. 560 565 } -
sound/module.mk
30 30 mods/rjp1.o \ 31 31 mods/soundfx.o \ 32 32 softsynth/adlib.o \ 33 softsynth/opl/dbopl.o \ 34 softsynth/opl/dosbox.o \ 35 softsynth/opl/mame.o \ 33 36 softsynth/ym2612.o \ 34 37 softsynth/fluidsynth.o \ 35 38 softsynth/mt32.o \ -
sound/fmopl.h
8 8 * modify it under the terms of the GNU General Public License 9 9 * as published by the Free Software Foundation; either version 2 10 10 * of the License, or (at your option) any later version. 11 11 * 12 12 * This program is distributed in the hope that it will be useful, 13 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 * GNU General Public License for more details. 16 16 * 17 17 * You should have received a copy of the GNU General Public License 18 18 * along with this program; if not, write to the Free Software 19 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 20 * 21 21 * $URL$ 22 22 * $Id$ 23 *24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.26 23 */ 27 24 28 29 25 #ifndef SOUND_FMOPL_H 30 26 #define SOUND_FMOPL_H 31 27 32 28 #include "common/scummsys.h" 33 #include "common/util.h"34 29 35 enum { 36 FMOPL_ENV_BITS_HQ = 16, 37 FMOPL_ENV_BITS_MQ = 8, 38 FMOPL_ENV_BITS_LQ = 8, 39 FMOPL_EG_ENT_HQ = 4096, 40 FMOPL_EG_ENT_MQ = 1024, 41 FMOPL_EG_ENT_LQ = 128 42 }; 30 namespace OPL { 43 31 32 class OPL { 33 public: 34 virtual ~OPL() {} 35 36 /** 37 * OPL type to emulate. 38 */ 39 enum kOplType { 40 kOpl2 = 0 41 }; 42 43 /** 44 * Initializes the OPL emulator. 45 * 46 * @param rate output sample rate 47 * @return true on success, false on failure 48 */ 49 virtual bool init(int rate) = 0; 50 51 /** 52 * Reinitializes the OPL emulator 53 */ 54 virtual void reset() = 0; 55 56 /** 57 * Writes a byte to the given I/O port. 58 * 59 * @param a port address 60 * @param v value, which will be written 61 */ 62 virtual void write(int a, int v) = 0; 63 64 /** 65 * Reads a byte from the given I/O port. 66 * 67 * @param a port address 68 * @return value read 69 */ 70 virtual byte read(int a) = 0; 71 72 /** 73 * Function to directly write to a specific OPL register. 74 * Note that this will currently only work for OPL2 and 75 * OPL3 types, not for a Dual OPL2 emulator. 76 * 77 * @param r hardware register number to write to 78 * @param v value, which will be written 79 */ 80 virtual void writeReg(int r, int v) = 0; 81 82 /** 83 * Read up to 'length' samples. 84 * 85 * Data will be in native endianess, 16 bit per sample, signed. 86 * For stereo OPL, buffer will be filled with interleaved 87 * left and right channel samples, starting with a left sample. 88 * Furthermore, the samples in the left and right are summed up. 89 * So if you request 4 samples from a stereo OPL, you will get 90 * a total of two left channel and two right channel samples. 91 */ 92 virtual void readBuffer(int16 *buffer, int length) = 0; 44 93 45 typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); 46 typedef void (*OPL_IRQHANDLER)(int param,int irq); 47 typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); 48 49 #define OPL_TYPE_WAVESEL 0x01 /* waveform select */ 50 51 /* Saving is necessary for member of the 'R' mark for suspend/resume */ 52 /* ---------- OPL one of slot ---------- */ 53 typedef struct fm_opl_slot { 54 int TL; /* total level :TL << 8 */ 55 int TLL; /* adjusted now TL */ 56 uint8 KSR; /* key scale rate :(shift down bit) */ 57 int *AR; /* attack rate :&AR_TABLE[AR<<2] */ 58 int *DR; /* decay rate :&DR_TABLE[DR<<2] */ 59 int SL; /* sustain level :SL_TABLE[SL] */ 60 int *RR; /* release rate :&DR_TABLE[RR<<2] */ 61 uint8 ksl; /* keyscale level :(shift down bits) */ 62 uint8 ksr; /* key scale rate :kcode>>KSR */ 63 uint mul; /* multiple :ML_TABLE[ML] */ 64 uint Cnt; /* frequency count */ 65 uint Incr; /* frequency step */ 66 67 /* envelope generator state */ 68 uint8 eg_typ;/* envelope type flag */ 69 uint8 evm; /* envelope phase */ 70 int evc; /* envelope counter */ 71 int eve; /* envelope counter end point */ 72 int evs; /* envelope counter step */ 73 int evsa; /* envelope step for AR :AR[ksr] */ 74 int evsd; /* envelope step for DR :DR[ksr] */ 75 int evsr; /* envelope step for RR :RR[ksr] */ 76 77 /* LFO */ 78 uint8 ams; /* ams flag */ 79 uint8 vib; /* vibrate flag */ 80 /* wave selector */ 81 int **wavetable; 82 } OPL_SLOT; 83 84 /* ---------- OPL one of channel ---------- */ 85 typedef struct fm_opl_channel { 86 OPL_SLOT SLOT[2]; 87 uint8 CON; /* connection type */ 88 uint8 FB; /* feed back :(shift down bit)*/ 89 int *connect1; /* slot1 output pointer */ 90 int *connect2; /* slot2 output pointer */ 91 int op1_out[2]; /* slot1 output for selfeedback */ 92 93 /* phase generator state */ 94 uint block_fnum; /* block+fnum */ 95 uint8 kcode; /* key code : KeyScaleCode */ 96 uint fc; /* Freq. Increment base */ 97 uint ksl_base; /* KeyScaleLevel Base step */ 98 uint8 keyon; /* key on/off flag */ 99 } OPL_CH; 100 101 /* OPL state */ 102 typedef struct fm_opl_f { 103 uint8 type; /* chip type */ 104 int clock; /* master clock (Hz) */ 105 int rate; /* sampling rate (Hz) */ 106 double freqbase; /* frequency base */ 107 double TimerBase; /* Timer base time (==sampling time) */ 108 uint8 address; /* address register */ 109 uint8 status; /* status flag */ 110 uint8 statusmask; /* status mask */ 111 uint mode; /* Reg.08 : CSM , notesel,etc. */ 112 113 /* Timer */ 114 int T[2]; /* timer counter */ 115 uint8 st[2]; /* timer enable */ 116 117 /* FM channel slots */ 118 OPL_CH *P_CH; /* pointer of CH */ 119 int max_ch; /* maximum channel */ 120 121 /* Rythm sention */ 122 uint8 rythm; /* Rythm mode , key flag */ 123 124 /* time tables */ 125 int AR_TABLE[76]; /* atttack rate tables */ 126 int DR_TABLE[76]; /* decay rate tables */ 127 uint FN_TABLE[1024];/* fnumber -> increment counter */ 128 129 /* LFO */ 130 int *ams_table; 131 int *vib_table; 132 int amsCnt; 133 int amsIncr; 134 int vibCnt; 135 int vibIncr; 136 137 /* wave selector enable flag */ 138 uint8 wavesel; 139 140 /* external event callback handler */ 141 OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ 142 int TimerParam; /* TIMER parameter */ 143 OPL_IRQHANDLER IRQHandler; /* IRQ handler */ 144 int IRQParam; /* IRQ parameter */ 145 OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ 146 int UpdateParam; /* stream update parameter */ 147 148 Common::RandomSource rnd; 149 } FM_OPL; 150 151 /* ---------- Generic interface section ---------- */ 152 #define OPL_TYPE_YM3526 (0) 153 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) 94 static OPL *create(kOplType type = kOpl2); 95 }; 154 96 155 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM); 97 } // end of namespace OPL 98 99 // Legacy API 100 typedef OPL::OPL FM_OPL; 156 101 157 FM_OPL *OPLCreate(int type, int clock, int rate);158 102 void OPLDestroy(FM_OPL *OPL); 159 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset);160 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param);161 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param);162 103 163 104 void OPLResetChip(FM_OPL *OPL); 164 intOPLWrite(FM_OPL *OPL, int a, int v);105 void OPLWrite(FM_OPL *OPL, int a, int v); 165 106 unsigned char OPLRead(FM_OPL *OPL, int a); 166 int OPLTimerOver(FM_OPL *OPL, int c);167 107 void OPLWriteReg(FM_OPL *OPL, int r, int v); 168 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length , int interleave = 0);108 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length); 169 109 170 110 // Factory method 171 111 FM_OPL *makeAdlibOPL(int rate); 172 112 173 113 #endif 114 -
sound/fmopl.cpp
8 8 * modify it under the terms of the GNU General Public License 9 9 * as published by the Free Software Foundation; either version 2 10 10 * of the License, or (at your option) any later version. 11 11 * 12 12 * This program is distributed in the hope that it will be useful, 13 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 * GNU General Public License for more details. 16 16 * 17 17 * You should have received a copy of the GNU General Public License 18 18 * along with this program; if not, write to the Free Software 19 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 20 * 21 21 * $URL$ 22 22 * $Id$ 23 *24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.26 23 */ 27 24 28 #include <stdio.h>29 #include <stdlib.h>30 #include <string.h>31 #include <stdarg.h>32 #include <math.h>33 34 25 #include "sound/fmopl.h" 35 26 36 #if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) 37 #include "common/config-manager.h" 38 #endif 39 40 /* -------------------- preliminary define section --------------------- */ 41 /* attack/decay rate time rate */ 42 #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ 43 #define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ 44 45 #define FREQ_BITS 24 /* frequency turn */ 46 47 /* counter bits = 20 , octerve 7 */ 48 #define FREQ_RATE (1<<(FREQ_BITS-20)) 49 #define TL_BITS (FREQ_BITS+2) 50 51 /* final output shift , limit minimum and maximum */ 52 #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ 53 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB) 54 #define OPL_MINOUT (-0x8000<<OPL_OUTSB) 55 56 /* -------------------- quality selection --------------------- */ 57 58 /* sinwave entries */ 59 /* used static memory = SIN_ENT * 4 (byte) */ 60 #ifdef __DS__ 61 #include "dsmain.h" 62 #define SIN_ENT_SHIFT 8 63 #else 64 #define SIN_ENT_SHIFT 11 65 #endif 66 #define SIN_ENT (1<<SIN_ENT_SHIFT) 67 68 /* output level entries (envelope,sinwave) */ 69 /* envelope counter lower bits */ 70 int ENV_BITS; 71 /* envelope output entries */ 72 int EG_ENT; 73 74 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */ 75 /* used static memory = EG_ENT*4 (byte) */ 76 int EG_OFF; /* OFF */ 77 int EG_DED; 78 int EG_DST; /* DECAY START */ 79 int EG_AED; 80 #define EG_AST 0 /* ATTACK START */ 81 82 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */ 83 84 /* LFO table entries */ 85 #define VIB_ENT 512 86 #define VIB_SHIFT (32-9) 87 #define AMS_ENT 512 88 #define AMS_SHIFT (32-9) 89 90 #define VIB_RATE_SHIFT 8 91 #define VIB_RATE (1<<VIB_RATE_SHIFT) 92 93 /* -------------------- local defines , macros --------------------- */ 94 95 /* register number to channel number , slot offset */ 96 #define SLOT1 0 97 #define SLOT2 1 98 99 /* envelope phase */ 100 #define ENV_MOD_RR 0x00 101 #define ENV_MOD_DR 0x01 102 #define ENV_MOD_AR 0x02 103 104 /* -------------------- tables --------------------- */ 105 static const int slot_array[32] = { 106 0, 2, 4, 1, 3, 5,-1,-1, 107 6, 8,10, 7, 9,11,-1,-1, 108 12,14,16,13,15,17,-1,-1, 109 -1,-1,-1,-1,-1,-1,-1,-1 110 }; 111 112 static uint KSL_TABLE[8 * 16]; 113 114 static const double KSL_TABLE_SEED[8 * 16] = { 115 /* OCT 0 */ 116 0.000, 0.000, 0.000, 0.000, 117 0.000, 0.000, 0.000, 0.000, 118 0.000, 0.000, 0.000, 0.000, 119 0.000, 0.000, 0.000, 0.000, 120 /* OCT 1 */ 121 0.000, 0.000, 0.000, 0.000, 122 0.000, 0.000, 0.000, 0.000, 123 0.000, 0.750, 1.125, 1.500, 124 1.875, 2.250, 2.625, 3.000, 125 /* OCT 2 */ 126 0.000, 0.000, 0.000, 0.000, 127 0.000, 1.125, 1.875, 2.625, 128 3.000, 3.750, 4.125, 4.500, 129 4.875, 5.250, 5.625, 6.000, 130 /* OCT 3 */ 131 0.000, 0.000, 0.000, 1.875, 132 3.000, 4.125, 4.875, 5.625, 133 6.000, 6.750, 7.125, 7.500, 134 7.875, 8.250, 8.625, 9.000, 135 /* OCT 4 */ 136 0.000, 0.000, 3.000, 4.875, 137 6.000, 7.125, 7.875, 8.625, 138 9.000, 9.750, 10.125, 10.500, 139 10.875, 11.250, 11.625, 12.000, 140 /* OCT 5 */ 141 0.000, 3.000, 6.000, 7.875, 142 9.000, 10.125, 10.875, 11.625, 143 12.000, 12.750, 13.125, 13.500, 144 13.875, 14.250, 14.625, 15.000, 145 /* OCT 6 */ 146 0.000, 6.000, 9.000, 10.875, 147 12.000, 13.125, 13.875, 14.625, 148 15.000, 15.750, 16.125, 16.500, 149 16.875, 17.250, 17.625, 18.000, 150 /* OCT 7 */ 151 0.000, 9.000, 12.000, 13.875, 152 15.000, 16.125, 16.875, 17.625, 153 18.000, 18.750, 19.125, 19.500, 154 19.875, 20.250, 20.625, 21.000 155 }; 156 157 /* sustain level table (3db per step) */ 158 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ 27 #include "sound/softsynth/opl/dosbox.h" 28 #include "sound/softsynth/opl/mame.h" 159 29 160 static int SL_TABLE[16]; 30 namespace OPL { 161 31 162 static const uint SL_TABLE_SEED[16] = { 163 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31 164 }; 165 166 #define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */ 167 /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ 168 /* TL_TABLE[ 0 to TL_MAX ] : plus section */ 169 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ 170 static int *TL_TABLE; 171 172 /* pointers to TL_TABLE with sinwave output offset */ 173 static int **SIN_TABLE; 174 175 /* LFO table */ 176 static int *AMS_TABLE; 177 static int *VIB_TABLE; 178 179 /* envelope output curve table */ 180 /* attack + decay + OFF */ 181 //static int ENV_CURVE[2*EG_ENT+1]; 182 //static int ENV_CURVE[2 * 4096 + 1]; // to keep it static ... 183 static int *ENV_CURVE; 184 185 186 /* multiple table */ 187 #define ML(a) (int)(a * 2) 188 static const uint MUL_TABLE[16]= { 189 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ 190 ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00), 191 ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00) 192 }; 193 #undef ML 194 195 /* dummy attack / decay rate ( when rate == 0 ) */ 196 static int RATE_0[16]= 197 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 198 199 /* -------------------- static state --------------------- */ 200 201 /* lock level of common table */ 202 static int num_lock = 0; 203 204 /* work table */ 205 static void *cur_chip = NULL; /* current chip point */ 206 /* currenct chip state */ 207 /* static OPLSAMPLE *bufL,*bufR; */ 208 static OPL_CH *S_CH; 209 static OPL_CH *E_CH; 210 OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; 211 212 static int outd[1]; 213 static int ams; 214 static int vib; 215 int *ams_table; 216 int *vib_table; 217 static int amsIncr; 218 static int vibIncr; 219 static int feedback2; /* connect for SLOT 2 */ 220 221 /* --------------------- rebuild tables ------------------- */ 222 223 #define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2))) 224 #define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST 225 226 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) { 227 int i; 228 229 ENV_BITS = ENV_BITS_PARAM; 230 EG_ENT = EG_ENT_PARAM; 231 EG_OFF = ((2 * EG_ENT)<<ENV_BITS); /* OFF */ 232 EG_DED = EG_OFF; 233 EG_DST = (EG_ENT << ENV_BITS); /* DECAY START */ 234 EG_AED = EG_DST; 235 //EG_STEP = (96.0/EG_ENT); 236 237 for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++) 238 KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]); 239 240 for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++) 241 SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]); 242 } 243 244 #undef SC_KSL 245 #undef SC_SL 246 247 /* --------------------- subroutines --------------------- */ 248 249 /* status set and IRQ handling */ 250 inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) { 251 /* set status flag */ 252 OPL->status |= flag; 253 if(!(OPL->status & 0x80)) { 254 if(OPL->status & OPL->statusmask) { /* IRQ on */ 255 OPL->status |= 0x80; 256 /* callback user interrupt handler (IRQ is OFF to ON) */ 257 if(OPL->IRQHandler) 258 (OPL->IRQHandler)(OPL->IRQParam,1); 259 } 260 } 32 OPL *OPL::create(kOplType type) { 33 // return new MAME::OPL_MAME(); 34 return new DOSBox::OPL_DOSBox(type); 261 35 } 262 36 263 /* status reset and IRQ handling */ 264 inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) { 265 /* reset status flag */ 266 OPL->status &= ~flag; 267 if((OPL->status & 0x80)) { 268 if (!(OPL->status & OPL->statusmask)) { 269 OPL->status &= 0x7f; 270 /* callback user interrupt handler (IRQ is ON to OFF) */ 271 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); 272 } 273 } 274 } 275 276 /* IRQ mask set */ 277 inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) { 278 OPL->statusmask = flag; 279 /* IRQ handling check */ 280 OPL_STATUS_SET(OPL,0); 281 OPL_STATUS_RESET(OPL,0); 282 } 283 284 /* ----- key on ----- */ 285 inline void OPL_KEYON(OPL_SLOT *SLOT) { 286 /* sin wave restart */ 287 SLOT->Cnt = 0; 288 /* set attack */ 289 SLOT->evm = ENV_MOD_AR; 290 SLOT->evs = SLOT->evsa; 291 SLOT->evc = EG_AST; 292 SLOT->eve = EG_AED; 293 } 294 295 /* ----- key off ----- */ 296 inline void OPL_KEYOFF(OPL_SLOT *SLOT) { 297 if( SLOT->evm > ENV_MOD_RR) { 298 /* set envelope counter from envleope output */ 299 300 // WORKAROUND: The Kyra engine does something very strange when 301 // starting a new song. For each channel: 302 // 303 // * The release rate is set to "fastest". 304 // * Any note is keyed off. 305 // * A very low-frequency note is keyed on. 306 // 307 // Usually, what happens next is that the real notes is keyed 308 // on immediately, in which case there's no problem. 309 // 310 // However, if the note is again keyed off (because the channel 311 // begins on a rest rather than a note), the envelope counter 312 // was moved from the very lowest point on the attack curve to 313 // the very highest point on the release curve. 314 // 315 // Again, this might not be a problem, if the release rate is 316 // still set to "fastest". But in many cases, it had already 317 // been increased. And, possibly because of inaccuracies in the 318 // envelope generator, that would cause the note to "fade out" 319 // for quite a long time. 320 // 321 // What we really need is a way to find the correct starting 322 // point for the envelope counter, and that may be what the 323 // commented-out line below is meant to do. For now, simply 324 // handle the pathological case. 325 326 if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST) 327 SLOT->evc = EG_DED; 328 else if( !(SLOT->evc & EG_DST) ) 329 //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST; 330 SLOT->evc = EG_DST; 331 SLOT->eve = EG_DED; 332 SLOT->evs = SLOT->evsr; 333 SLOT->evm = ENV_MOD_RR; 334 } 335 } 336 337 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */ 338 339 /* return : envelope output */ 340 inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) { 341 /* calcrate envelope generator */ 342 if((SLOT->evc += SLOT->evs) >= SLOT->eve) { 343 switch( SLOT->evm ) { 344 case ENV_MOD_AR: /* ATTACK -> DECAY1 */ 345 /* next DR */ 346 SLOT->evm = ENV_MOD_DR; 347 SLOT->evc = EG_DST; 348 SLOT->eve = SLOT->SL; 349 SLOT->evs = SLOT->evsd; 350 break; 351 case ENV_MOD_DR: /* DECAY -> SL or RR */ 352 SLOT->evc = SLOT->SL; 353 SLOT->eve = EG_DED; 354 if(SLOT->eg_typ) { 355 SLOT->evs = 0; 356 } else { 357 SLOT->evm = ENV_MOD_RR; 358 SLOT->evs = SLOT->evsr; 359 } 360 break; 361 case ENV_MOD_RR: /* RR -> OFF */ 362 SLOT->evc = EG_OFF; 363 SLOT->eve = EG_OFF + 1; 364 SLOT->evs = 0; 365 break; 366 } 367 } 368 /* calcrate envelope */ 369 return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0); 370 } 371 372 /* set algorythm connection */ 373 static void set_algorythm(OPL_CH *CH) { 374 int *carrier = &outd[0]; 375 CH->connect1 = CH->CON ? carrier : &feedback2; 376 CH->connect2 = carrier; 377 } 378 379 /* ---------- frequency counter for operater update ---------- */ 380 inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) { 381 int ksr; 382 383 /* frequency step counter */ 384 SLOT->Incr = CH->fc * SLOT->mul; 385 ksr = CH->kcode >> SLOT->KSR; 386 387 if( SLOT->ksr != ksr ) { 388 SLOT->ksr = ksr; 389 /* attack , decay rate recalcration */ 390 SLOT->evsa = SLOT->AR[ksr]; 391 SLOT->evsd = SLOT->DR[ksr]; 392 SLOT->evsr = SLOT->RR[ksr]; 393 } 394 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); 395 } 396 397 /* set multi,am,vib,EG-TYP,KSR,mul */ 398 inline void set_mul(FM_OPL *OPL, int slot, int v) { 399 OPL_CH *CH = &OPL->P_CH[slot>>1]; 400 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 401 402 SLOT->mul = MUL_TABLE[v & 0x0f]; 403 SLOT->KSR = (v & 0x10) ? 0 : 2; 404 SLOT->eg_typ = (v & 0x20) >> 5; 405 SLOT->vib = (v & 0x40); 406 SLOT->ams = (v & 0x80); 407 CALC_FCSLOT(CH, SLOT); 408 } 409 410 /* set ksl & tl */ 411 inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) { 412 OPL_CH *CH = &OPL->P_CH[slot>>1]; 413 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 414 int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */ 415 416 SLOT->ksl = ksl ? 3-ksl : 31; 417 SLOT->TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */ 418 419 if(!(OPL->mode & 0x80)) { /* not CSM latch total level */ 420 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl); 421 } 422 } 423 424 /* set attack rate & decay rate */ 425 inline void set_ar_dr(FM_OPL *OPL, int slot, int v) { 426 OPL_CH *CH = &OPL->P_CH[slot>>1]; 427 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 428 int ar = v >> 4; 429 int dr = v & 0x0f; 430 431 SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0; 432 SLOT->evsa = SLOT->AR[SLOT->ksr]; 433 if(SLOT->evm == ENV_MOD_AR) 434 SLOT->evs = SLOT->evsa; 435 436 SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0; 437 SLOT->evsd = SLOT->DR[SLOT->ksr]; 438 if(SLOT->evm == ENV_MOD_DR) 439 SLOT->evs = SLOT->evsd; 440 } 441 442 /* set sustain level & release rate */ 443 inline void set_sl_rr(FM_OPL *OPL, int slot, int v) { 444 OPL_CH *CH = &OPL->P_CH[slot>>1]; 445 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 446 int sl = v >> 4; 447 int rr = v & 0x0f; 448 449 SLOT->SL = SL_TABLE[sl]; 450 if(SLOT->evm == ENV_MOD_DR) 451 SLOT->eve = SLOT->SL; 452 SLOT->RR = &OPL->DR_TABLE[rr<<2]; 453 SLOT->evsr = SLOT->RR[SLOT->ksr]; 454 if(SLOT->evm == ENV_MOD_RR) 455 SLOT->evs = SLOT->evsr; 456 } 457 458 /* operator output calcrator */ 459 460 #define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env] 461 /* ---------- calcrate one of channel ---------- */ 462 inline void OPL_CALC_CH(OPL_CH *CH) { 463 uint env_out; 464 OPL_SLOT *SLOT; 465 466 feedback2 = 0; 467 /* SLOT 1 */ 468 SLOT = &CH->SLOT[SLOT1]; 469 env_out=OPL_CALC_SLOT(SLOT); 470 if(env_out < (uint)(EG_ENT - 1)) { 471 /* PG */ 472 if(SLOT->vib) 473 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 474 else 475 SLOT->Cnt += SLOT->Incr; 476 /* connection */ 477 if(CH->FB) { 478 int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB; 479 CH->op1_out[1] = CH->op1_out[0]; 480 *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1); 481 } else { 482 *CH->connect1 += OP_OUT(SLOT, env_out, 0); 483 } 484 } else { 485 CH->op1_out[1] = CH->op1_out[0]; 486 CH->op1_out[0] = 0; 487 } 488 /* SLOT 2 */ 489 SLOT = &CH->SLOT[SLOT2]; 490 env_out=OPL_CALC_SLOT(SLOT); 491 if(env_out < (uint)(EG_ENT - 1)) { 492 /* PG */ 493 if(SLOT->vib) 494 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 495 else 496 SLOT->Cnt += SLOT->Incr; 497 /* connection */ 498 outd[0] += OP_OUT(SLOT, env_out, feedback2); 499 } 500 } 501 502 /* ---------- calcrate rythm block ---------- */ 503 #define WHITE_NOISE_db 6.0 504 inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) { 505 uint env_tam, env_sd, env_top, env_hh; 506 // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)), 507 // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to 508 // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024, 509 // or 128, so we can safely avoid any FP ops. 510 int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4); 511 512 int tone8; 37 } // end of namespace OPL 513 38 514 OPL_SLOT *SLOT; 515 int env_out; 516 517 /* BD : same as FM serial mode and output level is large */ 518 feedback2 = 0; 519 /* SLOT 1 */ 520 SLOT = &CH[6].SLOT[SLOT1]; 521 env_out = OPL_CALC_SLOT(SLOT); 522 if(env_out < EG_ENT-1) { 523 /* PG */ 524 if(SLOT->vib) 525 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 526 else 527 SLOT->Cnt += SLOT->Incr; 528 /* connection */ 529 if(CH[6].FB) { 530 int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB; 531 CH[6].op1_out[1] = CH[6].op1_out[0]; 532 feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1); 533 } 534 else { 535 feedback2 = OP_OUT(SLOT, env_out, 0); 536 } 537 } else { 538 feedback2 = 0; 539 CH[6].op1_out[1] = CH[6].op1_out[0]; 540 CH[6].op1_out[0] = 0; 541 } 542 /* SLOT 2 */ 543 SLOT = &CH[6].SLOT[SLOT2]; 544 env_out = OPL_CALC_SLOT(SLOT); 545 if(env_out < EG_ENT-1) { 546 /* PG */ 547 if(SLOT->vib) 548 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 549 else 550 SLOT->Cnt += SLOT->Incr; 551 /* connection */ 552 outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2; 553 } 554 555 // SD (17) = mul14[fnum7] + white noise 556 // TAM (15) = mul15[fnum8] 557 // TOP (18) = fnum6(mul18[fnum8]+whitenoise) 558 // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise 559 env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise; 560 env_tam =OPL_CALC_SLOT(SLOT8_1); 561 env_top = OPL_CALC_SLOT(SLOT8_2); 562 env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise; 563 564 /* PG */ 565 if(SLOT7_1->vib) 566 SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1); 567 else 568 SLOT7_1->Cnt += 2 * SLOT7_1->Incr; 569 if(SLOT7_2->vib) 570 SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3); 571 else 572 SLOT7_2->Cnt += (CH[7].fc * 8); 573 if(SLOT8_1->vib) 574 SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT; 575 else 576 SLOT8_1->Cnt += SLOT8_1->Incr; 577 if(SLOT8_2->vib) 578 SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4); 579 else 580 SLOT8_2->Cnt += (CH[8].fc * 48); 581 582 tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); 583 584 /* SD */ 585 if(env_sd < (uint)(EG_ENT - 1)) 586 outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8; 587 /* TAM */ 588 if(env_tam < (uint)(EG_ENT - 1)) 589 outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2; 590 /* TOP-CY */ 591 if(env_top < (uint)(EG_ENT - 1)) 592 outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2; 593 /* HH */ 594 if(env_hh < (uint)(EG_ENT-1)) 595 outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2; 596 } 597 598 /* ----------- initialize time tabls ----------- */ 599 static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) { 600 int i; 601 double rate; 602 603 /* make attack rate & decay rate tables */ 604 for (i = 0; i < 4; i++) 605 OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; 606 for (i = 4; i <= 60; i++) { 607 rate = OPL->freqbase; /* frequency rate */ 608 if(i < 60) 609 rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ 610 rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */ 611 rate *= (double)(EG_ENT << ENV_BITS); 612 OPL->AR_TABLE[i] = (int)(rate / ARRATE); 613 OPL->DR_TABLE[i] = (int)(rate / DRRATE); 614 } 615 for (i = 60; i < 76; i++) { 616 OPL->AR_TABLE[i] = EG_AED-1; 617 OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; 618 } 619 } 620 621 /* ---------- generic table initialize ---------- */ 622 static int OPLOpenTable(void) { 623 int s,t; 624 double rate; 625 int i,j; 626 double pom; 627 628 #ifdef __DS__ 629 DS::fastRamReset(); 630 631 TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *)); 632 SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *)); 633 #else 634 635 /* allocate dynamic tables */ 636 if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL) 637 return 0; 638 639 if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) { 640 free(TL_TABLE); 641 return 0; 642 } 643 #endif 644 645 if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) { 646 free(TL_TABLE); 647 free(SIN_TABLE); 648 return 0; 649 } 650 651 if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) { 652 free(TL_TABLE); 653 free(SIN_TABLE); 654 free(AMS_TABLE); 655 return 0; 656 } 657 /* make total level table */ 658 for (t = 0; t < EG_ENT - 1 ; t++) { 659 rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */ 660 TL_TABLE[ t] = (int)rate; 661 TL_TABLE[TL_MAX + t] = -TL_TABLE[t]; 662 } 663 /* fill volume off area */ 664 for (t = EG_ENT - 1; t < TL_MAX; t++) { 665 TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0; 666 } 667 668 /* make sinwave table (total level offet) */ 669 /* degree 0 = degree 180 = off */ 670 SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1]; 671 for (s = 1;s <= SIN_ENT / 4; s++) { 672 pom = sin(2 * PI * s / SIN_ENT); /* sin */ 673 pom = 20 * log10(1 / pom); /* decibel */ 674 j = int(pom / EG_STEP); /* TL_TABLE steps */ 675 676 /* degree 0 - 90 , degree 180 - 90 : plus section */ 677 SIN_TABLE[ s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j]; 678 /* degree 180 - 270 , degree 360 - 270 : minus section */ 679 SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j]; 680 } 681 for (s = 0;s < SIN_ENT; s++) { 682 SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; 683 SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)]; 684 SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s]; 685 } 686 687 688 ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1)); 689 690 /* envelope counter -> envelope output table */ 691 for (i=0; i < EG_ENT; i++) { 692 /* ATTACK curve */ 693 pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT; 694 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */ 695 ENV_CURVE[i] = (int)pom; 696 /* DECAY ,RELEASE curve */ 697 ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i; 698 } 699 /* off */ 700 ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1; 701 /* make LFO ams table */ 702 for (i=0; i < AMS_ENT; i++) { 703 pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */ 704 AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */ 705 AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */ 706 } 707 /* make LFO vibrate table */ 708 for (i=0; i < VIB_ENT; i++) { 709 /* 100cent = 1seminote = 6% ?? */ 710 pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */ 711 VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */ 712 VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */ 713 } 714 return 1; 39 void OPLDestroy(FM_OPL *OPL) { 40 delete OPL; 715 41 } 716 42 717 static void OPLCloseTable(void) { 718 free(TL_TABLE); 719 free(SIN_TABLE); 720 free(AMS_TABLE); 721 free(VIB_TABLE); 722 free(ENV_CURVE); 43 void OPLResetChip(FM_OPL *OPL) { 44 OPL->reset(); 723 45 } 724 46 725 /* CSM Key Controll */ 726 inline void CSMKeyControll(OPL_CH *CH) { 727 OPL_SLOT *slot1 = &CH->SLOT[SLOT1]; 728 OPL_SLOT *slot2 = &CH->SLOT[SLOT2]; 729 /* all key off */ 730 OPL_KEYOFF(slot1); 731 OPL_KEYOFF(slot2); 732 /* total level latch */ 733 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); 734 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); 735 /* key on */ 736 CH->op1_out[0] = CH->op1_out[1] = 0; 737 OPL_KEYON(slot1); 738 OPL_KEYON(slot2); 47 void OPLWrite(FM_OPL *OPL, int a, int v) { 48 OPL->write(a, v); 739 49 } 740 50 741 /* ---------- opl initialize ---------- */ 742 static void OPL_initalize(FM_OPL *OPL) { 743 int fn; 744 745 /* frequency base */ 746 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0; 747 /* Timer base time */ 748 OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 ); 749 /* make time tables */ 750 init_timetables(OPL, OPL_ARRATE, OPL_DRRATE); 751 /* make fnumber -> increment counter table */ 752 for( fn=0; fn < 1024; fn++) { 753 OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2); 754 } 755 /* LFO freq.table */ 756 OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0); 757 OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0); 51 unsigned char OPLRead(FM_OPL *OPL, int a) { 52 return OPL->read(a); 758 53 } 759 54 760 /* ---------- write a OPL registers ---------- */761 55 void OPLWriteReg(FM_OPL *OPL, int r, int v) { 762 OPL_CH *CH; 763 int slot; 764 uint block_fnum; 765 766 switch(r & 0xe0) { 767 case 0x00: /* 00-1f:controll */ 768 switch(r & 0x1f) { 769 case 0x01: 770 /* wave selector enable */ 771 if(OPL->type&OPL_TYPE_WAVESEL) { 772 OPL->wavesel = v & 0x20; 773 if(!OPL->wavesel) { 774 /* preset compatible mode */ 775 int c; 776 for(c=0; c<OPL->max_ch; c++) { 777 OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; 778 OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; 779 } 780 } 781 } 782 return; 783 case 0x02: /* Timer 1 */ 784 OPL->T[0] = (256-v) * 4; 785 break; 786 case 0x03: /* Timer 2 */ 787 OPL->T[1] = (256-v) * 16; 788 return; 789 case 0x04: /* IRQ clear / mask and Timer enable */ 790 if(v & 0x80) { /* IRQ flag clear */ 791 OPL_STATUS_RESET(OPL, 0x7f); 792 } else { /* set IRQ mask ,timer enable*/ 793 uint8 st1 = v & 1; 794 uint8 st2 = (v >> 1) & 1; 795 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ 796 OPL_STATUS_RESET(OPL, v & 0x78); 797 OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01); 798 /* timer 2 */ 799 if(OPL->st[1] != st2) { 800 double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0; 801 OPL->st[1] = st2; 802 if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval); 803 } 804 /* timer 1 */ 805 if(OPL->st[0] != st1) { 806 double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0; 807 OPL->st[0] = st1; 808 if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval); 809 } 810 } 811 return; 812 } 813 break; 814 case 0x20: /* am,vib,ksr,eg type,mul */ 815 slot = slot_array[r&0x1f]; 816 if(slot == -1) 817 return; 818 set_mul(OPL,slot,v); 819 return; 820 case 0x40: 821 slot = slot_array[r&0x1f]; 822 if(slot == -1) 823 return; 824 set_ksl_tl(OPL,slot,v); 825 return; 826 case 0x60: 827 slot = slot_array[r&0x1f]; 828 if(slot == -1) 829 return; 830 set_ar_dr(OPL,slot,v); 831 return; 832 case 0x80: 833 slot = slot_array[r&0x1f]; 834 if(slot == -1) 835 return; 836 set_sl_rr(OPL,slot,v); 837 return; 838 case 0xa0: 839 switch(r) { 840 case 0xbd: 841 /* amsep,vibdep,r,bd,sd,tom,tc,hh */ 842 { 843 uint8 rkey = OPL->rythm ^ v; 844 OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0]; 845 OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0]; 846 OPL->rythm = v & 0x3f; 847 if(OPL->rythm & 0x20) { 848 /* BD key on/off */ 849 if(rkey & 0x10) { 850 if(v & 0x10) { 851 OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; 852 OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); 853 OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); 854 } else { 855 OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); 856 OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); 857 } 858 } 859 /* SD key on/off */ 860 if(rkey & 0x08) { 861 if(v & 0x08) 862 OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); 863 else 864 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); 865 }/* TAM key on/off */ 866 if(rkey & 0x04) { 867 if(v & 0x04) 868 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); 869 else 870 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); 871 } 872 /* TOP-CY key on/off */ 873 if(rkey & 0x02) { 874 if(v & 0x02) 875 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); 876 else 877 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); 878 } 879 /* HH key on/off */ 880 if(rkey & 0x01) { 881 if(v & 0x01) 882 OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); 883 else 884 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); 885 } 886 } 887 } 888 return; 889 890 default: 891 break; 892 } 893 /* keyon,block,fnum */ 894 if((r & 0x0f) > 8) 895 return; 896 CH = &OPL->P_CH[r & 0x0f]; 897 if(!(r&0x10)) { /* a0-a8 */ 898 block_fnum = (CH->block_fnum & 0x1f00) | v; 899 } else { /* b0-b8 */ 900 int keyon = (v >> 5) & 1; 901 block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff); 902 if(CH->keyon != keyon) { 903 if((CH->keyon=keyon)) { 904 CH->op1_out[0] = CH->op1_out[1] = 0; 905 OPL_KEYON(&CH->SLOT[SLOT1]); 906 OPL_KEYON(&CH->SLOT[SLOT2]); 907 } else { 908 OPL_KEYOFF(&CH->SLOT[SLOT1]); 909 OPL_KEYOFF(&CH->SLOT[SLOT2]); 910 } 911 } 912 } 913 /* update */ 914 if(CH->block_fnum != block_fnum) { 915 int blockRv = 7 - (block_fnum >> 10); 916 int fnum = block_fnum & 0x3ff; 917 CH->block_fnum = block_fnum; 918 CH->ksl_base = KSL_TABLE[block_fnum >> 6]; 919 CH->fc = OPL->FN_TABLE[fnum] >> blockRv; 920 CH->kcode = CH->block_fnum >> 9; 921 if((OPL->mode & 0x40) && CH->block_fnum & 0x100) 922 CH->kcode |=1; 923 CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); 924 CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); 925 } 926 return; 927 case 0xc0: 928 /* FB,C */ 929 if((r & 0x0f) > 8) 930 return; 931 CH = &OPL->P_CH[r&0x0f]; 932 { 933 int feedback = (v >> 1) & 7; 934 CH->FB = feedback ? (8 + 1) - feedback : 0; 935 CH->CON = v & 1; 936 set_algorythm(CH); 937 } 938 return; 939 case 0xe0: /* wave type */ 940 slot = slot_array[r & 0x1f]; 941 if(slot == -1) 942 return; 943 CH = &OPL->P_CH[slot>>1]; 944 if(OPL->wavesel) { 945 CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT]; 946 } 947 return; 948 } 949 } 950 951 /* lock/unlock for common table */ 952 static int OPL_LockTable(void) { 953 num_lock++; 954 if(num_lock>1) 955 return 0; 956 /* first time */ 957 cur_chip = NULL; 958 /* allocate total level table (128kb space) */ 959 if(!OPLOpenTable()) { 960 num_lock--; 961 return -1; 962 } 963 return 0; 56 OPL->writeReg(r, v); 964 57 } 965 58 966 static void OPL_UnLockTable(void) { 967 if(num_lock) 968 num_lock--; 969 if(num_lock) 970 return; 971 /* last time */ 972 cur_chip = NULL; 973 OPLCloseTable(); 974 } 975 976 /*******************************************************************************/ 977 /* YM3812 local section */ 978 /*******************************************************************************/ 979 980 /* ---------- update one of chip ----------- */ 981 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave) { 982 int i; 983 int data; 984 int16 *buf = buffer; 985 uint amsCnt = OPL->amsCnt; 986 uint vibCnt = OPL->vibCnt; 987 uint8 rythm = OPL->rythm & 0x20; 988 OPL_CH *CH, *R_CH; 989 990 991 if((void *)OPL != cur_chip) { 992 cur_chip = (void *)OPL; 993 /* channel pointers */ 994 S_CH = OPL->P_CH; 995 E_CH = &S_CH[9]; 996 /* rythm slot */ 997 SLOT7_1 = &S_CH[7].SLOT[SLOT1]; 998 SLOT7_2 = &S_CH[7].SLOT[SLOT2]; 999 SLOT8_1 = &S_CH[8].SLOT[SLOT1]; 1000 SLOT8_2 = &S_CH[8].SLOT[SLOT2]; 1001 /* LFO state */ 1002 amsIncr = OPL->amsIncr; 1003 vibIncr = OPL->vibIncr; 1004 ams_table = OPL->ams_table; 1005 vib_table = OPL->vib_table; 1006 } 1007 R_CH = rythm ? &S_CH[6] : E_CH; 1008 for(i = 0; i < length; i++) { 1009 /* channel A channel B channel C */ 1010 /* LFO */ 1011 ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT]; 1012 vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT]; 1013 outd[0] = 0; 1014 /* FM part */ 1015 for(CH=S_CH; CH < R_CH; CH++) 1016 OPL_CALC_CH(CH); 1017 /* Rythn part */ 1018 if(rythm) 1019 OPL_CALC_RH(OPL, S_CH); 1020 /* limit check */ 1021 data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT); 1022 /* store to sound buffer */ 1023 buf[i << interleave] = data >> OPL_OUTSB; 1024 } 1025 1026 OPL->amsCnt = amsCnt; 1027 OPL->vibCnt = vibCnt; 59 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) { 60 OPL->readBuffer(buffer, length); 1028 61 } 1029 62 1030 /* ---------- reset a chip ---------- */ 1031 void OPLResetChip(FM_OPL *OPL) { 1032 int c,s; 1033 int i; 63 // Factory method 64 FM_OPL *makeAdlibOPL(int rate) { 65 FM_OPL *opl = OPL::OPL::create(); 1034 66 1035 /* reset chip */ 1036 OPL->mode = 0; /* normal mode */ 1037 OPL_STATUS_RESET(OPL, 0x7f); 1038 /* reset with register write */ 1039 OPLWriteReg(OPL, 0x01,0); /* wabesel disable */ 1040 OPLWriteReg(OPL, 0x02,0); /* Timer1 */ 1041 OPLWriteReg(OPL, 0x03,0); /* Timer2 */ 1042 OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */ 1043 for(i = 0xff; i >= 0x20; i--) 1044 OPLWriteReg(OPL,i,0); 1045 /* reset OPerator parameter */ 1046 for(c = 0; c < OPL->max_ch ;c++ ) { 1047 OPL_CH *CH = &OPL->P_CH[c]; 1048 /* OPL->P_CH[c].PAN = OPN_CENTER; */ 1049 for(s = 0; s < 2; s++ ) { 1050 /* wave table */ 1051 CH->SLOT[s].wavetable = &SIN_TABLE[0]; 1052 /* CH->SLOT[s].evm = ENV_MOD_RR; */ 1053 CH->SLOT[s].evc = EG_OFF; 1054 CH->SLOT[s].eve = EG_OFF + 1; 1055 CH->SLOT[s].evs = 0; 67 if (opl) { 68 if (!opl->init(rate)) { 69 delete opl; 70 opl = 0; 1056 71 } 1057 72 } 1058 }1059 1060 /* ---------- Create a virtual YM3812 ---------- */1061 /* 'rate' is sampling rate and 'bufsiz' is the size of the */1062 FM_OPL *OPLCreate(int type, int clock, int rate) {1063 char *ptr;1064 FM_OPL *OPL;1065 int state_size;1066 int max_ch = 9; /* normaly 9 channels */1067 73 1068 if( OPL_LockTable() == -1) 1069 return NULL; 1070 /* allocate OPL state space */ 1071 state_size = sizeof(FM_OPL); 1072 state_size += sizeof(OPL_CH) * max_ch; 1073 1074 /* allocate memory block */ 1075 ptr = (char *)calloc(state_size, 1); 1076 if(ptr == NULL) 1077 return NULL; 1078 1079 /* clear */ 1080 memset(ptr, 0, state_size); 1081 OPL = (FM_OPL *)ptr; ptr += sizeof(FM_OPL); 1082 OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch; 1083 1084 /* set channel state pointer */ 1085 OPL->type = type; 1086 OPL->clock = clock; 1087 OPL->rate = rate; 1088 OPL->max_ch = max_ch; 1089 1090 /* init grobal tables */ 1091 OPL_initalize(OPL); 1092 1093 /* reset chip */ 1094 OPLResetChip(OPL); 1095 return OPL; 74 return opl; 1096 75 } 1097 76 1098 /* ---------- Destroy one of vietual YM3812 ---------- */1099 void OPLDestroy(FM_OPL *OPL) {1100 OPL_UnLockTable();1101 free(OPL);1102 }1103 1104 /* ---------- Option handlers ---------- */1105 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {1106 OPL->TimerHandler = TimerHandler;1107 OPL->TimerParam = channelOffset;1108 }1109 1110 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {1111 OPL->IRQHandler = IRQHandler;1112 OPL->IRQParam = param;1113 }1114 1115 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {1116 OPL->UpdateHandler = UpdateHandler;1117 OPL->UpdateParam = param;1118 }1119 1120 /* ---------- YM3812 I/O interface ---------- */1121 int OPLWrite(FM_OPL *OPL,int a,int v) {1122 if(!(a & 1)) { /* address port */1123 OPL->address = v & 0xff;1124 } else { /* data port */1125 if(OPL->UpdateHandler)1126 OPL->UpdateHandler(OPL->UpdateParam,0);1127 OPLWriteReg(OPL, OPL->address,v);1128 }1129 return OPL->status >> 7;1130 }1131 1132 unsigned char OPLRead(FM_OPL *OPL,int a) {1133 if(!(a & 1)) { /* status port */1134 return OPL->status & (OPL->statusmask | 0x80);1135 }1136 /* data port */1137 switch(OPL->address) {1138 case 0x05: /* KeyBoard IN */1139 warning("OPL:read unmapped KEYBOARD port\n");1140 return 0;1141 case 0x19: /* I/O DATA */1142 warning("OPL:read unmapped I/O port\n");1143 return 0;1144 case 0x1a: /* PCM-DATA */1145 return 0;1146 default:1147 break;1148 }1149 return 0;1150 }1151 1152 int OPLTimerOver(FM_OPL *OPL, int c) {1153 if(c) { /* Timer B */1154 OPL_STATUS_SET(OPL, 0x20);1155 } else { /* Timer A */1156 OPL_STATUS_SET(OPL, 0x40);1157 /* CSM mode key,TL controll */1158 if(OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */1159 int ch;1160 if(OPL->UpdateHandler)1161 OPL->UpdateHandler(OPL->UpdateParam,0);1162 for(ch = 0; ch < 9; ch++)1163 CSMKeyControll(&OPL->P_CH[ch]);1164 }1165 }1166 /* reload timer */1167 if (OPL->TimerHandler)1168 (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);1169 return OPL->status >> 7;1170 }1171 1172 FM_OPL *makeAdlibOPL(int rate) {1173 // We need to emulate one YM3812 chip1174 int env_bits = FMOPL_ENV_BITS_HQ;1175 int eg_ent = FMOPL_EG_ENT_HQ;1176 #if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__)1177 if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {1178 env_bits = FMOPL_ENV_BITS_HQ;1179 eg_ent = FMOPL_EG_ENT_HQ;1180 } else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) {1181 env_bits = FMOPL_ENV_BITS_MQ;1182 eg_ent = FMOPL_EG_ENT_MQ;1183 } else {1184 env_bits = FMOPL_ENV_BITS_LQ;1185 eg_ent = FMOPL_EG_ENT_LQ;1186 }1187 #endif1188 1189 OPLBuildTables(env_bits, eg_ent);1190 return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);1191 } -
sound/softsynth/opl/dosbox.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 /* 26 * Based on AdLib emulation code of DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * Licensed under GPLv2+ 29 * http://www.dosbox.com 30 */ 31 32 #ifndef DISABLE_DOSBOX_OPL 33 34 #include "dosbox.h" 35 #include "dbopl.h" 36 37 #include "common/system.h" 38 39 #include <math.h> 40 #include <string.h> 41 42 namespace OPL { 43 namespace DOSBox { 44 45 Timer::Timer() { 46 masked = false; 47 overflow = false; 48 enabled = false; 49 counter = 0; 50 delay = 0; 51 } 52 53 void Timer::update(double time) { 54 if (!enabled || !delay) 55 return; 56 double deltaStart = time - startTime; 57 // Only set the overflow flag when not masked 58 if (deltaStart >= 0 && !masked) 59 overflow = 1; 60 } 61 62 void Timer::reset(double time) { 63 overflow = false; 64 if (!delay || !enabled) 65 return; 66 double delta = (time - startTime); 67 double rem = fmod(delta, delay); 68 double next = delay - rem; 69 startTime = time + next; 70 } 71 72 void Timer::stop() { 73 enabled = false; 74 } 75 76 void Timer::start(double time, int scale) { 77 //Don't enable again 78 if (enabled) 79 return; 80 enabled = true; 81 delay = 0.001 * (256 - counter) * scale; 82 startTime = time + delay; 83 } 84 85 bool Chip::write(uint32 reg, uint8 val) { 86 switch (reg) { 87 case 0x02: 88 timer[0].counter = val; 89 return true; 90 case 0x03: 91 timer[1].counter = val; 92 return true; 93 case 0x04: 94 // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess 95 // it should be like this... 96 double time = g_system->getMillis() / 1000.0; 97 98 if (val & 0x80) { 99 timer[0].reset(time); 100 timer[1].reset(time); 101 } else { 102 timer[0].update(time); 103 timer[1].update(time); 104 105 if (val & 0x1) 106 timer[0].start(time, 80); 107 else 108 timer[0].stop(); 109 110 timer[0].masked = (val & 0x40) > 0; 111 112 if (timer[0].masked) 113 timer[0].overflow = false; 114 115 if (val & 0x2) 116 timer[1].start(time, 320); 117 else 118 timer[1].stop(); 119 120 timer[1].masked = (val & 0x20) > 0; 121 122 if (timer[1].masked) 123 timer[1].overflow = false; 124 } 125 return true; 126 } 127 return false; 128 } 129 130 uint8 Chip::read() { 131 // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess 132 // it should be like this... 133 double time = g_system->getMillis() / 1000.0; 134 135 timer[0].update(time); 136 timer[1].update(time); 137 138 uint8 ret = 0; 139 //Overflow won't be set if a channel is masked 140 if (timer[0].overflow) { 141 ret |= 0x40; 142 ret |= 0x80; 143 } 144 if (timer[1].overflow) { 145 ret |= 0x20; 146 ret |= 0x80; 147 } 148 return ret; 149 } 150 151 OPL_DOSBox::OPL_DOSBox(kOplType type) : _type(type), _rate(0), _handler(0) { 152 } 153 154 OPL_DOSBox::~OPL_DOSBox() { 155 free(); 156 } 157 158 void OPL_DOSBox::free() { 159 delete _handler; 160 _handler = 0; 161 } 162 163 bool OPL_DOSBox::init(int rate) { 164 free(); 165 166 _reg.dual[0] = 0; 167 _reg.dual[1] = 0; 168 _reg.normal = 0; 169 170 memset(_chip, 0, sizeof(_chip)); 171 switch (_type) { 172 case kOpl2: 173 _handler = new DBOPL::Handler(); 174 break; 175 176 default: 177 return false; 178 } 179 180 _handler->init(rate); 181 _rate = rate; 182 return true; 183 } 184 185 void OPL_DOSBox::reset() { 186 // TODO: Find a nicer way to reset the emulator 187 init(_rate); 188 } 189 190 void OPL_DOSBox::write(int port, int val) { 191 if (port&1) { 192 switch (_type) { 193 case kOpl2: 194 //case kOpl3: 195 if (!_chip[0].write(_reg.normal, val)) 196 _handler->writeReg(_reg.normal, val); 197 break; 198 /*case kDualOpl2: 199 // Not a 0x??8 port, then write to a specific port 200 if (!(port & 0x8)) { 201 byte index = (port & 2) >> 1; 202 dualWrite(index, _reg.dual[index], val); 203 } else { 204 //Write to both ports 205 dualWrite(0, _reg.dual[0], val); 206 dualWrite(1, _reg.dual[1], val); 207 } 208 break;*/ 209 } 210 } else { 211 // Ask the handler to write the address 212 // Make sure to clip them in the right range 213 switch (_type) { 214 case kOpl2: 215 _reg.normal = _handler->writeAddr(port, val) & 0xff; 216 break; 217 /*case kOpl3: 218 _reg.normal = _handler->writeAddr(port, val) & 0x1ff; 219 break; 220 case kDualOpl2: 221 // Not a 0x?88 port, when write to a specific side 222 if (!(port & 0x8)) { 223 byte index = (port & 2) >> 1; 224 _reg.dual[index] = val & 0xff; 225 } else { 226 _reg.dual[0] = val & 0xff; 227 _reg.dual[1] = val & 0xff; 228 } 229 break;*/ 230 } 231 } 232 } 233 234 byte OPL_DOSBox::read(int port) { 235 switch (_type) { 236 case kOpl2: 237 if (!(port & 1)) 238 //Make sure the low bits are 6 on opl2 239 return _chip[0].read() | 0x6; 240 break; 241 /*case kOpl3: 242 if (!(port & 1)) 243 return _chip[0].read(); 244 break; 245 case kDualOpl2: 246 // Only return for the lower ports 247 if (port & 1) 248 return 0xff; 249 // Make sure the low bits are 6 on opl2 250 return _chip[(port >> 1) & 1].read() | 0x6;*/ 251 } 252 return 0; 253 } 254 255 void OPL_DOSBox::writeReg(int r, int v) { 256 byte tempReg = 0; 257 switch (_type) { 258 case kOpl2: 259 //case kOpl3: 260 // We can't use _handler->writeReg here directly, since it would miss timer changes. 261 262 // Backup old setup register 263 tempReg = _reg.normal; 264 265 // We need to set the register we want to write to via port 0x388 266 write(0x388, r); 267 // Do the real writing to the register 268 write(0x389, v); 269 // Restore the old register 270 write(0x388, tempReg); 271 break; 272 273 //case kDualOpl2: 274 // error("Can't use OPL_DOSBox::writeReg on Dual OPL2"); 275 // break; 276 }; 277 } 278 279 void OPL_DOSBox::readBuffer(int16 *buffer, int length) { 280 // For stereo OPL cards, we divide the sample count by 2, 281 // to match stereo AudioStream behavior. 282 if (_type != kOpl2) 283 length >>= 1; 284 285 _handler->generate(buffer, length); 286 } 287 288 } // end of namespace DOSBox 289 } // end of namespace OPL 290 291 #endif // !DISABLE_DOSBOX_ADLIB -
sound/softsynth/opl/mame.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.cpp $ 22 * $Id: fmopl.cpp 38211 2009-02-15 10:07:50Z sev $ 23 * 24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by 25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug. 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <stdarg.h> 32 #include <math.h> 33 34 #include "mame.h" 35 36 #if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) 37 #include "common/config-manager.h" 38 #endif 39 40 namespace OPL { 41 namespace MAME { 42 43 OPL_MAME::~OPL_MAME() { 44 MAME::OPLDestroy(_opl); 45 _opl = 0; 46 } 47 48 bool OPL_MAME::init(int rate) { 49 if (_opl) 50 MAME::OPLDestroy(_opl); 51 52 _opl = MAME::makeAdlibOPL(rate); 53 return (_opl != 0); 54 } 55 56 void OPL_MAME::reset() { 57 MAME::OPLResetChip(_opl); 58 } 59 60 void OPL_MAME::write(int a, int v) { 61 MAME::OPLWrite(_opl, a, v); 62 } 63 64 byte OPL_MAME::read(int a) { 65 return MAME::OPLRead(_opl, a); 66 } 67 68 void OPL_MAME::writeReg(int r, int v) { 69 MAME::OPLWriteReg(_opl, r, v); 70 } 71 72 void OPL_MAME::readBuffer(int16 *buffer, int length) { 73 MAME::YM3812UpdateOne(_opl, buffer, length); 74 } 75 76 /* -------------------- preliminary define section --------------------- */ 77 /* attack/decay rate time rate */ 78 #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ 79 #define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ 80 81 #define FREQ_BITS 24 /* frequency turn */ 82 83 /* counter bits = 20 , octerve 7 */ 84 #define FREQ_RATE (1<<(FREQ_BITS-20)) 85 #define TL_BITS (FREQ_BITS+2) 86 87 /* final output shift , limit minimum and maximum */ 88 #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ 89 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB) 90 #define OPL_MINOUT (-0x8000<<OPL_OUTSB) 91 92 /* -------------------- quality selection --------------------- */ 93 94 /* sinwave entries */ 95 /* used static memory = SIN_ENT * 4 (byte) */ 96 #ifdef __DS__ 97 #include "dsmain.h" 98 #define SIN_ENT_SHIFT 8 99 #else 100 #define SIN_ENT_SHIFT 11 101 #endif 102 #define SIN_ENT (1<<SIN_ENT_SHIFT) 103 104 /* output level entries (envelope,sinwave) */ 105 /* envelope counter lower bits */ 106 int ENV_BITS; 107 /* envelope output entries */ 108 int EG_ENT; 109 110 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */ 111 /* used static memory = EG_ENT*4 (byte) */ 112 int EG_OFF; /* OFF */ 113 int EG_DED; 114 int EG_DST; /* DECAY START */ 115 int EG_AED; 116 #define EG_AST 0 /* ATTACK START */ 117 118 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */ 119 120 /* LFO table entries */ 121 #define VIB_ENT 512 122 #define VIB_SHIFT (32-9) 123 #define AMS_ENT 512 124 #define AMS_SHIFT (32-9) 125 126 #define VIB_RATE_SHIFT 8 127 #define VIB_RATE (1<<VIB_RATE_SHIFT) 128 129 /* -------------------- local defines , macros --------------------- */ 130 131 /* register number to channel number , slot offset */ 132 #define SLOT1 0 133 #define SLOT2 1 134 135 /* envelope phase */ 136 #define ENV_MOD_RR 0x00 137 #define ENV_MOD_DR 0x01 138 #define ENV_MOD_AR 0x02 139 140 /* -------------------- tables --------------------- */ 141 static const int slot_array[32] = { 142 0, 2, 4, 1, 3, 5,-1,-1, 143 6, 8,10, 7, 9,11,-1,-1, 144 12,14,16,13,15,17,-1,-1, 145 -1,-1,-1,-1,-1,-1,-1,-1 146 }; 147 148 static uint KSL_TABLE[8 * 16]; 149 150 static const double KSL_TABLE_SEED[8 * 16] = { 151 /* OCT 0 */ 152 0.000, 0.000, 0.000, 0.000, 153 0.000, 0.000, 0.000, 0.000, 154 0.000, 0.000, 0.000, 0.000, 155 0.000, 0.000, 0.000, 0.000, 156 /* OCT 1 */ 157 0.000, 0.000, 0.000, 0.000, 158 0.000, 0.000, 0.000, 0.000, 159 0.000, 0.750, 1.125, 1.500, 160 1.875, 2.250, 2.625, 3.000, 161 /* OCT 2 */ 162 0.000, 0.000, 0.000, 0.000, 163 0.000, 1.125, 1.875, 2.625, 164 3.000, 3.750, 4.125, 4.500, 165 4.875, 5.250, 5.625, 6.000, 166 /* OCT 3 */ 167 0.000, 0.000, 0.000, 1.875, 168 3.000, 4.125, 4.875, 5.625, 169 6.000, 6.750, 7.125, 7.500, 170 7.875, 8.250, 8.625, 9.000, 171 /* OCT 4 */ 172 0.000, 0.000, 3.000, 4.875, 173 6.000, 7.125, 7.875, 8.625, 174 9.000, 9.750, 10.125, 10.500, 175 10.875, 11.250, 11.625, 12.000, 176 /* OCT 5 */ 177 0.000, 3.000, 6.000, 7.875, 178 9.000, 10.125, 10.875, 11.625, 179 12.000, 12.750, 13.125, 13.500, 180 13.875, 14.250, 14.625, 15.000, 181 /* OCT 6 */ 182 0.000, 6.000, 9.000, 10.875, 183 12.000, 13.125, 13.875, 14.625, 184 15.000, 15.750, 16.125, 16.500, 185 16.875, 17.250, 17.625, 18.000, 186 /* OCT 7 */ 187 0.000, 9.000, 12.000, 13.875, 188 15.000, 16.125, 16.875, 17.625, 189 18.000, 18.750, 19.125, 19.500, 190 19.875, 20.250, 20.625, 21.000 191 }; 192 193 /* sustain level table (3db per step) */ 194 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ 195 196 static int SL_TABLE[16]; 197 198 static const uint SL_TABLE_SEED[16] = { 199 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31 200 }; 201 202 #define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */ 203 /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ 204 /* TL_TABLE[ 0 to TL_MAX ] : plus section */ 205 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ 206 static int *TL_TABLE; 207 208 /* pointers to TL_TABLE with sinwave output offset */ 209 static int **SIN_TABLE; 210 211 /* LFO table */ 212 static int *AMS_TABLE; 213 static int *VIB_TABLE; 214 215 /* envelope output curve table */ 216 /* attack + decay + OFF */ 217 //static int ENV_CURVE[2*EG_ENT+1]; 218 //static int ENV_CURVE[2 * 4096 + 1]; // to keep it static ... 219 static int *ENV_CURVE; 220 221 222 /* multiple table */ 223 #define ML(a) (int)(a * 2) 224 static const uint MUL_TABLE[16]= { 225 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ 226 ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00), 227 ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00) 228 }; 229 #undef ML 230 231 /* dummy attack / decay rate ( when rate == 0 ) */ 232 static int RATE_0[16]= 233 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 234 235 /* -------------------- static state --------------------- */ 236 237 /* lock level of common table */ 238 static int num_lock = 0; 239 240 /* work table */ 241 static void *cur_chip = NULL; /* current chip point */ 242 /* currenct chip state */ 243 /* static OPLSAMPLE *bufL,*bufR; */ 244 static OPL_CH *S_CH; 245 static OPL_CH *E_CH; 246 OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; 247 248 static int outd[1]; 249 static int ams; 250 static int vib; 251 int *ams_table; 252 int *vib_table; 253 static int amsIncr; 254 static int vibIncr; 255 static int feedback2; /* connect for SLOT 2 */ 256 257 /* --------------------- rebuild tables ------------------- */ 258 259 #define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2))) 260 #define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST 261 262 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) { 263 int i; 264 265 ENV_BITS = ENV_BITS_PARAM; 266 EG_ENT = EG_ENT_PARAM; 267 EG_OFF = ((2 * EG_ENT)<<ENV_BITS); /* OFF */ 268 EG_DED = EG_OFF; 269 EG_DST = (EG_ENT << ENV_BITS); /* DECAY START */ 270 EG_AED = EG_DST; 271 //EG_STEP = (96.0/EG_ENT); 272 273 for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++) 274 KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]); 275 276 for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++) 277 SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]); 278 } 279 280 #undef SC_KSL 281 #undef SC_SL 282 283 /* --------------------- subroutines --------------------- */ 284 285 /* status set and IRQ handling */ 286 inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) { 287 /* set status flag */ 288 OPL->status |= flag; 289 if(!(OPL->status & 0x80)) { 290 if(OPL->status & OPL->statusmask) { /* IRQ on */ 291 OPL->status |= 0x80; 292 /* callback user interrupt handler (IRQ is OFF to ON) */ 293 if(OPL->IRQHandler) 294 (OPL->IRQHandler)(OPL->IRQParam,1); 295 } 296 } 297 } 298 299 /* status reset and IRQ handling */ 300 inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) { 301 /* reset status flag */ 302 OPL->status &= ~flag; 303 if((OPL->status & 0x80)) { 304 if (!(OPL->status & OPL->statusmask)) { 305 OPL->status &= 0x7f; 306 /* callback user interrupt handler (IRQ is ON to OFF) */ 307 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); 308 } 309 } 310 } 311 312 /* IRQ mask set */ 313 inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) { 314 OPL->statusmask = flag; 315 /* IRQ handling check */ 316 OPL_STATUS_SET(OPL,0); 317 OPL_STATUS_RESET(OPL,0); 318 } 319 320 /* ----- key on ----- */ 321 inline void OPL_KEYON(OPL_SLOT *SLOT) { 322 /* sin wave restart */ 323 SLOT->Cnt = 0; 324 /* set attack */ 325 SLOT->evm = ENV_MOD_AR; 326 SLOT->evs = SLOT->evsa; 327 SLOT->evc = EG_AST; 328 SLOT->eve = EG_AED; 329 } 330 331 /* ----- key off ----- */ 332 inline void OPL_KEYOFF(OPL_SLOT *SLOT) { 333 if( SLOT->evm > ENV_MOD_RR) { 334 /* set envelope counter from envleope output */ 335 336 // WORKAROUND: The Kyra engine does something very strange when 337 // starting a new song. For each channel: 338 // 339 // * The release rate is set to "fastest". 340 // * Any note is keyed off. 341 // * A very low-frequency note is keyed on. 342 // 343 // Usually, what happens next is that the real notes is keyed 344 // on immediately, in which case there's no problem. 345 // 346 // However, if the note is again keyed off (because the channel 347 // begins on a rest rather than a note), the envelope counter 348 // was moved from the very lowest point on the attack curve to 349 // the very highest point on the release curve. 350 // 351 // Again, this might not be a problem, if the release rate is 352 // still set to "fastest". But in many cases, it had already 353 // been increased. And, possibly because of inaccuracies in the 354 // envelope generator, that would cause the note to "fade out" 355 // for quite a long time. 356 // 357 // What we really need is a way to find the correct starting 358 // point for the envelope counter, and that may be what the 359 // commented-out line below is meant to do. For now, simply 360 // handle the pathological case. 361 362 if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST) 363 SLOT->evc = EG_DED; 364 else if( !(SLOT->evc & EG_DST) ) 365 //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST; 366 SLOT->evc = EG_DST; 367 SLOT->eve = EG_DED; 368 SLOT->evs = SLOT->evsr; 369 SLOT->evm = ENV_MOD_RR; 370 } 371 } 372 373 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */ 374 375 /* return : envelope output */ 376 inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) { 377 /* calcrate envelope generator */ 378 if((SLOT->evc += SLOT->evs) >= SLOT->eve) { 379 switch( SLOT->evm ) { 380 case ENV_MOD_AR: /* ATTACK -> DECAY1 */ 381 /* next DR */ 382 SLOT->evm = ENV_MOD_DR; 383 SLOT->evc = EG_DST; 384 SLOT->eve = SLOT->SL; 385 SLOT->evs = SLOT->evsd; 386 break; 387 case ENV_MOD_DR: /* DECAY -> SL or RR */ 388 SLOT->evc = SLOT->SL; 389 SLOT->eve = EG_DED; 390 if(SLOT->eg_typ) { 391 SLOT->evs = 0; 392 } else { 393 SLOT->evm = ENV_MOD_RR; 394 SLOT->evs = SLOT->evsr; 395 } 396 break; 397 case ENV_MOD_RR: /* RR -> OFF */ 398 SLOT->evc = EG_OFF; 399 SLOT->eve = EG_OFF + 1; 400 SLOT->evs = 0; 401 break; 402 } 403 } 404 /* calcrate envelope */ 405 return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0); 406 } 407 408 /* set algorythm connection */ 409 static void set_algorythm(OPL_CH *CH) { 410 int *carrier = &outd[0]; 411 CH->connect1 = CH->CON ? carrier : &feedback2; 412 CH->connect2 = carrier; 413 } 414 415 /* ---------- frequency counter for operater update ---------- */ 416 inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) { 417 int ksr; 418 419 /* frequency step counter */ 420 SLOT->Incr = CH->fc * SLOT->mul; 421 ksr = CH->kcode >> SLOT->KSR; 422 423 if( SLOT->ksr != ksr ) { 424 SLOT->ksr = ksr; 425 /* attack , decay rate recalcration */ 426 SLOT->evsa = SLOT->AR[ksr]; 427 SLOT->evsd = SLOT->DR[ksr]; 428 SLOT->evsr = SLOT->RR[ksr]; 429 } 430 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); 431 } 432 433 /* set multi,am,vib,EG-TYP,KSR,mul */ 434 inline void set_mul(FM_OPL *OPL, int slot, int v) { 435 OPL_CH *CH = &OPL->P_CH[slot>>1]; 436 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 437 438 SLOT->mul = MUL_TABLE[v & 0x0f]; 439 SLOT->KSR = (v & 0x10) ? 0 : 2; 440 SLOT->eg_typ = (v & 0x20) >> 5; 441 SLOT->vib = (v & 0x40); 442 SLOT->ams = (v & 0x80); 443 CALC_FCSLOT(CH, SLOT); 444 } 445 446 /* set ksl & tl */ 447 inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) { 448 OPL_CH *CH = &OPL->P_CH[slot>>1]; 449 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 450 int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */ 451 452 SLOT->ksl = ksl ? 3-ksl : 31; 453 SLOT->TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */ 454 455 if(!(OPL->mode & 0x80)) { /* not CSM latch total level */ 456 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl); 457 } 458 } 459 460 /* set attack rate & decay rate */ 461 inline void set_ar_dr(FM_OPL *OPL, int slot, int v) { 462 OPL_CH *CH = &OPL->P_CH[slot>>1]; 463 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 464 int ar = v >> 4; 465 int dr = v & 0x0f; 466 467 SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0; 468 SLOT->evsa = SLOT->AR[SLOT->ksr]; 469 if(SLOT->evm == ENV_MOD_AR) 470 SLOT->evs = SLOT->evsa; 471 472 SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0; 473 SLOT->evsd = SLOT->DR[SLOT->ksr]; 474 if(SLOT->evm == ENV_MOD_DR) 475 SLOT->evs = SLOT->evsd; 476 } 477 478 /* set sustain level & release rate */ 479 inline void set_sl_rr(FM_OPL *OPL, int slot, int v) { 480 OPL_CH *CH = &OPL->P_CH[slot>>1]; 481 OPL_SLOT *SLOT = &CH->SLOT[slot & 1]; 482 int sl = v >> 4; 483 int rr = v & 0x0f; 484 485 SLOT->SL = SL_TABLE[sl]; 486 if(SLOT->evm == ENV_MOD_DR) 487 SLOT->eve = SLOT->SL; 488 SLOT->RR = &OPL->DR_TABLE[rr<<2]; 489 SLOT->evsr = SLOT->RR[SLOT->ksr]; 490 if(SLOT->evm == ENV_MOD_RR) 491 SLOT->evs = SLOT->evsr; 492 } 493 494 /* operator output calcrator */ 495 496 #define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env] 497 /* ---------- calcrate one of channel ---------- */ 498 inline void OPL_CALC_CH(OPL_CH *CH) { 499 uint env_out; 500 OPL_SLOT *SLOT; 501 502 feedback2 = 0; 503 /* SLOT 1 */ 504 SLOT = &CH->SLOT[SLOT1]; 505 env_out=OPL_CALC_SLOT(SLOT); 506 if(env_out < (uint)(EG_ENT - 1)) { 507 /* PG */ 508 if(SLOT->vib) 509 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 510 else 511 SLOT->Cnt += SLOT->Incr; 512 /* connection */ 513 if(CH->FB) { 514 int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB; 515 CH->op1_out[1] = CH->op1_out[0]; 516 *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1); 517 } else { 518 *CH->connect1 += OP_OUT(SLOT, env_out, 0); 519 } 520 } else { 521 CH->op1_out[1] = CH->op1_out[0]; 522 CH->op1_out[0] = 0; 523 } 524 /* SLOT 2 */ 525 SLOT = &CH->SLOT[SLOT2]; 526 env_out=OPL_CALC_SLOT(SLOT); 527 if(env_out < (uint)(EG_ENT - 1)) { 528 /* PG */ 529 if(SLOT->vib) 530 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 531 else 532 SLOT->Cnt += SLOT->Incr; 533 /* connection */ 534 outd[0] += OP_OUT(SLOT, env_out, feedback2); 535 } 536 } 537 538 /* ---------- calcrate rythm block ---------- */ 539 #define WHITE_NOISE_db 6.0 540 inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) { 541 uint env_tam, env_sd, env_top, env_hh; 542 // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)), 543 // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to 544 // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024, 545 // or 128, so we can safely avoid any FP ops. 546 int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4); 547 548 int tone8; 549 550 OPL_SLOT *SLOT; 551 int env_out; 552 553 /* BD : same as FM serial mode and output level is large */ 554 feedback2 = 0; 555 /* SLOT 1 */ 556 SLOT = &CH[6].SLOT[SLOT1]; 557 env_out = OPL_CALC_SLOT(SLOT); 558 if(env_out < EG_ENT-1) { 559 /* PG */ 560 if(SLOT->vib) 561 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 562 else 563 SLOT->Cnt += SLOT->Incr; 564 /* connection */ 565 if(CH[6].FB) { 566 int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB; 567 CH[6].op1_out[1] = CH[6].op1_out[0]; 568 feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1); 569 } 570 else { 571 feedback2 = OP_OUT(SLOT, env_out, 0); 572 } 573 } else { 574 feedback2 = 0; 575 CH[6].op1_out[1] = CH[6].op1_out[0]; 576 CH[6].op1_out[0] = 0; 577 } 578 /* SLOT 2 */ 579 SLOT = &CH[6].SLOT[SLOT2]; 580 env_out = OPL_CALC_SLOT(SLOT); 581 if(env_out < EG_ENT-1) { 582 /* PG */ 583 if(SLOT->vib) 584 SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT; 585 else 586 SLOT->Cnt += SLOT->Incr; 587 /* connection */ 588 outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2; 589 } 590 591 // SD (17) = mul14[fnum7] + white noise 592 // TAM (15) = mul15[fnum8] 593 // TOP (18) = fnum6(mul18[fnum8]+whitenoise) 594 // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise 595 env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise; 596 env_tam =OPL_CALC_SLOT(SLOT8_1); 597 env_top = OPL_CALC_SLOT(SLOT8_2); 598 env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise; 599 600 /* PG */ 601 if(SLOT7_1->vib) 602 SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1); 603 else 604 SLOT7_1->Cnt += 2 * SLOT7_1->Incr; 605 if(SLOT7_2->vib) 606 SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3); 607 else 608 SLOT7_2->Cnt += (CH[7].fc * 8); 609 if(SLOT8_1->vib) 610 SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT; 611 else 612 SLOT8_1->Cnt += SLOT8_1->Incr; 613 if(SLOT8_2->vib) 614 SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4); 615 else 616 SLOT8_2->Cnt += (CH[8].fc * 48); 617 618 tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); 619 620 /* SD */ 621 if(env_sd < (uint)(EG_ENT - 1)) 622 outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8; 623 /* TAM */ 624 if(env_tam < (uint)(EG_ENT - 1)) 625 outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2; 626 /* TOP-CY */ 627 if(env_top < (uint)(EG_ENT - 1)) 628 outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2; 629 /* HH */ 630 if(env_hh < (uint)(EG_ENT-1)) 631 outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2; 632 } 633 634 /* ----------- initialize time tabls ----------- */ 635 static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) { 636 int i; 637 double rate; 638 639 /* make attack rate & decay rate tables */ 640 for (i = 0; i < 4; i++) 641 OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; 642 for (i = 4; i <= 60; i++) { 643 rate = OPL->freqbase; /* frequency rate */ 644 if(i < 60) 645 rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ 646 rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */ 647 rate *= (double)(EG_ENT << ENV_BITS); 648 OPL->AR_TABLE[i] = (int)(rate / ARRATE); 649 OPL->DR_TABLE[i] = (int)(rate / DRRATE); 650 } 651 for (i = 60; i < 76; i++) { 652 OPL->AR_TABLE[i] = EG_AED-1; 653 OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; 654 } 655 } 656 657 /* ---------- generic table initialize ---------- */ 658 static int OPLOpenTable(void) { 659 int s,t; 660 double rate; 661 int i,j; 662 double pom; 663 664 #ifdef __DS__ 665 DS::fastRamReset(); 666 667 TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *)); 668 SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *)); 669 #else 670 671 /* allocate dynamic tables */ 672 if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL) 673 return 0; 674 675 if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) { 676 free(TL_TABLE); 677 return 0; 678 } 679 #endif 680 681 if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) { 682 free(TL_TABLE); 683 free(SIN_TABLE); 684 return 0; 685 } 686 687 if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) { 688 free(TL_TABLE); 689 free(SIN_TABLE); 690 free(AMS_TABLE); 691 return 0; 692 } 693 /* make total level table */ 694 for (t = 0; t < EG_ENT - 1 ; t++) { 695 rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */ 696 TL_TABLE[ t] = (int)rate; 697 TL_TABLE[TL_MAX + t] = -TL_TABLE[t]; 698 } 699 /* fill volume off area */ 700 for (t = EG_ENT - 1; t < TL_MAX; t++) { 701 TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0; 702 } 703 704 /* make sinwave table (total level offet) */ 705 /* degree 0 = degree 180 = off */ 706 SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1]; 707 for (s = 1;s <= SIN_ENT / 4; s++) { 708 pom = sin(2 * PI * s / SIN_ENT); /* sin */ 709 pom = 20 * log10(1 / pom); /* decibel */ 710 j = int(pom / EG_STEP); /* TL_TABLE steps */ 711 712 /* degree 0 - 90 , degree 180 - 90 : plus section */ 713 SIN_TABLE[ s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j]; 714 /* degree 180 - 270 , degree 360 - 270 : minus section */ 715 SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j]; 716 } 717 for (s = 0;s < SIN_ENT; s++) { 718 SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; 719 SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)]; 720 SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s]; 721 } 722 723 724 ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1)); 725 726 /* envelope counter -> envelope output table */ 727 for (i=0; i < EG_ENT; i++) { 728 /* ATTACK curve */ 729 pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT; 730 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */ 731 ENV_CURVE[i] = (int)pom; 732 /* DECAY ,RELEASE curve */ 733 ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i; 734 } 735 /* off */ 736 ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1; 737 /* make LFO ams table */ 738 for (i=0; i < AMS_ENT; i++) { 739 pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */ 740 AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */ 741 AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */ 742 } 743 /* make LFO vibrate table */ 744 for (i=0; i < VIB_ENT; i++) { 745 /* 100cent = 1seminote = 6% ?? */ 746 pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */ 747 VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */ 748 VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */ 749 } 750 return 1; 751 } 752 753 static void OPLCloseTable(void) { 754 free(TL_TABLE); 755 free(SIN_TABLE); 756 free(AMS_TABLE); 757 free(VIB_TABLE); 758 free(ENV_CURVE); 759 } 760 761 /* CSM Key Controll */ 762 inline void CSMKeyControll(OPL_CH *CH) { 763 OPL_SLOT *slot1 = &CH->SLOT[SLOT1]; 764 OPL_SLOT *slot2 = &CH->SLOT[SLOT2]; 765 /* all key off */ 766 OPL_KEYOFF(slot1); 767 OPL_KEYOFF(slot2); 768 /* total level latch */ 769 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); 770 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); 771 /* key on */ 772 CH->op1_out[0] = CH->op1_out[1] = 0; 773 OPL_KEYON(slot1); 774 OPL_KEYON(slot2); 775 } 776 777 /* ---------- opl initialize ---------- */ 778 static void OPL_initalize(FM_OPL *OPL) { 779 int fn; 780 781 /* frequency base */ 782 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0; 783 /* Timer base time */ 784 OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 ); 785 /* make time tables */ 786 init_timetables(OPL, OPL_ARRATE, OPL_DRRATE); 787 /* make fnumber -> increment counter table */ 788 for( fn=0; fn < 1024; fn++) { 789 OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2); 790 } 791 /* LFO freq.table */ 792 OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0); 793 OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0); 794 } 795 796 /* ---------- write a OPL registers ---------- */ 797 void OPLWriteReg(FM_OPL *OPL, int r, int v) { 798 OPL_CH *CH; 799 int slot; 800 uint block_fnum; 801 802 switch(r & 0xe0) { 803 case 0x00: /* 00-1f:controll */ 804 switch(r & 0x1f) { 805 case 0x01: 806 /* wave selector enable */ 807 if(OPL->type&OPL_TYPE_WAVESEL) { 808 OPL->wavesel = v & 0x20; 809 if(!OPL->wavesel) { 810 /* preset compatible mode */ 811 int c; 812 for(c=0; c<OPL->max_ch; c++) { 813 OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; 814 OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; 815 } 816 } 817 } 818 return; 819 case 0x02: /* Timer 1 */ 820 OPL->T[0] = (256-v) * 4; 821 break; 822 case 0x03: /* Timer 2 */ 823 OPL->T[1] = (256-v) * 16; 824 return; 825 case 0x04: /* IRQ clear / mask and Timer enable */ 826 if(v & 0x80) { /* IRQ flag clear */ 827 OPL_STATUS_RESET(OPL, 0x7f); 828 } else { /* set IRQ mask ,timer enable*/ 829 uint8 st1 = v & 1; 830 uint8 st2 = (v >> 1) & 1; 831 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ 832 OPL_STATUS_RESET(OPL, v & 0x78); 833 OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01); 834 /* timer 2 */ 835 if(OPL->st[1] != st2) { 836 double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0; 837 OPL->st[1] = st2; 838 if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval); 839 } 840 /* timer 1 */ 841 if(OPL->st[0] != st1) { 842 double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0; 843 OPL->st[0] = st1; 844 if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval); 845 } 846 } 847 return; 848 } 849 break; 850 case 0x20: /* am,vib,ksr,eg type,mul */ 851 slot = slot_array[r&0x1f]; 852 if(slot == -1) 853 return; 854 set_mul(OPL,slot,v); 855 return; 856 case 0x40: 857 slot = slot_array[r&0x1f]; 858 if(slot == -1) 859 return; 860 set_ksl_tl(OPL,slot,v); 861 return; 862 case 0x60: 863 slot = slot_array[r&0x1f]; 864 if(slot == -1) 865 return; 866 set_ar_dr(OPL,slot,v); 867 return; 868 case 0x80: 869 slot = slot_array[r&0x1f]; 870 if(slot == -1) 871 return; 872 set_sl_rr(OPL,slot,v); 873 return; 874 case 0xa0: 875 switch(r) { 876 case 0xbd: 877 /* amsep,vibdep,r,bd,sd,tom,tc,hh */ 878 { 879 uint8 rkey = OPL->rythm ^ v; 880 OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0]; 881 OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0]; 882 OPL->rythm = v & 0x3f; 883 if(OPL->rythm & 0x20) { 884 /* BD key on/off */ 885 if(rkey & 0x10) { 886 if(v & 0x10) { 887 OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; 888 OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); 889 OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); 890 } else { 891 OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); 892 OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); 893 } 894 } 895 /* SD key on/off */ 896 if(rkey & 0x08) { 897 if(v & 0x08) 898 OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); 899 else 900 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); 901 }/* TAM key on/off */ 902 if(rkey & 0x04) { 903 if(v & 0x04) 904 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); 905 else 906 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); 907 } 908 /* TOP-CY key on/off */ 909 if(rkey & 0x02) { 910 if(v & 0x02) 911 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); 912 else 913 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); 914 } 915 /* HH key on/off */ 916 if(rkey & 0x01) { 917 if(v & 0x01) 918 OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); 919 else 920 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); 921 } 922 } 923 } 924 return; 925 926 default: 927 break; 928 } 929 /* keyon,block,fnum */ 930 if((r & 0x0f) > 8) 931 return; 932 CH = &OPL->P_CH[r & 0x0f]; 933 if(!(r&0x10)) { /* a0-a8 */ 934 block_fnum = (CH->block_fnum & 0x1f00) | v; 935 } else { /* b0-b8 */ 936 int keyon = (v >> 5) & 1; 937 block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff); 938 if(CH->keyon != keyon) { 939 if((CH->keyon=keyon)) { 940 CH->op1_out[0] = CH->op1_out[1] = 0; 941 OPL_KEYON(&CH->SLOT[SLOT1]); 942 OPL_KEYON(&CH->SLOT[SLOT2]); 943 } else { 944 OPL_KEYOFF(&CH->SLOT[SLOT1]); 945 OPL_KEYOFF(&CH->SLOT[SLOT2]); 946 } 947 } 948 } 949 /* update */ 950 if(CH->block_fnum != block_fnum) { 951 int blockRv = 7 - (block_fnum >> 10); 952 int fnum = block_fnum & 0x3ff; 953 CH->block_fnum = block_fnum; 954 CH->ksl_base = KSL_TABLE[block_fnum >> 6]; 955 CH->fc = OPL->FN_TABLE[fnum] >> blockRv; 956 CH->kcode = CH->block_fnum >> 9; 957 if((OPL->mode & 0x40) && CH->block_fnum & 0x100) 958 CH->kcode |=1; 959 CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); 960 CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); 961 } 962 return; 963 case 0xc0: 964 /* FB,C */ 965 if((r & 0x0f) > 8) 966 return; 967 CH = &OPL->P_CH[r&0x0f]; 968 { 969 int feedback = (v >> 1) & 7; 970 CH->FB = feedback ? (8 + 1) - feedback : 0; 971 CH->CON = v & 1; 972 set_algorythm(CH); 973 } 974 return; 975 case 0xe0: /* wave type */ 976 slot = slot_array[r & 0x1f]; 977 if(slot == -1) 978 return; 979 CH = &OPL->P_CH[slot>>1]; 980 if(OPL->wavesel) { 981 CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT]; 982 } 983 return; 984 } 985 } 986 987 /* lock/unlock for common table */ 988 static int OPL_LockTable(void) { 989 num_lock++; 990 if(num_lock>1) 991 return 0; 992 /* first time */ 993 cur_chip = NULL; 994 /* allocate total level table (128kb space) */ 995 if(!OPLOpenTable()) { 996 num_lock--; 997 return -1; 998 } 999 return 0; 1000 } 1001 1002 static void OPL_UnLockTable(void) { 1003 if(num_lock) 1004 num_lock--; 1005 if(num_lock) 1006 return; 1007 /* last time */ 1008 cur_chip = NULL; 1009 OPLCloseTable(); 1010 } 1011 1012 /*******************************************************************************/ 1013 /* YM3812 local section */ 1014 /*******************************************************************************/ 1015 1016 /* ---------- update one of chip ----------- */ 1017 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave) { 1018 int i; 1019 int data; 1020 int16 *buf = buffer; 1021 uint amsCnt = OPL->amsCnt; 1022 uint vibCnt = OPL->vibCnt; 1023 uint8 rythm = OPL->rythm & 0x20; 1024 OPL_CH *CH, *R_CH; 1025 1026 1027 if((void *)OPL != cur_chip) { 1028 cur_chip = (void *)OPL; 1029 /* channel pointers */ 1030 S_CH = OPL->P_CH; 1031 E_CH = &S_CH[9]; 1032 /* rythm slot */ 1033 SLOT7_1 = &S_CH[7].SLOT[SLOT1]; 1034 SLOT7_2 = &S_CH[7].SLOT[SLOT2]; 1035 SLOT8_1 = &S_CH[8].SLOT[SLOT1]; 1036 SLOT8_2 = &S_CH[8].SLOT[SLOT2]; 1037 /* LFO state */ 1038 amsIncr = OPL->amsIncr; 1039 vibIncr = OPL->vibIncr; 1040 ams_table = OPL->ams_table; 1041 vib_table = OPL->vib_table; 1042 } 1043 R_CH = rythm ? &S_CH[6] : E_CH; 1044 for(i = 0; i < length; i++) { 1045 /* channel A channel B channel C */ 1046 /* LFO */ 1047 ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT]; 1048 vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT]; 1049 outd[0] = 0; 1050 /* FM part */ 1051 for(CH=S_CH; CH < R_CH; CH++) 1052 OPL_CALC_CH(CH); 1053 /* Rythn part */ 1054 if(rythm) 1055 OPL_CALC_RH(OPL, S_CH); 1056 /* limit check */ 1057 data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT); 1058 /* store to sound buffer */ 1059 buf[i << interleave] = data >> OPL_OUTSB; 1060 } 1061 1062 OPL->amsCnt = amsCnt; 1063 OPL->vibCnt = vibCnt; 1064 } 1065 1066 /* ---------- reset a chip ---------- */ 1067 void OPLResetChip(FM_OPL *OPL) { 1068 int c,s; 1069 int i; 1070 1071 /* reset chip */ 1072 OPL->mode = 0; /* normal mode */ 1073 OPL_STATUS_RESET(OPL, 0x7f); 1074 /* reset with register write */ 1075 OPLWriteReg(OPL, 0x01,0); /* wabesel disable */ 1076 OPLWriteReg(OPL, 0x02,0); /* Timer1 */ 1077 OPLWriteReg(OPL, 0x03,0); /* Timer2 */ 1078 OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */ 1079 for(i = 0xff; i >= 0x20; i--) 1080 OPLWriteReg(OPL,i,0); 1081 /* reset OPerator parameter */ 1082 for(c = 0; c < OPL->max_ch ;c++ ) { 1083 OPL_CH *CH = &OPL->P_CH[c]; 1084 /* OPL->P_CH[c].PAN = OPN_CENTER; */ 1085 for(s = 0; s < 2; s++ ) { 1086 /* wave table */ 1087 CH->SLOT[s].wavetable = &SIN_TABLE[0]; 1088 /* CH->SLOT[s].evm = ENV_MOD_RR; */ 1089 CH->SLOT[s].evc = EG_OFF; 1090 CH->SLOT[s].eve = EG_OFF + 1; 1091 CH->SLOT[s].evs = 0; 1092 } 1093 } 1094 } 1095 1096 /* ---------- Create a virtual YM3812 ---------- */ 1097 /* 'rate' is sampling rate and 'bufsiz' is the size of the */ 1098 FM_OPL *OPLCreate(int type, int clock, int rate) { 1099 char *ptr; 1100 FM_OPL *OPL; 1101 int state_size; 1102 int max_ch = 9; /* normaly 9 channels */ 1103 1104 if( OPL_LockTable() == -1) 1105 return NULL; 1106 /* allocate OPL state space */ 1107 state_size = sizeof(FM_OPL); 1108 state_size += sizeof(OPL_CH) * max_ch; 1109 1110 /* allocate memory block */ 1111 ptr = (char *)calloc(state_size, 1); 1112 if(ptr == NULL) 1113 return NULL; 1114 1115 /* clear */ 1116 memset(ptr, 0, state_size); 1117 OPL = (FM_OPL *)ptr; ptr += sizeof(FM_OPL); 1118 OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch; 1119 1120 /* set channel state pointer */ 1121 OPL->type = type; 1122 OPL->clock = clock; 1123 OPL->rate = rate; 1124 OPL->max_ch = max_ch; 1125 1126 /* init grobal tables */ 1127 OPL_initalize(OPL); 1128 1129 /* reset chip */ 1130 OPLResetChip(OPL); 1131 return OPL; 1132 } 1133 1134 /* ---------- Destroy one of vietual YM3812 ---------- */ 1135 void OPLDestroy(FM_OPL *OPL) { 1136 OPL_UnLockTable(); 1137 free(OPL); 1138 } 1139 1140 /* ---------- Option handlers ---------- */ 1141 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) { 1142 OPL->TimerHandler = TimerHandler; 1143 OPL->TimerParam = channelOffset; 1144 } 1145 1146 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) { 1147 OPL->IRQHandler = IRQHandler; 1148 OPL->IRQParam = param; 1149 } 1150 1151 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) { 1152 OPL->UpdateHandler = UpdateHandler; 1153 OPL->UpdateParam = param; 1154 } 1155 1156 /* ---------- YM3812 I/O interface ---------- */ 1157 int OPLWrite(FM_OPL *OPL,int a,int v) { 1158 if(!(a & 1)) { /* address port */ 1159 OPL->address = v & 0xff; 1160 } else { /* data port */ 1161 if(OPL->UpdateHandler) 1162 OPL->UpdateHandler(OPL->UpdateParam,0); 1163 OPLWriteReg(OPL, OPL->address,v); 1164 } 1165 return OPL->status >> 7; 1166 } 1167 1168 unsigned char OPLRead(FM_OPL *OPL,int a) { 1169 if(!(a & 1)) { /* status port */ 1170 return OPL->status & (OPL->statusmask | 0x80); 1171 } 1172 /* data port */ 1173 switch(OPL->address) { 1174 case 0x05: /* KeyBoard IN */ 1175 warning("OPL:read unmapped KEYBOARD port\n"); 1176 return 0; 1177 case 0x19: /* I/O DATA */ 1178 warning("OPL:read unmapped I/O port\n"); 1179 return 0; 1180 case 0x1a: /* PCM-DATA */ 1181 return 0; 1182 default: 1183 break; 1184 } 1185 return 0; 1186 } 1187 1188 int OPLTimerOver(FM_OPL *OPL, int c) { 1189 if(c) { /* Timer B */ 1190 OPL_STATUS_SET(OPL, 0x20); 1191 } else { /* Timer A */ 1192 OPL_STATUS_SET(OPL, 0x40); 1193 /* CSM mode key,TL controll */ 1194 if(OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */ 1195 int ch; 1196 if(OPL->UpdateHandler) 1197 OPL->UpdateHandler(OPL->UpdateParam,0); 1198 for(ch = 0; ch < 9; ch++) 1199 CSMKeyControll(&OPL->P_CH[ch]); 1200 } 1201 } 1202 /* reload timer */ 1203 if (OPL->TimerHandler) 1204 (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase); 1205 return OPL->status >> 7; 1206 } 1207 1208 FM_OPL *makeAdlibOPL(int rate) { 1209 // We need to emulate one YM3812 chip 1210 int env_bits = FMOPL_ENV_BITS_HQ; 1211 int eg_ent = FMOPL_EG_ENT_HQ; 1212 #if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__) 1213 if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) { 1214 env_bits = FMOPL_ENV_BITS_HQ; 1215 eg_ent = FMOPL_EG_ENT_HQ; 1216 } else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) { 1217 env_bits = FMOPL_ENV_BITS_MQ; 1218 eg_ent = FMOPL_EG_ENT_MQ; 1219 } else { 1220 env_bits = FMOPL_ENV_BITS_LQ; 1221 eg_ent = FMOPL_EG_ENT_LQ; 1222 } 1223 #endif 1224 1225 OPLBuildTables(env_bits, eg_ent); 1226 return OPLCreate(OPL_TYPE_YM3812, 3579545, rate); 1227 } 1228 1229 } // end of namespace MAME 1230 } // end of namespace OPL 1231 -
sound/softsynth/opl/dbopl.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 /* 26 * Based on AdLib emulation code of DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * Licensed under GPLv2+ 29 * http://www.dosbox.com 30 31 * Original source file header: 32 33 * Copyright (C) 2002-2009 The DOSBox Team 34 * 35 * This program is free software; you can redistribute it and/or modify 36 * it under the terms of the GNU General Public License as published by 37 * the Free Software Foundation; either version 2 of the License, or 38 * (at your option) any later version. 39 * 40 * This program is distributed in the hope that it will be useful, 41 * but WITHOUT ANY WARRANTY; without even the implied warranty of 42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 43 * GNU General Public License for more details. 44 * 45 * You should have received a copy of the GNU General Public License 46 * along with this program; if not, write to the Free Software 47 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 48 */ 49 50 /* 51 DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator. 52 Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2 53 Except for the table generation it's all integer math 54 Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms 55 The generation was based on the MAME implementation but tried to have it use less memory and be faster in general 56 MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times 57 58 //TODO Don't delay first operator 1 sample in opl3 mode 59 //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter 60 //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though? 61 //TODO don't use variables in work structure for tremolo and vibrato but give the variables as parameters to GetSample 62 //TODO Since the vibrato takes 1024 samples it's easier to run the emulator in same vibrato chunks, vibrato would be costfree 63 64 //DUNNO Keyon in 4op, switch to 2op without keyoff. 65 */ 66 67 #ifndef DISABLE_DOSBOX_OPL 68 69 #include "dbopl.h" 70 #include <stddef.h> // for ptrdiff_t 71 72 #ifndef PI 73 #define PI 3.14159265358979323846 74 #endif 75 76 #ifndef INLINE 77 #define INLINE 78 #endif 79 80 #define OFFS(type,item) (((ptrdiff_t)(&((type*)42)->type::item))-42) 81 82 namespace OPL { 83 namespace DOSBox { 84 namespace DBOPL { 85 86 #define MAX_SAMPLES 256 87 #define OPLRATE ((double)(14318180.0 / 288.0)) 88 89 //Only need 4 valid bits at the top for vibrato 90 #define VIBRATO_SH ( 32 - 4 ) 91 //Need 6 bits of accuracy 92 #define TREMOLO_SH ( 32 - 6 ) 93 #define TREMOLO_TABLE 52 94 95 //Wave bits available in the top of the 32bit range 96 //Original adlib uses 10.10, we use 12.20 97 //Have to keep some bits in the top to allow for freqmul 0.5 98 #define WAVE_BITS 12 99 #define WAVE_SH ( 32 - WAVE_BITS ) 100 #define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) 101 102 //Maximum amount of attenuation bits 103 //Envelope goes to 511, 9 bits 104 #if (DBOPL_WAVE == WAVE_TABLEMUL ) 105 //Uses the value directly 106 #define ENV_BITS ( 9 ) 107 #else 108 //Add 3 bits here for more accuracy and would have to be shifted up either way 109 #define ENV_BITS ( 9 ) 110 #endif 111 //Limits of the envelope with those bits and when the envelope goes silent 112 #define ENV_MIN 0 113 #define ENV_EXTRA ( ENV_BITS - 9 ) 114 #define ENV_MAX ( 511 << ENV_EXTRA ) 115 #define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) 116 #define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT ) 117 118 //Attack/decay/release rate counter shift 119 #define RATE_SH 24 120 #define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) 121 //Has to fit within 16bit lookuptable 122 #define MUL_SH 16 123 124 //Check some ranges 125 #if ENV_EXTRA > 3 126 #error Too many envelope bits 127 #endif 128 129 130 //How much to substract from the base value for the final attenuation 131 static const Bit8u KslCreateTable[16] = { 132 //0 will always be be lower than 7 * 8 133 64, 32, 24, 19, 134 16, 12, 11, 10, 135 8, 6, 5, 4, 136 3, 2, 1, 0, 137 }; 138 139 #define M(_X_) ((Bit8u)( (_X_) * 2)) 140 static const Bit8u FreqCreateTable[16] = { 141 M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ), 142 M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15) 143 }; 144 #undef M 145 146 //We're not including the highest attack rate, that gets a special value 147 static const Bit8u AttackSamplesTable[13] = { 148 69, 55, 46, 40, 149 35, 29, 23, 20, 150 19, 15, 11, 10, 151 9 152 }; 153 //On a real opl these values take 8 samples to reach and are based upon larger tables 154 static const Bit8u EnvelopeIncreaseTable[13] = { 155 4, 5, 6, 7, 156 8, 10, 12, 14, 157 16, 20, 24, 28, 158 32, 159 }; 160 161 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) 162 static Bit16u ExpTable[ 256 ]; 163 #endif 164 165 #if ( DBOPL_WAVE == WAVE_HANDLER ) 166 //PI table used by WAVEHANDLER 167 static Bit16u SinTable[ 512 ]; 168 #endif 169 170 #if ( DBOPL_WAVE > WAVE_HANDLER ) 171 //Layout of the waveform table in 512 entry intervals 172 //With overlapping waves we reduce the table to half it's size 173 174 // | |//\\|____|WAV7|//__|/\ |____|/\/\| 175 // |\\//| | |WAV7| | \/| | | 176 // |06 |0126|17 |7 |3 |4 |4 5 |5 | 177 178 //6 is just 0 shifted and masked 179 180 static Bit16s WaveTable[ 8 * 512 ]; 181 //Distance into WaveTable the wave starts 182 static const Bit16u WaveBaseTable[8] = { 183 0x000, 0x200, 0x200, 0x800, 184 0xa00, 0xc00, 0x100, 0x400, 185 186 }; 187 //Mask the counter with this 188 static const Bit16u WaveMaskTable[8] = { 189 1023, 1023, 511, 511, 190 1023, 1023, 512, 1023, 191 }; 192 193 //Where to start the counter on at keyon 194 static const Bit16u WaveStartTable[8] = { 195 512, 0, 0, 0, 196 0, 512, 512, 256, 197 }; 198 #endif 199 200 #if ( DBOPL_WAVE == WAVE_TABLEMUL ) 201 static Bit16u MulTable[ 384 ]; 202 #endif 203 204 static Bit8u KslTable[ 8 * 16 ]; 205 static Bit8u TremoloTable[ TREMOLO_TABLE ]; 206 //Start of a channel behind the chip struct start 207 static Bit16u ChanOffsetTable[32]; 208 //Start of an operator behind the chip struct start 209 static Bit16u OpOffsetTable[64]; 210 211 //The lower bits are the shift of the operator vibrato value 212 //The highest bit is right shifted to generate -1 or 0 for negation 213 //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 214 static const Bit8s VibratoTable[ 8 ] = { 215 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, 216 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 217 }; 218 219 //Shift strength for the ksl value determined by ksl strength 220 static const Bit8u KslShiftTable[4] = { 221 31,1,2,0 222 }; 223 224 //Generate a table index and table shift value using input value from a selected rate 225 static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) { 226 if ( val < 13 * 4 ) { //Rate 0 - 12 227 shift = 12 - ( val >> 2 ); 228 index = val & 3; 229 } else if ( val < 15 * 4 ) { //rate 13 - 14 230 shift = 0; 231 index = val - 12 * 4; 232 } else { //rate 15 and up 233 shift = 0; 234 index = 12; 235 } 236 } 237 238 #if ( DBOPL_WAVE == WAVE_HANDLER ) 239 /* 240 Generate the different waveforms out of the sine/exponetial table using handlers 241 */ 242 static inline Bits MakeVolume( Bitu wave, Bitu volume ) { 243 Bitu total = wave + volume; 244 Bitu index = total & 0xff; 245 Bitu sig = ExpTable[ index ]; 246 Bitu exp = total >> 8; 247 #if 0 248 //Check if we overflow the 31 shift limit 249 if ( exp >= 32 ) { 250 LOG_MSG( "WTF %d %d", total, exp ); 251 } 252 #endif 253 return (sig >> exp); 254 }; 255 256 static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { 257 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 258 Bitu wave = SinTable[i & 511]; 259 return (MakeVolume( wave, volume ) ^ neg) - neg; 260 } 261 static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) { 262 Bit32u wave = SinTable[i & 511]; 263 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); 264 return MakeVolume( wave, volume ); 265 } 266 static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) { 267 Bitu wave = SinTable[i & 511]; 268 return MakeVolume( wave, volume ); 269 } 270 static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) { 271 Bitu wave = SinTable[i & 255]; 272 wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); 273 return MakeVolume( wave, volume ); 274 } 275 static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) { 276 //Twice as fast 277 i <<= 1; 278 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 279 Bitu wave = SinTable[i & 511]; 280 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); 281 return (MakeVolume( wave, volume ) ^ neg) - neg; 282 } 283 static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) { 284 //Twice as fast 285 i <<= 1; 286 Bitu wave = SinTable[i & 511]; 287 wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); 288 return MakeVolume( wave, volume ); 289 } 290 static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) { 291 Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 292 return (MakeVolume( 0, volume ) ^ neg) - neg; 293 } 294 static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) { 295 //Negative is reversed here 296 Bits neg = (( i >> 9) & 1) - 1; 297 Bitu wave = (i << 3); 298 //When negative the volume also runs backwards 299 wave = ((wave ^ neg) - neg) & 4095; 300 return (MakeVolume( wave, volume ) ^ neg) - neg; 301 } 302 303 static const WaveHandler WaveHandlerTable[8] = { 304 WaveForm0, WaveForm1, WaveForm2, WaveForm3, 305 WaveForm4, WaveForm5, WaveForm6, WaveForm7 306 }; 307 308 #endif 309 310 //Structto hold the data everything well yeh works with 311 static struct { 312 Bitu samples; 313 Bits vibrato; 314 Bits tremolo; 315 inline void SetVibrato( Bit8s vib ) { 316 vibrato = vib; 317 vibrato &= ~0x80; 318 } 319 Bit32s output[MAX_SAMPLES * 2]; 320 //Could intermix the vib/trem table for slightly better cache hits 321 Bit8s vibTable[MAX_SAMPLES]; 322 Bit8s tremTable[MAX_SAMPLES]; 323 } Work; 324 325 /* 326 Operator 327 */ 328 329 //We zero out when rate == 0 330 inline void Operator::UpdateAttack( const Chip* chip ) { 331 Bit8u rate = reg60 >> 4; 332 if ( rate ) { 333 Bit8u val = (rate << 2) + ksr; 334 attackAdd = chip->attackRates[ val ]; 335 rateZero &= ~(1 << ATTACK); 336 } else { 337 attackAdd = 0; 338 rateZero |= (1 << ATTACK); 339 } 340 } 341 inline void Operator::UpdateDecay( const Chip* chip ) { 342 Bit8u rate = reg60 & 0xf; 343 if ( rate ) { 344 Bit8u val = (rate << 2) + ksr; 345 decayAdd = chip->linearRates[ val ]; 346 rateZero &= ~(1 << DECAY); 347 } else { 348 decayAdd = 0; 349 rateZero |= (1 << DECAY); 350 } 351 } 352 inline void Operator::UpdateRelease( const Chip* chip ) { 353 Bit8u rate = reg80 & 0xf; 354 if ( rate ) { 355 Bit8u val = (rate << 2) + ksr; 356 releaseAdd = chip->linearRates[ val ]; 357 rateZero &= ~(1 << RELEASE); 358 if ( !(reg20 & MASK_SUSTAIN ) ) { 359 rateZero &= ~( 1 << SUSTAIN ); 360 } 361 } else { 362 rateZero |= (1 << RELEASE); 363 releaseAdd = 0; 364 if ( !(reg20 & MASK_SUSTAIN ) ) { 365 rateZero |= ( 1 << SUSTAIN ); 366 } 367 } 368 } 369 370 inline void Operator::UpdateAttenuation( ) { 371 Bit8u kslBase = (chanData >> SHIFT_KSLBASE) & 0xff; 372 Bit32u tl = reg40 & 0x3f; 373 Bit8u kslShift = KslShiftTable[ reg40 >> 6 ]; 374 //Make sure the attenuation goes to the right bits 375 totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max 376 totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift; 377 } 378 379 void Operator::UpdateFrequency( ) { 380 Bit32u freq = chanData & (( 1 << 10 ) - 1); 381 Bit32u block = (chanData >> 10) & 0xff; 382 383 waveAdd = (freq << block) * freqMul; 384 if ( reg20 & MASK_VIBRATO ) { 385 vibStrength = (Bit8u)(freq >> 7); 386 vibrato = ( vibStrength << block ) * freqMul; 387 } else { 388 vibStrength = 0; 389 vibrato = 0; 390 } 391 } 392 393 void Operator::UpdateRates( const Chip* chip ) { 394 //Mame seems to reverse this where enabling ksr actually lowers 395 //the rate, but pdf manuals says otherwise? 396 Bit8u newKsr = (chanData >> SHIFT_KEYCODE) & 0xff; 397 if ( !( reg20 & MASK_KSR ) ) { 398 newKsr >>= 2; 399 } 400 if ( ksr == newKsr ) 401 return; 402 ksr = newKsr; 403 UpdateAttack( chip ); 404 UpdateDecay( chip ); 405 UpdateRelease( chip ); 406 } 407 408 INLINE Bit32s Operator::RateForward( Bit32u add ) { 409 rateIndex += add; 410 Bit32s ret = rateIndex >> RATE_SH; 411 rateIndex = rateIndex & RATE_MASK; 412 return ret; 413 } 414 415 template< Operator::State yes> 416 Bits Operator::TemplateVolume( ) { 417 Bit32s vol = activeLevel; 418 Bit32s change; 419 switch ( yes ) { 420 case OFF: 421 return ENV_MAX; 422 case ATTACK: 423 change = RateForward( attackAdd ); 424 if ( !change ) 425 return vol; 426 vol += ( (~vol) * change ) >> 3; 427 if ( vol < ENV_MIN ) { 428 activeLevel = ENV_MIN; 429 rateIndex = 0; 430 SetState( DECAY ); 431 return ENV_MIN; 432 } 433 break; 434 case DECAY: 435 vol += RateForward( decayAdd ); 436 if ( vol >= sustainLevel ) { 437 //Check if we didn't overshoot max attenuation, then just go off 438 if ( vol >= ENV_MAX ) { 439 activeLevel = ENV_MAX; 440 SetState( OFF ); 441 return ENV_MAX; 442 } 443 //Continue as sustain 444 rateIndex = 0; 445 SetState( SUSTAIN ); 446 } 447 break; 448 case SUSTAIN: 449 if ( reg20 & MASK_SUSTAIN ) { 450 return vol; 451 } 452 //In sustain phase, but not sustaining, do regular release 453 case RELEASE: 454 vol += RateForward( releaseAdd );; 455 if ( vol >= ENV_MAX ) { 456 activeLevel = ENV_MAX; 457 SetState( OFF ); 458 return ENV_MAX; 459 } 460 break; 461 } 462 activeLevel = vol; 463 return vol; 464 } 465 466 static const VolumeHandler VolumeHandlerTable[5] = { 467 &Operator::TemplateVolume< Operator::OFF >, 468 &Operator::TemplateVolume< Operator::RELEASE >, 469 &Operator::TemplateVolume< Operator::SUSTAIN >, 470 &Operator::TemplateVolume< Operator::DECAY >, 471 &Operator::TemplateVolume< Operator::ATTACK > 472 }; 473 474 INLINE Bitu Operator::ForwardVolume() { 475 return totalLevel + (this->*volHandler)() 476 #if defined ( DBOPL_TREMOLO ) 477 + (Work.tremolo & tremoloMask) 478 #endif 479 ; 480 } 481 482 483 INLINE Bitu Operator::ForwardWave() { 484 #if defined ( DBOPL_VIBRATO ) 485 if ( vibStrength >> (Bit8u)(Work.vibrato) ) { 486 Bit32s add = vibrato >> (Bit8u)(Work.vibrato); 487 //Sign extend over the shift value 488 Bit32s neg = Work.vibrato >> 16; 489 //Negate the add with -1 or 0 490 add = ( add ^ neg ) - neg; 491 waveIndex += add + waveAdd; 492 return waveIndex >> WAVE_SH; 493 } 494 #endif 495 waveIndex += waveAdd; 496 return waveIndex >> WAVE_SH; 497 } 498 499 500 void Operator::Write20( const Chip* chip, Bit8u val ) { 501 Bit8u change = (reg20 ^ val ); 502 if ( !change ) 503 return; 504 reg20 = val; 505 //Shift the tremolo bit over the entire register, saved a branch, YES! 506 tremoloMask = (Bit8s)(val) >> 7; 507 tremoloMask &= ~(( 1 << ENV_EXTRA ) -1); 508 //Update specific features based on changes 509 if ( change & MASK_KSR ) { 510 UpdateRates( chip ); 511 } 512 //With sustain enable the volume doesn't change 513 if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) { 514 rateZero |= ( 1 << SUSTAIN ); 515 } else { 516 rateZero &= ~( 1 << SUSTAIN ); 517 } 518 //Frequency multiplier or vibrato changed 519 if ( change & (0xf | MASK_VIBRATO) ) { 520 freqMul = chip->freqMul[ val & 0xf ]; 521 UpdateFrequency(); 522 } 523 } 524 525 void Operator::Write40( const Chip* chip, Bit8u val ) { 526 if (!(reg40 ^ val )) 527 return; 528 reg40 = val; 529 UpdateAttenuation( ); 530 } 531 532 void Operator::Write60( const Chip* chip, Bit8u val ) { 533 Bit8u change = reg60 ^ val; 534 reg60 = val; 535 if ( change & 0x0f ) { 536 UpdateDecay( chip ); 537 } 538 if ( change & 0xf0 ) { 539 UpdateAttack( chip ); 540 } 541 } 542 543 void Operator::Write80( const Chip* chip, Bit8u val ) { 544 Bit8u change = (reg80 ^ val ); 545 if ( !change ) 546 return; 547 reg80 = val; 548 Bit8u sustain = val >> 4; 549 //Turn 0xf into 0x1f 550 sustain |= ( sustain + 1) & 0x10; 551 sustainLevel = sustain << ( ENV_BITS - 5 ); 552 if ( change & 0x0f ) { 553 UpdateRelease( chip ); 554 } 555 } 556 557 void Operator::WriteE0( const Chip* chip, Bit8u val ) { 558 if ( !(regE0 ^ val) ) 559 return; 560 //in opl3 mode you can always selet 7 waveforms regardless of waveformselect 561 Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) ); 562 regE0 = val; 563 #if ( DBOPL_WAVE == WAVE_HANDLER ) 564 waveHandler = WaveHandlerTable[ waveForm ]; 565 #else 566 waveBase = WaveTable + WaveBaseTable[ waveForm ]; 567 waveStart = WaveStartTable[ waveForm ] << WAVE_SH; 568 waveMask = WaveMaskTable[ waveForm ]; 569 #endif 570 } 571 572 INLINE void Operator::SetState( Bit8u s ) { 573 state = s; 574 volHandler = VolumeHandlerTable[ s ]; 575 } 576 577 INLINE bool Operator::Silent() const { 578 if ( !ENV_SILENT( totalLevel + activeLevel ) ) 579 return false; 580 if ( !(rateZero & ( 1 << state ) ) ) 581 return false; 582 return true; 583 } 584 585 void Operator::KeyOn( Bit8u mask ) { 586 if ( !keyOn ) { 587 //Restart the frequency generator 588 #if ( DBOPL_WAVE > WAVE_HANDLER ) 589 waveIndex = waveStart; 590 #else 591 waveIndex = 0; 592 #endif 593 rateIndex = 0; 594 SetState( ATTACK ); 595 } 596 keyOn |= mask; 597 } 598 599 void Operator::KeyOff( Bit8u mask ) { 600 keyOn &= ~mask; 601 if ( !keyOn ) { 602 if ( state != OFF ) { 603 SetState( RELEASE ); 604 } 605 } 606 } 607 608 INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { 609 #if ( DBOPL_WAVE == WAVE_HANDLER ) 610 return waveHandler( index, vol << ( 3 - ENV_EXTRA ) ); 611 #elif ( DBOPL_WAVE == WAVE_TABLEMUL ) 612 return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; 613 #elif ( DBOPL_WAVE == WAVE_TABLELOG ) 614 Bit32s wave = waveBase[ index & waveMask ]; 615 Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); 616 Bit32s sig = ExpTable[ total & 0xff ]; 617 Bit32u exp = total >> 8; 618 Bit32s neg = wave >> 16; 619 return ((sig ^ neg) - neg) >> exp; 620 #else 621 #error "No valid wave routine" 622 #endif 623 } 624 625 Bits INLINE Operator::GetSample( Bits modulation ) { 626 Bitu vol = ForwardVolume(); 627 if ( ENV_SILENT( vol ) ) { 628 //Simply forward the wave 629 waveIndex += waveAdd; 630 return 0; 631 } else { 632 Bitu index = ForwardWave(); 633 index += modulation; 634 return GetWave( index, vol ); 635 } 636 } 637 638 Operator::Operator() { 639 chanData = 0; 640 freqMul = 0; 641 waveIndex = 0; 642 waveAdd = 0; 643 keyOn = 0; 644 ksr = 0; 645 reg20 = 0; 646 reg40 = 0; 647 reg60 = 0; 648 reg80 = 0; 649 regE0 = 0; 650 SetState( OFF ); 651 rateZero = (1 << OFF); 652 sustainLevel = ENV_MAX; 653 activeLevel = ENV_MAX; 654 totalLevel = ENV_MAX; 655 } 656 657 /* 658 Channel 659 */ 660 661 Channel::Channel() { 662 old[0] = old[1] = 0; 663 chanData = 0; 664 regB0 = 0; 665 regC0 = 0; 666 maskLeft = -1; 667 maskRight = -1; 668 feedback = 31; 669 fourMask = 0; 670 synthHandler = &Channel::BlockTemplate< sm2FM >; 671 } 672 673 void Channel::SetChanData( const Chip* chip, Bit32u data ) { 674 Bit32u change = chanData ^ data; 675 chanData = data; 676 Op( 0 )->chanData = data; 677 Op( 1 )->chanData = data; 678 //Since a frequency update triggered this, always update frequency 679 Op( 0 )->UpdateFrequency(); 680 Op( 1 )->UpdateFrequency(); 681 if ( change & ( 0xff << SHIFT_KSLBASE ) ) { 682 Op( 0 )->UpdateAttenuation(); 683 Op( 1 )->UpdateAttenuation(); 684 } 685 if ( change & ( 0xff << SHIFT_KEYCODE ) ) { 686 Op( 0 )->UpdateRates( chip ); 687 Op( 1 )->UpdateRates( chip ); 688 } 689 } 690 691 void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) { 692 //Extrace the frequency bits 693 Bit32u data = chanData & 0xffff; 694 Bit32u kslBase = KslTable[ data >> 6 ]; 695 Bit32u keyCode = ( data & 0x1c00) >> 9; 696 if ( chip->reg08 & 0x40 ) { 697 keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ 698 } else { 699 keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ 700 } 701 //Add the keycode and ksl into the highest bits of chanData 702 data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); 703 ( this + 0 )->SetChanData( chip, data ); 704 if ( fourOp & 0x3f ) { 705 ( this + 1 )->SetChanData( chip, data ); 706 } 707 } 708 709 void Channel::WriteA0( const Chip* chip, Bit8u val ) { 710 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; 711 //Don't handle writes to silent fourop channels 712 if ( fourOp > 0x80 ) 713 return; 714 Bit32u change = (chanData ^ val ) & 0xff; 715 if ( change ) { 716 chanData ^= change; 717 UpdateFrequency( chip, fourOp ); 718 } 719 } 720 721 void Channel::WriteB0( const Chip* chip, Bit8u val ) { 722 Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask; 723 //Don't handle writes to silent fourop channels 724 if ( fourOp > 0x80 ) 725 return; 726 Bitu change = (chanData ^ ( val << 8 ) ) & 0x1f00; 727 if ( change ) { 728 chanData ^= change; 729 UpdateFrequency( chip, fourOp ); 730 } 731 //Check for a change in the keyon/off state 732 if ( !(( val ^ regB0) & 0x20)) 733 return; 734 regB0 = val; 735 if ( val & 0x20 ) { 736 Op(0)->KeyOn( 0x1 ); 737 Op(1)->KeyOn( 0x1 ); 738 if ( fourOp & 0x3f ) { 739 ( this + 1 )->Op(0)->KeyOn( 1 ); 740 ( this + 1 )->Op(1)->KeyOn( 1 ); 741 } 742 } else { 743 Op(0)->KeyOff( 0x1 ); 744 Op(1)->KeyOff( 0x1 ); 745 if ( fourOp & 0x3f ) { 746 ( this + 1 )->Op(0)->KeyOff( 1 ); 747 ( this + 1 )->Op(1)->KeyOff( 1 ); 748 } 749 } 750 } 751 752 void Channel::WriteC0( const Chip* chip, Bit8u val ) { 753 Bit8u change = val ^ regC0; 754 if ( !change ) 755 return; 756 regC0 = val; 757 feedback = ( val >> 1 ) & 7; 758 if ( feedback ) { 759 //We shift the input to the right 10 bit wave index value 760 feedback = 9 - feedback; 761 } else { 762 feedback = 31; 763 } 764 //Select the new synth mode 765 if ( chip->opl3Active ) { 766 //4-op mode enabled for this channel 767 if ( (chip->reg104 & fourMask) & 0x3f ) { 768 Channel* chan0, *chan1; 769 //Check if it's the 2nd channel in a 4-op 770 if ( !(fourMask & 0x80 ) ) { 771 chan0 = this; 772 chan1 = this + 1; 773 } else { 774 chan0 = this - 1; 775 chan1 = this; 776 } 777 778 Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); 779 switch ( synth ) { 780 case 0: 781 chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >; 782 break; 783 case 1: 784 chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >; 785 break; 786 case 2: 787 chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >; 788 break; 789 case 3: 790 chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >; 791 break; 792 } 793 //Disable updating percussion channels 794 } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) { 795 796 //Regular dual op, am or fm 797 } else if ( val & 1 ) { 798 synthHandler = &Channel::BlockTemplate< sm3AM >; 799 } else { 800 synthHandler = &Channel::BlockTemplate< sm3FM >; 801 } 802 maskLeft = ( val & 0x10 ) ? -1 : 0; 803 maskRight = ( val & 0x20 ) ? -1 : 0; 804 //opl2 active 805 } else { 806 //Disable updating percussion channels 807 if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { 808 809 //Regular dual op, am or fm 810 } else if ( val & 1 ) { 811 synthHandler = &Channel::BlockTemplate< sm2AM >; 812 } else { 813 synthHandler = &Channel::BlockTemplate< sm2FM >; 814 } 815 } 816 } 817 818 void Channel::ResetC0( const Chip* chip ) { 819 Bit8u val = regC0; 820 regC0 ^= 0xff; 821 WriteC0( chip, val ); 822 } 823 824 template< bool opl3Mode> 825 void Channel::GeneratePercussion( Bit32s* output ) { 826 Channel* chan = this; 827 828 //BassDrum 829 Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; 830 old[0] = old[1]; 831 old[1] = Op(0)->GetSample( mod ); 832 833 //When bassdrum is in AM mode first operator is ignoed 834 if ( chan->regC0 & 1 ) { 835 mod = 0; 836 } else { 837 mod = old[0]; 838 } 839 Bit32s sample = Op(1)->GetSample( mod ); 840 841 Operator* op2 = ( this + 1 )->Op(0); 842 Operator* op4 = ( this + 2 )->Op(0); 843 844 //Precalculate stuff used by other oupts 845 Bit32u noiseBit = rand() & 0x2; 846 Bit32u c2 = op2->ForwardWave(); 847 //(bit 7 ^ bit 2) | bit 3 -> combined in bit 1 848 Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 ); 849 Bit32u c4 = op4->ForwardWave(); 850 //bit 5 ^ bit 3 to bit 1 851 Bit32u gateBit = ( c4 >> 4 ) ^ ( c4 >> 3 ); 852 phaseBit = (phaseBit | gateBit) & 0x2; 853 854 //Hi-Hat 855 Bit32u hhVol = op2->ForwardVolume(); 856 if ( !ENV_SILENT( hhVol ) ) { 857 /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ 858 /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ 859 Bit32u hhIndex = ( phaseBit << 8 ) | ( 0xd0 >> ( phaseBit ^ noiseBit ) ); 860 sample += op2->GetWave( hhIndex, hhVol ); 861 } 862 //Snare Drum 863 Operator* op3 = ( this + 1 )->Op(1); 864 Bit32u sdVol = op3->ForwardVolume(); 865 if ( !ENV_SILENT( sdVol ) ) { 866 Bit32u sdBits = 0x100 + (c2 & 0x100); 867 Bit32u sdIndex = sdBits ^ ( noiseBit << 7 ); 868 sample += op3->GetWave( sdIndex, sdVol ); 869 } 870 //Tom-tom 871 sample += op4->GetSample( 0 ); 872 //Top-Cymbal 873 Operator* op5 = ( this + 2 )->Op(1); 874 Bit32u tcVol = op5->ForwardVolume(); 875 if ( !ENV_SILENT( tcVol ) ) { 876 Bit32u tcIndex = (1 + phaseBit) << 8; 877 sample += op5->GetWave( tcIndex, tcVol ); 878 } 879 sample <<= 1; 880 if ( opl3Mode ) { 881 output[0] += sample; 882 output[1] += sample; 883 } else { 884 output[0] += sample; 885 } 886 } 887 888 template<SynthMode mode> 889 Channel* Channel::BlockTemplate( ) { 890 switch( mode ) { 891 case sm2AM: 892 case sm3AM: 893 if ( Op(0)->Silent() && Op(1)->Silent() ) { 894 old[0] = old[1] = 0; 895 return (this + 1); 896 } 897 break; 898 case sm2FM: 899 case sm3FM: 900 if ( Op(1)->Silent() ) { 901 old[0] = old[1] = 0; 902 return (this + 1); 903 } 904 break; 905 case sm3FMFM: 906 if ( Op(3)->Silent() ) { 907 old[0] = old[1] = 0; 908 return (this + 2); 909 } 910 break; 911 case sm3AMFM: 912 if ( Op(0)->Silent() && Op(3)->Silent() ) { 913 old[0] = old[1] = 0; 914 return (this + 2); 915 } 916 break; 917 case sm3FMAM: 918 if ( Op(1)->Silent() && Op(3)->Silent() ) { 919 old[0] = old[1] = 0; 920 return (this + 2); 921 } 922 break; 923 case sm3AMAM: 924 if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) { 925 old[0] = old[1] = 0; 926 return (this + 2); 927 } 928 break; 929 // TODO: Check this 930 default: 931 break; 932 } 933 for ( Bitu i = 0; i < Work.samples; i++ ) { 934 Work.vibrato = Work.vibTable[i]; 935 Work.tremolo = Work.tremTable[i]; 936 937 //Early out for percussion handlers 938 if ( mode == sm2Percussion ) { 939 GeneratePercussion<false>( Work.output + i ); 940 continue; //Prevent some unitialized value bitching 941 } else if ( mode == sm3Percussion ) { 942 GeneratePercussion<true>( Work.output + i * 2 ); 943 continue; //Prevent some unitialized value bitching 944 } 945 946 //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise 947 Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; 948 old[0] = old[1]; 949 old[1] = Op(0)->GetSample( mod ); 950 Bit32s sample; 951 Bit32s out0 = old[0]; 952 if ( mode == sm2AM || mode == sm3AM ) { 953 sample = out0 + Op(1)->GetSample( 0 ); 954 } else if ( mode == sm2FM || mode == sm3FM ) { 955 sample = Op(1)->GetSample( out0 ); 956 } else if ( mode == sm3FMFM ) { 957 Bits next = Op(1)->GetSample( out0 ); 958 next = Op(2)->GetSample( next ); 959 sample = Op(3)->GetSample( next ); 960 } else if ( mode == sm3AMFM ) { 961 sample = out0; 962 Bits next = Op(1)->GetSample( 0 ); 963 next = Op(2)->GetSample( next ); 964 sample += Op(3)->GetSample( next ); 965 } else if ( mode == sm3FMAM ) { 966 sample = Op(1)->GetSample( out0 ); 967 Bits next = Op(2)->GetSample( 0 ); 968 sample += Op(3)->GetSample( next ); 969 } else if ( mode == sm3AMAM ) { 970 sample = out0; 971 Bits next = Op(1)->GetSample( 0 ); 972 sample += Op(2)->GetSample( next ); 973 sample += Op(3)->GetSample( 0 ); 974 } 975 switch( mode ) { 976 case sm2AM: 977 case sm2FM: 978 Work.output[ i ] += sample; 979 break; 980 case sm3AM: 981 case sm3FM: 982 case sm3FMFM: 983 case sm3AMFM: 984 case sm3FMAM: 985 case sm3AMAM: 986 Work.output[ i * 2 + 0 ] += sample & maskLeft; 987 Work.output[ i * 2 + 1 ] += sample & maskRight; 988 break; 989 // TODO: Check this 990 default: 991 break; 992 } 993 } 994 switch( mode ) { 995 case sm2AM: 996 case sm2FM: 997 case sm3AM: 998 case sm3FM: 999 return ( this + 1 ); 1000 case sm3FMFM: 1001 case sm3AMFM: 1002 case sm3FMAM: 1003 case sm3AMAM: 1004 return( this + 2 ); 1005 case sm2Percussion: 1006 case sm3Percussion: 1007 return( this + 3 ); 1008 } 1009 return 0; 1010 } 1011 1012 /* 1013 Chip 1014 */ 1015 1016 Chip::Chip() { 1017 reg08 = 0; 1018 reg04 = 0; 1019 regBD = 0; 1020 reg104 = 0; 1021 opl3Active = 0; 1022 } 1023 1024 1025 Bit8u Chip::ForwardTremolo( ) { 1026 tremoloCounter += tremoloAdd; 1027 if ( tremoloCounter >= (uint)(TREMOLO_TABLE << TREMOLO_SH) ) { 1028 tremoloCounter -= (uint)(TREMOLO_TABLE << TREMOLO_SH); 1029 } 1030 Bitu index = tremoloCounter >> TREMOLO_SH; 1031 return TremoloTable[ index ] >> tremoloShift; 1032 } 1033 1034 Bit8s Chip::ForwardVibrato( ) { 1035 vibratoCounter += vibratoAdd; 1036 Bitu index = vibratoCounter >> VIBRATO_SH; 1037 //Vibrato shift, basically makes the shift greater reducing the actual final value 1038 return VibratoTable[index & 7] + vibratoShift; 1039 } 1040 1041 void Chip::WriteBD( Bit8u val ) { 1042 Bit8u change = regBD ^ val; 1043 if ( !change ) 1044 return; 1045 regBD = val; 1046 //TODO could do this with shift and xor? 1047 vibratoShift = (val & 0x40) ? 0x00 : 0x01; 1048 tremoloShift = (val & 0x80) ? 0x00 : 0x02; 1049 if ( val & 0x20 ) { 1050 //Drum was just enabled, make sure channel 6 has the right synth 1051 if ( change & 0x20 ) { 1052 if ( opl3Active ) { 1053 chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; 1054 } else { 1055 chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; 1056 } 1057 } 1058 //Bass Drum 1059 if ( val & 0x10 ) { 1060 chan[6].op[0].KeyOn( 0x2 ); 1061 chan[6].op[1].KeyOn( 0x2 ); 1062 } else { 1063 chan[6].op[0].KeyOff( 0x2 ); 1064 chan[6].op[1].KeyOff( 0x2 ); 1065 } 1066 //Hi-Hat 1067 if ( val & 0x1 ) { 1068 chan[7].op[0].KeyOn( 0x2 ); 1069 } else { 1070 chan[7].op[0].KeyOff( 0x2 ); 1071 } 1072 //Snare 1073 if ( val & 0x8 ) { 1074 chan[7].op[1].KeyOn( 0x2 ); 1075 } else { 1076 chan[7].op[1].KeyOff( 0x2 ); 1077 } 1078 //Tom-Tom 1079 if ( val & 0x4 ) { 1080 chan[8].op[0].KeyOn( 0x2 ); 1081 } else { 1082 chan[8].op[0].KeyOff( 0x2 ); 1083 } 1084 //Top Cymbal 1085 if ( val & 0x2 ) { 1086 chan[8].op[1].KeyOn( 0x2 ); 1087 } else { 1088 chan[8].op[1].KeyOff( 0x2 ); 1089 } 1090 //Toggle keyoffs when we turn off the percussion 1091 } else if ( change & 0x20 ) { 1092 //Trigger a reset to setup the original synth handler 1093 chan[6].ResetC0( this ); 1094 chan[6].op[0].KeyOff( 0x2 ); 1095 chan[6].op[1].KeyOff( 0x2 ); 1096 chan[7].op[0].KeyOff( 0x2 ); 1097 chan[7].op[1].KeyOff( 0x2 ); 1098 chan[8].op[0].KeyOff( 0x2 ); 1099 chan[8].op[1].KeyOff( 0x2 ); 1100 } 1101 } 1102 1103 1104 #define REGOP( _FUNC_ ) \ 1105 index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ 1106 if ( OpOffsetTable[ index ] ) { \ 1107 Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \ 1108 regOp->_FUNC_( this, val ); \ 1109 } 1110 1111 #define REGCHAN( _FUNC_ ) \ 1112 index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ 1113 if ( ChanOffsetTable[ index ] ) { \ 1114 Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \ 1115 regChan->_FUNC_( this, val ); \ 1116 } 1117 1118 void Chip::WriteReg( Bit32u reg, Bit8u val ) { 1119 Bitu index; 1120 switch ( (reg & 0xf0) >> 4 ) { 1121 case 0x00 >> 4: 1122 if ( reg == 0x01 ) { 1123 waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; 1124 } else if ( reg == 0x104 ) { 1125 //Only detect changes in lowest 6 bits 1126 if ( !((reg104 ^ val) & 0x3f) ) 1127 return; 1128 //Always keep the highest bit enabled, for checking > 0x80 1129 reg104 = 0x80 | ( val & 0x3f ); 1130 } else if ( reg == 0x105 ) { 1131 //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register 1132 if ( !((opl3Active ^ val) & 1 ) ) 1133 return; 1134 opl3Active = ( val & 1 ) ? 0xff : 0; 1135 //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers 1136 for ( int i = 0; i < 18;i++ ) { 1137 chan[i].ResetC0( this ); 1138 } 1139 } else if ( reg == 0x08 ) { 1140 reg08 = val; 1141 } 1142 case 0x10 >> 4: 1143 break; 1144 case 0x20 >> 4: 1145 case 0x30 >> 4: 1146 REGOP( Write20 ); 1147 break; 1148 case 0x40 >> 4: 1149 case 0x50 >> 4: 1150 REGOP( Write40 ); 1151 break; 1152 case 0x60 >> 4: 1153 case 0x70 >> 4: 1154 REGOP( Write60 ); 1155 break; 1156 case 0x80 >> 4: 1157 case 0x90 >> 4: 1158 REGOP( Write80 ); 1159 break; 1160 case 0xa0 >> 4: 1161 REGCHAN( WriteA0 ); 1162 break; 1163 case 0xb0 >> 4: 1164 if ( reg == 0xbd ) { 1165 WriteBD( val ); 1166 } else { 1167 REGCHAN( WriteB0 ); 1168 } 1169 break; 1170 case 0xc0 >> 4: 1171 REGCHAN( WriteC0 ); 1172 case 0xd0 >> 4: 1173 break; 1174 case 0xe0 >> 4: 1175 case 0xf0 >> 4: 1176 REGOP( WriteE0 ); 1177 break; 1178 } 1179 } 1180 1181 1182 Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { 1183 switch ( port & 3 ) { 1184 case 0: 1185 return val; 1186 case 2: 1187 if ( opl3Active || (val == 0x05) ) 1188 return 0x100 | val; 1189 else 1190 return val; 1191 } 1192 return 0; 1193 } 1194 1195 void Chip::GenerateBlock2( Bitu samples ) { 1196 Work.samples = samples; 1197 for ( Bitu i = 0; i < Work.samples; i++ ) { 1198 Work.vibTable[i] = ForwardVibrato(); 1199 Work.tremTable[i] = ForwardTremolo(); 1200 Work.output[i] = 0; 1201 } 1202 int count = 0; 1203 for( Channel* ch = chan; ch < chan + 9; ) { 1204 count++; 1205 ch = (ch->*(ch->synthHandler))(); 1206 } 1207 } 1208 1209 void Chip::GenerateBlock3( Bitu samples ) { 1210 Work.samples = samples; 1211 for ( Bitu i = 0; i < Work.samples; i++ ) { 1212 Work.vibTable[i] = ForwardVibrato(); 1213 Work.tremTable[i] = ForwardTremolo(); 1214 Work.output[i*2 + 0] = 0; 1215 Work.output[i*2 + 1] = 0; 1216 } 1217 int count = 0; 1218 for( Channel* ch = chan; ch < chan + 18; ) { 1219 count++; 1220 ch = (ch->*(ch->synthHandler))(); 1221 } 1222 } 1223 1224 void Chip::Setup( Bit32u rate ) { 1225 //Vibrato forwards every 1024 samples 1226 vibratoAdd = (Bit32u)((double)rate * (double)( 1 << (VIBRATO_SH - 10) ) / OPLRATE); 1227 vibratoCounter = 0; 1228 //tremolo forwards every 64 samples 1229 //We use a 52 entry table, real is 210, so repeat each sample an extra 4 times 1230 tremoloAdd = (Bit32u)((double)rate * (double)( 1 << (TREMOLO_SH - 6 - 2) ) / OPLRATE); 1231 tremoloCounter = 0; 1232 //10 bits of frequency counter 1233 //With higher octave this gets shifted up 1234 //-1 since the freqCreateTable = *2 1235 double scale = (OPLRATE * (double)( 1 << ( WAVE_SH - 10 - 1))) / rate; 1236 for ( int i = 0; i < 16; i++ ) { 1237 //Use rounding with 0.5 1238 freqMul[i] = (Bit32u)( 0.5 + scale * FreqCreateTable[ i ] ); 1239 } 1240 1241 scale = OPLRATE / rate; 1242 //-3 since the real envelope takes 8 steps to reach the single value we supply 1243 for ( Bit8u i = 0; i < 76; i++ ) { 1244 Bit8u index, shift; 1245 EnvelopeSelect( i, index, shift ); 1246 linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); 1247 } 1248 //Generate the best matching attack rate 1249 for ( Bit8u i = 0; i < 62; i++ ) { 1250 Bit8u index, shift; 1251 EnvelopeSelect( i, index, shift ); 1252 //Original amount of samples the attack would take 1253 Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); 1254 1255 Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); 1256 Bit32s bestAdd; 1257 Bit32u bestDiff = 1 << 30; 1258 for( Bit32u passes = 0; passes < 16; passes ++ ) { 1259 Bit32s volume = ENV_MAX; 1260 Bit32s samples = 0; 1261 Bit32u count = 0; 1262 while ( volume > 0 && samples < original * 2 ) { 1263 count += guessAdd; 1264 Bit32s change = count >> RATE_SH; 1265 count &= RATE_MASK; 1266 if ( change ) { 1267 volume += ( ~volume * change ) >> 3; 1268 } 1269 samples++; 1270 1271 } 1272 Bit32s diff = original - samples; 1273 Bit32u lDiff = labs( diff ); 1274 //Init last on first pass 1275 if ( lDiff < bestDiff ) { 1276 bestDiff = lDiff; 1277 bestAdd = guessAdd; 1278 if ( !bestDiff ) 1279 break; 1280 } 1281 //Below our target 1282 if ( diff < 0 ) { 1283 //Better than the last time 1284 Bit32s mul = ((original - diff) << 12) / original; 1285 guessAdd = ((guessAdd * mul) >> 12); 1286 guessAdd++; 1287 } else if ( diff > 0 ) { 1288 Bit32s mul = ((original - diff) << 12) / original; 1289 guessAdd = (guessAdd * mul) >> 12; 1290 guessAdd--; 1291 } 1292 } 1293 attackRates[i] = bestAdd; 1294 } 1295 for ( Bit8u i = 62; i < 76; i++ ) { 1296 //This should provide instant volume maximizing 1297 attackRates[i] = 8 << RATE_SH; 1298 } 1299 //Setup the channels with the correct four op flags 1300 //Channels are accessed through a table so they appear linear here 1301 chan[ 0].fourMask = 0x00 | ( 1 << 0 ); 1302 chan[ 1].fourMask = 0x80 | ( 1 << 0 ); 1303 chan[ 2].fourMask = 0x00 | ( 1 << 1 ); 1304 chan[ 3].fourMask = 0x80 | ( 1 << 1 ); 1305 chan[ 4].fourMask = 0x00 | ( 1 << 2 ); 1306 chan[ 5].fourMask = 0x80 | ( 1 << 2 ); 1307 1308 chan[ 9].fourMask = 0x00 | ( 1 << 3 ); 1309 chan[10].fourMask = 0x80 | ( 1 << 3 ); 1310 chan[11].fourMask = 0x00 | ( 1 << 4 ); 1311 chan[12].fourMask = 0x80 | ( 1 << 4 ); 1312 chan[13].fourMask = 0x00 | ( 1 << 5 ); 1313 chan[14].fourMask = 0x80 | ( 1 << 5 ); 1314 1315 //mark the percussion channels 1316 chan[ 6].fourMask = 0x40; 1317 chan[ 7].fourMask = 0x40; 1318 chan[ 8].fourMask = 0x40; 1319 1320 //Clear Everything in opl3 mode 1321 WriteReg( 0x105, 0x1 ); 1322 for ( int i = 0; i < 512; i++ ) { 1323 if ( i == 0x105 ) 1324 continue; 1325 WriteReg( i, 0xff ); 1326 WriteReg( i, 0x0 ); 1327 } 1328 WriteReg( 0x105, 0x0 ); 1329 //Clear everything in opl2 mode 1330 for ( int i = 0; i < 255; i++ ) { 1331 WriteReg( i, 0xff ); 1332 WriteReg( i, 0x0 ); 1333 } 1334 } 1335 1336 static bool doneTables = false; 1337 void InitTables( void ) { 1338 if ( doneTables ) 1339 return; 1340 doneTables = true; 1341 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) 1342 //Exponential volume table, same as the real adlib 1343 for ( int i = 0; i < 256; i++ ) { 1344 //Save them in reverse 1345 ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); 1346 ExpTable[i] += 1024; //or remove the -1 oh well :) 1347 //Preshift to the left once so the final volume can shift to the right 1348 ExpTable[i] *= 2; 1349 } 1350 #endif 1351 #if ( DBOPL_WAVE == WAVE_HANDLER ) 1352 //Add 0.5 for the trunc rounding of the integer cast 1353 //Do a PI sinetable instead of the original 0.5 PI 1354 for ( int i = 0; i < 512; i++ ) { 1355 SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); 1356 } 1357 #endif 1358 #if ( DBOPL_WAVE == WAVE_TABLEMUL ) 1359 //Multiplication based tables 1360 for ( int i = 0; i < 384; i++ ) { 1361 int s = i * 8; 1362 //TODO maybe keep some of the precision errors of the original table? 1363 double val = ( 0.5 + ( pow(2, -1 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); 1364 MulTable[i] = (Bit16u)(val); 1365 } 1366 1367 //Sine Wave Base 1368 for ( int i = 0; i < 512; i++ ) { 1369 WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); 1370 WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; 1371 } 1372 //Exponential wave 1373 for ( int i = 0; i < 256; i++ ) { 1374 WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2, -1 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); 1375 WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; 1376 } 1377 #endif 1378 #if ( DBOPL_WAVE == WAVE_TABLELOG ) 1379 //Sine Wave Base 1380 for ( int i = 0; i < 512; i++ ) { 1381 WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); 1382 WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; 1383 } 1384 //Exponential wave 1385 for ( int i = 0; i < 256; i++ ) { 1386 WaveTable[ 0x700 + i ] = i * 8; 1387 WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; 1388 } 1389 #endif 1390 1391 // | |//\\|____|WAV7|//__|/\ |____|/\/\| 1392 // |\\//| | |WAV7| | \/| | | 1393 // |06 |0126|27 |7 |3 |4 |4 5 |5 | 1394 1395 #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) 1396 for ( int i = 0; i < 256; i++ ) { 1397 //Fill silence gaps 1398 WaveTable[ 0x400 + i ] = WaveTable[0]; 1399 WaveTable[ 0x500 + i ] = WaveTable[0]; 1400 WaveTable[ 0x900 + i ] = WaveTable[0]; 1401 WaveTable[ 0xc00 + i ] = WaveTable[0]; 1402 WaveTable[ 0xd00 + i ] = WaveTable[0]; 1403 //Replicate sines in other pieces 1404 WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; 1405 //double speed sines 1406 WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; 1407 WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; 1408 WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; 1409 WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; 1410 } 1411 #endif 1412 1413 //Create the ksl table 1414 for ( int oct = 0; oct < 8; oct++ ) { 1415 int base = oct * 8; 1416 for ( int i = 0; i < 16; i++ ) { 1417 int val = base - KslCreateTable[i]; 1418 if ( val < 0 ) 1419 val = 0; 1420 //*4 for the final range to match attenuation range 1421 KslTable[ oct * 16 + i ] = val * 4; 1422 } 1423 } 1424 //Create the Tremolo table, just increase and decrease a triangle wave 1425 for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) { 1426 Bit8u val = i << ENV_EXTRA; 1427 TremoloTable[i] = val; 1428 TremoloTable[TREMOLO_TABLE - 1 - i] = val; 1429 } 1430 //Create a table with offsets of the channels from the start of the chip 1431 for ( Bitu i = 0; i < 32; i++ ) { 1432 Bitu index = i & 0xf; 1433 if ( index >= 9 ) { 1434 ChanOffsetTable[i] = 0; 1435 continue; 1436 } 1437 //Make sure the four op channels follow eachother 1438 if ( index < 6 ) { 1439 index = (index % 3) * 2 + ( index / 3 ); 1440 } 1441 //Add back the bits for highest ones 1442 if ( i >= 16 ) 1443 index += 9; 1444 ChanOffsetTable[i] = OFFS(Chip, chan) + index * sizeof(Channel); 1445 } 1446 //Same for operators 1447 for ( Bitu i = 0; i < 64; i++ ) { 1448 if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { 1449 OpOffsetTable[i] = 0; 1450 continue; 1451 } 1452 Bitu chNum = (i / 8) * 3 + (i % 8) % 3; 1453 //Make sure we use 16 and up for the 2nd range to match the chanoffset gap 1454 if ( chNum >= 12 ) 1455 chNum += 16 - 12; 1456 Bitu opNum = ( i % 8 ) / 3; 1457 OpOffsetTable[i] = ChanOffsetTable[ chNum ] + OFFS(Channel, op) + opNum * sizeof(Operator); 1458 } 1459 } 1460 1461 Bit32u Handler::writeAddr( Bit32u port, Bit8u val ) { 1462 return chip.WriteAddr( port, val ); 1463 1464 } 1465 void Handler::writeReg( Bit32u addr, Bit8u val ) { 1466 chip.WriteReg( addr, val ); 1467 } 1468 1469 void Handler::generate( Bit16s *chan, Bitu samples ) { 1470 // Opl3 is stereo thus we half the number of samples here. 1471 1472 while (samples > 0) { 1473 Bitu todo = samples > MAX_SAMPLES ? MAX_SAMPLES : samples; 1474 samples -= todo; 1475 if ( !chip.opl3Active ) { 1476 chip.GenerateBlock2( todo ); 1477 for (uint i = 0; i < todo; ++i) 1478 chan[i] = Work.output[i]; 1479 chan += todo; 1480 } else { 1481 chip.GenerateBlock3( samples ); 1482 for (uint i = 0; i < (todo << 1); ++i) 1483 chan[i] = Work.output[i]; 1484 chan += (todo << 1); 1485 } 1486 } 1487 } 1488 1489 void Handler::init( Bitu rate ) { 1490 InitTables(); 1491 chip.Setup( rate ); 1492 } 1493 1494 } // end of namespace DBOPL 1495 } // end of namespace DOSBox 1496 } // end of namespace OPL 1497 1498 #endif 1499 -
sound/softsynth/opl/dosbox.h
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 /* 26 * Based on OPL emulation code of DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * Licensed under GPLv2+ 29 * http://www.dosbox.com 30 */ 31 32 #ifndef SOUND_SOFTSYNTH_OPL_DOSBOX_H 33 #define SOUND_SOFTSYNTH_OPL_DOSBOX_H 34 35 #ifndef DISABLE_DOSBOX_OPL 36 37 #include "sound/fmopl.h" 38 39 namespace OPL { 40 namespace DOSBox { 41 42 class Handler; 43 44 struct Timer { 45 double startTime; 46 double delay; 47 bool enabled, overflow, masked; 48 uint8 counter; 49 50 Timer(); 51 52 //Call update before making any further changes 53 void update(double time); 54 55 //On a reset make sure the start is in sync with the next cycle 56 void reset(double time); 57 58 void stop(); 59 60 void start(double time, int scale); 61 }; 62 63 struct Chip { 64 //Last selected register 65 Timer timer[2]; 66 //Check for it being a write to the timer 67 bool write(uint32 addr, uint8 val); 68 //Read the current timer state, will use current double 69 uint8 read(); 70 }; 71 72 class Handler { 73 public: 74 virtual ~Handler() {} 75 76 // Write an address to a chip, returns the address the chip sets 77 virtual uint32 writeAddr(uint32 port, uint8 val) = 0; 78 // Write to a specific register in the chip 79 virtual void writeReg(uint32 addr, uint8 val) = 0; 80 // Generate a certain amount of samples 81 virtual void generate(int16 *chan, uint samples) = 0; 82 // Initialize at a specific sample rate and mode 83 virtual void init(uint rate) = 0; 84 }; 85 86 class OPL_DOSBox : public OPL { 87 private: 88 kOplType _type; 89 uint _rate; 90 91 Handler *_handler; 92 Chip _chip[2]; 93 union { 94 uint16 normal; 95 uint8 dual[2]; 96 } _reg; 97 98 void free(); 99 public: 100 OPL_DOSBox(kOplType type); 101 ~OPL_DOSBox(); 102 103 bool init(int rate); 104 void reset(); 105 106 void write(int a, int v); 107 byte read(int a); 108 109 void writeReg(int r, int v); 110 111 void readBuffer(int16 *buffer, int length); 112 }; 113 114 } // end of namespace DOSBox 115 } // end of namespace OPL 116 117 #endif // !DISABLE_DOSBOX_OPL 118 119 #endif 120 -
sound/softsynth/opl/mame.h
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.h $ 22 * $Id: fmopl.h 38211 2009-02-15 10:07:50Z sev $ 23 * 24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by 25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug. 26 */ 27 28 29 #ifndef SOUND_SOFTSYNTH_OPL_MAME_H 30 #define SOUND_SOFTSYNTH_OPL_MAME_H 31 32 #include "common/scummsys.h" 33 #include "common/util.h" 34 35 #include "sound/fmopl.h" 36 37 namespace OPL { 38 namespace MAME { 39 40 enum { 41 FMOPL_ENV_BITS_HQ = 16, 42 FMOPL_ENV_BITS_MQ = 8, 43 FMOPL_ENV_BITS_LQ = 8, 44 FMOPL_EG_ENT_HQ = 4096, 45 FMOPL_EG_ENT_MQ = 1024, 46 FMOPL_EG_ENT_LQ = 128 47 }; 48 49 50 typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); 51 typedef void (*OPL_IRQHANDLER)(int param,int irq); 52 typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); 53 54 #define OPL_TYPE_WAVESEL 0x01 /* waveform select */ 55 56 /* Saving is necessary for member of the 'R' mark for suspend/resume */ 57 /* ---------- OPL one of slot ---------- */ 58 typedef struct fm_opl_slot { 59 int TL; /* total level :TL << 8 */ 60 int TLL; /* adjusted now TL */ 61 uint8 KSR; /* key scale rate :(shift down bit) */ 62 int *AR; /* attack rate :&AR_TABLE[AR<<2] */ 63 int *DR; /* decay rate :&DR_TABLE[DR<<2] */ 64 int SL; /* sustain level :SL_TABLE[SL] */ 65 int *RR; /* release rate :&DR_TABLE[RR<<2] */ 66 uint8 ksl; /* keyscale level :(shift down bits) */ 67 uint8 ksr; /* key scale rate :kcode>>KSR */ 68 uint mul; /* multiple :ML_TABLE[ML] */ 69 uint Cnt; /* frequency count */ 70 uint Incr; /* frequency step */ 71 72 /* envelope generator state */ 73 uint8 eg_typ;/* envelope type flag */ 74 uint8 evm; /* envelope phase */ 75 int evc; /* envelope counter */ 76 int eve; /* envelope counter end point */ 77 int evs; /* envelope counter step */ 78 int evsa; /* envelope step for AR :AR[ksr] */ 79 int evsd; /* envelope step for DR :DR[ksr] */ 80 int evsr; /* envelope step for RR :RR[ksr] */ 81 82 /* LFO */ 83 uint8 ams; /* ams flag */ 84 uint8 vib; /* vibrate flag */ 85 /* wave selector */ 86 int **wavetable; 87 } OPL_SLOT; 88 89 /* ---------- OPL one of channel ---------- */ 90 typedef struct fm_opl_channel { 91 OPL_SLOT SLOT[2]; 92 uint8 CON; /* connection type */ 93 uint8 FB; /* feed back :(shift down bit)*/ 94 int *connect1; /* slot1 output pointer */ 95 int *connect2; /* slot2 output pointer */ 96 int op1_out[2]; /* slot1 output for selfeedback */ 97 98 /* phase generator state */ 99 uint block_fnum; /* block+fnum */ 100 uint8 kcode; /* key code : KeyScaleCode */ 101 uint fc; /* Freq. Increment base */ 102 uint ksl_base; /* KeyScaleLevel Base step */ 103 uint8 keyon; /* key on/off flag */ 104 } OPL_CH; 105 106 /* OPL state */ 107 typedef struct fm_opl_f { 108 uint8 type; /* chip type */ 109 int clock; /* master clock (Hz) */ 110 int rate; /* sampling rate (Hz) */ 111 double freqbase; /* frequency base */ 112 double TimerBase; /* Timer base time (==sampling time) */ 113 uint8 address; /* address register */ 114 uint8 status; /* status flag */ 115 uint8 statusmask; /* status mask */ 116 uint mode; /* Reg.08 : CSM , notesel,etc. */ 117 118 /* Timer */ 119 int T[2]; /* timer counter */ 120 uint8 st[2]; /* timer enable */ 121 122 /* FM channel slots */ 123 OPL_CH *P_CH; /* pointer of CH */ 124 int max_ch; /* maximum channel */ 125 126 /* Rythm sention */ 127 uint8 rythm; /* Rythm mode , key flag */ 128 129 /* time tables */ 130 int AR_TABLE[76]; /* atttack rate tables */ 131 int DR_TABLE[76]; /* decay rate tables */ 132 uint FN_TABLE[1024];/* fnumber -> increment counter */ 133 134 /* LFO */ 135 int *ams_table; 136 int *vib_table; 137 int amsCnt; 138 int amsIncr; 139 int vibCnt; 140 int vibIncr; 141 142 /* wave selector enable flag */ 143 uint8 wavesel; 144 145 /* external event callback handler */ 146 OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ 147 int TimerParam; /* TIMER parameter */ 148 OPL_IRQHANDLER IRQHandler; /* IRQ handler */ 149 int IRQParam; /* IRQ parameter */ 150 OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ 151 int UpdateParam; /* stream update parameter */ 152 153 Common::RandomSource rnd; 154 } FM_OPL; 155 156 /* ---------- Generic interface section ---------- */ 157 #define OPL_TYPE_YM3526 (0) 158 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) 159 160 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM); 161 162 FM_OPL *OPLCreate(int type, int clock, int rate); 163 void OPLDestroy(FM_OPL *OPL); 164 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset); 165 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param); 166 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param); 167 168 void OPLResetChip(FM_OPL *OPL); 169 int OPLWrite(FM_OPL *OPL, int a, int v); 170 unsigned char OPLRead(FM_OPL *OPL, int a); 171 int OPLTimerOver(FM_OPL *OPL, int c); 172 void OPLWriteReg(FM_OPL *OPL, int r, int v); 173 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave = 0); 174 175 // Factory method 176 FM_OPL *makeAdlibOPL(int rate); 177 178 // OPL API implementation 179 class OPL_MAME : public OPL { 180 private: 181 FM_OPL *_opl; 182 public: 183 OPL_MAME() : _opl(0) {} 184 ~OPL_MAME(); 185 186 bool init(int rate); 187 void reset(); 188 189 void write(int a, int v); 190 byte read(int a); 191 192 void writeReg(int r, int v); 193 194 void readBuffer(int16 *buffer, int length); 195 }; 196 197 } // end of namespace MAME 198 } // end of namespace OPL 199 200 #endif -
sound/softsynth/opl/dbopl.h
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 */ 24 25 /* 26 * Based on AdLib emulation code of DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * Licensed under GPLv2+ 29 * http://www.dosbox.com 30 31 * Original source file header: 32 33 * Copyright (C) 2002-2009 The DOSBox Team 34 * 35 * This program is free software; you can redistribute it and/or modify 36 * it under the terms of the GNU General Public License as published by 37 * the Free Software Foundation; either version 2 of the License, or 38 * (at your option) any later version. 39 * 40 * This program is distributed in the hope that it will be useful, 41 * but WITHOUT ANY WARRANTY; without even the implied warranty of 42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 43 * GNU General Public License for more details. 44 * 45 * You should have received a copy of the GNU General Public License 46 * along with this program; if not, write to the Free Software 47 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 48 */ 49 50 #ifndef DISABLE_DOSBOX_OPL 51 52 #ifndef SOUND_SOFTSYNTH_OPL_DBOPL_H 53 #define SOUND_SOFTSYNTH_OPL_DBOPL_H 54 55 #include "common/scummsys.h" 56 #include "dosbox.h" 57 58 #ifndef DB_FASTCALL 59 #define DB_FASTCALL 60 #endif 61 62 //Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume 63 #define WAVE_HANDLER 10 64 //Use a logarithmic wavetable with an exponential table for volume 65 #define WAVE_TABLELOG 11 66 //Use a linear wavetable with a multiply table for volume 67 #define WAVE_TABLEMUL 12 68 69 //Select the type of wave generator routine 70 #define DBOPL_WAVE WAVE_TABLEMUL 71 //Enable vibrato in the output 72 #define DBOPL_VIBRATO 73 //Enable tremolo in the output 74 #define DBOPL_TREMOLO 75 76 namespace OPL { 77 namespace DOSBox { 78 namespace DBOPL { 79 80 // Define types required by DOSBox code 81 typedef int Bits; 82 typedef uint Bitu; 83 typedef int8 Bit8s; 84 typedef uint8 Bit8u; 85 typedef int16 Bit16s; 86 typedef uint16 Bit16u; 87 typedef int32 Bit32s; 88 typedef uint32 Bit32u; 89 90 struct Chip; 91 struct Operator; 92 struct Channel; 93 94 #if (DBOPL_WAVE == WAVE_HANDLER) 95 typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); 96 #endif 97 98 typedef Bits ( DBOPL::Operator::*VolumeHandler) ( ); 99 typedef Channel* ( DBOPL::Channel::*SynthHandler) ( ); 100 101 //Different synth modes that can generate blocks of data 102 enum SynthMode { 103 smNone, 104 sm2AM, 105 sm2FM, 106 sm2Percussion, 107 sm3AM, 108 sm3FM, 109 sm3FMFM, 110 sm3AMFM, 111 sm3FMAM, 112 sm3AMAM, 113 sm3Percussion 114 }; 115 116 //Shifts for the values contained in chandata variable 117 enum { 118 SHIFT_KSLBASE = 16, 119 SHIFT_KEYCODE = 24 120 }; 121 122 struct Operator { 123 public: 124 //Masks for operator 20 values 125 enum { 126 MASK_KSR = 0x10, 127 MASK_SUSTAIN = 0x20, 128 MASK_VIBRATO = 0x40, 129 MASK_TREMOLO = 0x80 130 }; 131 132 enum State { 133 OFF, 134 RELEASE, 135 SUSTAIN, 136 DECAY, 137 ATTACK 138 }; 139 140 VolumeHandler volHandler; 141 142 #if (DBOPL_WAVE == WAVE_HANDLER) 143 WaveHandler waveHandler; //Routine that generate a wave 144 #else 145 Bit16s* waveBase; 146 Bit32u waveMask; 147 Bit32u waveStart; 148 #endif 149 Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index 150 Bit32u waveAdd; 151 152 Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this 153 Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? 154 Bit32u vibrato; //Scaled up vibrato strength 155 Bit32s sustainLevel; //When stopping at sustain level stop here 156 Bit32s totalLevel; //totalLeve is added to every generated volume 157 Bit32s activeLevel; //The currently active volume 158 159 Bit32u attackAdd; //Timers for the different states of the envelope 160 Bit32u decayAdd; 161 Bit32u releaseAdd; 162 Bit32u rateIndex; //Current position of the evenlope 163 164 Bit8u rateZero; //Bits for the different states of the envelope having no changes 165 Bit8u keyOn; //Bitmask of different values that can generate keyon 166 //Registers, also used to check for changes 167 Bit8u reg20, reg40, reg60, reg80, regE0; 168 //Active part of the envelope we're in 169 Bit8u state; 170 //0xff when tremolo is enabled 171 Bit8u tremoloMask; 172 //Strength of the vibrato 173 Bit8u vibStrength; 174 //Keep track of the calculated KSR so we can check for changes 175 Bit8u ksr; 176 private: 177 void SetState( Bit8u s ); 178 void UpdateAttack( const Chip* chip ); 179 void UpdateRelease( const Chip* chip ); 180 void UpdateDecay( const Chip* chip ); 181 public: 182 void UpdateAttenuation(); 183 void UpdateRates( const Chip* chip ); 184 void UpdateFrequency( ); 185 186 void Write20( const Chip* chip, Bit8u val ); 187 void Write40( const Chip* chip, Bit8u val ); 188 void Write60( const Chip* chip, Bit8u val ); 189 void Write80( const Chip* chip, Bit8u val ); 190 void WriteE0( const Chip* chip, Bit8u val ); 191 192 bool Silent() const; 193 void KeyOn( Bit8u mask); 194 void KeyOff( Bit8u mask); 195 196 template< State state> 197 Bits TemplateVolume( ); 198 199 Bit32s RateForward( Bit32u add ); 200 Bitu ForwardWave(); 201 Bitu ForwardVolume(); 202 203 Bits GetSample( Bits modulation ); 204 Bits GetWave( Bitu index, Bitu vol ); 205 public: 206 Operator(); 207 }; 208 209 struct Channel { 210 Operator op[2]; 211 inline Operator* Op( Bitu index ) { 212 return &( ( this + (index >> 1) )->op[ index & 1 ]); 213 } 214 SynthHandler synthHandler; 215 Bit32u chanData; //Frequency/octave and derived values 216 Bit32s old[2]; //Old data for feedback 217 218 Bit8u feedback; //Feedback shift 219 Bit8u regB0; //Register values to check for changes 220 Bit8u regC0; 221 //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel 222 Bit8u fourMask; 223 Bit8s maskLeft; //Sign extended values for both channel's panning 224 Bit8s maskRight; 225 226 //Forward the channel data to the operators of the channel 227 void SetChanData( const Chip* chip, Bit32u data ); 228 //Change in the chandata, check for new values and if we have to forward to operators 229 void UpdateFrequency( const Chip* chip, Bit8u fourOp ); 230 void WriteA0( const Chip* chip, Bit8u val ); 231 void WriteB0( const Chip* chip, Bit8u val ); 232 void WriteC0( const Chip* chip, Bit8u val ); 233 void ResetC0( const Chip* chip ); 234 235 //call this for the first channel 236 template< bool opl3Mode > 237 void GeneratePercussion( Bit32s* output ); 238 239 //Generate blocks of data in specific modes 240 template<SynthMode mode> 241 Channel* BlockTemplate( ); 242 Channel(); 243 }; 244 245 struct Chip { 246 //This is used as the base counter for vibrato and tremolo 247 Bit32u tremoloCounter; 248 Bit32u tremoloAdd; 249 Bit32u vibratoCounter; 250 Bit32u vibratoAdd; 251 252 //Frequency scales for the different multiplications 253 Bit32u freqMul[16]; 254 //Rates for decay and release for rate of this chip 255 Bit32u linearRates[76]; 256 //Best match attack rates for the rate of this chip 257 Bit32u attackRates[76]; 258 259 //18 channels with 2 operators each 260 Channel chan[18]; 261 262 Bit8u reg104; 263 Bit8u reg08; 264 Bit8u reg04; 265 Bit8u regBD; 266 Bit8u vibratoShift; 267 Bit8u tremoloShift; 268 //Mask for allowed wave forms 269 Bit8u waveFormMask; 270 //0 or -1 when enabled 271 Bit8s opl3Active; 272 273 Bit8u ForwardTremolo(); 274 Bit8s ForwardVibrato(); 275 276 void WriteBD( Bit8u val ); 277 void WriteReg(Bit32u reg, Bit8u val ); 278 279 Bit32u WriteAddr( Bit32u port, Bit8u val ); 280 281 void GenerateBlock2( Bitu samples ); 282 void GenerateBlock3( Bitu samples ); 283 284 void Generate( Bit32u samples ); 285 void Setup( Bit32u r ); 286 287 Chip(); 288 }; 289 290 struct Handler : public DOSBox::Handler { 291 DBOPL::Chip chip; 292 293 virtual Bit32u writeAddr( Bit32u port, Bit8u val ); 294 virtual void writeReg( Bit32u addr, Bit8u val ); 295 virtual void generate( Bit16s *chan, Bitu samples ); 296 virtual void init( Bitu rate ); 297 }; 298 299 } // end of namespace DBOPL 300 } // end of namespace DOSBox 301 } // end of namespace OPL 302 303 #endif 304 305 #endif 306