/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see .
*
*/
#ifndef NUVIE_SOUND_ADPLUG_OPL_CLASS_H
#define NUVIE_SOUND_ADPLUG_OPL_CLASS_H
#include "ultima/nuvie/sound/adplug/opl.h"
namespace Ultima {
namespace Nuvie {
#define HAS_YM3812 1
#define HAS_YM3526 0
#define HAS_Y8950 0
/* --- select emulation chips --- */
#define BUILD_YM3812 (HAS_YM3812)
#define BUILD_YM3526 (HAS_YM3526)
#define BUILD_Y8950 (HAS_Y8950)
/* select output bits size of output : 8 or 16 */
#define OPL_SAMPLE_BITS 16
#if (OPL_SAMPLE_BITS==16)
typedef int16 OPLSAMPLE;
#endif
#if (OPL_SAMPLE_BITS==8)
typedef int8 OPLSAMPLE;
#endif
typedef void (*OPL_TIMERHANDLER)(int channel, double interval_Sec);
typedef void (*OPL_IRQHANDLER)(int param, int irq);
typedef void (*OPL_UPDATEHANDLER)(int param, int min_interval_us);
typedef void (*OPL_PORTHANDLER_W)(int param, unsigned char data);
typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
/* Saving is necessary for member of the 'R' mark for suspend/resume */
typedef struct {
uint32 ar; /* attack rate: AR<<2 */
uint32 dr; /* decay rate: DR<<2 */
uint32 rr; /* release rate:RR<<2 */
uint8 KSR; /* key scale rate */
uint8 ksl; /* keyscale level */
uint8 ksr; /* key scale rate: kcode>>KSR */
uint8 mul; /* multiple: mul_tab[ML] */
/* Phase Generator */
uint32 Cnt; /* frequency counter */
uint32 Incr; /* frequency counter step */
uint8 FB; /* feedback shift value */
signed int *connect1; /* slot1 output pointer */
int32 op1_out[2]; /* slot1 output for feedback */
uint8 CON; /* connection (algorithm) type */
/* Envelope Generator */
uint8 eg_type; /* percussive/non-percussive mode */
uint8 state; /* phase type */
uint32 TL; /* total level: TL << 2 */
int32 TLL; /* adjusted now TL */
int32 volume; /* envelope counter */
uint32 sl; /* sustain level: sl_tab[SL] */
uint8 eg_sh_ar; /* (attack state) */
uint8 eg_sel_ar; /* (attack state) */
uint8 eg_sh_dr; /* (decay state) */
uint8 eg_sel_dr; /* (decay state) */
uint8 eg_sh_rr; /* (release state) */
uint8 eg_sel_rr; /* (release state) */
uint32 key; /* 0 = KEY OFF, >0 = KEY ON */
/* LFO */
uint32 AMmask; /* LFO Amplitude Modulation enable mask */
uint8 vib; /* LFO Phase Modulation enable flag (active high)*/
/* waveform select */
unsigned int wavetable;
} OPL_SLOT;
typedef struct {
OPL_SLOT SLOT[2];
/* phase generator state */
uint32 block_fnum; /* block+fnum */
uint32 fc; /* Freq. Increment base */
uint32 ksl_base; /* KeyScaleLevel Base step */
uint8 kcode; /* key code (for key scaling) */
} OPL_CH;
/* OPL state */
typedef struct fm_opl_f {
/* FM channel slots */
OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/
uint32 eg_cnt; /* global envelope generator counter */
uint32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */
uint32 eg_timer_add; /* step of eg_timer */
uint32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */
uint8 rhythm; /* Rhythm mode */
uint32 fn_tab[1024]; /* fnumber->increment counter */
/* LFO */
uint8 lfo_am_depth;
uint8 lfo_pm_depth_range;
uint32 lfo_am_cnt;
uint32 lfo_am_inc;
uint32 lfo_pm_cnt;
uint32 lfo_pm_inc;
uint32 noise_rng; /* 23 bit noise shift register */
uint32 noise_p; /* current noise 'phase' */
uint32 noise_f; /* current noise period */
uint8 wavesel; /* waveform select enable flag */
int T[2]; /* timer counters */
uint8 st[2]; /* timer enable */
/* external event callback handlers */
OPL_TIMERHANDLER TimerHandler; /* TIMER handler */
int TimerParam; /* TIMER parameter */
OPL_IRQHANDLER IRQHandler; /* IRQ handler */
int IRQParam; /* IRQ parameter */
OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */
int UpdateParam; /* stream update parameter */
uint8 type; /* chip type */
uint8 address; /* address register */
uint8 status; /* status flag */
uint8 statusmask; /* status mask */
uint8 mode; /* Reg.08 : CSM,notesel,etc. */
int clock; /* master clock (Hz) */
int rate; /* sampling rate (Hz) */
double freqbase; /* frequency base */
double TimerBase; /* Timer base time (==sampling time)*/
} FM_OPL;
#define MAX_OPL_CHIPS 2
/* sinwave entries */
#define SIN_BITS 10
#define SIN_LEN (1<