diff options
author | James Brown | 2002-04-23 17:52:30 +0000 |
---|---|---|
committer | James Brown | 2002-04-23 17:52:30 +0000 |
commit | 71ba38ba6479577310594afa58e00fccd571b2a1 (patch) | |
tree | dfcd395723dc3351bda82af2ef918823e5763637 /sound | |
parent | b1fd2d739a1b562fa4c15674dc24cf5a9a7ae9ed (diff) | |
download | scummvm-rg350-71ba38ba6479577310594afa58e00fccd571b2a1.tar.gz scummvm-rg350-71ba38ba6479577310594afa58e00fccd571b2a1.tar.bz2 scummvm-rg350-71ba38ba6479577310594afa58e00fccd571b2a1.zip |
LGPL'ed FMOpl from AdPlug.
svn-id: r4063
Diffstat (limited to 'sound')
-rw-r--r-- | sound/fmopl.cpp | 104 | ||||
-rw-r--r-- | sound/fmopl.h | 155 |
2 files changed, 139 insertions, 120 deletions
diff --git a/sound/fmopl.cpp b/sound/fmopl.cpp index 86ffaa6f00..65ce68a1df 100644 --- a/sound/fmopl.cpp +++ b/sound/fmopl.cpp @@ -1,3 +1,27 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 1999/2000 Tatsuyuki Satoh + * Copyright (C) 2001/2002 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + * LGPL licensed version of MAMEs fmopl (V0.37a modified) by + * Tatsuyuki Satoh. Included from LGPL'ed AdPlug. + */ + /* ** ** File: fmopl.c -- software implementation of FM sound generator @@ -32,8 +56,6 @@ #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ #define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ -#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */ - #define FREQ_BITS 24 /* frequency turn */ /* counter bits = 20 , octerve 7 */ @@ -97,9 +119,9 @@ static const int slot_array[32] = { /* key scale level */ /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */ -#define SC(mydb) ((UINT32) (mydb / (EG_STEP/2))) +#define SC(mydb) ((uint32) (mydb / (EG_STEP/2))) -static const UINT32 KSL_TABLE[8 * 16] = { +static const uint32 KSL_TABLE[8 * 16] = { /* OCT 0 */ SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), SC(0.000), @@ -146,7 +168,7 @@ static const UINT32 KSL_TABLE[8 * 16] = { /* sustain lebel table (3db per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ #define SC(db) ((int) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST) -static const INT32 SL_TABLE[16] = { +static const int32 SL_TABLE[16] = { SC(0), SC(1), SC(2), SC(3), SC(4), SC(5), SC(6), SC(7), SC(8), SC(9), SC(10), SC(11), SC(12), SC(13), SC(14), SC(31) }; @@ -156,22 +178,22 @@ static const INT32 SL_TABLE[16] = { /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ /* TL_TABLE[ 0 to TL_MAX ] : plus section */ /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ -static INT32 *TL_TABLE; +static int32 *TL_TABLE; /* pointers to TL_TABLE with sinwave output offset */ -static INT32 **SIN_TABLE; +static int32 **SIN_TABLE; /* LFO table */ -static INT32 *AMS_TABLE; -static INT32 *VIB_TABLE; +static int32 *AMS_TABLE; +static int32 *VIB_TABLE; /* envelope output curve table */ /* attack + decay + OFF */ -static INT32 ENV_CURVE[2 * EG_ENT + 1]; +static int32 ENV_CURVE[2 * EG_ENT + 1]; /* multiple table */ -#define ML(x) (UINT32)(2*(x)) -static const UINT32 MUL_TABLE[16] = { +#define ML(x) (uint32)(2*(x)) +static const uint32 MUL_TABLE[16] = { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00), @@ -181,7 +203,7 @@ static const UINT32 MUL_TABLE[16] = { #undef ML /* dummy attack / decay rate ( when rate == 0 ) */ -static INT32 RATE_0[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static int32 RATE_0[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* -------------------- static state --------------------- */ @@ -196,14 +218,14 @@ static OPL_CH *S_CH; static OPL_CH *E_CH; OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; -static INT32 outd[1]; -static INT32 ams; -static INT32 vib; -INT32 *ams_table; -INT32 *vib_table; -static INT32 amsIncr; -static INT32 vibIncr; -static INT32 feedback2; /* connect for SLOT 2 */ +static int32 outd[1]; +static int32 ams; +static int32 vib; +int32 *ams_table; +int32 *vib_table; +static int32 amsIncr; +static int32 vibIncr; +static int32 feedback2; /* connect for SLOT 2 */ /* --------------------- subroutines --------------------- */ @@ -283,7 +305,7 @@ INLINE void OPL_KEYOFF(OPL_SLOT * SLOT) /* ---------- calcrate Envelope Generator & Phase Generator ---------- */ /* return : envelope output */ -INLINE UINT32 OPL_CALC_SLOT(OPL_SLOT * SLOT) +INLINE uint32 OPL_CALC_SLOT(OPL_SLOT * SLOT) { /* calcrate envelope generator */ if ((SLOT->evc += SLOT->evs) >= SLOT->eve) { @@ -319,7 +341,7 @@ INLINE UINT32 OPL_CALC_SLOT(OPL_SLOT * SLOT) /* set algorythm connection */ static void set_algorythm(OPL_CH * CH) { - INT32 *carrier = &outd[0]; + int32 *carrier = &outd[0]; CH->connect1 = CH->CON ? carrier : &feedback2; CH->connect2 = carrier; } @@ -365,7 +387,7 @@ INLINE void set_ksl_tl(FM_OPL * OPL, int slot, int v) int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */ SLOT->ksl = ksl ? 3 - ksl : 31; - SLOT->TL = (INT32) ((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */ + SLOT->TL = (int32) ((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */ if (!(OPL->mode & 0x80)) { /* not CSM latch total level */ SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl); @@ -413,7 +435,7 @@ INLINE void set_sl_rr(FM_OPL * OPL, int slot, int v) /* ---------- calcrate one of channel ---------- */ INLINE void OPL_CALC_CH(OPL_CH * CH) { - UINT32 env_out; + uint32 env_out; OPL_SLOT *SLOT; feedback2 = 0; @@ -456,9 +478,9 @@ INLINE void OPL_CALC_CH(OPL_CH * CH) #define WHITE_NOISE_db 6.0 INLINE void OPL_CALC_RH(OPL_CH * CH) { - UINT32 env_tam, env_sd, env_top, env_hh; + uint32 env_tam, env_sd, env_top, env_hh; int whitenoise = (int)((rand() & 1) * (WHITE_NOISE_db / EG_STEP)); - INT32 tone8; + int32 tone8; OPL_SLOT *SLOT; int env_out; @@ -575,18 +597,18 @@ static int OPLOpenTable(void) double pom; /* allocate dynamic tables */ - if ((TL_TABLE = (INT32 *) malloc(TL_MAX * 2 * sizeof(INT32))) == NULL) + if ((TL_TABLE = (int32 *) malloc(TL_MAX * 2 * sizeof(int32))) == NULL) return 0; - if ((SIN_TABLE = (INT32 **) malloc(SIN_ENT * 4 * sizeof(INT32 *))) == NULL) { + if ((SIN_TABLE = (int32 **) malloc(SIN_ENT * 4 * sizeof(int32 *))) == NULL) { free(TL_TABLE); return 0; } - if ((AMS_TABLE = (INT32 *) malloc(AMS_ENT * 2 * sizeof(INT32))) == NULL) { + if ((AMS_TABLE = (int32 *) malloc(AMS_ENT * 2 * sizeof(int32))) == NULL) { free(SIN_TABLE); free(TL_TABLE); return 0; } - if ((VIB_TABLE = (INT32 *) malloc(VIB_ENT * 2 * sizeof(INT32))) == NULL) { + if ((VIB_TABLE = (int32 *) malloc(VIB_ENT * 2 * sizeof(int32))) == NULL) { free(AMS_TABLE); free(TL_TABLE); free(SIN_TABLE); @@ -699,10 +721,10 @@ static void OPL_initalize(FM_OPL * OPL) } /* LFO freq.table */ OPL->amsIncr = - (INT32) (OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * + (int32) (OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock / 3600000) : 0); OPL->vibIncr = - (INT32) (OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * + (int32) (OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock / 3600000) : 0); } @@ -740,8 +762,8 @@ void OPLWriteReg(FM_OPL * OPL, int r, int v) if (v & 0x80) { /* IRQ flag clear */ OPL_STATUS_RESET(OPL, 0x7f); } else { /* set IRQ mask ,timer enable */ - UINT8 st1 = v & 1; - UINT8 st2 = (v >> 1) & 1; + uint8 st1 = v & 1; + uint8 st2 = (v >> 1) & 1; /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ OPL_STATUS_RESET(OPL, v & 0x78); OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01); @@ -792,7 +814,7 @@ void OPLWriteReg(FM_OPL * OPL, int r, int v) case 0xbd: /* amsep,vibdep,r,bd,sd,tom,tc,hh */ { - UINT8 rkey = OPL->rythm ^ v; + uint8 rkey = OPL->rythm ^ v; OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0]; OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0]; OPL->rythm = v & 0x3f; @@ -870,7 +892,7 @@ void OPLWriteReg(FM_OPL * OPL, int r, int v) CH->ksl_base = KSL_TABLE[block_fnum >> 6]; CH->fc = OPL->FN_TABLE[fnum] >> blockRv; - CH->kcode = CH->block_fnum >> 9; + CH->kcode = (uint8)(CH->block_fnum >> 9); if ((OPL->mode & 0x40) && CH->block_fnum & 0x100) CH->kcode |= 1; CALC_FCSLOT(CH, &CH->SLOT[SLOT1]); @@ -934,14 +956,14 @@ static void OPL_UnLockTable(void) /*******************************************************************************/ /* ---------- update one of chip ----------- */ -void YM3812UpdateOne(FM_OPL * OPL, INT16 * buffer, int length) +void YM3812UpdateOne(FM_OPL * OPL, int16 * buffer, int length) { int i; int data; OPLSAMPLE *buf = buffer; - UINT32 amsCnt = OPL->amsCnt; - UINT32 vibCnt = OPL->vibCnt; - UINT8 rythm = OPL->rythm & 0x20; + uint32 amsCnt = OPL->amsCnt; + uint32 vibCnt = OPL->vibCnt; + uint8 rythm = OPL->rythm & 0x20; OPL_CH *CH, *R_CH; if ((void *)OPL != cur_chip) { diff --git a/sound/fmopl.h b/sound/fmopl.h index 6f19329552..c06aa9a278 100644 --- a/sound/fmopl.h +++ b/sound/fmopl.h @@ -1,35 +1,32 @@ -/* ENDER: Not GPLed. Replace or relicense before 0.2.0 */ +/* ScummVM - Scumm Interpreter + * Copyright (C) 1999/2000 Tatsuyuki Satoh + * Copyright (C) 2001/2002 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + * LGPL licensed version of MAMEs fmopl (V0.37a modified) by + * Tatsuyuki Satoh. Included from LGPL'ed AdPlug. + */ #ifndef __FMOPL_H_ #define __FMOPL_H_ +#include "scummsys.h" -/* --- select emulation chips --- */ -#define BUILD_YM3812 (HAS_YM3812) -#define BUILD_YM3526 (HAS_YM3526) -#define BUILD_Y8950 (HAS_Y8950) - -/* --- system optimize --- */ -/* select bit size of output : 8 or 16 */ -#define OPL_OUTPUT_BIT 16 - -/* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ -#endif - -#if (OPL_OUTPUT_BIT==16) -typedef INT16 OPLSAMPLE; -#endif -#if (OPL_OUTPUT_BIT==8) -typedef unsigned char OPLSAMPLE; -#endif - +typedef int16 OPLSAMPLE; typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); typedef void (*OPL_IRQHANDLER)(int param,int irq); @@ -47,79 +44,79 @@ typedef unsigned char (*OPL_PORTHANDLER_R)(int param); /* Saving is necessary for member of the 'R' mark for suspend/resume */ /* ---------- OPL one of slot ---------- */ typedef struct fm_opl_slot { - INT32 TL; /* total level :TL << 8 */ - INT32 TLL; /* adjusted now TL */ - UINT8 KSR; /* key scale rate :(shift down bit) */ - INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */ - INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */ - INT32 SL; /* sustin level :SL_TALBE[SL] */ - INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */ - UINT8 ksl; /* keyscale level :(shift down bits) */ - UINT8 ksr; /* key scale rate :kcode>>KSR */ - UINT32 mul; /* multiple :ML_TABLE[ML] */ - UINT32 Cnt; /* frequency count : */ - UINT32 Incr; /* frequency step : */ + int32 TL; /* total level :TL << 8 */ + int32 TLL; /* adjusted now TL */ + uint8 KSR; /* key scale rate :(shift down bit) */ + int32 *AR; /* attack rate :&AR_TABLE[AR<<2] */ + int32 *DR; /* decay rate :&DR_TALBE[DR<<2] */ + int32 SL; /* sustin level :SL_TALBE[SL] */ + int32 *RR; /* release rate :&DR_TABLE[RR<<2] */ + uint8 ksl; /* keyscale level :(shift down bits) */ + uint8 ksr; /* key scale rate :kcode>>KSR */ + uint32 mul; /* multiple :ML_TABLE[ML] */ + uint32 Cnt; /* frequency count : */ + uint32 Incr; /* frequency step : */ /* envelope generator state */ - UINT8 eg_typ; /* envelope type flag */ - UINT8 evm; /* envelope phase */ - INT32 evc; /* envelope counter */ - INT32 eve; /* envelope counter end point */ - INT32 evs; /* envelope counter step */ - INT32 evsa; /* envelope step for AR :AR[ksr] */ - INT32 evsd; /* envelope step for DR :DR[ksr] */ - INT32 evsr; /* envelope step for RR :RR[ksr] */ + uint8 eg_typ; /* envelope type flag */ + uint8 evm; /* envelope phase */ + int32 evc; /* envelope counter */ + int32 eve; /* envelope counter end point */ + int32 evs; /* envelope counter step */ + int32 evsa; /* envelope step for AR :AR[ksr] */ + int32 evsd; /* envelope step for DR :DR[ksr] */ + int32 evsr; /* envelope step for RR :RR[ksr] */ /* LFO */ - UINT8 ams; /* ams flag */ - UINT8 vib; /* vibrate flag */ + uint8 ams; /* ams flag */ + uint8 vib; /* vibrate flag */ /* wave selector */ - INT32 **wavetable; + int32 **wavetable; }OPL_SLOT; /* ---------- OPL one of channel ---------- */ typedef struct fm_opl_channel { OPL_SLOT SLOT[2]; - UINT8 CON; /* connection type */ - UINT8 FB; /* feed back :(shift down bit) */ - INT32 *connect1; /* slot1 output pointer */ - INT32 *connect2; /* slot2 output pointer */ - INT32 op1_out[2]; /* slot1 output for selfeedback */ + uint8 CON; /* connection type */ + uint8 FB; /* feed back :(shift down bit) */ + int32 *connect1; /* slot1 output pointer */ + int32 *connect2; /* slot2 output pointer */ + int32 op1_out[2]; /* slot1 output for selfeedback */ /* phase generator state */ - UINT32 block_fnum; /* block+fnum : */ - UINT8 kcode; /* key code : KeyScaleCode */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 keyon; /* key on/off flag */ + uint32 block_fnum; /* block+fnum : */ + uint8 kcode; /* key code : KeyScaleCode */ + uint32 fc; /* Freq. Increment base */ + uint32 ksl_base; /* KeyScaleLevel Base step */ + uint8 keyon; /* key on/off flag */ } OPL_CH; /* OPL state */ struct FM_OPL { - UINT8 type; /* chip type */ + uint8 type; /* chip type */ int clock; /* master clock (Hz) */ int rate; /* sampling rate (Hz) */ double freqbase; /* frequency base */ double TimerBase; /* Timer base time (==sampling time) */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT32 mode; /* Reg.08 : CSM , notesel,etc. */ + uint8 address; /* address register */ + uint8 status; /* status flag */ + uint8 statusmask; /* status mask */ + uint32 mode; /* Reg.08 : CSM , notesel,etc. */ /* Timer */ int T[2]; /* timer counter */ - UINT8 st[2]; /* timer enable */ + uint8 st[2]; /* timer enable */ /* FM channel slots */ OPL_CH *P_CH; /* pointer of CH */ int max_ch; /* maximum channel */ /* Rythm sention */ - UINT8 rythm; /* Rythm mode , key flag */ + uint8 rythm; /* Rythm mode , key flag */ /* time tables */ /* LFO */ - INT32 *ams_table; - INT32 *vib_table; - INT32 amsCnt; - INT32 amsIncr; - INT32 vibCnt; - INT32 vibIncr; + int32 *ams_table; + int32 *vib_table; + int32 amsCnt; + int32 amsIncr; + int32 vibCnt; + int32 vibIncr; /* wave selector enable flag */ - UINT8 wavesel; + uint8 wavesel; /* external event callback handler */ OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ int TimerParam; /* TIMER parameter */ @@ -127,9 +124,9 @@ struct FM_OPL { int IRQParam; /* IRQ parameter */ OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ int UpdateParam; /* stream update parameter */ - INT32 AR_TABLE[75]; /* atttack rate tables */ - INT32 DR_TABLE[75]; /* decay rate tables */ - UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */ + int32 AR_TABLE[75]; /* atttack rate tables */ + int32 DR_TABLE[75]; /* decay rate tables */ + uint32 FN_TABLE[1024]; /* fnumber -> increment counter */ }; /* ---------- Generic interface section ---------- */ @@ -151,6 +148,6 @@ int OPLTimerOver(FM_OPL *OPL,int c); void OPLWriteReg(FM_OPL *OPL, int r, int v); /* YM3626/YM3812 local section */ -void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); +void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length); #endif |