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 */ 22 23 #ifndef NUVIE_SOUND_ADPLUG_OPL_CLASS_H 24 #define NUVIE_SOUND_ADPLUG_OPL_CLASS_H 25 26 #include "ultima/nuvie/sound/adplug/opl.h" 27 28 namespace Ultima { 29 namespace Nuvie { 30 31 #define HAS_YM3812 1 32 33 /* --- select emulation chips --- */ 34 #define BUILD_YM3812 (HAS_YM3812) 35 #define BUILD_YM3526 (HAS_YM3526) 36 #define BUILD_Y8950 (HAS_Y8950) 37 38 /* select output bits size of output : 8 or 16 */ 39 #define OPL_SAMPLE_BITS 16 40 41 /* compiler dependence */ 42 #ifndef OSD_CPU_H 43 #define OSD_CPU_H 44 typedef unsigned char uint8; /* unsigned 8bit */ 45 typedef unsigned short UINT16; /* unsigned 16bit */ 46 typedef unsigned int uint32; /* unsigned 32bit */ 47 typedef signed char int8; /* signed 8bit */ 48 typedef signed short int16; /* signed 16bit */ 49 typedef signed int int32; /* signed 32bit */ 50 #endif 51 52 #if (OPL_SAMPLE_BITS==16) 53 typedef int16 OPLSAMPLE; 54 #endif 55 #if (OPL_SAMPLE_BITS==8) 56 typedef int8 OPLSAMPLE; 57 #endif 58 59 60 typedef void (*OPL_TIMERHANDLER)(int channel, double interval_Sec); 61 typedef void (*OPL_IRQHANDLER)(int param, int irq); 62 typedef void (*OPL_UPDATEHANDLER)(int param, int min_interval_us); 63 typedef void (*OPL_PORTHANDLER_W)(int param, unsigned char data); 64 typedef unsigned char (*OPL_PORTHANDLER_R)(int param); 65 66 /* Saving is necessary for member of the 'R' mark for suspend/resume */ 67 68 typedef struct { 69 uint32 ar; /* attack rate: AR<<2 */ 70 uint32 dr; /* decay rate: DR<<2 */ 71 uint32 rr; /* release rate:RR<<2 */ 72 uint8 KSR; /* key scale rate */ 73 uint8 ksl; /* keyscale level */ 74 uint8 ksr; /* key scale rate: kcode>>KSR */ 75 uint8 mul; /* multiple: mul_tab[ML] */ 76 77 /* Phase Generator */ 78 uint32 Cnt; /* frequency counter */ 79 uint32 Incr; /* frequency counter step */ 80 uint8 FB; /* feedback shift value */ 81 int32 *connect1; /* slot1 output pointer */ 82 int32 op1_out[2]; /* slot1 output for feedback */ 83 uint8 CON; /* connection (algorithm) type */ 84 85 /* Envelope Generator */ 86 uint8 eg_type; /* percussive/non-percussive mode */ 87 uint8 state; /* phase type */ 88 uint32 TL; /* total level: TL << 2 */ 89 int32 TLL; /* adjusted now TL */ 90 int32 volume; /* envelope counter */ 91 uint32 sl; /* sustain level: sl_tab[SL] */ 92 93 uint8 eg_sh_ar; /* (attack state) */ 94 uint8 eg_sel_ar; /* (attack state) */ 95 uint8 eg_sh_dr; /* (decay state) */ 96 uint8 eg_sel_dr; /* (decay state) */ 97 uint8 eg_sh_rr; /* (release state) */ 98 uint8 eg_sel_rr; /* (release state) */ 99 100 uint32 key; /* 0 = KEY OFF, >0 = KEY ON */ 101 102 /* LFO */ 103 uint32 AMmask; /* LFO Amplitude Modulation enable mask */ 104 uint8 vib; /* LFO Phase Modulation enable flag (active high)*/ 105 106 /* waveform select */ 107 unsigned int wavetable; 108 } OPL_SLOT; 109 110 typedef struct { 111 OPL_SLOT SLOT[2]; 112 /* phase generator state */ 113 uint32 block_fnum; /* block+fnum */ 114 uint32 fc; /* Freq. Increment base */ 115 uint32 ksl_base; /* KeyScaleLevel Base step */ 116 uint8 kcode; /* key code (for key scaling) */ 117 } OPL_CH; 118 119 /* OPL state */ 120 typedef struct fm_opl_f { 121 /* FM channel slots */ 122 OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ 123 124 uint32 eg_cnt; /* global envelope generator counter */ 125 uint32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ 126 uint32 eg_timer_add; /* step of eg_timer */ 127 uint32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ 128 129 uint8 rhythm; /* Rhythm mode */ 130 131 uint32 fn_tab[1024]; /* fnumber->increment counter */ 132 133 /* LFO */ 134 uint8 lfo_am_depth; 135 uint8 lfo_pm_depth_range; 136 uint32 lfo_am_cnt; 137 uint32 lfo_am_inc; 138 uint32 lfo_pm_cnt; 139 uint32 lfo_pm_inc; 140 141 uint32 noise_rng; /* 23 bit noise shift register */ 142 uint32 noise_p; /* current noise 'phase' */ 143 uint32 noise_f; /* current noise period */ 144 145 uint8 wavesel; /* waveform select enable flag */ 146 147 int T[2]; /* timer counters */ 148 uint8 st[2]; /* timer enable */ 149 150 /* external event callback handlers */ 151 OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ 152 int TimerParam; /* TIMER parameter */ 153 OPL_IRQHANDLER IRQHandler; /* IRQ handler */ 154 int IRQParam; /* IRQ parameter */ 155 OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ 156 int UpdateParam; /* stream update parameter */ 157 158 uint8 type; /* chip type */ 159 uint8 address; /* address register */ 160 uint8 status; /* status flag */ 161 uint8 statusmask; /* status mask */ 162 uint8 mode; /* Reg.08 : CSM,notesel,etc. */ 163 164 int clock; /* master clock (Hz) */ 165 int rate; /* sampling rate (Hz) */ 166 double freqbase; /* frequency base */ 167 double TimerBase; /* Timer base time (==sampling time)*/ 168 } FM_OPL; 169 170 #define MAX_OPL_CHIPS 2 171 172 /* sinwave entries */ 173 #define SIN_BITS 10 174 #define SIN_LEN (1<<SIN_BITS) 175 #define SIN_MASK (SIN_LEN-1) 176 177 #define TL_RES_LEN (256) /* 8 bits addressing (real chip) */ 178 179 /* TL_TAB_LEN is calculated as: 180 * 12 - sinus amplitude bits (Y axis) 181 * 2 - sinus sign bit (Y axis) 182 * TL_RES_LEN - sinus resolution (X axis) 183 */ 184 #define TL_TAB_LEN (12*2*TL_RES_LEN) 185 186 class OplClass: public Copl { 187 private: 188 189 FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */ 190 int YM3812NumChips; /* number of chips */ 191 192 signed int tl_tab[TL_TAB_LEN]; 193 194 /* sin waveform table in 'decibel' scale */ 195 /* four waveforms on OPL2 type chips */ 196 unsigned int sin_tab[SIN_LEN * 4]; 197 198 /* lock level of common table */ 199 int num_lock; 200 201 /* work table */ 202 void *cur_chip; /* current chip point */ 203 OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; 204 205 signed int phase_modulation; /* phase modulation input (SLOT 2) */ 206 signed int output[1]; 207 208 uint32 LFO_AM; 209 int32 LFO_PM; 210 211 bool use16bit, stereo; 212 int oplRate; 213 214 public: 215 OplClass(int rate, bool bit16, bool usestereo); // rate = sample rate ~OplClass()216 ~OplClass() override { 217 YM3812Shutdown(); 218 } 219 getRate()220 int getRate() { 221 return oplRate; 222 } 223 224 void update(short *buf, int samples); // fill buffer 225 226 // template methods 227 void write(int reg, int val) override; 228 void init() override; 229 230 private: 231 int YM3812Init(int num, int clock, int rate); 232 void YM3812Shutdown(void); 233 void YM3812ResetChip(int which); 234 int YM3812Write(int which, int a, int v); 235 unsigned char YM3812Read(int which, int a); 236 int YM3812TimerOver(int which, int c); 237 void YM3812UpdateOne(int which, int16 *buffer, int length); 238 239 void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); 240 void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); 241 void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); 242 243 int init_tables(void); 244 void OPLWriteReg(FM_OPL *OPL, int r, int v); 245 void OPLResetChip(FM_OPL *OPL); 246 int OPL_LockTable(void); 247 FM_OPL *OPLCreate(int type, int clock, int rate); 248 void OPL_UnLockTable(void); 249 void OPLDestroy(FM_OPL *OPL); 250 int OPLWrite(FM_OPL *OPL, int a, int v); 251 252 inline void advance_lfo(FM_OPL *OPL); 253 inline void advancex(FM_OPL *OPL); 254 inline signed int op_calc(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab); 255 inline signed int op_calc1(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab); 256 inline void OPL_CALC_CH(OPL_CH *CH); 257 inline void OPL_CALC_RH(OPL_CH *CH, unsigned int noise); 258 }; 259 260 } // End of namespace Nuvie 261 } // End of namespace Ultima 262 263 #endif 264