1 /* 2 * Copyright (C) 1999/2000 Tatsuyuki Satoh 3 * Copyright (C) 2001-2016 The ScummVM project 4 * Copyright (C) 2003 The Pentagram Team 5 * Copyright (C) 2002/2016 The Exult Team 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 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by 22 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug. 23 * 24 */ 25 26 #ifndef FMOPL_H 27 #define FMOPL_H 28 29 #ifdef USE_FMOPL_MIDI 30 31 #include "common_types.h" 32 33 namespace FMOpl_Pentagram { 34 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 }; 43 44 45 using OPL_TIMERHANDLER = void (*)(int channel, double interval_Sec); 46 using OPL_IRQHANDLER = void (*)(int param, int irq); 47 using OPL_UPDATEHANDLER = void (*)(int param, int min_interval_us); 48 49 #define OPL_TYPE_WAVESEL 0x01 /* waveform select */ 50 51 // Modulation Registers 52 #define INDEX_AVEKM_M 0 53 #define INDEX_KSLTL_M 2 54 #define INDEX_AD_M 4 55 #define INDEX_SR_M 6 56 #define INDEX_WAVE_M 8 57 58 // Carrier Registers 59 #define INDEX_AVEKM_C 1 60 #define INDEX_KSLTL_C 3 61 #define INDEX_AD_C 5 62 #define INDEX_SR_C 7 63 #define INDEX_WAVE_C 9 64 65 #define INDEX_FB_C 10 66 #define INDEX_PERC 11 67 68 #define CHP_CHAN 0 69 #define CHP_NOTE 1 70 #define CHP_COUNTER 2 71 #define CHP_VEL 3 72 73 /* Saving is necessary for member of the 'R' mark for suspend/resume */ 74 /* ---------- OPL one of slot ---------- */ 75 struct OPL_SLOT { 76 int TL; /* total level :TL << 8 */ 77 int TLL; /* adjusted now TL */ 78 uint8 KSR; /* key scale rate :(shift down bit) */ 79 int *AR; /* attack rate :&AR_TABLE[AR<<2] */ 80 int *DR; /* decay rate :&DR_TABLE[DR<<2] */ 81 int SL; /* sustain level :SL_TABLE[SL] */ 82 int *RR; /* release rate :&DR_TABLE[RR<<2] */ 83 uint8 ksl; /* keyscale level :(shift down bits) */ 84 uint8 ksr; /* key scale rate :kcode>>KSR */ 85 uint32 mul; /* multiple :ML_TABLE[ML] */ 86 uint32 Cnt; /* frequency count */ 87 uint32 Incr; /* frequency step */ 88 89 /* envelope generator state */ 90 uint8 eg_typ;/* envelope type flag */ 91 uint8 evm; /* envelope phase */ 92 int evc; /* envelope counter */ 93 int eve; /* envelope counter end point */ 94 int evs; /* envelope counter step */ 95 int evsa; /* envelope step for AR :AR[ksr] */ 96 int evsd; /* envelope step for DR :DR[ksr] */ 97 int evsr; /* envelope step for RR :RR[ksr] */ 98 99 /* LFO */ 100 uint8 ams; /* ams flag */ 101 uint8 vib; /* vibrate flag */ 102 /* wave selector */ 103 int **wavetable; 104 }; 105 106 /* ---------- OPL one of channel ---------- */ 107 struct OPL_CH { 108 OPL_SLOT SLOT[2]; 109 uint8 CON; /* connection type */ 110 uint8 FB; /* feed back :(shift down bit)*/ 111 int *connect1; /* slot1 output pointer */ 112 int *connect2; /* slot2 output pointer */ 113 int op1_out[2]; /* slot1 output for selfeedback */ 114 115 /* phase generator state */ 116 uint32 block_fnum; /* block+fnum */ 117 uint8 kcode; /* key code : KeyScaleCode */ 118 uint32 fc; /* Freq. Increment base */ 119 uint32 ksl_base; /* KeyScaleLevel Base step */ 120 uint8 keyon; /* key on/off flag */ 121 uint8 PAN; /* pan */ 122 }; 123 124 constexpr const size_t max_opl_channels = 9; 125 126 /* OPL state */ 127 struct FM_OPL { 128 uint8 type; /* chip type */ 129 int clock; /* master clock (Hz) */ 130 int rate; /* sampling rate (Hz) */ 131 double freqbase; /* frequency base */ 132 double TimerBase; /* Timer base time (==sampling time) */ 133 uint8 address; /* address register */ 134 uint8 status; /* status flag */ 135 uint8 statusmask; /* status mask */ 136 uint32 mode; /* Reg.08 : CSM , notesel,etc. */ 137 138 /* Timer */ 139 int T[2]; /* timer counter */ 140 uint8 st[2]; /* timer enable */ 141 142 /* FM channel slots */ 143 OPL_CH *P_CH; /* pointer of CH */ 144 int max_ch; /* maximum channel */ 145 146 /* Rythm sention */ 147 uint8 rythm; /* Rythm mode , key flag */ 148 149 /* time tables */ 150 int AR_TABLE[76]; /* atttack rate tables */ 151 int DR_TABLE[76]; /* decay rate tables */ 152 uint32 FN_TABLE[1024];/* fnumber -> increment counter */ 153 154 /* LFO */ 155 int *ams_table; 156 int *vib_table; 157 int amsCnt; 158 int amsIncr; 159 int vibCnt; 160 int vibIncr; 161 162 /* wave selector enable flag */ 163 uint8 wavesel; 164 165 /* external event callback handler */ 166 OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ 167 int TimerParam; /* TIMER parameter */ 168 OPL_IRQHANDLER IRQHandler; /* IRQ handler */ 169 int IRQParam; /* IRQ parameter */ 170 OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ 171 int UpdateParam; /* stream update parameter */ 172 173 OPL_CH channels[max_opl_channels]; 174 }; 175 176 /* ---------- Generic interface section ---------- */ 177 #define OPL_TYPE_YM3526 (0) 178 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) 179 180 // Modulation Registers 181 #define OPL_REG_AVEKM_M 0x20 182 #define OPL_REG_KSLTL_M 0x40 183 #define OPL_REG_AD_M 0x60 184 #define OPL_REG_SR_M 0x80 185 #define OPL_REG_WAVE_M 0xE0 186 187 // Carrier Registers 188 #define OPL_REG_AVEKM_C 0x23 189 #define OPL_REG_KSLTL_C 0x43 190 #define OPL_REG_AD_C 0x63 191 #define OPL_REG_SR_C 0x83 192 #define OPL_REG_WAVE_C 0xE3 193 194 #define OPL_REG_FB_C 0xC0 195 196 197 void OPLBuildTables(uint32 ENV_BITS_PARAM, uint32 EG_ENT_PARAM); 198 199 FM_OPL *OPLCreate(int type, int clock, int rate); 200 void OPLDestroy(FM_OPL *OPL); 201 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset); 202 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param); 203 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param); 204 205 void OPLResetChip(FM_OPL *OPL); 206 int OPLWrite(FM_OPL *OPL, int a, int v); 207 unsigned char OPLRead(FM_OPL *OPL, int a); 208 int OPLTimerOver(FM_OPL *OPL, int c); 209 void OPLWriteReg(FM_OPL *OPL, int r, int v); 210 void OPLSetPan(FM_OPL *OPL,int c, int pan); 211 212 // Factory method 213 FM_OPL *makeAdLibOPL(int rate); 214 215 void YM3812UpdateOne_Mono(FM_OPL *OPL, sint16 *buffer, int length); 216 void YM3812UpdateOne_Stereo(FM_OPL *OPL, sint16 *buffer, int length); 217 218 } 219 220 #endif //USE_FMOPL_MIDI 221 222 #endif //FMOPL_H 223