Ticket #9010: dosbox_adlib_v1.patch
File dosbox_adlib_v1.patch, 111.0 KB (added by , 15 years ago) |
---|
-
sound/module.mk
30 30 mods/rjp1.o \ 31 31 mods/soundfx.o \ 32 32 softsynth/adlib.o \ 33 softsynth/adlib/adlib.o \ 34 softsynth/adlib/dosbox.o \ 35 softsynth/adlib/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 #include "common/scummsys.h" 33 #include "common/util.h" 28 #include "softsynth/adlib/adlib.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 // Legacy API 31 typedef AdLib::AdLib FM_OPL; 43 32 44 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)154 155 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);156 157 FM_OPL *OPLCreate(int type, int clock, int rate);158 33 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 34 163 35 void OPLResetChip(FM_OPL *OPL); 164 intOPLWrite(FM_OPL *OPL, int a, int v);36 void OPLWrite(FM_OPL *OPL, int a, int v); 165 37 unsigned char OPLRead(FM_OPL *OPL, int a); 166 int OPLTimerOver(FM_OPL *OPL, int c);167 38 void OPLWriteReg(FM_OPL *OPL, int r, int v); 168 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length , int interleave = 0);39 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length); 169 40 170 41 // Factory method 171 42 FM_OPL *makeAdlibOPL(int rate); 172 43 173 44 #endif 45 -
sound/fmopl.cpp
1 /* ScummVM - Graphic Adventure Engine2 *3 * ScummVM is the legal property of its developers, whose names4 * are too numerous to list here. Please refer to the COPYRIGHT5 * file distributed with this source distribution.6 *7 * This program is free software; you can redistribute it and/or8 * modify it under the terms of the GNU General Public License9 * as published by the Free Software Foundation; either version 210 * 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 of14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 * GNU General Public License for more details.16 17 * You should have received a copy of the GNU General Public License18 * along with this program; if not, write to the Free Software19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.20 *21 * $URL$22 * $Id$23 *24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by25 * 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 "sound/fmopl.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 #endif39 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 863 #else64 #define SIN_ENT_SHIFT 1165 #endif66 #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 51286 #define VIB_SHIFT (32-9)87 #define AMS_ENT 51288 #define AMS_SHIFT (32-9)89 90 #define VIB_RATE_SHIFT 891 #define VIB_RATE (1<<VIB_RATE_SHIFT)92 93 /* -------------------- local defines , macros --------------------- */94 95 /* register number to channel number , slot offset */96 #define SLOT1 097 #define SLOT2 198 99 /* envelope phase */100 #define ENV_MOD_RR 0x00101 #define ENV_MOD_DR 0x01102 #define ENV_MOD_AR 0x02103 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,-1110 };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.000155 };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)*/159 160 static int SL_TABLE[16];161 162 static const uint SL_TABLE_SEED[16] = {163 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31164 };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 ML194 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_DST225 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_KSL245 #undef SC_SL246 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 }261 }262 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 when301 // 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 keyed308 // on immediately, in which case there's no problem.309 //310 // However, if the note is again keyed off (because the channel311 // begins on a rest rather than a note), the envelope counter312 // was moved from the very lowest point on the attack curve to313 // the very highest point on the release curve.314 //315 // Again, this might not be a problem, if the release rate is316 // still set to "fastest". But in many cases, it had already317 // been increased. And, possibly because of inaccuracies in the318 // 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 starting322 // point for the envelope counter, and that may be what the323 // commented-out line below is meant to do. For now, simply324 // 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 else475 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 else496 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.0504 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 to508 // 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;513 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 else527 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 else550 SLOT->Cnt += SLOT->Incr;551 /* connection */552 outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;553 }554 555 // SD (17) = mul14[fnum7] + white noise556 // TAM (15) = mul15[fnum8]557 // TOP (18) = fnum6(mul18[fnum8]+whitenoise)558 // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise559 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 else568 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 else572 SLOT7_2->Cnt += (CH[7].fc * 8);573 if(SLOT8_1->vib)574 SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;575 else576 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 else580 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 #else634 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 #endif644 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;715 }716 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);723 }724 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);739 }740 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);758 }759 760 /* ---------- write a OPL registers ---------- */761 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 else864 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 else870 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 else877 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 else884 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;964 }965 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;1028 }1029 1030 /* ---------- reset a chip ---------- */1031 void OPLResetChip(FM_OPL *OPL) {1032 int c,s;1033 int i;1034 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;1056 }1057 }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 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;1096 }1097 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/adlib/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 #ifndef DISABLE_DOSBOX_ADLIB 26 27 #include "dosbox.h" 28 29 #include "common/system.h" 30 31 #include <math.h> 32 #include <string.h> 33 34 /* 35 * Based on AdLib emulation from DOSBox 36 * Copyright (C) 2002-2009 The DOSBox Team 37 * http://www.dosbox.com 38 */ 39 40 namespace AdLib { 41 namespace DOSBox { 42 43 Timer::Timer() { 44 masked = false; 45 overflow = false; 46 enabled = false; 47 counter = 0; 48 delay = 0; 49 } 50 51 void Timer::Update(double time) { 52 if (!enabled || !delay) 53 return; 54 double deltaStart = time - start; 55 // Only set the overflow flag when not masked 56 if (deltaStart >= 0 && !masked) 57 overflow = 1; 58 } 59 60 void Timer::Reset(double time) { 61 overflow = false; 62 if (!delay || !enabled) 63 return; 64 double delta = (time - start); 65 double rem = fmod( delta, delay ); 66 double next = delay - rem; 67 start = time + next; 68 } 69 70 void Timer::Stop() { 71 enabled = false; 72 } 73 74 void Timer::Start(double time, int scale) { 75 //Don't enable again 76 if (enabled) 77 return; 78 enabled = true; 79 delay = 0.001 * (256 - counter) * scale; 80 start = time + delay; 81 } 82 83 bool Chip::Write(uint32 reg, uint8 val) { 84 switch (reg) { 85 case 0x02: 86 timer[0].counter = val; 87 return true; 88 case 0x03: 89 timer[1].counter = val; 90 return true; 91 case 0x04: 92 // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess 93 // it should be like this... 94 double time = g_system->getMillis() / 1000.0; 95 if (val & 0x80) { 96 timer[0].Reset(time); 97 timer[1].Reset(time); 98 } else { 99 timer[0].Update(time); 100 timer[1].Update(time); 101 102 if (val & 0x1) 103 timer[0].Start(time, 80); 104 else 105 timer[0].Stop(); 106 107 timer[0].masked = (val & 0x40) > 0; 108 109 if (timer[0].masked) 110 timer[0].overflow = false; 111 112 if (val & 0x2) 113 timer[1].Start(time, 320); 114 else 115 timer[1].Stop(); 116 117 timer[1].masked = (val & 0x20) > 0; 118 119 if (timer[1].masked) 120 timer[1].overflow = false; 121 } 122 return true; 123 } 124 return false; 125 } 126 127 uint8 Chip::Read() { 128 // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess 129 // it should be like this... 130 double time = g_system->getMillis() / 1000.0; 131 132 timer[0].Update(time); 133 timer[1].Update(time); 134 135 uint8 ret = 0; 136 //Overflow won't be set if a channel is masked 137 if (timer[0].overflow) { 138 ret |= 0x40; 139 ret |= 0x80; 140 } 141 if (timer[1].overflow) { 142 ret |= 0x20; 143 ret |= 0x80; 144 } 145 return ret; 146 } 147 148 class Handler { 149 public: 150 virtual ~Handler() {} 151 152 // Write an address to a chip, returns the address the chip sets 153 virtual uint32 WriteAddr(uint32 port, uint8 val) = 0; 154 // Write to a specific register in the chip 155 virtual void WriteReg(uint32 addr, uint8 val) = 0; 156 // Generate a certain amount of samples 157 virtual void Generate(int16 *chan, uint samples) = 0; 158 // Initialize at a specific sample rate and mode 159 virtual void Init(uint rate) = 0; 160 }; 161 162 // TODO: The DOSBox AdLib code is only capable of *one* instance, we 163 // would need to restructure the code to allow multiple instances. 164 namespace OPL2 { 165 #include "opl.cpp" 166 167 struct Handler : public DOSBox::Handler { 168 void WriteReg(uint32 reg, uint8 val) { 169 adlib_write(reg, val); 170 } 171 uint32 WriteAddr(uint32 port, uint8 val) { 172 return val; 173 } 174 void Generate(int16 *chan, uint samples) { 175 adlib_getsample(chan, samples); 176 } 177 void Init(uint rate) { 178 adlib_init(rate); 179 } 180 }; 181 } // end of namespace OPL2 182 183 AdLib_DOSBox::AdLib_DOSBox() : _type(kOpl2), _rate(0), _handler(0) { 184 } 185 186 AdLib_DOSBox::~AdLib_DOSBox() { 187 free(); 188 } 189 190 void AdLib_DOSBox::free() { 191 delete _handler; 192 _handler = 0; 193 } 194 195 void AdLib_DOSBox::init(int rate, kOplType type) { 196 free(); 197 198 _reg.dual[0] = 0; 199 _reg.dual[1] = 0; 200 _reg.normal = 0; 201 202 memset(_chip, 0, sizeof(_chip)); 203 204 switch (type) { 205 case kOpl2: 206 _type = type; 207 _handler = new OPL2::Handler(); 208 break; 209 } 210 211 _handler->Init(rate); 212 _rate = rate; 213 } 214 215 void AdLib_DOSBox::reset() { 216 // TODO: Find a nicer way to reset the emulator 217 init(_rate, _type); 218 } 219 220 void AdLib_DOSBox::write(int port, int val) { 221 if (port&1) { 222 switch (_type) { 223 case kOpl2: 224 //case MODE_OPL3: 225 if (!_chip[0].Write(_reg.normal, val)) 226 _handler->WriteReg(_reg.normal, val); 227 break; 228 /*case MODE_DUALOPL2: 229 //Not a 0x??8 port, then write to a specific port 230 if ( !(port & 0x8) ) { 231 Bit8u index = ( port & 2 ) >> 1; 232 DualWrite( index, reg.dual[index], val ); 233 } else { 234 //Write to both ports 235 DualWrite( 0, reg.dual[0], val ); 236 DualWrite( 1, reg.dual[1], val ); 237 } 238 break;*/ 239 } 240 } else { 241 // Ask the handler to write the address 242 // Make sure to clip them in the right range 243 switch (_type) { 244 case kOpl2: 245 _reg.normal = _handler->WriteAddr(port, val) & 0xff; 246 break; 247 /*case MODE_OPL3: 248 _reg.normal = _handler->WriteAddr(port, val) & 0x1ff; 249 break; 250 case MODE_DUALOPL2: 251 //Not a 0x?88 port, when write to a specific side 252 if ( !(port & 0x8) ) { 253 Bit8u index = ( port & 2 ) >> 1; 254 reg.dual[index] = val & 0xff; 255 } else { 256 reg.dual[0] = val & 0xff; 257 reg.dual[1] = val & 0xff; 258 } 259 break;*/ 260 } 261 } 262 } 263 264 byte AdLib_DOSBox::read(int port) { 265 switch (_type) { 266 case kOpl2: 267 //We allocated 4 ports, so just return -1 for the higher ones 268 if (!(port & 3)) 269 //Make sure the low bits are 6 on opl2 270 return _chip[0].Read() | 0x6; 271 else 272 return 0xff; 273 /*case MODE_OPL3: 274 //We allocated 4 ports, so just return -1 for the higher ones 275 if ( !(port & 3 ) ) { 276 return chip[0].Read(); 277 } else { 278 return 0xff; 279 } 280 case MODE_DUALOPL2: 281 //Only return for the lower ports 282 if ( port & 1 ) { 283 return 0xff; 284 } 285 //Make sure the low bits are 6 on opl2 286 return chip[ (port >> 1) & 1].Read() | 0x6;*/ 287 } 288 return 0; 289 } 290 291 void AdLib_DOSBox::writeReg(int r, int v) { 292 //debug("%.02X: %.02X", r, v); 293 _handler->WriteReg(r, v); 294 } 295 296 void AdLib_DOSBox::readBuffer(int16 *buffer, int length) { 297 _handler->Generate(buffer, length); 298 } 299 300 } // end of namespace DOSBox 301 } // end of namespace AdLib 302 303 #endif // !DISABLE_DOSBOX_ADLIB -
sound/softsynth/adlib/opl.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 * OPL2/OPL3 emulation library from DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * http://www.dosbox.com 29 */ 30 31 /* 32 * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman 33 * Copyright (C) 1998-2001 Ken Silverman 34 * Ken Silverman's official web site: "http://www.advsys.net/ken" 35 */ 36 37 #define fltype double 38 39 /* 40 define Bits, Bitu, Bit32s, Bit32u, Bit16s, Bit16u, Bit8s, Bit8u here 41 */ 42 typedef uint Bitu; 43 typedef int Bits; 44 typedef uint32 Bit32u; 45 typedef int32 Bit32s; 46 typedef uint16 Bit16u; 47 typedef int16 Bit16s; 48 typedef uint8 Bit8u; 49 typedef int8 Bit8s; 50 51 #undef NUM_CHANNELS 52 #if defined(OPLTYPE_IS_OPL3) 53 #define NUM_CHANNELS 18 54 #else 55 #define NUM_CHANNELS 9 56 #endif 57 58 #define MAXOPERATORS (NUM_CHANNELS*2) 59 60 61 #define FL05 ((fltype)0.5) 62 #define FL2 ((fltype)2.0) 63 64 #ifdef PI 65 #undef PI 66 #endif 67 68 #define PI ((fltype)3.1415926535897932384626433832795) 69 70 71 #define FIXEDPT 0x10000 // fixed-point calculations using 16+16 72 #define FIXEDPT_LFO 0x1000000 // fixed-point calculations using 8+24 73 74 #define WAVEPREC 1024 // waveform precision (10 bits) 75 76 #define INTFREQU ((fltype)(14318180.0 / 288.0)) // clocking of the chip 77 78 79 #define OF_TYPE_ATT 0 80 #define OF_TYPE_DEC 1 81 #define OF_TYPE_REL 2 82 #define OF_TYPE_SUS 3 83 #define OF_TYPE_SUS_NOKEEP 4 84 #define OF_TYPE_OFF 5 85 86 #define ARC_CONTROL 0x00 87 #define ARC_TVS_KSR_MUL 0x20 88 #define ARC_KSL_OUTLEV 0x40 89 #define ARC_ATTR_DECR 0x60 90 #define ARC_SUSL_RELR 0x80 91 #define ARC_FREQ_NUM 0xa0 92 #define ARC_KON_BNUM 0xb0 93 #define ARC_PERC_MODE 0xbd 94 #define ARC_FEEDBACK 0xc0 95 #define ARC_WAVE_SEL 0xe0 96 97 #define ARC_SECONDSET 0x100 // second operator set for OPL3 98 99 100 #define OP_ACT_OFF 0x00 101 #define OP_ACT_NORMAL 0x01 // regular channel activated (bitmasked) 102 #define OP_ACT_PERC 0x02 // percussion channel activated (bitmasked) 103 104 #define BLOCKBUF_SIZE 512 105 106 107 // vibrato constants 108 #define VIBTAB_SIZE 8 109 #define VIBFAC 70/50000 // no braces, integer mul/div 110 111 // tremolo constants and table 112 #define TREMTAB_SIZE 53 113 #define TREM_FREQ ((fltype)(3.7)) // tremolo at 3.7hz 114 115 116 /* operator struct definition 117 For OPL2 all 9 channels consist of two operators each, carrier and modulator. 118 Channel x has operators x as modulator and operators (9+x) as carrier. 119 For OPL3 all 18 channels consist either of two operators (2op mode) or four 120 operators (4op mode) which is determined through register4 of the second 121 adlib register set. 122 Only the channels 0,1,2 (first set) and 9,10,11 (second set) can act as 123 4op channels. The two additional operators for a channel y come from the 124 2op channel y+3 so the operatorss y, (9+y), y+3, (9+y)+3 make up a 4op 125 channel. 126 */ 127 typedef struct operator_struct { 128 Bit32s cval, lastcval; // current output/last output (used for feedback) 129 Bit32u tcount, wfpos, tinc; // time (position in waveform) and time increment 130 fltype amp, step_amp; // and amplification (envelope) 131 fltype vol; // volume 132 fltype sustain_level; // sustain level 133 Bit32s mfbi; // feedback amount 134 fltype a0, a1, a2, a3; // attack rate function coefficients 135 fltype decaymul, releasemul; // decay/release rate functions 136 Bit32u op_state; // current state of operator (attack/decay/sustain/release/off) 137 Bit32u toff; 138 Bit32s freq_high; // highest three bits of the frequency, used for vibrato calculations 139 Bit16s* cur_wform; // start of selected waveform 140 Bit32u cur_wmask; // mask for selected waveform 141 Bit32u act_state; // activity state (regular, percussion) 142 bool sus_keep; // keep sustain level when decay finished 143 bool vibrato,tremolo; // vibrato/tremolo enable bits 144 145 // variables used to provide non-continuous envelopes 146 Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed 147 Bits cur_env_step; // current (standardized) sample position 148 Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode) 149 Bit8u step_skip_pos; // position of 8-cyclic step skipping (always 2^x to check against mask) 150 Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then) 151 152 #if defined(OPLTYPE_IS_OPL3) 153 bool is_4op,is_4op_attached; // base of a 4op channel/part of a 4op channel 154 Bit32s left_pan,right_pan; // opl3 stereo panning amount 155 #endif 156 } op_type; 157 158 // per-chip variables 159 Bitu chip_num; 160 op_type op[MAXOPERATORS]; 161 162 Bits int_samplerate; 163 164 Bit8u status; 165 Bit32u index; 166 #if defined(OPLTYPE_IS_OPL3) 167 Bit8u adlibreg[512]; // adlib register set (including second set) 168 Bit8u wave_sel[44]; // waveform selection 169 #else 170 Bit8u adlibreg[256]; // adlib register set 171 Bit8u wave_sel[22]; // waveform selection 172 #endif 173 174 175 // vibrato/tremolo increment/counter 176 Bit32u vibtab_pos; 177 Bit32u vibtab_add; 178 Bit32u tremtab_pos; 179 Bit32u tremtab_add; 180 181 182 // enable an operator 183 void enable_operator(Bitu regbase, op_type* op_pt); 184 185 // functions to change parameters of an operator 186 void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt); 187 188 void change_attackrate(Bitu regbase, op_type* op_pt); 189 void change_decayrate(Bitu regbase, op_type* op_pt); 190 void change_releaserate(Bitu regbase, op_type* op_pt); 191 void change_sustainlevel(Bitu regbase, op_type* op_pt); 192 void change_waveform(Bitu regbase, op_type* op_pt); 193 void change_keepsustain(Bitu regbase, op_type* op_pt); 194 void change_vibrato(Bitu regbase, op_type* op_pt); 195 void change_feedback(Bitu chanbase, op_type* op_pt); 196 197 // general functions 198 void adlib_init(Bit32u samplerate); 199 void adlib_write(Bitu idx, Bit8u val); 200 void adlib_getsample(Bit16s* sndptr, Bits numsamples); 201 202 Bitu adlib_reg_read(Bitu port); 203 void adlib_write_index(Bitu port, Bit8u val); 204 205 static Bit32u generator_add; // should be a chip parameter -
sound/softsynth/adlib/mame.cpp
31 31 #include <stdarg.h> 32 32 #include <math.h> 33 33 34 #include " sound/fmopl.h"34 #include "mame.h" 35 35 36 36 #if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__) 37 37 #include "common/config-manager.h" 38 38 #endif 39 39 40 namespace AdLib { 41 namespace MAME { 42 40 43 /* -------------------- preliminary define section --------------------- */ 41 44 /* attack/decay rate time rate */ 42 45 #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ … … 1189 1192 OPLBuildTables(env_bits, eg_ent); 1190 1193 return OPLCreate(OPL_TYPE_YM3812, 3579545, rate); 1191 1194 } 1195 1196 } // end of namespace MAME 1197 } // end of namespace AdLib 1198 -
sound/softsynth/adlib/adlib.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 #ifndef SOUND_SOFTSYNTH_ADLIB_ADLIB_H 26 #define SOUND_SOFTSYNTH_ADLIB_ADLIB_H 27 28 #include "common/scummsys.h" 29 30 namespace AdLib { 31 32 // TODO: Document and move to sound/adlib.h or sound/fmopl.h 33 class AdLib { 34 public: 35 virtual ~AdLib() {} 36 37 enum kOplType { 38 kOpl2 = 0 39 }; 40 41 virtual void init(int rate, kOplType type = kOpl2) = 0; 42 virtual void reset() = 0; 43 44 virtual void write(int a, int v) = 0; 45 virtual byte read(int a) = 0; 46 47 virtual void writeReg(int r, int v) = 0; 48 49 virtual void readBuffer(int16 *buffer, int length) = 0; 50 51 static AdLib *createInstance(); 52 }; 53 54 } // end of namespace AdLib 55 56 #endif 57 -
sound/softsynth/adlib/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 AdLib emulation from DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * http://www.dosbox.com 29 */ 30 31 #ifndef SOUND_SOFTSYNTH_ADLIB_DOSBOX_H 32 #define SOUND_SOFTSYNTH_ADLIB_DOSBOX_H 33 34 #ifndef DISABLE_DOSBOX_ADLIB 35 36 #include "adlib.h" 37 38 namespace AdLib { 39 namespace DOSBox { 40 41 class Handler; 42 43 struct Timer { 44 double start; 45 double delay; 46 bool enabled, overflow, masked; 47 uint8 counter; 48 49 Timer(); 50 51 //Call update before making any further changes 52 void Update(double time); 53 54 //On a reset make sure the start is in sync with the next cycle 55 void Reset(double time); 56 57 void Stop(); 58 59 void Start(double time, int scale); 60 }; 61 62 struct Chip { 63 //Last selected register 64 Timer timer[2]; 65 //Check for it being a write to the timer 66 bool Write(uint32 addr, uint8 val); 67 //Read the current timer state, will use current double 68 uint8 Read(); 69 }; 70 71 class AdLib_DOSBox : public AdLib { 72 private: 73 kOplType _type; 74 uint _rate; 75 76 Handler *_handler; 77 Chip _chip[2]; 78 union { 79 uint16 normal; 80 uint8 dual[2]; 81 } _reg; 82 83 void free(); 84 public: 85 AdLib_DOSBox(); 86 ~AdLib_DOSBox(); 87 88 void init(int rate, kOplType type); 89 void reset(); 90 91 void write(int a, int v); 92 byte read(int a); 93 94 void writeReg(int r, int v); 95 96 void readBuffer(int16 *buffer, int length); 97 }; 98 99 } // end of namespace DOSBox 100 } // end of namespace AdLib 101 102 #endif // !DISABLE_DOSBOX_ADLIB 103 104 #endif 105 -
sound/softsynth/adlib/mame.h
26 26 */ 27 27 28 28 29 #ifndef SOUND_ FMOPL_H30 #define SOUND_ FMOPL_H29 #ifndef SOUND_SOFTSYNTH_ADLIB_FMOPL_H 30 #define SOUND_SOFTSYNTH_ADLIB_FMOPL_H 31 31 32 32 #include "common/scummsys.h" 33 33 #include "common/util.h" 34 34 35 namespace AdLib { 36 namespace MAME { 37 35 38 enum { 36 39 FMOPL_ENV_BITS_HQ = 16, 37 40 FMOPL_ENV_BITS_MQ = 8, … … 170 173 // Factory method 171 174 FM_OPL *makeAdlibOPL(int rate); 172 175 176 } // end of namespace MAME 177 } // end of namespace AdLib 178 173 179 #endif -
sound/softsynth/adlib/opl.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 * OPL2/OPL3 emulation library from DOSBox 27 * Copyright (C) 2002-2009 The DOSBox Team 28 * http://www.dosbox.com 29 */ 30 31 /* 32 * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman 33 * Copyright (C) 1998-2001 Ken Silverman 34 * Ken Silverman's official web site: "http://www.advsys.net/ken" 35 */ 36 37 #include "opl.h" 38 39 static fltype recipsamp; // inverse of sampling rate 40 static Bit16s wavtable[WAVEPREC*3]; // wave form table 41 42 // vibrato/tremolo tables 43 static Bit32s vib_table[VIBTAB_SIZE]; 44 static Bit32s trem_table[TREMTAB_SIZE*2]; 45 46 static Bit32s vibval_const[BLOCKBUF_SIZE]; 47 static Bit32s tremval_const[BLOCKBUF_SIZE]; 48 49 // vibrato value tables (used per-operator) 50 static Bit32s vibval_var1[BLOCKBUF_SIZE]; 51 static Bit32s vibval_var2[BLOCKBUF_SIZE]; 52 //static Bit32s vibval_var3[BLOCKBUF_SIZE]; 53 //static Bit32s vibval_var4[BLOCKBUF_SIZE]; 54 55 // vibrato/trmolo value table pointers 56 static Bit32s *vibval1, *vibval2, *vibval3, *vibval4; 57 static Bit32s *tremval1, *tremval2, *tremval3, *tremval4; 58 59 60 // key scale level lookup table 61 static const fltype kslmul[4] = { 62 0.0, 0.5, 0.25, 1.0 // -> 0, 3, 1.5, 6 dB/oct 63 }; 64 65 // frequency multiplicator lookup table 66 static const fltype frqmul_tab[16] = { 67 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15 68 }; 69 // calculated frequency multiplication values (depend on sampling rate) 70 static float frqmul[16]; 71 72 // key scale levels 73 static Bit8u kslev[8][16]; 74 75 // map a channel number to the register offset of the modulator (=register base) 76 static const Bit8u modulatorbase[9] = { 77 0,1,2, 78 8,9,10, 79 16,17,18 80 }; 81 82 // map a register base to a modulator operator number or operator number 83 #if defined(OPLTYPE_IS_OPL3) 84 static const Bit8u regbase2modop[44] = { 85 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8, // first set 86 18,19,20,18,19,20,0,0,21,22,23,21,22,23,0,0,24,25,26,24,25,26 // second set 87 }; 88 static const Bit8u regbase2op[44] = { 89 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17, // first set 90 18,19,20,27,28,29,0,0,21,22,23,30,31,32,0,0,24,25,26,33,34,35 // second set 91 }; 92 #else 93 static const Bit8u regbase2modop[22] = { 94 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8 95 }; 96 static const Bit8u regbase2op[22] = { 97 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17 98 }; 99 #endif 100 101 102 // start of the waveform 103 static Bit32u waveform[8] = { 104 WAVEPREC, 105 WAVEPREC>>1, 106 WAVEPREC, 107 (WAVEPREC*3)>>2, 108 0, 109 0, 110 (WAVEPREC*5)>>2, 111 WAVEPREC<<1 112 }; 113 114 // length of the waveform as mask 115 static Bit32u wavemask[8] = { 116 WAVEPREC-1, 117 WAVEPREC-1, 118 (WAVEPREC>>1)-1, 119 (WAVEPREC>>1)-1, 120 WAVEPREC-1, 121 ((WAVEPREC*3)>>2)-1, 122 WAVEPREC>>1, 123 WAVEPREC-1 124 }; 125 126 // where the first entry resides 127 static Bit32u wavestart[8] = { 128 0, 129 WAVEPREC>>1, 130 0, 131 WAVEPREC>>2, 132 0, 133 0, 134 0, 135 WAVEPREC>>3 136 }; 137 138 // envelope generator function constants 139 static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744}; 140 static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608}; 141 142 143 void operator_advance(op_type* op_pt, Bit32s vib) { 144 op_pt->wfpos = op_pt->tcount; // waveform position 145 146 // advance waveform time 147 op_pt->tcount += op_pt->tinc; 148 op_pt->tcount += (Bit32s)(op_pt->tinc)*vib/FIXEDPT; 149 150 op_pt->generator_pos += generator_add; 151 } 152 153 void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) { 154 Bit32u c1 = op_pt1->tcount/FIXEDPT; 155 Bit32u c3 = op_pt3->tcount/FIXEDPT; 156 Bit32u phasebit = (((c1 & 0x88) ^ ((c1<<5) & 0x80)) | ((c3 ^ (c3<<2)) & 0x20)) ? 0x02 : 0x00; 157 158 Bit32u noisebit = rand()&1; 159 160 Bit32u snare_phase_bit = (((Bitu)((op_pt1->tcount/FIXEDPT) / 0x100))&1); 161 162 //Hihat 163 Bit32u inttm = (phasebit<<8) | (0x34<<(phasebit ^ (noisebit<<1))); 164 op_pt1->wfpos = inttm*FIXEDPT; // waveform position 165 // advance waveform time 166 op_pt1->tcount += op_pt1->tinc; 167 op_pt1->tcount += (Bit32s)(op_pt1->tinc)*vib1/FIXEDPT; 168 op_pt1->generator_pos += generator_add; 169 170 //Snare 171 inttm = ((1+snare_phase_bit) ^ noisebit)<<8; 172 op_pt2->wfpos = inttm*FIXEDPT; // waveform position 173 // advance waveform time 174 op_pt2->tcount += op_pt2->tinc; 175 op_pt2->tcount += (Bit32s)(op_pt2->tinc)*vib2/FIXEDPT; 176 op_pt2->generator_pos += generator_add; 177 178 //Cymbal 179 inttm = (1+phasebit)<<8; 180 op_pt3->wfpos = inttm*FIXEDPT; // waveform position 181 // advance waveform time 182 op_pt3->tcount += op_pt3->tinc; 183 op_pt3->tcount += (Bit32s)(op_pt3->tinc)*vib3/FIXEDPT; 184 op_pt3->generator_pos += generator_add; 185 } 186 187 188 // output level is sustained, mode changes only when operator is turned off (->release) 189 // or when the keep-sustained bit is turned off (->sustain_nokeep) 190 void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) { 191 if (op_pt->op_state != OF_TYPE_OFF) { 192 op_pt->lastcval = op_pt->cval; 193 Bit32u i = (Bit32u)((op_pt->wfpos+modulator)/FIXEDPT); 194 195 // wform: -16384 to 16383 (0x4000) 196 // trem : 32768 to 65535 (0x10000) 197 // step_amp: 0.0 to 1.0 198 // vol : 1/2^14 to 1/2^29 (/0x4000; /1../0x8000) 199 200 op_pt->cval = (Bit32s)(op_pt->step_amp*op_pt->vol*op_pt->cur_wform[i&op_pt->cur_wmask]*trem/16.0); 201 } 202 } 203 204 205 // no action, operator is off 206 void operator_off(op_type* /*op_pt*/) { 207 } 208 209 // output level is sustained, mode changes only when operator is turned off (->release) 210 // or when the keep-sustained bit is turned off (->sustain_nokeep) 211 void operator_sustain(op_type* op_pt) { 212 Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples 213 for (Bit32u ct=0; ct<num_steps_add; ct++) { 214 op_pt->cur_env_step++; 215 } 216 op_pt->generator_pos -= num_steps_add*FIXEDPT; 217 } 218 219 // operator in release mode, if output level reaches zero the operator is turned off 220 void operator_release(op_type* op_pt) { 221 // ??? boundary? 222 if (op_pt->amp > 0.00000001) { 223 // release phase 224 op_pt->amp *= op_pt->releasemul; 225 } 226 227 Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples 228 for (Bit32u ct=0; ct<num_steps_add; ct++) { 229 op_pt->cur_env_step++; // sample counter 230 if ((op_pt->cur_env_step & op_pt->env_step_r)==0) { 231 if (op_pt->amp <= 0.00000001) { 232 // release phase finished, turn off this operator 233 op_pt->amp = 0.0; 234 if (op_pt->op_state == OF_TYPE_REL) { 235 op_pt->op_state = OF_TYPE_OFF; 236 } 237 } 238 op_pt->step_amp = op_pt->amp; 239 } 240 } 241 op_pt->generator_pos -= num_steps_add*FIXEDPT; 242 } 243 244 // operator in decay mode, if sustain level is reached the output level is either 245 // kept (sustain level keep enabled) or the operator is switched into release mode 246 void operator_decay(op_type* op_pt) { 247 if (op_pt->amp > op_pt->sustain_level) { 248 // decay phase 249 op_pt->amp *= op_pt->decaymul; 250 } 251 252 Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples 253 for (Bit32u ct=0; ct<num_steps_add; ct++) { 254 op_pt->cur_env_step++; 255 if ((op_pt->cur_env_step & op_pt->env_step_d)==0) { 256 if (op_pt->amp <= op_pt->sustain_level) { 257 // decay phase finished, sustain level reached 258 if (op_pt->sus_keep) { 259 // keep sustain level (until turned off) 260 op_pt->op_state = OF_TYPE_SUS; 261 op_pt->amp = op_pt->sustain_level; 262 } else { 263 // next: release phase 264 op_pt->op_state = OF_TYPE_SUS_NOKEEP; 265 } 266 } 267 op_pt->step_amp = op_pt->amp; 268 } 269 } 270 op_pt->generator_pos -= num_steps_add*FIXEDPT; 271 } 272 273 // operator in attack mode, if full output level is reached, 274 // the operator is switched into decay mode 275 void operator_attack(op_type* op_pt) { 276 op_pt->amp = ((op_pt->a3*op_pt->amp + op_pt->a2)*op_pt->amp + op_pt->a1)*op_pt->amp + op_pt->a0; 277 278 Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples 279 for (Bit32u ct=0; ct<num_steps_add; ct++) { 280 op_pt->cur_env_step++; // next sample 281 if ((op_pt->cur_env_step & op_pt->env_step_a)==0) { // check if next step already reached 282 if (op_pt->amp > 1.0) { 283 // attack phase finished, next: decay 284 op_pt->op_state = OF_TYPE_DEC; 285 op_pt->amp = 1.0; 286 op_pt->step_amp = 1.0; 287 } 288 op_pt->step_skip_pos <<= 1; 289 if (op_pt->step_skip_pos==0) op_pt->step_skip_pos = 1; 290 if (op_pt->step_skip_pos & op_pt->env_step_skip_a) { // check if required to skip next step 291 op_pt->step_amp = op_pt->amp; 292 } 293 } 294 } 295 op_pt->generator_pos -= num_steps_add*FIXEDPT; 296 } 297 298 299 typedef void (*optype_fptr)(op_type*); 300 301 optype_fptr opfuncs[6] = { 302 operator_attack, 303 operator_decay, 304 operator_release, 305 operator_sustain, // sustain phase (keeping level) 306 operator_release, // sustain_nokeep phase (release-style) 307 operator_off 308 }; 309 310 void change_attackrate(Bitu regbase, op_type* op_pt) { 311 Bits attackrate = adlibreg[ARC_ATTR_DECR+regbase]>>4; 312 if (attackrate) { 313 fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*recipsamp); 314 // attack rate coefficients 315 op_pt->a0 = (fltype)(0.0377*f); 316 op_pt->a1 = (fltype)(10.73*f+1); 317 op_pt->a2 = (fltype)(-17.57*f); 318 op_pt->a3 = (fltype)(7.42*f); 319 320 Bits step_skip = attackrate*4 + op_pt->toff; 321 Bits steps = step_skip >> 2; 322 op_pt->env_step_a = (1<<(steps<=12?12-steps:0))-1; 323 324 Bits step_num = (step_skip<=48)?(4-(step_skip&3)):0; 325 static Bit8u step_skip_mask[5] = {0xff, 0xfe, 0xee, 0xba, 0xaa}; 326 op_pt->env_step_skip_a = step_skip_mask[step_num]; 327 328 #if defined(OPLTYPE_IS_OPL3) 329 if (step_skip>=60) { 330 #else 331 if (step_skip>=62) { 332 #endif 333 op_pt->a0 = (fltype)(2.0); // something that triggers an immediate transition to amp:=1.0 334 op_pt->a1 = (fltype)(0.0); 335 op_pt->a2 = (fltype)(0.0); 336 op_pt->a3 = (fltype)(0.0); 337 } 338 } else { 339 // attack disabled 340 op_pt->a0 = 0.0; 341 op_pt->a1 = 1.0; 342 op_pt->a2 = 0.0; 343 op_pt->a3 = 0.0; 344 op_pt->env_step_a = 0; 345 op_pt->env_step_skip_a = 0; 346 } 347 } 348 349 void change_decayrate(Bitu regbase, op_type* op_pt) { 350 Bits decayrate = adlibreg[ARC_ATTR_DECR+regbase]&15; 351 // decaymul should be 1.0 when decayrate==0 352 if (decayrate) { 353 fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); 354 op_pt->decaymul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(decayrate+(op_pt->toff>>2))))); 355 Bits steps = (decayrate*4 + op_pt->toff) >> 2; 356 op_pt->env_step_d = (1<<(steps<=12?12-steps:0))-1; 357 } else { 358 op_pt->decaymul = 1.0; 359 op_pt->env_step_d = 0; 360 } 361 } 362 363 void change_releaserate(Bitu regbase, op_type* op_pt) { 364 Bits releaserate = adlibreg[ARC_SUSL_RELR+regbase]&15; 365 // releasemul should be 1.0 when releaserate==0 366 if (releaserate) { 367 fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); 368 op_pt->releasemul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(releaserate+(op_pt->toff>>2))))); 369 Bits steps = (releaserate*4 + op_pt->toff) >> 2; 370 op_pt->env_step_r = (1<<(steps<=12?12-steps:0))-1; 371 } else { 372 op_pt->releasemul = 1.0; 373 op_pt->env_step_r = 0; 374 } 375 } 376 377 void change_sustainlevel(Bitu regbase, op_type* op_pt) { 378 Bits sustainlevel = adlibreg[ARC_SUSL_RELR+regbase]>>4; 379 // sustainlevel should be 0.0 when sustainlevel==15 (max) 380 if (sustainlevel<15) { 381 op_pt->sustain_level = (fltype)(pow(FL2,(fltype)sustainlevel * (-FL05))); 382 } else { 383 op_pt->sustain_level = 0.0; 384 } 385 } 386 387 void change_waveform(Bitu regbase, op_type* op_pt) { 388 #if defined(OPLTYPE_IS_OPL3) 389 if (regbase>=ARC_SECONDSET) regbase -= (ARC_SECONDSET-22); // second set starts at 22 390 #endif 391 // waveform selection 392 op_pt->cur_wmask = wavemask[wave_sel[regbase]]; 393 op_pt->cur_wform = &wavtable[waveform[wave_sel[regbase]]]; 394 // (might need to be adapted to waveform type here...) 395 } 396 397 void change_keepsustain(Bitu regbase, op_type* op_pt) { 398 op_pt->sus_keep = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x20)>0; 399 if (op_pt->op_state==OF_TYPE_SUS) { 400 if (!op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS_NOKEEP; 401 } else if (op_pt->op_state==OF_TYPE_SUS_NOKEEP) { 402 if (op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS; 403 } 404 } 405 406 // enable/disable vibrato/tremolo LFO effects 407 void change_vibrato(Bitu regbase, op_type* op_pt) { 408 op_pt->vibrato = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x40)!=0; 409 op_pt->tremolo = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x80)!=0; 410 } 411 412 // change amount of self-feedback 413 void change_feedback(Bitu chanbase, op_type* op_pt) { 414 Bits feedback = adlibreg[ARC_FEEDBACK+chanbase]&14; 415 if (feedback) op_pt->mfbi = (Bit32s)(pow(FL2,(fltype)((feedback>>1)+8))); 416 else op_pt->mfbi = 0; 417 } 418 419 void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt) { 420 // frequency 421 Bit32u frn = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)adlibreg[ARC_FREQ_NUM+chanbase]; 422 // block number/octave 423 Bit32u oct = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])>>2)&7); 424 op_pt->freq_high = (Bit32s)((frn>>7)&7); 425 426 // keysplit 427 Bit32u note_sel = (adlibreg[8]>>6)&1; 428 op_pt->toff = ((frn>>9)&(note_sel^1)) | ((frn>>8)¬e_sel); 429 op_pt->toff += (oct<<1); 430 431 // envelope scaling (KSR) 432 if (!(adlibreg[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2; 433 434 // 20+a0+b0: 435 op_pt->tinc = (Bit32u)((((fltype)(frn<<oct))*frqmul[adlibreg[ARC_TVS_KSR_MUL+regbase]&15])); 436 // 40+a0+b0: 437 fltype vol_in = (fltype)((fltype)(adlibreg[ARC_KSL_OUTLEV+regbase]&63) + 438 kslmul[adlibreg[ARC_KSL_OUTLEV+regbase]>>6]*kslev[oct][frn>>6]); 439 op_pt->vol = (fltype)(pow(FL2,(fltype)(vol_in * -0.125 - 14))); 440 441 // operator frequency changed, care about features that depend on it 442 change_attackrate(regbase,op_pt); 443 change_decayrate(regbase,op_pt); 444 change_releaserate(regbase,op_pt); 445 } 446 447 void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) { 448 // check if this is really an off-on transition 449 if (op_pt->act_state == OP_ACT_OFF) { 450 Bits wselbase = regbase; 451 if (wselbase>=ARC_SECONDSET) wselbase -= (ARC_SECONDSET-22); // second set starts at 22 452 453 op_pt->tcount = wavestart[wave_sel[wselbase]]*FIXEDPT; 454 455 // start with attack mode 456 op_pt->op_state = OF_TYPE_ATT; 457 op_pt->act_state |= act_type; 458 } 459 } 460 461 void disable_operator(op_type* op_pt, Bit32u act_type) { 462 // check if this is really an on-off transition 463 if (op_pt->act_state != OP_ACT_OFF) { 464 op_pt->act_state &= (~act_type); 465 if (op_pt->act_state == OP_ACT_OFF) { 466 if (op_pt->op_state != OF_TYPE_OFF) op_pt->op_state = OF_TYPE_REL; 467 } 468 } 469 } 470 471 void adlib_init(Bit32u samplerate) { 472 Bits i, j, oct; 473 474 int_samplerate = samplerate; 475 476 generator_add = (Bit32u)(INTFREQU*FIXEDPT/int_samplerate); 477 478 479 memset((void *)adlibreg,0,sizeof(adlibreg)); 480 memset((void *)op,0,sizeof(op_type)*MAXOPERATORS); 481 memset((void *)wave_sel,0,sizeof(wave_sel)); 482 483 for (i=0;i<MAXOPERATORS;i++) { 484 op[i].op_state = OF_TYPE_OFF; 485 op[i].act_state = OP_ACT_OFF; 486 op[i].amp = 0.0; 487 op[i].step_amp = 0.0; 488 op[i].vol = 0.0; 489 op[i].tcount = 0; 490 op[i].tinc = 0; 491 op[i].toff = 0; 492 op[i].cur_wmask = wavemask[0]; 493 op[i].cur_wform = &wavtable[waveform[0]]; 494 op[i].freq_high = 0; 495 496 op[i].generator_pos = 0; 497 op[i].cur_env_step = 0; 498 op[i].env_step_a = 0; 499 op[i].env_step_d = 0; 500 op[i].env_step_r = 0; 501 op[i].step_skip_pos = 0; 502 op[i].env_step_skip_a = 0; 503 504 #if defined(OPLTYPE_IS_OPL3) 505 op[i].is_4op = false; 506 op[i].is_4op_attached = false; 507 op[i].left_pan = 2; 508 op[i].right_pan = 2; 509 #endif 510 } 511 512 recipsamp = 1.0 / (fltype)int_samplerate; 513 for (i=15;i>=0;i--) { 514 frqmul[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*recipsamp); 515 } 516 517 status = 0; 518 index = 0; 519 520 521 // create vibrato table 522 vib_table[0] = 8; 523 vib_table[1] = 4; 524 vib_table[2] = 0; 525 vib_table[3] = -4; 526 for (i=4; i<VIBTAB_SIZE; i++) vib_table[i] = vib_table[i-4]*-1; 527 528 // vibrato at ~6.1 ?? (opl3 docs say 6.1, opl4 docs say 6.0, y8950 docs say 6.4) 529 vibtab_add = VIBTAB_SIZE*FIXEDPT_LFO/8192*INTFREQU/int_samplerate; 530 vibtab_pos = 0; 531 532 for (i=0; i<BLOCKBUF_SIZE; i++) vibval_const[i] = 0; 533 534 535 // create tremolo table 536 Bit32s trem_table_int[TREMTAB_SIZE]; 537 for (i=0; i<14; i++) trem_table_int[i] = i-13; // upwards (13 to 26 -> -0.5/6 to 0) 538 for (i=14; i<41; i++) trem_table_int[i] = -i+14; // downwards (26 to 0 -> 0 to -1/6) 539 for (i=41; i<53; i++) trem_table_int[i] = i-40-26; // upwards (1 to 12 -> -1/6 to -0.5/6) 540 541 for (i=0; i<TREMTAB_SIZE; i++) { 542 // 0.0 .. -26/26*4.8/6 == [0.0 .. -0.8], 4/53 steps == [1 .. 0.57] 543 fltype trem_val1=(fltype)(((fltype)trem_table_int[i])*4.8/26.0/6.0); // 4.8db 544 fltype trem_val2=(fltype)((fltype)((Bit32s)(trem_table_int[i]/4))*1.2/6.0/6.0); // 1.2db (larger stepping) 545 546 trem_table[i] = (Bit32s)(pow(FL2,trem_val1)*FIXEDPT); 547 trem_table[TREMTAB_SIZE+i] = (Bit32s)(pow(FL2,trem_val2)*FIXEDPT); 548 } 549 550 // tremolo at 3.7hz 551 tremtab_add = (Bit32u)((fltype)TREMTAB_SIZE * TREM_FREQ * FIXEDPT_LFO / (fltype)int_samplerate); 552 tremtab_pos = 0; 553 554 for (i=0; i<BLOCKBUF_SIZE; i++) tremval_const[i] = FIXEDPT; 555 556 557 static Bitu initfirstime = 0; 558 if (!initfirstime) { 559 initfirstime = 1; 560 561 // create waveform tables 562 for (i=0;i<(WAVEPREC>>1);i++) { 563 wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); 564 wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); 565 wavtable[i] = wavtable[(i<<1) +WAVEPREC]; 566 // table to be verified, alternative: (zero-less) 567 /* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1)-1)*PI/WAVEPREC)); 568 wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)(((i*2+1)<<1) )*PI/WAVEPREC)); 569 wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ 570 } 571 for (i=0;i<(WAVEPREC>>3);i++) { 572 wavtable[i+(WAVEPREC<<1)] = wavtable[i+(WAVEPREC>>3)]-16384; 573 wavtable[i+((WAVEPREC*17)>>3)] = wavtable[i+(WAVEPREC>>2)]+16384; 574 } 575 576 // key scale level table verified ([table in book]*8/3) 577 kslev[7][0] = 0; kslev[7][1] = 24; kslev[7][2] = 32; kslev[7][3] = 37; 578 kslev[7][4] = 40; kslev[7][5] = 43; kslev[7][6] = 45; kslev[7][7] = 47; 579 kslev[7][8] = 48; 580 for (i=9;i<16;i++) kslev[7][i] = (Bit8u)(i+41); 581 for (j=6;j>=0;j--) { 582 for (i=0;i<16;i++) { 583 oct = (Bits)kslev[j+1][i]-8; 584 if (oct < 0) oct = 0; 585 kslev[j][i] = (Bit8u)oct; 586 } 587 } 588 } 589 590 } 591 592 593 594 void adlib_write(Bitu idx, Bit8u val) { 595 Bit32u second_set = idx&0x100; 596 //Bit8u old_val = adlibreg[idx]; 597 adlibreg[idx] = val; 598 599 switch (idx&0xf0) { 600 case ARC_CONTROL: 601 // here we check for the second set registers, too: 602 switch (idx) { 603 case 0x02: // timer1 counter 604 case 0x03: // timer2 counter 605 break; 606 case 0x04: 607 // IRQ reset, timer mask/start 608 if (val&0x80) { 609 // clear IRQ bits in status register 610 status &= ~0x60; 611 } else { 612 status = 0; 613 } 614 break; 615 #if defined(OPLTYPE_IS_OPL3) 616 case 0x04|ARC_SECONDSET: 617 // 4op enable/disable switches for each possible channel 618 op[0].is_4op = (val&1)>0; 619 op[3].is_4op_attached = op[0].is_4op; 620 op[1].is_4op = (val&2)>0; 621 op[4].is_4op_attached = op[1].is_4op; 622 op[2].is_4op = (val&4)>0; 623 op[5].is_4op_attached = op[2].is_4op; 624 op[18].is_4op = (val&8)>0; 625 op[21].is_4op_attached = op[18].is_4op; 626 op[19].is_4op = (val&16)>0; 627 op[22].is_4op_attached = op[19].is_4op; 628 op[20].is_4op = (val&32)>0; 629 op[23].is_4op_attached = op[20].is_4op; 630 break; 631 case 0x05|ARC_SECONDSET: 632 break; 633 #endif 634 case 0x08: 635 // CSW, note select 636 break; 637 default: 638 break; 639 } 640 break; 641 case ARC_TVS_KSR_MUL: 642 case ARC_TVS_KSR_MUL+0x10: { 643 // tremolo/vibrato/sustain keeping enabled; key scale rate; frequency multiplication 644 int num = idx&7; 645 Bitu base = (idx-ARC_TVS_KSR_MUL)&0xff; 646 if ((num<6) && (base<22)) { 647 Bitu modop = regbase2modop[second_set?(base+22):base]; 648 Bitu regbase = base+second_set; 649 Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; 650 651 // change tremolo/vibrato and sustain keeping of this operator 652 op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; 653 change_keepsustain(regbase,op_ptr); 654 change_vibrato(regbase,op_ptr); 655 656 // change frequency calculations of this operator as 657 // key scale rate and frequency multiplicator can be changed 658 #if defined(OPLTYPE_IS_OPL3) 659 if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { 660 // operator uses frequency of channel 661 change_frequency(chanbase-3,regbase,op_ptr); 662 } else { 663 change_frequency(chanbase,regbase,op_ptr); 664 } 665 #else 666 change_frequency(chanbase,base,op_ptr); 667 #endif 668 } 669 } 670 break; 671 case ARC_KSL_OUTLEV: 672 case ARC_KSL_OUTLEV+0x10: { 673 // key scale level; output rate 674 int num = idx&7; 675 Bitu base = (idx-ARC_KSL_OUTLEV)&0xff; 676 if ((num<6) && (base<22)) { 677 Bitu modop = regbase2modop[second_set?(base+22):base]; 678 Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; 679 680 // change frequency calculations of this operator as 681 // key scale level and output rate can be changed 682 op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; 683 #if defined(OPLTYPE_IS_OPL3) 684 Bitu regbase = base+second_set; 685 if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { 686 // operator uses frequency of channel 687 change_frequency(chanbase-3,regbase,op_ptr); 688 } else { 689 change_frequency(chanbase,regbase,op_ptr); 690 } 691 #else 692 change_frequency(chanbase,base,op_ptr); 693 #endif 694 } 695 } 696 break; 697 case ARC_ATTR_DECR: 698 case ARC_ATTR_DECR+0x10: { 699 // attack/decay rates 700 int num = idx&7; 701 Bitu base = (idx-ARC_ATTR_DECR)&0xff; 702 if ((num<6) && (base<22)) { 703 Bitu regbase = base+second_set; 704 705 // change attack rate and decay rate of this operator 706 op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; 707 change_attackrate(regbase,op_ptr); 708 change_decayrate(regbase,op_ptr); 709 } 710 } 711 break; 712 case ARC_SUSL_RELR: 713 case ARC_SUSL_RELR+0x10: { 714 // sustain level; release rate 715 int num = idx&7; 716 Bitu base = (idx-ARC_SUSL_RELR)&0xff; 717 if ((num<6) && (base<22)) { 718 Bitu regbase = base+second_set; 719 720 // change sustain level and release rate of this operator 721 op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; 722 change_releaserate(regbase,op_ptr); 723 change_sustainlevel(regbase,op_ptr); 724 } 725 } 726 break; 727 case ARC_FREQ_NUM: { 728 // 0xa0-0xa8 low8 frequency 729 Bitu base = (idx-ARC_FREQ_NUM)&0xff; 730 if (base<9) { 731 Bits opbase = second_set?(base+18):base; 732 #if defined(OPLTYPE_IS_OPL3) 733 if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; 734 #endif 735 // regbase of modulator: 736 Bits modbase = modulatorbase[base]+second_set; 737 738 Bitu chanbase = base+second_set; 739 740 change_frequency(chanbase,modbase,&op[opbase]); 741 change_frequency(chanbase,modbase+3,&op[opbase+9]); 742 #if defined(OPLTYPE_IS_OPL3) 743 // for 4op channels all four operators are modified to the frequency of the channel 744 if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { 745 change_frequency(chanbase,modbase+8,&op[opbase+3]); 746 change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); 747 } 748 #endif 749 } 750 } 751 break; 752 case ARC_KON_BNUM: { 753 if (idx == ARC_PERC_MODE) { 754 #if defined(OPLTYPE_IS_OPL3) 755 if (second_set) return; 756 #endif 757 758 if ((val&0x30) == 0x30) { // BassDrum active 759 enable_operator(16,&op[6],OP_ACT_PERC); 760 change_frequency(6,16,&op[6]); 761 enable_operator(16+3,&op[6+9],OP_ACT_PERC); 762 change_frequency(6,16+3,&op[6+9]); 763 } else { 764 disable_operator(&op[6],OP_ACT_PERC); 765 disable_operator(&op[6+9],OP_ACT_PERC); 766 } 767 if ((val&0x28) == 0x28) { // Snare active 768 enable_operator(17+3,&op[16],OP_ACT_PERC); 769 change_frequency(7,17+3,&op[16]); 770 } else { 771 disable_operator(&op[16],OP_ACT_PERC); 772 } 773 if ((val&0x24) == 0x24) { // TomTom active 774 enable_operator(18,&op[8],OP_ACT_PERC); 775 change_frequency(8,18,&op[8]); 776 } else { 777 disable_operator(&op[8],OP_ACT_PERC); 778 } 779 if ((val&0x22) == 0x22) { // Cymbal active 780 enable_operator(18+3,&op[8+9],OP_ACT_PERC); 781 change_frequency(8,18+3,&op[8+9]); 782 } else { 783 disable_operator(&op[8+9],OP_ACT_PERC); 784 } 785 if ((val&0x21) == 0x21) { // Hihat active 786 enable_operator(17,&op[7],OP_ACT_PERC); 787 change_frequency(7,17,&op[7]); 788 } else { 789 disable_operator(&op[7],OP_ACT_PERC); 790 } 791 792 break; 793 } 794 // regular 0xb0-0xb8 795 Bitu base = (idx-ARC_KON_BNUM)&0xff; 796 if (base<9) { 797 Bits opbase = second_set?(base+18):base; 798 #if defined(OPLTYPE_IS_OPL3) 799 if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; 800 #endif 801 // regbase of modulator: 802 Bits modbase = modulatorbase[base]+second_set; 803 804 if (val&32) { 805 // operator switched on 806 enable_operator(modbase,&op[opbase],OP_ACT_NORMAL); // modulator (if 2op) 807 enable_operator(modbase+3,&op[opbase+9],OP_ACT_NORMAL); // carrier (if 2op) 808 #if defined(OPLTYPE_IS_OPL3) 809 // for 4op channels all four operators are switched on 810 if ((adlibreg[0x105]&1) && op[opbase].is_4op) { 811 // turn on chan+3 operators as well 812 enable_operator(modbase+8,&op[opbase+3],OP_ACT_NORMAL); 813 enable_operator(modbase+3+8,&op[opbase+3+9],OP_ACT_NORMAL); 814 } 815 #endif 816 } else { 817 // operator switched off 818 disable_operator(&op[opbase],OP_ACT_NORMAL); 819 disable_operator(&op[opbase+9],OP_ACT_NORMAL); 820 #if defined(OPLTYPE_IS_OPL3) 821 // for 4op channels all four operators are switched off 822 if ((adlibreg[0x105]&1) && op[opbase].is_4op) { 823 // turn off chan+3 operators as well 824 disable_operator(&op[opbase+3],OP_ACT_NORMAL); 825 disable_operator(&op[opbase+3+9],OP_ACT_NORMAL); 826 } 827 #endif 828 } 829 830 Bitu chanbase = base+second_set; 831 832 // change frequency calculations of modulator and carrier (2op) as 833 // the frequency of the channel has changed 834 change_frequency(chanbase,modbase,&op[opbase]); 835 change_frequency(chanbase,modbase+3,&op[opbase+9]); 836 #if defined(OPLTYPE_IS_OPL3) 837 // for 4op channels all four operators are modified to the frequency of the channel 838 if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { 839 // change frequency calculations of chan+3 operators as well 840 change_frequency(chanbase,modbase+8,&op[opbase+3]); 841 change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); 842 } 843 #endif 844 } 845 } 846 break; 847 case ARC_FEEDBACK: { 848 // 0xc0-0xc8 feedback/modulation type (AM/FM) 849 Bitu base = (idx-ARC_FEEDBACK)&0xff; 850 if (base<9) { 851 Bits opbase = second_set?(base+18):base; 852 Bitu chanbase = base+second_set; 853 change_feedback(chanbase,&op[opbase]); 854 #if defined(OPLTYPE_IS_OPL3) 855 // OPL3 panning 856 op[opbase].left_pan = ((val&0x10)>>4)+((val&0x40)>>6); 857 op[opbase].right_pan = ((val&0x20)>>5)+((val&0x80)>>7); 858 #endif 859 } 860 } 861 break; 862 case ARC_WAVE_SEL: 863 case ARC_WAVE_SEL+0x10: { 864 int num = idx&7; 865 Bitu base = (idx-ARC_WAVE_SEL)&0xff; 866 if ((num<6) && (base<22)) { 867 #if defined(OPLTYPE_IS_OPL3) 868 Bits wselbase = second_set?(base+22):base; // for easier mapping onto wave_sel[] 869 // change waveform 870 if (adlibreg[0x105]&1) wave_sel[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible 871 else wave_sel[wselbase] = val&3; 872 op_type* op_ptr = &op[regbase2modop[wselbase]+((num<3) ? 0 : 9)]; 873 change_waveform(wselbase,op_ptr); 874 #else 875 if (adlibreg[0x01]&0x20) { 876 // wave selection enabled, change waveform 877 wave_sel[base] = val&3; 878 op_type* op_ptr = &op[regbase2modop[base]+((num<3) ? 0 : 9)]; 879 change_waveform(base,op_ptr); 880 } 881 #endif 882 } 883 } 884 break; 885 default: 886 break; 887 } 888 } 889 890 891 Bitu adlib_reg_read(Bitu port) { 892 #if defined(OPLTYPE_IS_OPL3) 893 // opl3-detection routines require ret&6 to be zero 894 if ((port&1)==0) { 895 return status; 896 } 897 return 0x00; 898 #else 899 // opl2-detection routines require ret&6 to be 6 900 if ((port&1)==0) { 901 return status|6; 902 } 903 return 0xff; 904 #endif 905 } 906 907 void adlib_write_index(Bitu port, Bit8u val) { 908 index = val; 909 #if defined(OPLTYPE_IS_OPL3) 910 if ((port&3)!=0) { 911 // possibly second set 912 if (((adlibreg[0x105]&1)!=0) || (index==5)) index |= ARC_SECONDSET; 913 } 914 #endif 915 } 916 917 static inline void clipit16(Bit32s ival, Bit16s* outval) { 918 if (ival<32768) { 919 if (ival>-32769) { 920 *outval=(Bit16s)ival; 921 } else { 922 *outval = -32768; 923 } 924 } else { 925 *outval = 32767; 926 } 927 } 928 929 930 931 // be careful with this 932 // uses cptr and chanval, outputs into outbufl(/outbufr) 933 // for opl3 check if opl3-mode is enabled (which uses stereo panning) 934 #undef CHANVAL_OUT 935 #if defined(OPLTYPE_IS_OPL3) 936 #define CHANVAL_OUT \ 937 if (adlibreg[0x105]&1) { \ 938 outbufl[i] += chanval*cptr[0].left_pan; \ 939 outbufr[i] += chanval*cptr[0].right_pan; \ 940 } else { \ 941 outbufl[i] += chanval*2; \ 942 } 943 #else 944 #define CHANVAL_OUT \ 945 outbufl[i] += chanval; 946 #endif 947 948 void adlib_getsample(Bit16s* sndptr, Bits numsamples) { 949 Bits i, endsamples; 950 op_type* cptr; 951 952 Bit32s outbufl[BLOCKBUF_SIZE]; 953 #if defined(OPLTYPE_IS_OPL3) 954 // second output buffer (right channel for opl3 stereo) 955 Bit32s outbufr[BLOCKBUF_SIZE]; 956 #endif 957 958 // vibrato/tremolo lookup tables (global, to possibly be used by all operators) 959 Bit32s vib_lut[BLOCKBUF_SIZE]; 960 Bit32s trem_lut[BLOCKBUF_SIZE]; 961 962 Bits samples_to_process = numsamples; 963 964 for (Bits cursmp=0; cursmp<samples_to_process; cursmp+=endsamples) { 965 endsamples = samples_to_process-cursmp; 966 if (endsamples>BLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE; 967 968 memset((void*)&outbufl,0,endsamples*sizeof(Bit32s)); 969 #if defined(OPLTYPE_IS_OPL3) 970 // clear second output buffer (opl3 stereo) 971 if (adlibreg[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s)); 972 #endif 973 974 // calculate vibrato/tremolo lookup tables 975 Bit32s vib_tshift = ((adlibreg[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching 976 for (i=0;i<endsamples;i++) { 977 // cycle through vibrato table 978 vibtab_pos += vibtab_add; 979 if (vibtab_pos/FIXEDPT_LFO>=VIBTAB_SIZE) vibtab_pos-=VIBTAB_SIZE*FIXEDPT_LFO; 980 vib_lut[i] = vib_table[vibtab_pos/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents 981 982 // cycle through tremolo table 983 tremtab_pos += tremtab_add; 984 if (tremtab_pos/FIXEDPT_LFO>=TREMTAB_SIZE) tremtab_pos-=TREMTAB_SIZE*FIXEDPT_LFO; 985 if (adlibreg[ARC_PERC_MODE]&0x80) trem_lut[i] = trem_table[tremtab_pos/FIXEDPT_LFO]; 986 else trem_lut[i] = trem_table[TREMTAB_SIZE+tremtab_pos/FIXEDPT_LFO]; 987 } 988 989 if (adlibreg[ARC_PERC_MODE]&0x20) { 990 //BassDrum 991 cptr = &op[6]; 992 if (adlibreg[ARC_FEEDBACK+6]&1) { 993 // additive synthesis 994 if (cptr[9].op_state != OF_TYPE_OFF) { 995 if (cptr[9].vibrato) { 996 vibval1 = vibval_var1; 997 for (i=0;i<endsamples;i++) 998 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 999 } else vibval1 = vibval_const; 1000 if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1001 else tremval1 = tremval_const; 1002 1003 // calculate channel output 1004 for (i=0;i<endsamples;i++) { 1005 operator_advance(&cptr[9],vibval1[i]); 1006 opfuncs[cptr[9].op_state](&cptr[9]); 1007 operator_output(&cptr[9],0,tremval1[i]); 1008 1009 Bit32s chanval = cptr[9].cval*2; 1010 CHANVAL_OUT 1011 } 1012 } 1013 } else { 1014 // frequency modulation 1015 if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[0].op_state != OF_TYPE_OFF)) { 1016 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1017 vibval1 = vibval_var1; 1018 for (i=0;i<endsamples;i++) 1019 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1020 } else vibval1 = vibval_const; 1021 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1022 vibval2 = vibval_var2; 1023 for (i=0;i<endsamples;i++) 1024 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1025 } else vibval2 = vibval_const; 1026 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1027 else tremval1 = tremval_const; 1028 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1029 else tremval2 = tremval_const; 1030 1031 // calculate channel output 1032 for (i=0;i<endsamples;i++) { 1033 operator_advance(&cptr[0],vibval1[i]); 1034 opfuncs[cptr[0].op_state](&cptr[0]); 1035 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1036 1037 operator_advance(&cptr[9],vibval2[i]); 1038 opfuncs[cptr[9].op_state](&cptr[9]); 1039 operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); 1040 1041 Bit32s chanval = cptr[9].cval*2; 1042 CHANVAL_OUT 1043 } 1044 } 1045 } 1046 1047 //TomTom (j=8) 1048 if (op[8].op_state != OF_TYPE_OFF) { 1049 cptr = &op[8]; 1050 if (cptr[0].vibrato) { 1051 vibval3 = vibval_var1; 1052 for (i=0;i<endsamples;i++) 1053 vibval3[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1054 } else vibval3 = vibval_const; 1055 1056 if (cptr[0].tremolo) tremval3 = trem_lut; // tremolo enabled, use table 1057 else tremval3 = tremval_const; 1058 1059 // calculate channel output 1060 for (i=0;i<endsamples;i++) { 1061 operator_advance(&cptr[0],vibval3[i]); 1062 opfuncs[cptr[0].op_state](&cptr[0]); //TomTom 1063 operator_output(&cptr[0],0,tremval3[i]); 1064 Bit32s chanval = cptr[0].cval*2; 1065 CHANVAL_OUT 1066 } 1067 } 1068 1069 //Snare/Hihat (j=7), Cymbal (j=8) 1070 if ((op[7].op_state != OF_TYPE_OFF) || (op[16].op_state != OF_TYPE_OFF) || 1071 (op[17].op_state != OF_TYPE_OFF)) { 1072 cptr = &op[7]; 1073 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1074 vibval1 = vibval_var1; 1075 for (i=0;i<endsamples;i++) 1076 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1077 } else vibval1 = vibval_const; 1078 if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) { 1079 vibval2 = vibval_var2; 1080 for (i=0;i<endsamples;i++) 1081 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1082 } else vibval2 = vibval_const; 1083 1084 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1085 else tremval1 = tremval_const; 1086 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1087 else tremval2 = tremval_const; 1088 1089 cptr = &op[8]; 1090 if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) { 1091 vibval4 = vibval_var2; 1092 for (i=0;i<endsamples;i++) 1093 vibval4[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1094 } else vibval4 = vibval_const; 1095 1096 if (cptr[9].tremolo) tremval4 = trem_lut; // tremolo enabled, use table 1097 else tremval4 = tremval_const; 1098 1099 // calculate channel output 1100 for (i=0;i<endsamples;i++) { 1101 operator_advance_drums(&op[7],vibval1[i],&op[7+9],vibval2[i],&op[8+9],vibval4[i]); 1102 1103 opfuncs[op[7].op_state](&op[7]); //Hihat 1104 operator_output(&op[7],0,tremval1[i]); 1105 1106 opfuncs[op[7+9].op_state](&op[7+9]); //Snare 1107 operator_output(&op[7+9],0,tremval2[i]); 1108 1109 opfuncs[op[8+9].op_state](&op[8+9]); //Cymbal 1110 operator_output(&op[8+9],0,tremval4[i]); 1111 1112 Bit32s chanval = (op[7].cval + op[7+9].cval + op[8+9].cval)*2; 1113 CHANVAL_OUT 1114 } 1115 } 1116 } 1117 1118 Bitu max_channel = NUM_CHANNELS; 1119 #if defined(OPLTYPE_IS_OPL3) 1120 if ((adlibreg[0x105]&1)==0) max_channel = NUM_CHANNELS/2; 1121 #endif 1122 for (Bits cur_ch=max_channel-1; cur_ch>=0; cur_ch--) { 1123 // skip drum/percussion operators 1124 if ((adlibreg[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue; 1125 1126 Bitu k = cur_ch; 1127 #if defined(OPLTYPE_IS_OPL3) 1128 if (cur_ch < 9) { 1129 cptr = &op[cur_ch]; 1130 } else { 1131 cptr = &op[cur_ch+9]; // second set is operator18-operator35 1132 k += (-9+256); // second set uses registers 0x100 onwards 1133 } 1134 // check if this operator is part of a 4-op 1135 if ((adlibreg[0x105]&1) && cptr->is_4op_attached) continue; 1136 #else 1137 cptr = &op[cur_ch]; 1138 #endif 1139 1140 // check for FM/AM 1141 if (adlibreg[ARC_FEEDBACK+k]&1) { 1142 #if defined(OPLTYPE_IS_OPL3) 1143 if ((adlibreg[0x105]&1) && cptr->is_4op) { 1144 if (adlibreg[ARC_FEEDBACK+k+3]&1) { 1145 // AM-AM-style synthesis (op1[fb] + (op2 * op3) + op4) 1146 if (cptr[0].op_state != OF_TYPE_OFF) { 1147 if (cptr[0].vibrato) { 1148 vibval1 = vibval_var1; 1149 for (i=0;i<endsamples;i++) 1150 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1151 } else vibval1 = vibval_const; 1152 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1153 else tremval1 = tremval_const; 1154 1155 // calculate channel output 1156 for (i=0;i<endsamples;i++) { 1157 operator_advance(&cptr[0],vibval1[i]); 1158 opfuncs[cptr[0].op_state](&cptr[0]); 1159 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1160 1161 Bit32s chanval = cptr[0].cval; 1162 CHANVAL_OUT 1163 } 1164 } 1165 1166 if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { 1167 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1168 vibval1 = vibval_var1; 1169 for (i=0;i<endsamples;i++) 1170 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1171 } else vibval1 = vibval_const; 1172 if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1173 else tremval1 = tremval_const; 1174 if (cptr[3].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1175 else tremval2 = tremval_const; 1176 1177 // calculate channel output 1178 for (i=0;i<endsamples;i++) { 1179 operator_advance(&cptr[9],vibval1[i]); 1180 opfuncs[cptr[9].op_state](&cptr[9]); 1181 operator_output(&cptr[9],0,tremval1[i]); 1182 1183 operator_advance(&cptr[3],0); 1184 opfuncs[cptr[3].op_state](&cptr[3]); 1185 operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]); 1186 1187 Bit32s chanval = cptr[3].cval; 1188 CHANVAL_OUT 1189 } 1190 } 1191 1192 if (cptr[3+9].op_state != OF_TYPE_OFF) { 1193 if (cptr[3+9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1194 else tremval1 = tremval_const; 1195 1196 // calculate channel output 1197 for (i=0;i<endsamples;i++) { 1198 operator_advance(&cptr[3+9],0); 1199 opfuncs[cptr[3+9].op_state](&cptr[3+9]); 1200 operator_output(&cptr[3+9],0,tremval1[i]); 1201 1202 Bit32s chanval = cptr[3+9].cval; 1203 CHANVAL_OUT 1204 } 1205 } 1206 } else { 1207 // AM-FM-style synthesis (op1[fb] + (op2 * op3 * op4)) 1208 if (cptr[0].op_state != OF_TYPE_OFF) { 1209 if (cptr[0].vibrato) { 1210 vibval1 = vibval_var1; 1211 for (i=0;i<endsamples;i++) 1212 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1213 } else vibval1 = vibval_const; 1214 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1215 else tremval1 = tremval_const; 1216 1217 // calculate channel output 1218 for (i=0;i<endsamples;i++) { 1219 operator_advance(&cptr[0],vibval1[i]); 1220 opfuncs[cptr[0].op_state](&cptr[0]); 1221 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1222 1223 Bit32s chanval = cptr[0].cval; 1224 CHANVAL_OUT 1225 } 1226 } 1227 1228 if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { 1229 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1230 vibval1 = vibval_var1; 1231 for (i=0;i<endsamples;i++) 1232 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1233 } else vibval1 = vibval_const; 1234 if (cptr[9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1235 else tremval1 = tremval_const; 1236 if (cptr[3].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1237 else tremval2 = tremval_const; 1238 if (cptr[3+9].tremolo) tremval3 = trem_lut; // tremolo enabled, use table 1239 else tremval3 = tremval_const; 1240 1241 // calculate channel output 1242 for (i=0;i<endsamples;i++) { 1243 operator_advance(&cptr[9],vibval1[i]); 1244 opfuncs[cptr[9].op_state](&cptr[9]); 1245 operator_output(&cptr[9],0,tremval1[i]); 1246 1247 operator_advance(&cptr[3],0); 1248 opfuncs[cptr[3].op_state](&cptr[3]); 1249 operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]); 1250 1251 operator_advance(&cptr[3+9],0); 1252 opfuncs[cptr[3+9].op_state](&cptr[3+9]); 1253 operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval3[i]); 1254 1255 Bit32s chanval = cptr[3+9].cval; 1256 CHANVAL_OUT 1257 } 1258 } 1259 } 1260 continue; 1261 } 1262 #endif 1263 // 2op additive synthesis 1264 if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue; 1265 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1266 vibval1 = vibval_var1; 1267 for (i=0;i<endsamples;i++) 1268 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1269 } else vibval1 = vibval_const; 1270 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1271 vibval2 = vibval_var2; 1272 for (i=0;i<endsamples;i++) 1273 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1274 } else vibval2 = vibval_const; 1275 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1276 else tremval1 = tremval_const; 1277 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1278 else tremval2 = tremval_const; 1279 1280 // calculate channel output 1281 for (i=0;i<endsamples;i++) { 1282 // carrier1 1283 operator_advance(&cptr[0],vibval1[i]); 1284 opfuncs[cptr[0].op_state](&cptr[0]); 1285 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1286 1287 // carrier2 1288 operator_advance(&cptr[9],vibval2[i]); 1289 opfuncs[cptr[9].op_state](&cptr[9]); 1290 operator_output(&cptr[9],0,tremval2[i]); 1291 1292 Bit32s chanval = cptr[9].cval + cptr[0].cval; 1293 CHANVAL_OUT 1294 } 1295 } else { 1296 #if defined(OPLTYPE_IS_OPL3) 1297 if ((adlibreg[0x105]&1) && cptr->is_4op) { 1298 if (adlibreg[ARC_FEEDBACK+k+3]&1) { 1299 // FM-AM-style synthesis ((op1[fb] * op2) + (op3 * op4)) 1300 if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { 1301 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1302 vibval1 = vibval_var1; 1303 for (i=0;i<endsamples;i++) 1304 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1305 } else vibval1 = vibval_const; 1306 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1307 vibval2 = vibval_var2; 1308 for (i=0;i<endsamples;i++) 1309 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1310 } else vibval2 = vibval_const; 1311 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1312 else tremval1 = tremval_const; 1313 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1314 else tremval2 = tremval_const; 1315 1316 // calculate channel output 1317 for (i=0;i<endsamples;i++) { 1318 operator_advance(&cptr[0],vibval1[i]); 1319 opfuncs[cptr[0].op_state](&cptr[0]); 1320 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1321 1322 operator_advance(&cptr[9],vibval2[i]); 1323 opfuncs[cptr[9].op_state](&cptr[9]); 1324 operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); 1325 1326 Bit32s chanval = cptr[9].cval; 1327 CHANVAL_OUT 1328 } 1329 } 1330 1331 if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { 1332 if (cptr[3].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1333 else tremval1 = tremval_const; 1334 if (cptr[3+9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1335 else tremval2 = tremval_const; 1336 1337 // calculate channel output 1338 for (i=0;i<endsamples;i++) { 1339 operator_advance(&cptr[3],0); 1340 opfuncs[cptr[3].op_state](&cptr[3]); 1341 operator_output(&cptr[3],0,tremval1[i]); 1342 1343 operator_advance(&cptr[3+9],0); 1344 opfuncs[cptr[3+9].op_state](&cptr[3+9]); 1345 operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval2[i]); 1346 1347 Bit32s chanval = cptr[3+9].cval; 1348 CHANVAL_OUT 1349 } 1350 } 1351 1352 } else { 1353 // FM-FM-style synthesis (op1[fb] * op2 * op3 * op4) 1354 if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF) || 1355 (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { 1356 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1357 vibval1 = vibval_var1; 1358 for (i=0;i<endsamples;i++) 1359 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1360 } else vibval1 = vibval_const; 1361 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1362 vibval2 = vibval_var2; 1363 for (i=0;i<endsamples;i++) 1364 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1365 } else vibval2 = vibval_const; 1366 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1367 else tremval1 = tremval_const; 1368 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1369 else tremval2 = tremval_const; 1370 if (cptr[3].tremolo) tremval3 = trem_lut; // tremolo enabled, use table 1371 else tremval3 = tremval_const; 1372 if (cptr[3+9].tremolo) tremval4 = trem_lut; // tremolo enabled, use table 1373 else tremval4 = tremval_const; 1374 1375 // calculate channel output 1376 for (i=0;i<endsamples;i++) { 1377 operator_advance(&cptr[0],vibval1[i]); 1378 opfuncs[cptr[0].op_state](&cptr[0]); 1379 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1380 1381 operator_advance(&cptr[9],vibval2[i]); 1382 opfuncs[cptr[9].op_state](&cptr[9]); 1383 operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); 1384 1385 operator_advance(&cptr[3],0); 1386 opfuncs[cptr[3].op_state](&cptr[3]); 1387 operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval3[i]); 1388 1389 operator_advance(&cptr[3+9],0); 1390 opfuncs[cptr[3+9].op_state](&cptr[3+9]); 1391 operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval4[i]); 1392 1393 Bit32s chanval = cptr[3+9].cval; 1394 CHANVAL_OUT 1395 } 1396 } 1397 } 1398 continue; 1399 } 1400 #endif 1401 // 2op frequency modulation 1402 if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue; 1403 if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { 1404 vibval1 = vibval_var1; 1405 for (i=0;i<endsamples;i++) 1406 vibval1[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); 1407 } else vibval1 = vibval_const; 1408 if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { 1409 vibval2 = vibval_var2; 1410 for (i=0;i<endsamples;i++) 1411 vibval2[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); 1412 } else vibval2 = vibval_const; 1413 if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table 1414 else tremval1 = tremval_const; 1415 if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table 1416 else tremval2 = tremval_const; 1417 1418 // calculate channel output 1419 for (i=0;i<endsamples;i++) { 1420 // modulator 1421 operator_advance(&cptr[0],vibval1[i]); 1422 opfuncs[cptr[0].op_state](&cptr[0]); 1423 operator_output(&cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,tremval1[i]); 1424 1425 // carrier 1426 operator_advance(&cptr[9],vibval2[i]); 1427 opfuncs[cptr[9].op_state](&cptr[9]); 1428 operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); 1429 1430 Bit32s chanval = cptr[9].cval; 1431 CHANVAL_OUT 1432 } 1433 } 1434 } 1435 1436 #if defined(OPLTYPE_IS_OPL3) 1437 if (adlibreg[0x105]&1) { 1438 // convert to 16bit samples (stereo) 1439 for (i=0;i<endsamples;i++) { 1440 clipit16(outbufl[i],sndptr++); 1441 clipit16(outbufr[i],sndptr++); 1442 } 1443 } else { 1444 // convert to 16bit samples (mono) 1445 for (i=0;i<endsamples;i++) { 1446 clipit16(outbufl[i],sndptr++); 1447 clipit16(outbufl[i],sndptr++); 1448 } 1449 } 1450 #else 1451 // convert to 16bit samples 1452 for (i=0;i<endsamples;i++) 1453 clipit16(outbufl[i],sndptr++); 1454 #endif 1455 1456 } 1457 } -
sound/softsynth/adlib/adlib.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 #include "adlib.h" 27 28 #include "mame.h" 29 #include "dosbox.h" 30 31 namespace AdLib { 32 33 // Wrapper around old MAME fmopl 34 35 // TODO: Move to mame.h (?) 36 37 class AdLib_MAME : public AdLib { 38 private: 39 MAME::FM_OPL *_opl; 40 public: 41 AdLib_MAME() : _opl(0) {} 42 ~AdLib_MAME(); 43 44 void init(int rate, kOplType type); 45 void reset(); 46 47 void write(int a, int v); 48 byte read(int a); 49 50 void writeReg(int r, int v); 51 52 void readBuffer(int16 *buffer, int length); 53 }; 54 55 AdLib_MAME::~AdLib_MAME() { 56 MAME::OPLDestroy(_opl); 57 _opl = 0; 58 } 59 60 void AdLib_MAME::init(int rate, kOplType type) { 61 if (_opl) 62 MAME::OPLDestroy(_opl); 63 64 _opl = MAME::makeAdlibOPL(rate); 65 } 66 67 void AdLib_MAME::reset() { 68 MAME::OPLResetChip(_opl); 69 } 70 71 void AdLib_MAME::write(int a, int v) { 72 MAME::OPLWrite(_opl, a, v); 73 } 74 75 byte AdLib_MAME::read(int a) { 76 return MAME::OPLRead(_opl, a); 77 } 78 79 void AdLib_MAME::writeReg(int r, int v) { 80 MAME::OPLWriteReg(_opl, r, v); 81 } 82 83 void AdLib_MAME::readBuffer(int16 *buffer, int length) { 84 MAME::YM3812UpdateOne(_opl, buffer, length); 85 } 86 87 // Factory for creating AdLib emulator 88 89 AdLib *AdLib::createInstance() { 90 // return new AdLib_MAME(); 91 return new DOSBox::AdLib_DOSBox(); 92 } 93 94 } // end of namespace AdLib 95 -
engines/sci/sfx/softseq/opl2.cpp
47 47 #include "../softseq.h" 48 48 #include "../adlib.h" 49 49 50 #include "sound/fmopl.h" 50 // FIXME: This code seems to heavily rely on the MAME fmopl emulator, 51 // thus we will use it directly. 52 #include "sound/softsynth/adlib/mame.h" 51 53 54 using namespace AdLib::MAME; 55 52 56 namespace Sci { 53 57 54 58 // FIXME: Instead of hardcoding SAMPLE_RATE we should call Mixer::getOutputRate()