aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorJames Brown2002-04-23 17:52:30 +0000
committerJames Brown2002-04-23 17:52:30 +0000
commit71ba38ba6479577310594afa58e00fccd571b2a1 (patch)
treedfcd395723dc3351bda82af2ef918823e5763637 /sound
parentb1fd2d739a1b562fa4c15674dc24cf5a9a7ae9ed (diff)
downloadscummvm-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.cpp104
-rw-r--r--sound/fmopl.h155
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