Ticket #9010: dosbox_adlib_v3.patch

File dosbox_adlib_v3.patch, 150.4 KB (added by lordhoto, 15 years ago)

Working patch against r40119.

  • engines/sci/sfx/softseq/opl2.cpp

     
    4747#include "../softseq.h"
    4848#include "../adlib.h"
    4949
    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"
    5153
     54using namespace AdLib::MAME;
     55
    5256namespace Sci {
    5357
    5458// FIXME: Instead of hardcoding SAMPLE_RATE we should call Mixer::getOutputRate()
  • sound/module.mk

     
    3030        mods/rjp1.o \
    3131        mods/soundfx.o \
    3232        softsynth/adlib.o \
     33        softsynth/adlib/adlib.o \
     34        softsynth/adlib/dosbox.o \
     35        softsynth/adlib/mame.o \
    3336        softsynth/ym2612.o \
    3437        softsynth/fluidsynth.o \
    3538        softsynth/mt32.o \
  • sound/fmopl.h

     
    88 * modify it under the terms of the GNU General Public License
    99 * as published by the Free Software Foundation; either version 2
    1010 * of the License, or (at your option) any later version.
    11 
     11 *
    1212 * This program is distributed in the hope that it will be useful,
    1313 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515 * GNU General Public License for more details.
    16 
     16 *
    1717 * You should have received a copy of the GNU General Public License
    1818 * along with this program; if not, write to the Free Software
    1919 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    2020 *
    2121 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.h $
    2222 * $Id: fmopl.h 38211 2009-02-15 10:07:50Z sev $
    23  *
    24  * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
    25  * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
    2623 */
    2724
    28 
    2925#ifndef SOUND_FMOPL_H
    3026#define SOUND_FMOPL_H
    3127
    32 #include "common/scummsys.h"
    33 #include "common/util.h"
     28#include "softsynth/adlib/adlib.h"
    3429
    35 enum {
    36         FMOPL_ENV_BITS_HQ = 16,
    37         FMOPL_ENV_BITS_MQ = 8,
    38         FMOPL_ENV_BITS_LQ = 8,
    39         FMOPL_EG_ENT_HQ = 4096,
    40         FMOPL_EG_ENT_MQ = 1024,
    41         FMOPL_EG_ENT_LQ = 128
    42 };
    43 
    44 
    45 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)
     30// Legacy API
     31typedef AdLib::AdLib FM_OPL;
    15432
    155 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);
    156 
    157 FM_OPL *OPLCreate(int type, int clock, int rate);
    15833void 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);
    16234
    16335void OPLResetChip(FM_OPL *OPL);
    164 int OPLWrite(FM_OPL *OPL, int a, int v);
     36void OPLWrite(FM_OPL *OPL, int a, int v);
    16537unsigned char OPLRead(FM_OPL *OPL, int a);
    166 int OPLTimerOver(FM_OPL *OPL, int c);
    16738void OPLWriteReg(FM_OPL *OPL, int r, int v);
    168 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave = 0);
     39void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length);
    16940
    17041// Factory method
    17142FM_OPL *makeAdlibOPL(int rate);
    17243
    17344#endif
     45
  • sound/fmopl.cpp

     
    88 * modify it under the terms of the GNU General Public License
    99 * as published by the Free Software Foundation; either version 2
    1010 * of the License, or (at your option) any later version.
    11 
     11 *
    1212 * This program is distributed in the hope that it will be useful,
    1313 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515 * GNU General Public License for more details.
    16 
     16 *
    1717 * You should have received a copy of the GNU General Public License
    1818 * along with this program; if not, write to the Free Software
    1919 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    2020 *
    2121 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.cpp $
    2222 * $Id: fmopl.cpp 38211 2009-02-15 10:07:50Z sev $
    23  *
    24  * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
    25  * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
    2623 */
    2724
    28 #include <stdio.h>
    29 #include <stdlib.h>
    30 #include <string.h>
    31 #include <stdarg.h>
    32 #include <math.h>
    33 
    3425#include "sound/fmopl.h"
    3526
    36 #if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__)
    37 #include "common/config-manager.h"
    38 #endif
    39 
    40 /* -------------------- preliminary define section --------------------- */
    41 /* attack/decay rate time rate */
    42 #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
    43 #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
    44 
    45 #define FREQ_BITS 24                    /* frequency turn          */
    46 
    47 /* counter bits = 20 , octerve 7 */
    48 #define FREQ_RATE   (1<<(FREQ_BITS-20))
    49 #define TL_BITS    (FREQ_BITS+2)
    50 
    51 /* final output shift , limit minimum and maximum */
    52 #define OPL_OUTSB   (TL_BITS+3-16)              /* OPL output final shift 16bit */
    53 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
    54 #define OPL_MINOUT (-0x8000<<OPL_OUTSB)
    55 
    56 /* -------------------- quality selection --------------------- */
    57 
    58 /* sinwave entries */
    59 /* used static memory = SIN_ENT * 4 (byte) */
    60 #ifdef __DS__
    61 #include "dsmain.h"
    62 #define SIN_ENT_SHIFT 8
    63 #else
    64 #define SIN_ENT_SHIFT 11
    65 #endif
    66 #define SIN_ENT (1<<SIN_ENT_SHIFT)
    67 
    68 /* output level entries (envelope,sinwave) */
    69 /* envelope counter lower bits */
    70 int ENV_BITS;
    71 /* envelope output entries */
    72 int EG_ENT;
    73 
    74 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
    75 /* used static  memory = EG_ENT*4 (byte)                     */
    76 int EG_OFF;                                                              /* OFF */
    77 int EG_DED;
    78 int EG_DST;                                                              /* DECAY START */
    79 int EG_AED;
    80 #define EG_AST   0                       /* ATTACK START */
    81 
    82 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
    83 
    84 /* LFO table entries */
    85 #define VIB_ENT 512
    86 #define VIB_SHIFT (32-9)
    87 #define AMS_ENT 512
    88 #define AMS_SHIFT (32-9)
    89 
    90 #define VIB_RATE_SHIFT 8
    91 #define VIB_RATE (1<<VIB_RATE_SHIFT)
    92 
    93 /* -------------------- local defines , macros --------------------- */
    94 
    95 /* register number to channel number , slot offset */
    96 #define SLOT1 0
    97 #define SLOT2 1
    98 
    99 /* envelope phase */
    100 #define ENV_MOD_RR  0x00
    101 #define ENV_MOD_DR  0x01
    102 #define ENV_MOD_AR  0x02
    103 
    104 /* -------------------- tables --------------------- */
    105 static const int slot_array[32] = {
    106          0, 2, 4, 1, 3, 5,-1,-1,
    107          6, 8,10, 7, 9,11,-1,-1,
    108         12,14,16,13,15,17,-1,-1,
    109         -1,-1,-1,-1,-1,-1,-1,-1
    110 };
    111 
    112 static uint KSL_TABLE[8 * 16];
    113 
    114 static const double KSL_TABLE_SEED[8 * 16] = {
    115         /* OCT 0 */
    116         0.000, 0.000, 0.000, 0.000,
    117         0.000, 0.000, 0.000, 0.000,
    118         0.000, 0.000, 0.000, 0.000,
    119         0.000, 0.000, 0.000, 0.000,
    120         /* OCT 1 */
    121         0.000, 0.000, 0.000, 0.000,
    122         0.000, 0.000, 0.000, 0.000,
    123         0.000, 0.750, 1.125, 1.500,
    124         1.875, 2.250, 2.625, 3.000,
    125         /* OCT 2 */
    126         0.000, 0.000, 0.000, 0.000,
    127         0.000, 1.125, 1.875, 2.625,
    128         3.000, 3.750, 4.125, 4.500,
    129         4.875, 5.250, 5.625, 6.000,
    130         /* OCT 3 */
    131         0.000, 0.000, 0.000, 1.875,
    132         3.000, 4.125, 4.875, 5.625,
    133         6.000, 6.750, 7.125, 7.500,
    134         7.875, 8.250, 8.625, 9.000,
    135         /* OCT 4 */
    136         0.000, 0.000, 3.000, 4.875,
    137         6.000, 7.125, 7.875, 8.625,
    138         9.000, 9.750, 10.125, 10.500,
    139         10.875, 11.250, 11.625, 12.000,
    140         /* OCT 5 */
    141         0.000, 3.000, 6.000, 7.875,
    142         9.000, 10.125, 10.875, 11.625,
    143         12.000, 12.750, 13.125, 13.500,
    144         13.875, 14.250, 14.625, 15.000,
    145         /* OCT 6 */
    146         0.000, 6.000, 9.000, 10.875,
    147         12.000, 13.125, 13.875, 14.625,
    148         15.000, 15.750, 16.125, 16.500,
    149         16.875, 17.250, 17.625, 18.000,
    150         /* OCT 7 */
    151         0.000, 9.000, 12.000, 13.875,
    152         15.000, 16.125, 16.875, 17.625,
    153         18.000, 18.750, 19.125, 19.500,
    154         19.875, 20.250, 20.625, 21.000
    155 };
    156 
    157 /* sustain level table (3db per step) */
    158 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
    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, 31
    164 };
    165 
    166 #define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
    167 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
    168 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
    169 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
    170 static int *TL_TABLE;
    171 
    172 /* pointers to TL_TABLE with sinwave output offset */
    173 static int **SIN_TABLE;
    174 
    175 /* LFO table */
    176 static int *AMS_TABLE;
    177 static int *VIB_TABLE;
    178 
    179 /* envelope output curve table */
    180 /* attack + decay + OFF */
    181 //static int ENV_CURVE[2*EG_ENT+1];
    182 //static int ENV_CURVE[2 * 4096 + 1];   // to keep it static ...
    183 static int *ENV_CURVE;
    184 
    185 
    186 /* multiple table */
    187 #define ML(a) (int)(a * 2)
    188 static const uint MUL_TABLE[16]= {
    189 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
    190         ML(0.50), ML(1.00), ML(2.00),  ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
    191         ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
    192 };
    193 #undef ML
    194 
    195 /* dummy attack / decay rate ( when rate == 0 ) */
    196 static int RATE_0[16]=
    197 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    198 
    199 /* -------------------- static state --------------------- */
    200 
    201 /* lock level of common table */
    202 static int num_lock = 0;
    203 
    204 /* work table */
    205 static void *cur_chip = NULL;   /* current chip point */
    206 /* currenct chip state */
    207 /* static OPLSAMPLE  *bufL,*bufR; */
    208 static OPL_CH *S_CH;
    209 static OPL_CH *E_CH;
    210 OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
    211 
    212 static int outd[1];
    213 static int ams;
    214 static int vib;
    215 int *ams_table;
    216 int *vib_table;
    217 static int amsIncr;
    218 static int vibIncr;
    219 static int feedback2;           /* connect for SLOT 2 */
    220 
    221 /* --------------------- rebuild tables ------------------- */
    222 
    223 #define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2)))
    224 #define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
    225 
    226 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
    227         int i;
    228 
    229         ENV_BITS = ENV_BITS_PARAM;
    230         EG_ENT = EG_ENT_PARAM;
    231         EG_OFF = ((2 * EG_ENT)<<ENV_BITS);  /* OFF          */
    232         EG_DED = EG_OFF;
    233         EG_DST = (EG_ENT << ENV_BITS);     /* DECAY  START */
    234         EG_AED = EG_DST;
    235         //EG_STEP = (96.0/EG_ENT);
    236 
    237         for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++)
    238                 KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
    239 
    240         for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++)
    241                 SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
    242 }
    243 
    244 #undef SC_KSL
    245 #undef SC_SL
    246 
    247 /* --------------------- subroutines  --------------------- */
    248 
    249 /* status set and IRQ handling */
    250 inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
    251         /* set status flag */
    252         OPL->status |= flag;
    253         if(!(OPL->status & 0x80)) {
    254                 if(OPL->status & OPL->statusmask) {     /* IRQ on */
    255                         OPL->status |= 0x80;
    256                         /* callback user interrupt handler (IRQ is OFF to ON) */
    257                         if(OPL->IRQHandler)
    258                                 (OPL->IRQHandler)(OPL->IRQParam,1);
    259                 }
    260         }
    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 when
    301                 // starting a new song. For each channel:
    302                 //
    303                 // * The release rate is set to "fastest".
    304                 // * Any note is keyed off.
    305                 // * A very low-frequency note is keyed on.
    306                 //
    307                 // Usually, what happens next is that the real notes is keyed
    308                 // on immediately, in which case there's no problem.
    309                 //
    310                 // However, if the note is again keyed off (because the channel
    311                 // begins on a rest rather than a note), the envelope counter
    312                 // was moved from the very lowest point on the attack curve to
    313                 // the very highest point on the release curve.
    314                 //
    315                 // Again, this might not be a problem, if the release rate is
    316                 // still set to "fastest". But in many cases, it had already
    317                 // been increased. And, possibly because of inaccuracies in the
    318                 // envelope generator, that would cause the note to "fade out"
    319                 // for quite a long time.
    320                 //
    321                 // What we really need is a way to find the correct starting
    322                 // point for the envelope counter, and that may be what the
    323                 // commented-out line below is meant to do. For now, simply
    324                 // handle the pathological case.
    325 
    326                 if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
    327                         SLOT->evc = EG_DED;
    328                 else if( !(SLOT->evc & EG_DST) )
    329                         //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
    330                         SLOT->evc = EG_DST;
    331                 SLOT->eve = EG_DED;
    332                 SLOT->evs = SLOT->evsr;
    333                 SLOT->evm = ENV_MOD_RR;
    334         }
    335 }
    336 
    337 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
    338 
    339 /* return : envelope output */
    340 inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
    341         /* calcrate envelope generator */
    342         if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
    343                 switch( SLOT->evm ) {
    344                 case ENV_MOD_AR: /* ATTACK -> DECAY1 */
    345                         /* next DR */
    346                         SLOT->evm = ENV_MOD_DR;
    347                         SLOT->evc = EG_DST;
    348                         SLOT->eve = SLOT->SL;
    349                         SLOT->evs = SLOT->evsd;
    350                         break;
    351                 case ENV_MOD_DR: /* DECAY -> SL or RR */
    352                         SLOT->evc = SLOT->SL;
    353                         SLOT->eve = EG_DED;
    354                         if(SLOT->eg_typ) {
    355                                 SLOT->evs = 0;
    356                         } else {
    357                                 SLOT->evm = ENV_MOD_RR;
    358                                 SLOT->evs = SLOT->evsr;
    359                         }
    360                         break;
    361                 case ENV_MOD_RR: /* RR -> OFF */
    362                         SLOT->evc = EG_OFF;
    363                         SLOT->eve = EG_OFF + 1;
    364                         SLOT->evs = 0;
    365                         break;
    366                 }
    367         }
    368         /* calcrate envelope */
    369         return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
    370 }
    371 
    372 /* set algorythm connection */
    373 static void set_algorythm(OPL_CH *CH) {
    374         int *carrier = &outd[0];
    375         CH->connect1 = CH->CON ? carrier : &feedback2;
    376         CH->connect2 = carrier;
    377 }
    378 
    379 /* ---------- frequency counter for operater update ---------- */
    380 inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
    381         int ksr;
    382 
    383         /* frequency step counter */
    384         SLOT->Incr = CH->fc * SLOT->mul;
    385         ksr = CH->kcode >> SLOT->KSR;
    386 
    387         if( SLOT->ksr != ksr ) {
    388                 SLOT->ksr = ksr;
    389                 /* attack , decay rate recalcration */
    390                 SLOT->evsa = SLOT->AR[ksr];
    391                 SLOT->evsd = SLOT->DR[ksr];
    392                 SLOT->evsr = SLOT->RR[ksr];
    393         }
    394         SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
    395 }
    396 
    397 /* set multi,am,vib,EG-TYP,KSR,mul */
    398 inline void set_mul(FM_OPL *OPL, int slot, int v) {
    399         OPL_CH   *CH   = &OPL->P_CH[slot>>1];
    400         OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
    401 
    402         SLOT->mul    = MUL_TABLE[v & 0x0f];
    403         SLOT->KSR    = (v & 0x10) ? 0 : 2;
    404         SLOT->eg_typ = (v & 0x20) >> 5;
    405         SLOT->vib    = (v & 0x40);
    406         SLOT->ams    = (v & 0x80);
    407         CALC_FCSLOT(CH, SLOT);
    408 }
    409 
    410 /* set ksl & tl */
    411 inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
    412         OPL_CH   *CH   = &OPL->P_CH[slot>>1];
    413         OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
    414         int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
    415 
    416         SLOT->ksl = ksl ? 3-ksl : 31;
    417         SLOT->TL  = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
    418 
    419         if(!(OPL->mode & 0x80)) {       /* not CSM latch total level */
    420                 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
    421         }
    422 }
    423 
    424 /* set attack rate & decay rate  */
    425 inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
    426         OPL_CH   *CH   = &OPL->P_CH[slot>>1];
    427         OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
    428         int ar = v >> 4;
    429         int dr = v & 0x0f;
    430 
    431         SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
    432         SLOT->evsa = SLOT->AR[SLOT->ksr];
    433         if(SLOT->evm == ENV_MOD_AR)
    434                 SLOT->evs = SLOT->evsa;
    435 
    436         SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
    437         SLOT->evsd = SLOT->DR[SLOT->ksr];
    438         if(SLOT->evm == ENV_MOD_DR)
    439                 SLOT->evs = SLOT->evsd;
    440 }
    441 
    442 /* set sustain level & release rate */
    443 inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
    444         OPL_CH   *CH   = &OPL->P_CH[slot>>1];
    445         OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
    446         int sl = v >> 4;
    447         int rr = v & 0x0f;
    448 
    449         SLOT->SL = SL_TABLE[sl];
    450         if(SLOT->evm == ENV_MOD_DR)
    451                 SLOT->eve = SLOT->SL;
    452         SLOT->RR = &OPL->DR_TABLE[rr<<2];
    453         SLOT->evsr = SLOT->RR[SLOT->ksr];
    454         if(SLOT->evm == ENV_MOD_RR)
    455                 SLOT->evs = SLOT->evsr;
    456 }
    457 
    458 /* operator output calcrator */
    459 
    460 #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env]
    461 /* ---------- calcrate one of channel ---------- */
    462 inline void OPL_CALC_CH(OPL_CH *CH) {
    463         uint env_out;
    464         OPL_SLOT *SLOT;
    465 
    466         feedback2 = 0;
    467         /* SLOT 1 */
    468         SLOT = &CH->SLOT[SLOT1];
    469         env_out=OPL_CALC_SLOT(SLOT);
    470         if(env_out < (uint)(EG_ENT - 1)) {
    471                 /* PG */
    472                 if(SLOT->vib)
    473                         SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
    474                 else
    475                         SLOT->Cnt += SLOT->Incr;
    476                 /* connection */
    477                 if(CH->FB) {
    478                         int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
    479                         CH->op1_out[1] = CH->op1_out[0];
    480                         *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
    481                 } else {
    482                         *CH->connect1 += OP_OUT(SLOT, env_out, 0);
    483                 }
    484         } else {
    485                 CH->op1_out[1] = CH->op1_out[0];
    486                 CH->op1_out[0] = 0;
    487         }
    488         /* SLOT 2 */
    489         SLOT = &CH->SLOT[SLOT2];
    490         env_out=OPL_CALC_SLOT(SLOT);
    491         if(env_out < (uint)(EG_ENT - 1)) {
    492                 /* PG */
    493                 if(SLOT->vib)
    494                         SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
    495                 else
    496                         SLOT->Cnt += SLOT->Incr;
    497                 /* connection */
    498                 outd[0] += OP_OUT(SLOT, env_out, feedback2);
    499         }
    500 }
    501 
    502 /* ---------- calcrate rythm block ---------- */
    503 #define WHITE_NOISE_db 6.0
    504 inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
    505         uint env_tam, env_sd, env_top, env_hh;
    506         // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
    507         // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
    508         // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
    509         // or 128, so we can safely avoid any FP ops.
    510         int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4);
    511 
    512         int tone8;
    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                 else
    527                         SLOT->Cnt += SLOT->Incr;
    528                 /* connection */
    529                 if(CH[6].FB) {
    530                         int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
    531                         CH[6].op1_out[1] = CH[6].op1_out[0];
    532                         feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
    533                 }
    534                 else {
    535                         feedback2 = OP_OUT(SLOT, env_out, 0);
    536                 }
    537         } else {
    538                 feedback2 = 0;
    539                 CH[6].op1_out[1] = CH[6].op1_out[0];
    540                 CH[6].op1_out[0] = 0;
    541         }
    542         /* SLOT 2 */
    543         SLOT = &CH[6].SLOT[SLOT2];
    544         env_out = OPL_CALC_SLOT(SLOT);
    545         if(env_out < EG_ENT-1) {
    546                 /* PG */
    547                 if(SLOT->vib)
    548                         SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
    549                 else
    550                         SLOT->Cnt += SLOT->Incr;
    551                 /* connection */
    552                 outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
    553         }
    554 
    555         // SD  (17) = mul14[fnum7] + white noise
    556         // TAM (15) = mul15[fnum8]
    557         // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
    558         // HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
    559         env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
    560         env_tam =OPL_CALC_SLOT(SLOT8_1);
    561         env_top = OPL_CALC_SLOT(SLOT8_2);
    562         env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
    563 
    564         /* PG */
    565         if(SLOT7_1->vib)
    566                 SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1);
    567         else
    568                 SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
    569         if(SLOT7_2->vib)
    570                 SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3);
    571         else
    572                 SLOT7_2->Cnt += (CH[7].fc * 8);
    573         if(SLOT8_1->vib)
    574                 SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;
    575         else
    576                 SLOT8_1->Cnt += SLOT8_1->Incr;
    577         if(SLOT8_2->vib)
    578                 SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4);
    579         else
    580                 SLOT8_2->Cnt += (CH[8].fc * 48);
    581 
    582         tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
    583 
    584         /* SD */
    585         if(env_sd < (uint)(EG_ENT - 1))
    586                 outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
    587         /* TAM */
    588         if(env_tam < (uint)(EG_ENT - 1))
    589                 outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
    590         /* TOP-CY */
    591         if(env_top < (uint)(EG_ENT - 1))
    592                 outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
    593         /* HH */
    594         if(env_hh  < (uint)(EG_ENT-1))
    595                 outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
    596 }
    597 
    598 /* ----------- initialize time tabls ----------- */
    599 static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
    600         int i;
    601         double rate;
    602 
    603         /* make attack rate & decay rate tables */
    604         for (i = 0; i < 4; i++)
    605                 OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
    606         for (i = 4; i <= 60; i++) {
    607                 rate = OPL->freqbase;                                           /* frequency rate */
    608                 if(i < 60)
    609                         rate *= 1.0 + (i & 3) * 0.25;           /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
    610                 rate *= 1 << ((i >> 2) - 1);                                            /* b2-5 : shift bit */
    611                 rate *= (double)(EG_ENT << ENV_BITS);
    612                 OPL->AR_TABLE[i] = (int)(rate / ARRATE);
    613                 OPL->DR_TABLE[i] = (int)(rate / DRRATE);
    614         }
    615         for (i = 60; i < 76; i++) {
    616                 OPL->AR_TABLE[i] = EG_AED-1;
    617                 OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
    618         }
    619 }
    620 
    621 /* ---------- generic table initialize ---------- */
    622 static int OPLOpenTable(void) {
    623         int s,t;
    624         double rate;
    625         int i,j;
    626         double pom;
    627 
    628 #ifdef __DS__
    629         DS::fastRamReset();
    630 
    631         TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *));
    632         SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *));
    633 #else
    634 
    635         /* allocate dynamic tables */
    636         if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
    637                 return 0;
    638 
    639         if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
    640                 free(TL_TABLE);
    641                 return 0;
    642         }
    643 #endif
    644 
    645         if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
    646                 free(TL_TABLE);
    647                 free(SIN_TABLE);
    648                 return 0;
    649         }
    650 
    651         if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
    652                 free(TL_TABLE);
    653                 free(SIN_TABLE);
    654                 free(AMS_TABLE);
    655                 return 0;
    656         }
    657         /* make total level table */
    658         for (t = 0; t < EG_ENT - 1 ; t++) {
    659                 rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20);      /* dB -> voltage */
    660                 TL_TABLE[         t] =  (int)rate;
    661                 TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
    662         }
    663         /* fill volume off area */
    664         for (t = EG_ENT - 1; t < TL_MAX; t++) {
    665                 TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
    666         }
    667 
    668         /* make sinwave table (total level offet) */
    669         /* degree 0 = degree 180                   = off */
    670         SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
    671         for (s = 1;s <= SIN_ENT / 4; s++) {
    672                 pom = sin(2 * PI * s / SIN_ENT); /* sin     */
    673                 pom = 20 * log10(1 / pom);         /* decibel */
    674                 j = int(pom / EG_STEP);         /* TL_TABLE steps */
    675 
    676                 /* degree 0   -  90    , degree 180 -  90 : plus section */
    677                 SIN_TABLE[          s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
    678                 /* degree 180 - 270    , degree 360 - 270 : minus section */
    679                 SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
    680         }
    681         for (s = 0;s < SIN_ENT; s++) {
    682                 SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
    683                 SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
    684                 SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
    685         }
    686 
    687 
    688         ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1));
    689 
    690         /* envelope counter -> envelope output table */
    691         for (i=0; i < EG_ENT; i++) {
    692                 /* ATTACK curve */
    693                 pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
    694                 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
    695                 ENV_CURVE[i] = (int)pom;
    696                 /* DECAY ,RELEASE curve */
    697                 ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
    698         }
    699         /* off */
    700         ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
    701         /* make LFO ams table */
    702         for (i=0; i < AMS_ENT; i++) {
    703                 pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
    704                 AMS_TABLE[i]         = (int)((1.0 / EG_STEP) * pom); /* 1dB   */
    705                 AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
    706         }
    707         /* make LFO vibrate table */
    708         for (i=0; i < VIB_ENT; i++) {
    709                 /* 100cent = 1seminote = 6% ?? */
    710                 pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
    711                 VIB_TABLE[i]         = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
    712                 VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
    713         }
    714         return 1;
    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                                         else
    864                                                 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
    865                                 }/* TAM key on/off */
    866                                 if(rkey & 0x04) {
    867                                         if(v & 0x04)
    868                                                 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
    869                                         else
    870                                                 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
    871                                 }
    872                                 /* TOP-CY key on/off */
    873                                 if(rkey & 0x02) {
    874                                         if(v & 0x02)
    875                                                 OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
    876                                         else
    877                                                 OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
    878                                 }
    879                                 /* HH key on/off */
    880                                 if(rkey & 0x01) {
    881                                         if(v & 0x01)
    882                                                 OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
    883                                         else
    884                                                 OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
    885                                 }
    886                         }
    887                         }
    888                         return;
    889 
    890                 default:
    891                         break;
    892                 }
    893                 /* keyon,block,fnum */
    894                 if((r & 0x0f) > 8)
    895                         return;
    896                 CH = &OPL->P_CH[r & 0x0f];
    897                 if(!(r&0x10)) { /* a0-a8 */
    898                         block_fnum  = (CH->block_fnum & 0x1f00) | v;
    899                 } else {        /* b0-b8 */
    900                         int keyon = (v >> 5) & 1;
    901                         block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
    902                         if(CH->keyon != keyon) {
    903                                 if((CH->keyon=keyon)) {
    904                                         CH->op1_out[0] = CH->op1_out[1] = 0;
    905                                         OPL_KEYON(&CH->SLOT[SLOT1]);
    906                                         OPL_KEYON(&CH->SLOT[SLOT2]);
    907                                 } else {
    908                                         OPL_KEYOFF(&CH->SLOT[SLOT1]);
    909                                         OPL_KEYOFF(&CH->SLOT[SLOT2]);
    910                                 }
    911                         }
    912                 }
    913                 /* update */
    914                 if(CH->block_fnum != block_fnum) {
    915                         int blockRv = 7 - (block_fnum >> 10);
    916                         int fnum = block_fnum & 0x3ff;
    917                         CH->block_fnum = block_fnum;
    918                         CH->ksl_base = KSL_TABLE[block_fnum >> 6];
    919                         CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
    920                         CH->kcode = CH->block_fnum >> 9;
    921                         if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
    922                                 CH->kcode |=1;
    923                         CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
    924                         CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
    925                 }
    926                 return;
    927         case 0xc0:
    928                 /* FB,C */
    929                 if((r & 0x0f) > 8)
    930                         return;
    931                 CH = &OPL->P_CH[r&0x0f];
    932                 {
    933                         int feedback = (v >> 1) & 7;
    934                         CH->FB = feedback ? (8 + 1) - feedback : 0;
    935                         CH->CON = v & 1;
    936                         set_algorythm(CH);
    937                 }
    938                 return;
    939         case 0xe0: /* wave type */
    940                 slot = slot_array[r & 0x1f];
    941                 if(slot == -1)
    942                         return;
    943                 CH = &OPL->P_CH[slot>>1];
    944                 if(OPL->wavesel) {
    945                         CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
    946                 }
    947                 return;
    948         }
    949 }
    950 
    951 /* lock/unlock for common table */
    952 static int OPL_LockTable(void) {
    953         num_lock++;
    954         if(num_lock>1)
    955                 return 0;
    956         /* first time */
    957         cur_chip = NULL;
    958         /* allocate total level table (128kb space) */
    959         if(!OPLOpenTable()) {
    960                 num_lock--;
    961                 return -1;
    962         }
    963         return 0;
    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 ----------       */
    109927void 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;
     28        delete OPL;
    110829}
    110930
    1110 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
    1111         OPL->IRQHandler     = IRQHandler;
    1112         OPL->IRQParam = param;
     31void OPLResetChip(FM_OPL *OPL) {
     32        OPL->reset();
    111333}
    111434
    1115 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
    1116         OPL->UpdateHandler = UpdateHandler;
    1117         OPL->UpdateParam = param;
     35void OPLWrite(FM_OPL *OPL, int a, int v) {
     36        OPL->write(a, v);
    111837}
    111938
    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;
     39unsigned char OPLRead(FM_OPL *OPL, int a) {
     40        return OPL->read(a);
    113041}
    113142
    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;
     43void OPLWriteReg(FM_OPL *OPL, int r, int v) {
     44        OPL->writeReg(r, v);
    115045}
    115146
    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;
     47void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
     48        OPL->readBuffer(buffer, length);
    117049}
    117150
     51// Factory method
    117252FM_OPL *makeAdlibOPL(int rate) {
    1173         // We need to emulate one YM3812 chip
    1174         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 #endif
    1188 
    1189         OPLBuildTables(env_bits, eg_ent);
    1190         return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
     53        FM_OPL *opl = AdLib::AdLib::createInstance();
     54        if (opl)
     55                opl->init(rate);
     56        return opl;
    119157}
     58
  • 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
     40namespace AdLib {
     41namespace DOSBox {
     42
     43Timer::Timer() {
     44        masked = false;
     45        overflow = false;
     46        enabled = false;
     47        counter = 0;
     48        delay = 0;
     49}
     50
     51void Timer::update(double time) {
     52        if (!enabled || !delay)
     53                return;
     54        double deltaStart = time - startTime;
     55        // Only set the overflow flag when not masked
     56        if (deltaStart >= 0 && !masked)
     57                overflow = 1;
     58}
     59
     60void Timer::reset(double time) {
     61        overflow = false;
     62        if (!delay || !enabled)
     63                return;
     64        double delta = (time - startTime);
     65        double rem = fmod(delta, delay);
     66        double next = delay - rem;
     67        startTime = time + next;               
     68}
     69
     70void Timer::stop() {
     71        enabled = false;
     72}
     73
     74void 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        startTime = time + delay;
     81}
     82
     83bool 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
     96                if (val & 0x80) {
     97                        timer[0].reset(time);
     98                        timer[1].reset(time);
     99                } else {
     100                        timer[0].update(time);
     101                        timer[1].update(time);
     102
     103                        if (val & 0x1)
     104                                timer[0].start(time, 80);
     105                        else
     106                                timer[0].stop();
     107
     108                        timer[0].masked = (val & 0x40) > 0;
     109
     110                        if (timer[0].masked)
     111                                timer[0].overflow = false;
     112
     113                        if (val & 0x2)
     114                                timer[1].start(time, 320);
     115                        else
     116                                timer[1].stop();
     117
     118                        timer[1].masked = (val & 0x20) > 0;
     119       
     120                        if (timer[1].masked)
     121                                timer[1].overflow = false;
     122                }
     123                return true;
     124        }
     125        return false;
     126}
     127
     128uint8 Chip::read() {
     129        // TODO: I couldn't get behind the PIC_FullIndex logic, but I would guess
     130        // it should be like this...
     131        double time = g_system->getMillis() / 1000.0;
     132
     133        timer[0].update(time);
     134        timer[1].update(time);
     135
     136        uint8 ret = 0;
     137        //Overflow won't be set if a channel is masked
     138        if (timer[0].overflow) {
     139                ret |= 0x40;
     140                ret |= 0x80;
     141        }
     142        if (timer[1].overflow) {
     143                ret |= 0x20;
     144                ret |= 0x80;
     145        }
     146        return ret;
     147}
     148
     149class Handler {
     150public:
     151        virtual ~Handler() {}
     152
     153        // Write an address to a chip, returns the address the chip sets
     154        virtual uint32 writeAddr(uint32 port, uint8 val) = 0;
     155        // Write to a specific register in the chip
     156        virtual void writeReg(uint32 addr, uint8 val) = 0;
     157        // Generate a certain amount of samples
     158        virtual void generate(int16 *chan, uint samples) = 0;
     159        // Initialize at a specific sample rate and mode
     160        virtual void init(uint rate) = 0;
     161};
     162
     163// TODO: The DOSBox AdLib code is only capable of *one* instance, we
     164// would need to restructure the code to allow multiple instances.
     165namespace OPL2 {
     166#include "opl.cpp"
     167
     168struct Handler : public DOSBox::Handler {
     169        void writeReg(uint32 reg, uint8 val) {
     170                adlib_write(reg, val);
     171        }
     172        uint32 writeAddr(uint32 port, uint8 val) {
     173                return val;
     174        }
     175        void generate(int16 *chan, uint samples) {
     176                adlib_getsample(chan, samples);
     177        }
     178        void init(uint rate) {
     179                adlib_init(rate);
     180        }
     181};
     182} // end of namespace OPL2
     183
     184AdLib_DOSBox::AdLib_DOSBox() : _type(kOpl2), _rate(0), _handler(0) {
     185}
     186
     187AdLib_DOSBox::~AdLib_DOSBox() {
     188        free();
     189}
     190
     191void AdLib_DOSBox::free() {
     192        delete _handler;
     193        _handler = 0;
     194}
     195
     196void AdLib_DOSBox::init(int rate, kOplType type) {
     197        free();
     198
     199        _reg.dual[0] = 0;
     200        _reg.dual[1] = 0;
     201        _reg.normal = 0;
     202
     203        memset(_chip, 0, sizeof(_chip));
     204        _type = type;
     205
     206        switch (_type) {
     207        case kOpl2:
     208                _handler = new OPL2::Handler();
     209                break;
     210        }
     211
     212        _handler->init(rate);
     213        _rate = rate;
     214}
     215
     216void AdLib_DOSBox::reset() {
     217        // TODO: Find a nicer way to reset the emulator
     218        init(_rate, _type);     
     219}
     220
     221void AdLib_DOSBox::write(int port, int val) {
     222        if (port&1) {
     223                switch (_type) {
     224                case kOpl2:
     225                //case kOpl3:
     226                        if (!_chip[0].write(_reg.normal, val))
     227                                _handler->writeReg(_reg.normal, val);
     228                        break;
     229                /*case kDualOpl2:
     230                        // Not a 0x??8 port, then write to a specific port
     231                        if (!(port & 0x8)) {
     232                                byte index = (port & 2) >> 1;
     233                                dualWrite(index, _reg.dual[index], val);
     234                        } else {
     235                                //Write to both ports
     236                                dualWrite(0, _reg.dual[0], val);
     237                                dualWrite(1, _reg.dual[1], val);
     238                        }
     239                        break;*/
     240                }
     241        } else {
     242                // Ask the handler to write the address
     243                // Make sure to clip them in the right range
     244                switch (_type) {
     245                case kOpl2:
     246                        _reg.normal = _handler->writeAddr(port, val) & 0xff;
     247                        break;
     248                /*case kOpl3:
     249                        _reg.normal = _handler->writeAddr(port, val) & 0x1ff;
     250                        break;
     251                case kDualOpl2:
     252                        // Not a 0x?88 port, when write to a specific side
     253                        if (!(port & 0x8)) {
     254                                byte index = (port & 2) >> 1;
     255                                _reg.dual[index] = val & 0xff;
     256                        } else {
     257                                _reg.dual[0] = val & 0xff;
     258                                _reg.dual[1] = val & 0xff;
     259                        }
     260                        break;*/
     261                }
     262        }
     263}
     264
     265byte AdLib_DOSBox::read(int port) {
     266        switch (_type) {
     267        case kOpl2:
     268                if (!(port & 1))
     269                        //Make sure the low bits are 6 on opl2
     270                        return _chip[0].read() | 0x6;
     271                break;
     272        /*case kOpl3:
     273                if (!(port & 1))
     274                        return _chip[0].read();
     275                break;
     276        case kDualOpl2:
     277                // Only return for the lower ports
     278                if (port & 1)
     279                        return 0xff;
     280                // Make sure the low bits are 6 on opl2
     281                return _chip[(port >> 1) & 1].read() | 0x6;*/
     282        }
     283        return 0;
     284}
     285
     286void AdLib_DOSBox::writeReg(int r, int v) {
     287        byte tempReg = 0;
     288        switch (_type) {
     289        case kOpl2:
     290        //case kOpl3:
     291                // We can't use _handler->writeReg here directly, since it would miss timer changes.
     292
     293                // Backup old setup register
     294                tempReg = _reg.normal;
     295
     296                // We need to set the register we want to write to via port 0x388
     297                write(0x388, r);
     298                // Do the real writing to the register
     299                write(0x389, v);
     300                // Restore the old register
     301                write(0x388, tempReg);
     302                break;
     303
     304        //case kDualOpl2:
     305        //      error("Can't use AdLib_DOSBox::writeReg on Dual OPL2");
     306        //      break;
     307        };
     308}
     309
     310void AdLib_DOSBox::readBuffer(int16 *buffer, int length) {
     311        _handler->generate(buffer, length);
     312}
     313
     314} // end of namespace DOSBox
     315} // end of namespace AdLib
     316
     317#endif // !DISABLE_DOSBOX_ADLIB
  • sound/softsynth/adlib/mame.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.cpp $
     22 * $Id: fmopl.cpp 38211 2009-02-15 10:07:50Z sev $
     23 *
     24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
     25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
     26 */
     27
     28#include <stdio.h>
     29#include <stdlib.h>
     30#include <string.h>
     31#include <stdarg.h>
     32#include <math.h>
     33
     34#include "mame.h"
     35
     36#if defined (_WIN32_WCE) || defined (__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined(GP2X) || defined (__MAEMO__) || defined(__DS__) || defined (__MINT__)
     37#include "common/config-manager.h"
     38#endif
     39
     40namespace AdLib {
     41namespace MAME {
     42
     43/* -------------------- preliminary define section --------------------- */
     44/* attack/decay rate time rate */
     45#define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
     46#define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
     47
     48#define FREQ_BITS 24                    /* frequency turn          */
     49
     50/* counter bits = 20 , octerve 7 */
     51#define FREQ_RATE   (1<<(FREQ_BITS-20))
     52#define TL_BITS    (FREQ_BITS+2)
     53
     54/* final output shift , limit minimum and maximum */
     55#define OPL_OUTSB   (TL_BITS+3-16)              /* OPL output final shift 16bit */
     56#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
     57#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
     58
     59/* -------------------- quality selection --------------------- */
     60
     61/* sinwave entries */
     62/* used static memory = SIN_ENT * 4 (byte) */
     63#ifdef __DS__
     64#include "dsmain.h"
     65#define SIN_ENT_SHIFT 8
     66#else
     67#define SIN_ENT_SHIFT 11
     68#endif
     69#define SIN_ENT (1<<SIN_ENT_SHIFT)
     70
     71/* output level entries (envelope,sinwave) */
     72/* envelope counter lower bits */
     73int ENV_BITS;
     74/* envelope output entries */
     75int EG_ENT;
     76
     77/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
     78/* used static  memory = EG_ENT*4 (byte)                     */
     79int EG_OFF;                                                              /* OFF */
     80int EG_DED;
     81int EG_DST;                                                              /* DECAY START */
     82int EG_AED;
     83#define EG_AST   0                       /* ATTACK START */
     84
     85#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
     86
     87/* LFO table entries */
     88#define VIB_ENT 512
     89#define VIB_SHIFT (32-9)
     90#define AMS_ENT 512
     91#define AMS_SHIFT (32-9)
     92
     93#define VIB_RATE_SHIFT 8
     94#define VIB_RATE (1<<VIB_RATE_SHIFT)
     95
     96/* -------------------- local defines , macros --------------------- */
     97
     98/* register number to channel number , slot offset */
     99#define SLOT1 0
     100#define SLOT2 1
     101
     102/* envelope phase */
     103#define ENV_MOD_RR  0x00
     104#define ENV_MOD_DR  0x01
     105#define ENV_MOD_AR  0x02
     106
     107/* -------------------- tables --------------------- */
     108static const int slot_array[32] = {
     109         0, 2, 4, 1, 3, 5,-1,-1,
     110         6, 8,10, 7, 9,11,-1,-1,
     111        12,14,16,13,15,17,-1,-1,
     112        -1,-1,-1,-1,-1,-1,-1,-1
     113};
     114
     115static uint KSL_TABLE[8 * 16];
     116
     117static const double KSL_TABLE_SEED[8 * 16] = {
     118        /* OCT 0 */
     119        0.000, 0.000, 0.000, 0.000,
     120        0.000, 0.000, 0.000, 0.000,
     121        0.000, 0.000, 0.000, 0.000,
     122        0.000, 0.000, 0.000, 0.000,
     123        /* OCT 1 */
     124        0.000, 0.000, 0.000, 0.000,
     125        0.000, 0.000, 0.000, 0.000,
     126        0.000, 0.750, 1.125, 1.500,
     127        1.875, 2.250, 2.625, 3.000,
     128        /* OCT 2 */
     129        0.000, 0.000, 0.000, 0.000,
     130        0.000, 1.125, 1.875, 2.625,
     131        3.000, 3.750, 4.125, 4.500,
     132        4.875, 5.250, 5.625, 6.000,
     133        /* OCT 3 */
     134        0.000, 0.000, 0.000, 1.875,
     135        3.000, 4.125, 4.875, 5.625,
     136        6.000, 6.750, 7.125, 7.500,
     137        7.875, 8.250, 8.625, 9.000,
     138        /* OCT 4 */
     139        0.000, 0.000, 3.000, 4.875,
     140        6.000, 7.125, 7.875, 8.625,
     141        9.000, 9.750, 10.125, 10.500,
     142        10.875, 11.250, 11.625, 12.000,
     143        /* OCT 5 */
     144        0.000, 3.000, 6.000, 7.875,
     145        9.000, 10.125, 10.875, 11.625,
     146        12.000, 12.750, 13.125, 13.500,
     147        13.875, 14.250, 14.625, 15.000,
     148        /* OCT 6 */
     149        0.000, 6.000, 9.000, 10.875,
     150        12.000, 13.125, 13.875, 14.625,
     151        15.000, 15.750, 16.125, 16.500,
     152        16.875, 17.250, 17.625, 18.000,
     153        /* OCT 7 */
     154        0.000, 9.000, 12.000, 13.875,
     155        15.000, 16.125, 16.875, 17.625,
     156        18.000, 18.750, 19.125, 19.500,
     157        19.875, 20.250, 20.625, 21.000
     158};
     159
     160/* sustain level table (3db per step) */
     161/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
     162
     163static int SL_TABLE[16];
     164
     165static const uint SL_TABLE_SEED[16] = {
     166        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31
     167};
     168
     169#define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
     170/* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
     171/* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
     172/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
     173static int *TL_TABLE;
     174
     175/* pointers to TL_TABLE with sinwave output offset */
     176static int **SIN_TABLE;
     177
     178/* LFO table */
     179static int *AMS_TABLE;
     180static int *VIB_TABLE;
     181
     182/* envelope output curve table */
     183/* attack + decay + OFF */
     184//static int ENV_CURVE[2*EG_ENT+1];
     185//static int ENV_CURVE[2 * 4096 + 1];   // to keep it static ...
     186static int *ENV_CURVE;
     187
     188
     189/* multiple table */
     190#define ML(a) (int)(a * 2)
     191static const uint MUL_TABLE[16]= {
     192/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
     193        ML(0.50), ML(1.00), ML(2.00),  ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
     194        ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
     195};
     196#undef ML
     197
     198/* dummy attack / decay rate ( when rate == 0 ) */
     199static int RATE_0[16]=
     200{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
     201
     202/* -------------------- static state --------------------- */
     203
     204/* lock level of common table */
     205static int num_lock = 0;
     206
     207/* work table */
     208static void *cur_chip = NULL;   /* current chip point */
     209/* currenct chip state */
     210/* static OPLSAMPLE  *bufL,*bufR; */
     211static OPL_CH *S_CH;
     212static OPL_CH *E_CH;
     213OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
     214
     215static int outd[1];
     216static int ams;
     217static int vib;
     218int *ams_table;
     219int *vib_table;
     220static int amsIncr;
     221static int vibIncr;
     222static int feedback2;           /* connect for SLOT 2 */
     223
     224/* --------------------- rebuild tables ------------------- */
     225
     226#define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2)))
     227#define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
     228
     229void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
     230        int i;
     231
     232        ENV_BITS = ENV_BITS_PARAM;
     233        EG_ENT = EG_ENT_PARAM;
     234        EG_OFF = ((2 * EG_ENT)<<ENV_BITS);  /* OFF          */
     235        EG_DED = EG_OFF;
     236        EG_DST = (EG_ENT << ENV_BITS);     /* DECAY  START */
     237        EG_AED = EG_DST;
     238        //EG_STEP = (96.0/EG_ENT);
     239
     240        for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++)
     241                KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
     242
     243        for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++)
     244                SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
     245}
     246
     247#undef SC_KSL
     248#undef SC_SL
     249
     250/* --------------------- subroutines  --------------------- */
     251
     252/* status set and IRQ handling */
     253inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
     254        /* set status flag */
     255        OPL->status |= flag;
     256        if(!(OPL->status & 0x80)) {
     257                if(OPL->status & OPL->statusmask) {     /* IRQ on */
     258                        OPL->status |= 0x80;
     259                        /* callback user interrupt handler (IRQ is OFF to ON) */
     260                        if(OPL->IRQHandler)
     261                                (OPL->IRQHandler)(OPL->IRQParam,1);
     262                }
     263        }
     264}
     265
     266/* status reset and IRQ handling */
     267inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
     268        /* reset status flag */
     269        OPL->status &= ~flag;
     270        if((OPL->status & 0x80)) {
     271                if (!(OPL->status & OPL->statusmask)) {
     272                        OPL->status &= 0x7f;
     273                        /* callback user interrupt handler (IRQ is ON to OFF) */
     274                        if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
     275                }
     276        }
     277}
     278
     279/* IRQ mask set */
     280inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
     281        OPL->statusmask = flag;
     282        /* IRQ handling check */
     283        OPL_STATUS_SET(OPL,0);
     284        OPL_STATUS_RESET(OPL,0);
     285}
     286
     287/* ----- key on  ----- */
     288inline void OPL_KEYON(OPL_SLOT *SLOT) {
     289        /* sin wave restart */
     290        SLOT->Cnt = 0;
     291        /* set attack */
     292        SLOT->evm = ENV_MOD_AR;
     293        SLOT->evs = SLOT->evsa;
     294        SLOT->evc = EG_AST;
     295        SLOT->eve = EG_AED;
     296}
     297
     298/* ----- key off ----- */
     299inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
     300        if( SLOT->evm > ENV_MOD_RR) {
     301                /* set envelope counter from envleope output */
     302
     303                // WORKAROUND: The Kyra engine does something very strange when
     304                // starting a new song. For each channel:
     305                //
     306                // * The release rate is set to "fastest".
     307                // * Any note is keyed off.
     308                // * A very low-frequency note is keyed on.
     309                //
     310                // Usually, what happens next is that the real notes is keyed
     311                // on immediately, in which case there's no problem.
     312                //
     313                // However, if the note is again keyed off (because the channel
     314                // begins on a rest rather than a note), the envelope counter
     315                // was moved from the very lowest point on the attack curve to
     316                // the very highest point on the release curve.
     317                //
     318                // Again, this might not be a problem, if the release rate is
     319                // still set to "fastest". But in many cases, it had already
     320                // been increased. And, possibly because of inaccuracies in the
     321                // envelope generator, that would cause the note to "fade out"
     322                // for quite a long time.
     323                //
     324                // What we really need is a way to find the correct starting
     325                // point for the envelope counter, and that may be what the
     326                // commented-out line below is meant to do. For now, simply
     327                // handle the pathological case.
     328
     329                if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
     330                        SLOT->evc = EG_DED;
     331                else if( !(SLOT->evc & EG_DST) )
     332                        //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
     333                        SLOT->evc = EG_DST;
     334                SLOT->eve = EG_DED;
     335                SLOT->evs = SLOT->evsr;
     336                SLOT->evm = ENV_MOD_RR;
     337        }
     338}
     339
     340/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
     341
     342/* return : envelope output */
     343inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
     344        /* calcrate envelope generator */
     345        if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
     346                switch( SLOT->evm ) {
     347                case ENV_MOD_AR: /* ATTACK -> DECAY1 */
     348                        /* next DR */
     349                        SLOT->evm = ENV_MOD_DR;
     350                        SLOT->evc = EG_DST;
     351                        SLOT->eve = SLOT->SL;
     352                        SLOT->evs = SLOT->evsd;
     353                        break;
     354                case ENV_MOD_DR: /* DECAY -> SL or RR */
     355                        SLOT->evc = SLOT->SL;
     356                        SLOT->eve = EG_DED;
     357                        if(SLOT->eg_typ) {
     358                                SLOT->evs = 0;
     359                        } else {
     360                                SLOT->evm = ENV_MOD_RR;
     361                                SLOT->evs = SLOT->evsr;
     362                        }
     363                        break;
     364                case ENV_MOD_RR: /* RR -> OFF */
     365                        SLOT->evc = EG_OFF;
     366                        SLOT->eve = EG_OFF + 1;
     367                        SLOT->evs = 0;
     368                        break;
     369                }
     370        }
     371        /* calcrate envelope */
     372        return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
     373}
     374
     375/* set algorythm connection */
     376static void set_algorythm(OPL_CH *CH) {
     377        int *carrier = &outd[0];
     378        CH->connect1 = CH->CON ? carrier : &feedback2;
     379        CH->connect2 = carrier;
     380}
     381
     382/* ---------- frequency counter for operater update ---------- */
     383inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
     384        int ksr;
     385
     386        /* frequency step counter */
     387        SLOT->Incr = CH->fc * SLOT->mul;
     388        ksr = CH->kcode >> SLOT->KSR;
     389
     390        if( SLOT->ksr != ksr ) {
     391                SLOT->ksr = ksr;
     392                /* attack , decay rate recalcration */
     393                SLOT->evsa = SLOT->AR[ksr];
     394                SLOT->evsd = SLOT->DR[ksr];
     395                SLOT->evsr = SLOT->RR[ksr];
     396        }
     397        SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
     398}
     399
     400/* set multi,am,vib,EG-TYP,KSR,mul */
     401inline void set_mul(FM_OPL *OPL, int slot, int v) {
     402        OPL_CH   *CH   = &OPL->P_CH[slot>>1];
     403        OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
     404
     405        SLOT->mul    = MUL_TABLE[v & 0x0f];
     406        SLOT->KSR    = (v & 0x10) ? 0 : 2;
     407        SLOT->eg_typ = (v & 0x20) >> 5;
     408        SLOT->vib    = (v & 0x40);
     409        SLOT->ams    = (v & 0x80);
     410        CALC_FCSLOT(CH, SLOT);
     411}
     412
     413/* set ksl & tl */
     414inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
     415        OPL_CH   *CH   = &OPL->P_CH[slot>>1];
     416        OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
     417        int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
     418
     419        SLOT->ksl = ksl ? 3-ksl : 31;
     420        SLOT->TL  = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
     421
     422        if(!(OPL->mode & 0x80)) {       /* not CSM latch total level */
     423                SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
     424        }
     425}
     426
     427/* set attack rate & decay rate  */
     428inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
     429        OPL_CH   *CH   = &OPL->P_CH[slot>>1];
     430        OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
     431        int ar = v >> 4;
     432        int dr = v & 0x0f;
     433
     434        SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
     435        SLOT->evsa = SLOT->AR[SLOT->ksr];
     436        if(SLOT->evm == ENV_MOD_AR)
     437                SLOT->evs = SLOT->evsa;
     438
     439        SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
     440        SLOT->evsd = SLOT->DR[SLOT->ksr];
     441        if(SLOT->evm == ENV_MOD_DR)
     442                SLOT->evs = SLOT->evsd;
     443}
     444
     445/* set sustain level & release rate */
     446inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
     447        OPL_CH   *CH   = &OPL->P_CH[slot>>1];
     448        OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
     449        int sl = v >> 4;
     450        int rr = v & 0x0f;
     451
     452        SLOT->SL = SL_TABLE[sl];
     453        if(SLOT->evm == ENV_MOD_DR)
     454                SLOT->eve = SLOT->SL;
     455        SLOT->RR = &OPL->DR_TABLE[rr<<2];
     456        SLOT->evsr = SLOT->RR[SLOT->ksr];
     457        if(SLOT->evm == ENV_MOD_RR)
     458                SLOT->evs = SLOT->evsr;
     459}
     460
     461/* operator output calcrator */
     462
     463#define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env]
     464/* ---------- calcrate one of channel ---------- */
     465inline void OPL_CALC_CH(OPL_CH *CH) {
     466        uint env_out;
     467        OPL_SLOT *SLOT;
     468
     469        feedback2 = 0;
     470        /* SLOT 1 */
     471        SLOT = &CH->SLOT[SLOT1];
     472        env_out=OPL_CALC_SLOT(SLOT);
     473        if(env_out < (uint)(EG_ENT - 1)) {
     474                /* PG */
     475                if(SLOT->vib)
     476                        SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
     477                else
     478                        SLOT->Cnt += SLOT->Incr;
     479                /* connection */
     480                if(CH->FB) {
     481                        int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
     482                        CH->op1_out[1] = CH->op1_out[0];
     483                        *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
     484                } else {
     485                        *CH->connect1 += OP_OUT(SLOT, env_out, 0);
     486                }
     487        } else {
     488                CH->op1_out[1] = CH->op1_out[0];
     489                CH->op1_out[0] = 0;
     490        }
     491        /* SLOT 2 */
     492        SLOT = &CH->SLOT[SLOT2];
     493        env_out=OPL_CALC_SLOT(SLOT);
     494        if(env_out < (uint)(EG_ENT - 1)) {
     495                /* PG */
     496                if(SLOT->vib)
     497                        SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
     498                else
     499                        SLOT->Cnt += SLOT->Incr;
     500                /* connection */
     501                outd[0] += OP_OUT(SLOT, env_out, feedback2);
     502        }
     503}
     504
     505/* ---------- calcrate rythm block ---------- */
     506#define WHITE_NOISE_db 6.0
     507inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
     508        uint env_tam, env_sd, env_top, env_hh;
     509        // This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
     510        // but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
     511        // int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
     512        // or 128, so we can safely avoid any FP ops.
     513        int whitenoise = OPL->rnd.getRandomBit() * (EG_ENT>>4);
     514
     515        int tone8;
     516
     517        OPL_SLOT *SLOT;
     518        int env_out;
     519
     520        /* BD : same as FM serial mode and output level is large */
     521        feedback2 = 0;
     522        /* SLOT 1 */
     523        SLOT = &CH[6].SLOT[SLOT1];
     524        env_out = OPL_CALC_SLOT(SLOT);
     525        if(env_out < EG_ENT-1) {
     526                /* PG */
     527                if(SLOT->vib)
     528                        SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
     529                else
     530                        SLOT->Cnt += SLOT->Incr;
     531                /* connection */
     532                if(CH[6].FB) {
     533                        int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
     534                        CH[6].op1_out[1] = CH[6].op1_out[0];
     535                        feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
     536                }
     537                else {
     538                        feedback2 = OP_OUT(SLOT, env_out, 0);
     539                }
     540        } else {
     541                feedback2 = 0;
     542                CH[6].op1_out[1] = CH[6].op1_out[0];
     543                CH[6].op1_out[0] = 0;
     544        }
     545        /* SLOT 2 */
     546        SLOT = &CH[6].SLOT[SLOT2];
     547        env_out = OPL_CALC_SLOT(SLOT);
     548        if(env_out < EG_ENT-1) {
     549                /* PG */
     550                if(SLOT->vib)
     551                        SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
     552                else
     553                        SLOT->Cnt += SLOT->Incr;
     554                /* connection */
     555                outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
     556        }
     557
     558        // SD  (17) = mul14[fnum7] + white noise
     559        // TAM (15) = mul15[fnum8]
     560        // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
     561        // HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
     562        env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
     563        env_tam =OPL_CALC_SLOT(SLOT8_1);
     564        env_top = OPL_CALC_SLOT(SLOT8_2);
     565        env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
     566
     567        /* PG */
     568        if(SLOT7_1->vib)
     569                SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1);
     570        else
     571                SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
     572        if(SLOT7_2->vib)
     573                SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3);
     574        else
     575                SLOT7_2->Cnt += (CH[7].fc * 8);
     576        if(SLOT8_1->vib)
     577                SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;
     578        else
     579                SLOT8_1->Cnt += SLOT8_1->Incr;
     580        if(SLOT8_2->vib)
     581                SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4);
     582        else
     583                SLOT8_2->Cnt += (CH[8].fc * 48);
     584
     585        tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
     586
     587        /* SD */
     588        if(env_sd < (uint)(EG_ENT - 1))
     589                outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
     590        /* TAM */
     591        if(env_tam < (uint)(EG_ENT - 1))
     592                outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
     593        /* TOP-CY */
     594        if(env_top < (uint)(EG_ENT - 1))
     595                outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
     596        /* HH */
     597        if(env_hh  < (uint)(EG_ENT-1))
     598                outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
     599}
     600
     601/* ----------- initialize time tabls ----------- */
     602static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
     603        int i;
     604        double rate;
     605
     606        /* make attack rate & decay rate tables */
     607        for (i = 0; i < 4; i++)
     608                OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
     609        for (i = 4; i <= 60; i++) {
     610                rate = OPL->freqbase;                                           /* frequency rate */
     611                if(i < 60)
     612                        rate *= 1.0 + (i & 3) * 0.25;           /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
     613                rate *= 1 << ((i >> 2) - 1);                                            /* b2-5 : shift bit */
     614                rate *= (double)(EG_ENT << ENV_BITS);
     615                OPL->AR_TABLE[i] = (int)(rate / ARRATE);
     616                OPL->DR_TABLE[i] = (int)(rate / DRRATE);
     617        }
     618        for (i = 60; i < 76; i++) {
     619                OPL->AR_TABLE[i] = EG_AED-1;
     620                OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
     621        }
     622}
     623
     624/* ---------- generic table initialize ---------- */
     625static int OPLOpenTable(void) {
     626        int s,t;
     627        double rate;
     628        int i,j;
     629        double pom;
     630
     631#ifdef __DS__
     632        DS::fastRamReset();
     633
     634        TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *));
     635        SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *));
     636#else
     637
     638        /* allocate dynamic tables */
     639        if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
     640                return 0;
     641
     642        if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
     643                free(TL_TABLE);
     644                return 0;
     645        }
     646#endif
     647
     648        if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
     649                free(TL_TABLE);
     650                free(SIN_TABLE);
     651                return 0;
     652        }
     653
     654        if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
     655                free(TL_TABLE);
     656                free(SIN_TABLE);
     657                free(AMS_TABLE);
     658                return 0;
     659        }
     660        /* make total level table */
     661        for (t = 0; t < EG_ENT - 1 ; t++) {
     662                rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20);      /* dB -> voltage */
     663                TL_TABLE[         t] =  (int)rate;
     664                TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
     665        }
     666        /* fill volume off area */
     667        for (t = EG_ENT - 1; t < TL_MAX; t++) {
     668                TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
     669        }
     670
     671        /* make sinwave table (total level offet) */
     672        /* degree 0 = degree 180                   = off */
     673        SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
     674        for (s = 1;s <= SIN_ENT / 4; s++) {
     675                pom = sin(2 * PI * s / SIN_ENT); /* sin     */
     676                pom = 20 * log10(1 / pom);         /* decibel */
     677                j = int(pom / EG_STEP);         /* TL_TABLE steps */
     678
     679                /* degree 0   -  90    , degree 180 -  90 : plus section */
     680                SIN_TABLE[          s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
     681                /* degree 180 - 270    , degree 360 - 270 : minus section */
     682                SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
     683        }
     684        for (s = 0;s < SIN_ENT; s++) {
     685                SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
     686                SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
     687                SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
     688        }
     689
     690
     691        ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1));
     692
     693        /* envelope counter -> envelope output table */
     694        for (i=0; i < EG_ENT; i++) {
     695                /* ATTACK curve */
     696                pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
     697                /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
     698                ENV_CURVE[i] = (int)pom;
     699                /* DECAY ,RELEASE curve */
     700                ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
     701        }
     702        /* off */
     703        ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
     704        /* make LFO ams table */
     705        for (i=0; i < AMS_ENT; i++) {
     706                pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
     707                AMS_TABLE[i]         = (int)((1.0 / EG_STEP) * pom); /* 1dB   */
     708                AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
     709        }
     710        /* make LFO vibrate table */
     711        for (i=0; i < VIB_ENT; i++) {
     712                /* 100cent = 1seminote = 6% ?? */
     713                pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
     714                VIB_TABLE[i]         = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
     715                VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
     716        }
     717        return 1;
     718}
     719
     720static void OPLCloseTable(void) {
     721        free(TL_TABLE);
     722        free(SIN_TABLE);
     723        free(AMS_TABLE);
     724        free(VIB_TABLE);
     725        free(ENV_CURVE);
     726}
     727
     728/* CSM Key Controll */
     729inline void CSMKeyControll(OPL_CH *CH) {
     730        OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
     731        OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
     732        /* all key off */
     733        OPL_KEYOFF(slot1);
     734        OPL_KEYOFF(slot2);
     735        /* total level latch */
     736        slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
     737        slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
     738        /* key on */
     739        CH->op1_out[0] = CH->op1_out[1] = 0;
     740        OPL_KEYON(slot1);
     741        OPL_KEYON(slot2);
     742}
     743
     744/* ---------- opl initialize ---------- */
     745static void OPL_initalize(FM_OPL *OPL) {
     746        int fn;
     747
     748        /* frequency base */
     749        OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
     750        /* Timer base time */
     751        OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
     752        /* make time tables */
     753        init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
     754        /* make fnumber -> increment counter table */
     755        for( fn=0; fn < 1024; fn++) {
     756                OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
     757        }
     758        /* LFO freq.table */
     759        OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0);
     760        OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0);
     761}
     762
     763/* ---------- write a OPL registers ---------- */
     764void OPLWriteReg(FM_OPL *OPL, int r, int v) {
     765        OPL_CH *CH;
     766        int slot;
     767        uint block_fnum;
     768
     769        switch(r & 0xe0) {
     770        case 0x00: /* 00-1f:controll */
     771                switch(r & 0x1f) {
     772                case 0x01:
     773                        /* wave selector enable */
     774                        if(OPL->type&OPL_TYPE_WAVESEL) {
     775                                OPL->wavesel = v & 0x20;
     776                                if(!OPL->wavesel) {
     777                                        /* preset compatible mode */
     778                                        int c;
     779                                        for(c=0; c<OPL->max_ch; c++) {
     780                                                OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
     781                                                OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
     782                                        }
     783                                }
     784                        }
     785                        return;
     786                case 0x02:      /* Timer 1 */
     787                        OPL->T[0] = (256-v) * 4;
     788                        break;
     789                case 0x03:      /* Timer 2 */
     790                        OPL->T[1] = (256-v) * 16;
     791                        return;
     792                case 0x04:      /* IRQ clear / mask and Timer enable */
     793                        if(v & 0x80) {  /* IRQ flag clear */
     794                                OPL_STATUS_RESET(OPL, 0x7f);
     795                        } else {        /* set IRQ mask ,timer enable*/
     796                                uint8 st1 = v & 1;
     797                                uint8 st2 = (v >> 1) & 1;
     798                                /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
     799                                OPL_STATUS_RESET(OPL, v & 0x78);
     800                                OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
     801                                /* timer 2 */
     802                                if(OPL->st[1] != st2) {
     803                                        double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
     804                                        OPL->st[1] = st2;
     805                                        if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
     806                                }
     807                                /* timer 1 */
     808                                if(OPL->st[0] != st1) {
     809                                        double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
     810                                        OPL->st[0] = st1;
     811                                        if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
     812                                }
     813                        }
     814                        return;
     815                }
     816                break;
     817        case 0x20:      /* am,vib,ksr,eg type,mul */
     818                slot = slot_array[r&0x1f];
     819                if(slot == -1)
     820                        return;
     821                set_mul(OPL,slot,v);
     822                return;
     823        case 0x40:
     824                slot = slot_array[r&0x1f];
     825                if(slot == -1)
     826                        return;
     827                set_ksl_tl(OPL,slot,v);
     828                return;
     829        case 0x60:
     830                slot = slot_array[r&0x1f];
     831                if(slot == -1)
     832                        return;
     833                set_ar_dr(OPL,slot,v);
     834                return;
     835        case 0x80:
     836                slot = slot_array[r&0x1f];
     837                if(slot == -1)
     838                        return;
     839                set_sl_rr(OPL,slot,v);
     840                return;
     841        case 0xa0:
     842                switch(r) {
     843                case 0xbd:
     844                        /* amsep,vibdep,r,bd,sd,tom,tc,hh */
     845                        {
     846                        uint8 rkey = OPL->rythm ^ v;
     847                        OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
     848                        OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
     849                        OPL->rythm  = v & 0x3f;
     850                        if(OPL->rythm & 0x20) {
     851                                /* BD key on/off */
     852                                if(rkey & 0x10) {
     853                                        if(v & 0x10) {
     854                                                OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
     855                                                OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
     856                                                OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
     857                                        } else {
     858                                                OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
     859                                                OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
     860                                        }
     861                                }
     862                                /* SD key on/off */
     863                                if(rkey & 0x08) {
     864                                        if(v & 0x08)
     865                                                OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
     866                                        else
     867                                                OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
     868                                }/* TAM key on/off */
     869                                if(rkey & 0x04) {
     870                                        if(v & 0x04)
     871                                                OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
     872                                        else
     873                                                OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
     874                                }
     875                                /* TOP-CY key on/off */
     876                                if(rkey & 0x02) {
     877                                        if(v & 0x02)
     878                                                OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
     879                                        else
     880                                                OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
     881                                }
     882                                /* HH key on/off */
     883                                if(rkey & 0x01) {
     884                                        if(v & 0x01)
     885                                                OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
     886                                        else
     887                                                OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
     888                                }
     889                        }
     890                        }
     891                        return;
     892
     893                default:
     894                        break;
     895                }
     896                /* keyon,block,fnum */
     897                if((r & 0x0f) > 8)
     898                        return;
     899                CH = &OPL->P_CH[r & 0x0f];
     900                if(!(r&0x10)) { /* a0-a8 */
     901                        block_fnum  = (CH->block_fnum & 0x1f00) | v;
     902                } else {        /* b0-b8 */
     903                        int keyon = (v >> 5) & 1;
     904                        block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
     905                        if(CH->keyon != keyon) {
     906                                if((CH->keyon=keyon)) {
     907                                        CH->op1_out[0] = CH->op1_out[1] = 0;
     908                                        OPL_KEYON(&CH->SLOT[SLOT1]);
     909                                        OPL_KEYON(&CH->SLOT[SLOT2]);
     910                                } else {
     911                                        OPL_KEYOFF(&CH->SLOT[SLOT1]);
     912                                        OPL_KEYOFF(&CH->SLOT[SLOT2]);
     913                                }
     914                        }
     915                }
     916                /* update */
     917                if(CH->block_fnum != block_fnum) {
     918                        int blockRv = 7 - (block_fnum >> 10);
     919                        int fnum = block_fnum & 0x3ff;
     920                        CH->block_fnum = block_fnum;
     921                        CH->ksl_base = KSL_TABLE[block_fnum >> 6];
     922                        CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
     923                        CH->kcode = CH->block_fnum >> 9;
     924                        if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
     925                                CH->kcode |=1;
     926                        CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
     927                        CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
     928                }
     929                return;
     930        case 0xc0:
     931                /* FB,C */
     932                if((r & 0x0f) > 8)
     933                        return;
     934                CH = &OPL->P_CH[r&0x0f];
     935                {
     936                        int feedback = (v >> 1) & 7;
     937                        CH->FB = feedback ? (8 + 1) - feedback : 0;
     938                        CH->CON = v & 1;
     939                        set_algorythm(CH);
     940                }
     941                return;
     942        case 0xe0: /* wave type */
     943                slot = slot_array[r & 0x1f];
     944                if(slot == -1)
     945                        return;
     946                CH = &OPL->P_CH[slot>>1];
     947                if(OPL->wavesel) {
     948                        CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
     949                }
     950                return;
     951        }
     952}
     953
     954/* lock/unlock for common table */
     955static int OPL_LockTable(void) {
     956        num_lock++;
     957        if(num_lock>1)
     958                return 0;
     959        /* first time */
     960        cur_chip = NULL;
     961        /* allocate total level table (128kb space) */
     962        if(!OPLOpenTable()) {
     963                num_lock--;
     964                return -1;
     965        }
     966        return 0;
     967}
     968
     969static void OPL_UnLockTable(void) {
     970        if(num_lock)
     971                num_lock--;
     972        if(num_lock)
     973                return;
     974        /* last time */
     975        cur_chip = NULL;
     976        OPLCloseTable();
     977}
     978
     979/*******************************************************************************/
     980/*              YM3812 local section                                                   */
     981/*******************************************************************************/
     982
     983/* ---------- update one of chip ----------- */
     984void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave) {
     985        int i;
     986        int data;
     987        int16 *buf = buffer;
     988        uint amsCnt = OPL->amsCnt;
     989        uint vibCnt = OPL->vibCnt;
     990        uint8 rythm = OPL->rythm & 0x20;
     991        OPL_CH *CH, *R_CH;
     992
     993
     994        if((void *)OPL != cur_chip) {
     995                cur_chip = (void *)OPL;
     996                /* channel pointers */
     997                S_CH = OPL->P_CH;
     998                E_CH = &S_CH[9];
     999                /* rythm slot */
     1000                SLOT7_1 = &S_CH[7].SLOT[SLOT1];
     1001                SLOT7_2 = &S_CH[7].SLOT[SLOT2];
     1002                SLOT8_1 = &S_CH[8].SLOT[SLOT1];
     1003                SLOT8_2 = &S_CH[8].SLOT[SLOT2];
     1004                /* LFO state */
     1005                amsIncr = OPL->amsIncr;
     1006                vibIncr = OPL->vibIncr;
     1007                ams_table = OPL->ams_table;
     1008                vib_table = OPL->vib_table;
     1009        }
     1010        R_CH = rythm ? &S_CH[6] : E_CH;
     1011        for(i = 0; i < length; i++) {
     1012                /*            channel A         channel B         channel C      */
     1013                /* LFO */
     1014                ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
     1015                vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
     1016                outd[0] = 0;
     1017                /* FM part */
     1018                for(CH=S_CH; CH < R_CH; CH++)
     1019                        OPL_CALC_CH(CH);
     1020                /* Rythn part */
     1021                if(rythm)
     1022                        OPL_CALC_RH(OPL, S_CH);
     1023                /* limit check */
     1024                data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT);
     1025                /* store to sound buffer */
     1026                buf[i << interleave] = data >> OPL_OUTSB;
     1027        }
     1028
     1029        OPL->amsCnt = amsCnt;
     1030        OPL->vibCnt = vibCnt;
     1031}
     1032
     1033/* ---------- reset a chip ---------- */
     1034void OPLResetChip(FM_OPL *OPL) {
     1035        int c,s;
     1036        int i;
     1037
     1038        /* reset chip */
     1039        OPL->mode = 0;  /* normal mode */
     1040        OPL_STATUS_RESET(OPL, 0x7f);
     1041        /* reset with register write */
     1042        OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
     1043        OPLWriteReg(OPL, 0x02,0); /* Timer1 */
     1044        OPLWriteReg(OPL, 0x03,0); /* Timer2 */
     1045        OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
     1046        for(i = 0xff; i >= 0x20; i--)
     1047                OPLWriteReg(OPL,i,0);
     1048        /* reset OPerator parameter */
     1049        for(c = 0; c < OPL->max_ch ;c++ ) {
     1050                OPL_CH *CH = &OPL->P_CH[c];
     1051                /* OPL->P_CH[c].PAN = OPN_CENTER; */
     1052                for(s = 0; s < 2; s++ ) {
     1053                        /* wave table */
     1054                        CH->SLOT[s].wavetable = &SIN_TABLE[0];
     1055                        /* CH->SLOT[s].evm = ENV_MOD_RR; */
     1056                        CH->SLOT[s].evc = EG_OFF;
     1057                        CH->SLOT[s].eve = EG_OFF + 1;
     1058                        CH->SLOT[s].evs = 0;
     1059                }
     1060        }
     1061}
     1062
     1063/* ----------  Create a virtual YM3812 ----------       */
     1064/* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
     1065FM_OPL *OPLCreate(int type, int clock, int rate) {
     1066        char *ptr;
     1067        FM_OPL *OPL;
     1068        int state_size;
     1069        int max_ch = 9; /* normaly 9 channels */
     1070
     1071        if( OPL_LockTable() == -1)
     1072                return NULL;
     1073        /* allocate OPL state space */
     1074        state_size  = sizeof(FM_OPL);
     1075        state_size += sizeof(OPL_CH) * max_ch;
     1076
     1077        /* allocate memory block */
     1078        ptr = (char *)calloc(state_size, 1);
     1079        if(ptr == NULL)
     1080                return NULL;
     1081
     1082        /* clear */
     1083        memset(ptr, 0, state_size);
     1084        OPL       = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
     1085        OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
     1086
     1087        /* set channel state pointer */
     1088        OPL->type  = type;
     1089        OPL->clock = clock;
     1090        OPL->rate  = rate;
     1091        OPL->max_ch = max_ch;
     1092
     1093        /* init grobal tables */
     1094        OPL_initalize(OPL);
     1095
     1096        /* reset chip */
     1097        OPLResetChip(OPL);
     1098        return OPL;
     1099}
     1100
     1101/* ----------  Destroy one of vietual YM3812 ----------       */
     1102void OPLDestroy(FM_OPL *OPL) {
     1103        OPL_UnLockTable();
     1104        free(OPL);
     1105}
     1106
     1107/* ----------  Option handlers ----------       */
     1108void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
     1109        OPL->TimerHandler   = TimerHandler;
     1110        OPL->TimerParam = channelOffset;
     1111}
     1112
     1113void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
     1114        OPL->IRQHandler     = IRQHandler;
     1115        OPL->IRQParam = param;
     1116}
     1117
     1118void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
     1119        OPL->UpdateHandler = UpdateHandler;
     1120        OPL->UpdateParam = param;
     1121}
     1122
     1123/* ---------- YM3812 I/O interface ---------- */
     1124int OPLWrite(FM_OPL *OPL,int a,int v) {
     1125        if(!(a & 1)) {  /* address port */
     1126                OPL->address = v & 0xff;
     1127        } else {        /* data port */
     1128                if(OPL->UpdateHandler)
     1129                        OPL->UpdateHandler(OPL->UpdateParam,0);
     1130                OPLWriteReg(OPL, OPL->address,v);
     1131        }
     1132        return OPL->status >> 7;
     1133}
     1134
     1135unsigned char OPLRead(FM_OPL *OPL,int a) {
     1136        if(!(a & 1)) {  /* status port */
     1137                return OPL->status & (OPL->statusmask | 0x80);
     1138        }
     1139        /* data port */
     1140        switch(OPL->address) {
     1141        case 0x05: /* KeyBoard IN */
     1142                warning("OPL:read unmapped KEYBOARD port\n");
     1143                return 0;
     1144        case 0x19: /* I/O DATA    */
     1145                warning("OPL:read unmapped I/O port\n");
     1146                return 0;
     1147        case 0x1a: /* PCM-DATA    */
     1148                return 0;
     1149        default:
     1150                break;
     1151        }
     1152        return 0;
     1153}
     1154
     1155int OPLTimerOver(FM_OPL *OPL, int c) {
     1156        if(c) { /* Timer B */
     1157                OPL_STATUS_SET(OPL, 0x20);
     1158        } else {        /* Timer A */
     1159                OPL_STATUS_SET(OPL, 0x40);
     1160                /* CSM mode key,TL controll */
     1161                if(OPL->mode & 0x80) {  /* CSM mode total level latch and auto key on */
     1162                        int ch;
     1163                        if(OPL->UpdateHandler)
     1164                                OPL->UpdateHandler(OPL->UpdateParam,0);
     1165                        for(ch = 0; ch < 9; ch++)
     1166                                CSMKeyControll(&OPL->P_CH[ch]);
     1167                }
     1168        }
     1169        /* reload timer */
     1170        if (OPL->TimerHandler)
     1171                (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);
     1172        return OPL->status >> 7;
     1173}
     1174
     1175FM_OPL *makeAdlibOPL(int rate) {
     1176        // We need to emulate one YM3812 chip
     1177        int env_bits = FMOPL_ENV_BITS_HQ;
     1178        int eg_ent = FMOPL_EG_ENT_HQ;
     1179#if defined (_WIN32_WCE) || defined(__SYMBIAN32__) || defined(PALMOS_MODE) || defined(__GP32__) || defined (GP2X) || defined(__MAEMO__) || defined(__DS__) || defined (__MINT__)
     1180        if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
     1181                env_bits = FMOPL_ENV_BITS_HQ;
     1182                eg_ent = FMOPL_EG_ENT_HQ;
     1183        } else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) {
     1184                env_bits = FMOPL_ENV_BITS_MQ;
     1185                eg_ent = FMOPL_EG_ENT_MQ;
     1186        } else {
     1187                env_bits = FMOPL_ENV_BITS_LQ;
     1188                eg_ent = FMOPL_EG_ENT_LQ;
     1189        }
     1190#endif
     1191
     1192        OPLBuildTables(env_bits, eg_ent);
     1193        return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
     1194}
     1195
     1196} // end of namespace MAME
     1197} // end of namespace AdLib
     1198
  • 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*/
     42typedef uint            Bitu;
     43typedef int                     Bits;
     44typedef uint32          Bit32u;
     45typedef int32           Bit32s;
     46typedef uint16          Bit16u;
     47typedef int16           Bit16s;
     48typedef uint8           Bit8u;
     49typedef 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*/
     127typedef 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
     159Bitu chip_num;
     160op_type op[MAXOPERATORS];
     161
     162Bits int_samplerate;
     163       
     164Bit8u status;
     165Bit32u index;
     166#if defined(OPLTYPE_IS_OPL3)
     167Bit8u adlibreg[512];    // adlib register set (including second set)
     168Bit8u wave_sel[44];             // waveform selection
     169#else
     170Bit8u adlibreg[256];    // adlib register set
     171Bit8u wave_sel[22];             // waveform selection
     172#endif
     173
     174
     175// vibrato/tremolo increment/counter
     176Bit32u vibtab_pos;
     177Bit32u vibtab_add;
     178Bit32u tremtab_pos;
     179Bit32u tremtab_add;
     180
     181
     182// enable an operator
     183void enable_operator(Bitu regbase, op_type* op_pt);
     184
     185// functions to change parameters of an operator
     186void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt);
     187
     188void change_attackrate(Bitu regbase, op_type* op_pt);
     189void change_decayrate(Bitu regbase, op_type* op_pt);
     190void change_releaserate(Bitu regbase, op_type* op_pt);
     191void change_sustainlevel(Bitu regbase, op_type* op_pt);
     192void change_waveform(Bitu regbase, op_type* op_pt);
     193void change_keepsustain(Bitu regbase, op_type* op_pt);
     194void change_vibrato(Bitu regbase, op_type* op_pt);
     195void change_feedback(Bitu chanbase, op_type* op_pt);
     196
     197// general functions
     198void adlib_init(Bit32u samplerate);
     199void adlib_write(Bitu idx, Bit8u val);
     200void adlib_getsample(Bit16s* sndptr, Bits numsamples);
     201
     202Bitu adlib_reg_read(Bitu port);
     203void adlib_write_index(Bitu port, Bit8u val);
     204
     205static Bit32u generator_add;    // should be a chip parameter
  • 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
     30namespace AdLib {
     31
     32// TODO: Document and move to sound/adlib.h or sound/fmopl.h
     33class AdLib {
     34public:
     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
     38namespace AdLib {
     39namespace DOSBox {
     40
     41class Handler;
     42
     43struct Timer {
     44        double startTime;
     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
     62struct 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
     71class AdLib_DOSBox : public AdLib {
     72private:
     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();
     84public:
     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

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/fmopl.h $
     22 * $Id: fmopl.h 38211 2009-02-15 10:07:50Z sev $
     23 *
     24 * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
     25 * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
     26 */
     27
     28
     29#ifndef SOUND_SOFTSYNTH_ADLIB_FMOPL_H
     30#define SOUND_SOFTSYNTH_ADLIB_FMOPL_H
     31
     32#include "common/scummsys.h"
     33#include "common/util.h"
     34
     35namespace AdLib {
     36namespace MAME {
     37
     38enum {
     39        FMOPL_ENV_BITS_HQ = 16,
     40        FMOPL_ENV_BITS_MQ = 8,
     41        FMOPL_ENV_BITS_LQ = 8,
     42        FMOPL_EG_ENT_HQ = 4096,
     43        FMOPL_EG_ENT_MQ = 1024,
     44        FMOPL_EG_ENT_LQ = 128
     45};
     46
     47
     48typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
     49typedef void (*OPL_IRQHANDLER)(int param,int irq);
     50typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
     51
     52#define OPL_TYPE_WAVESEL   0x01  /* waveform select    */
     53
     54/* Saving is necessary for member of the 'R' mark for suspend/resume */
     55/* ---------- OPL one of slot  ---------- */
     56typedef struct fm_opl_slot {
     57        int TL;         /* total level     :TL << 8                             */
     58        int TLL;        /* adjusted now TL                                              */
     59        uint8 KSR;      /* key scale rate  :(shift down bit)    */
     60        int *AR;        /* attack rate     :&AR_TABLE[AR<<2]    */
     61        int *DR;        /* decay rate      :&DR_TABLE[DR<<2]    */
     62        int SL;         /* sustain level   :SL_TABLE[SL]                */
     63        int *RR;        /* release rate    :&DR_TABLE[RR<<2]    */
     64        uint8 ksl;      /* keyscale level  :(shift down bits)   */
     65        uint8 ksr;      /* key scale rate  :kcode>>KSR                  */
     66        uint mul;       /* multiple        :ML_TABLE[ML]                */
     67        uint Cnt;       /* frequency count                                              */
     68        uint Incr;      /* frequency step                                               */
     69
     70        /* envelope generator state */
     71        uint8 eg_typ;/* envelope type flag                                      */
     72        uint8 evm;      /* envelope phase                                               */
     73        int evc;        /* envelope counter                                             */
     74        int eve;        /* envelope counter end point                   */
     75        int evs;        /* envelope counter step                                */
     76        int evsa;       /* envelope step for AR :AR[ksr]                */
     77        int evsd;       /* envelope step for DR :DR[ksr]                */
     78        int evsr;       /* envelope step for RR :RR[ksr]                */
     79
     80        /* LFO */
     81        uint8 ams;              /* ams flag                            */
     82        uint8 vib;              /* vibrate flag                        */
     83        /* wave selector */
     84        int **wavetable;
     85} OPL_SLOT;
     86
     87/* ---------- OPL one of channel  ---------- */
     88typedef struct fm_opl_channel {
     89        OPL_SLOT SLOT[2];
     90        uint8 CON;                      /* connection type                                      */
     91        uint8 FB;                       /* feed back       :(shift down bit)*/
     92        int *connect1;          /* slot1 output pointer                         */
     93        int *connect2;          /* slot2 output pointer                         */
     94        int op1_out[2];         /* slot1 output for selfeedback         */
     95
     96        /* phase generator state */
     97        uint block_fnum;        /* block+fnum                                           */
     98        uint8 kcode;            /* key code        : KeyScaleCode       */
     99        uint fc;                        /* Freq. Increment base                         */
     100        uint ksl_base;          /* KeyScaleLevel Base step                      */
     101        uint8 keyon;            /* key on/off flag                                      */
     102} OPL_CH;
     103
     104/* OPL state */
     105typedef struct fm_opl_f {
     106        uint8 type;                     /* chip type                         */
     107        int clock;                      /* master clock  (Hz)                */
     108        int rate;                       /* sampling rate (Hz)                */
     109        double freqbase;        /* frequency base                    */
     110        double TimerBase;       /* Timer base time (==sampling time) */
     111        uint8 address;          /* address register                  */
     112        uint8 status;           /* status flag                       */
     113        uint8 statusmask;       /* status mask                       */
     114        uint mode;                      /* Reg.08 : CSM , notesel,etc.       */
     115
     116        /* Timer */
     117        int T[2];                       /* timer counter                     */
     118        uint8 st[2];            /* timer enable                      */
     119
     120        /* FM channel slots */
     121        OPL_CH *P_CH;           /* pointer of CH                     */
     122        int     max_ch;                 /* maximum channel                   */
     123
     124        /* Rythm sention */
     125        uint8 rythm;            /* Rythm mode , key flag */
     126
     127        /* time tables */
     128        int AR_TABLE[76];       /* atttack rate tables                          */
     129        int DR_TABLE[76];       /* decay rate tables                            */
     130        uint FN_TABLE[1024];/* fnumber -> increment counter             */
     131
     132        /* LFO */
     133        int *ams_table;
     134        int *vib_table;
     135        int amsCnt;
     136        int amsIncr;
     137        int vibCnt;
     138        int vibIncr;
     139
     140        /* wave selector enable flag */
     141        uint8 wavesel;
     142
     143        /* external event callback handler */
     144        OPL_TIMERHANDLER  TimerHandler;         /* TIMER handler   */
     145        int TimerParam;                                         /* TIMER parameter */
     146        OPL_IRQHANDLER    IRQHandler;           /* IRQ handler    */
     147        int IRQParam;                                           /* IRQ parameter  */
     148        OPL_UPDATEHANDLER UpdateHandler;        /* stream update handler   */
     149        int UpdateParam;                                        /* stream update parameter */
     150
     151        Common::RandomSource rnd;
     152} FM_OPL;
     153
     154/* ---------- Generic interface section ---------- */
     155#define OPL_TYPE_YM3526 (0)
     156#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
     157
     158void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM);
     159
     160FM_OPL *OPLCreate(int type, int clock, int rate);
     161void OPLDestroy(FM_OPL *OPL);
     162void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset);
     163void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param);
     164void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param);
     165
     166void OPLResetChip(FM_OPL *OPL);
     167int OPLWrite(FM_OPL *OPL, int a, int v);
     168unsigned char OPLRead(FM_OPL *OPL, int a);
     169int OPLTimerOver(FM_OPL *OPL, int c);
     170void OPLWriteReg(FM_OPL *OPL, int r, int v);
     171void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length, int interleave = 0);
     172
     173// Factory method
     174FM_OPL *makeAdlibOPL(int rate);
     175
     176} // end of namespace MAME
     177} // end of namespace AdLib
     178
     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
     39static fltype recipsamp;        // inverse of sampling rate
     40static Bit16s wavtable[WAVEPREC*3];     // wave form table
     41
     42// vibrato/tremolo tables
     43static Bit32s vib_table[VIBTAB_SIZE];
     44static Bit32s trem_table[TREMTAB_SIZE*2];
     45
     46static Bit32s vibval_const[BLOCKBUF_SIZE];
     47static Bit32s tremval_const[BLOCKBUF_SIZE];
     48
     49// vibrato value tables (used per-operator)
     50static Bit32s vibval_var1[BLOCKBUF_SIZE];
     51static 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
     56static Bit32s *vibval1, *vibval2, *vibval3, *vibval4;
     57static Bit32s *tremval1, *tremval2, *tremval3, *tremval4;
     58
     59
     60// key scale level lookup table
     61static 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
     66static 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)
     70static float frqmul[16];
     71
     72// key scale levels
     73static Bit8u kslev[8][16];
     74
     75// map a channel number to the register offset of the modulator (=register base)
     76static 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)
     84static 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};
     88static 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
     93static 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};
     96static 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
     103static 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
     115static 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
     127static 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
     139static fltype attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
     140static fltype decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
     141
     142
     143void 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
     153void 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)
     190void 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
     206void 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)
     211void 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
     220void 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
     246void 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
     275void 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
     299typedef void (*optype_fptr)(op_type*);
     300
     301optype_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
     310void 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
     349void 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
     363void 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
     377void 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
     387void 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
     397void 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
     407void 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
     413void 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
     419void 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)&note_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
     447void 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
     461void 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
     471void 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
     594void 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
     891Bitu 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
     907void 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
     917static 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
     948void 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
     31namespace AdLib {
     32
     33// Wrapper around old MAME fmopl
     34
     35// TODO: Move to mame.h (?)
     36
     37class AdLib_MAME : public AdLib {
     38private:
     39        MAME::FM_OPL *_opl;
     40public:
     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
     55AdLib_MAME::~AdLib_MAME() {
     56        MAME::OPLDestroy(_opl);
     57        _opl = 0;
     58}
     59
     60void AdLib_MAME::init(int rate, kOplType type) {
     61        if (_opl)
     62                MAME::OPLDestroy(_opl);
     63
     64        _opl = MAME::makeAdlibOPL(rate);
     65}
     66
     67void AdLib_MAME::reset() {
     68        MAME::OPLResetChip(_opl);
     69}
     70
     71void AdLib_MAME::write(int a, int v) {
     72        MAME::OPLWrite(_opl, a, v);
     73}
     74
     75byte AdLib_MAME::read(int a) {
     76        return MAME::OPLRead(_opl, a);
     77}
     78
     79void AdLib_MAME::writeReg(int r, int v) {
     80        MAME::OPLWriteReg(_opl, r, v);
     81}
     82
     83void AdLib_MAME::readBuffer(int16 *buffer, int length) {
     84        MAME::YM3812UpdateOne(_opl, buffer, length);
     85}
     86
     87// Factory for creating AdLib emulator
     88
     89AdLib *AdLib::createInstance() {
     90//      return new AdLib_MAME();
     91        return new DOSBox::AdLib_DOSBox();
     92}
     93
     94} // end of namespace AdLib
     95