Nuked: Last of the update
This commit is contained in:
@@ -20,6 +20,12 @@
|
||||
#ifndef SOUND_OPL_NUKED_H
|
||||
#define SOUND_OPL_NUKED_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef OPL_ENABLE_STEREOEXT
|
||||
#define OPL_ENABLE_STEREOEXT 0
|
||||
#endif
|
||||
@@ -27,63 +33,66 @@
|
||||
#define OPL_WRITEBUF_SIZE 1024
|
||||
#define OPL_WRITEBUF_DELAY 2
|
||||
|
||||
struct chan;
|
||||
struct chip;
|
||||
typedef struct _opl3_slot opl3_slot;
|
||||
typedef struct _opl3_channel opl3_channel;
|
||||
typedef struct _opl3_chip opl3_chip;
|
||||
|
||||
typedef struct slot {
|
||||
struct chan *channel;
|
||||
struct chip *chip;
|
||||
int16_t out;
|
||||
int16_t fbmod;
|
||||
int16_t *mod;
|
||||
int16_t prout;
|
||||
int16_t eg_rout;
|
||||
int16_t eg_out;
|
||||
uint8_t eg_inc;
|
||||
uint8_t eg_gen;
|
||||
uint8_t eg_rate;
|
||||
uint8_t eg_ksl;
|
||||
uint8_t *trem;
|
||||
uint8_t reg_vib;
|
||||
uint8_t reg_type;
|
||||
uint8_t reg_ksr;
|
||||
uint8_t reg_mult;
|
||||
uint8_t reg_ksl;
|
||||
uint8_t reg_tl;
|
||||
uint8_t reg_ar;
|
||||
uint8_t reg_dr;
|
||||
uint8_t reg_sl;
|
||||
uint8_t reg_rr;
|
||||
uint8_t reg_wf;
|
||||
uint8_t key;
|
||||
uint32_t pg_reset;
|
||||
uint32_t pg_phase;
|
||||
uint16_t pg_phase_out;
|
||||
uint8_t slot_num;
|
||||
} opl3_slot;
|
||||
struct _opl3_slot {
|
||||
opl3_channel *channel;
|
||||
opl3_chip *chip;
|
||||
int16_t out;
|
||||
int16_t fbmod;
|
||||
int16_t *mod;
|
||||
int16_t prout;
|
||||
uint16_t eg_rout;
|
||||
uint16_t eg_out;
|
||||
uint8_t eg_inc;
|
||||
uint8_t eg_gen;
|
||||
uint8_t eg_rate;
|
||||
uint8_t eg_ksl;
|
||||
uint8_t *trem;
|
||||
uint8_t reg_vib;
|
||||
uint8_t reg_type;
|
||||
uint8_t reg_ksr;
|
||||
uint8_t reg_mult;
|
||||
uint8_t reg_ksl;
|
||||
uint8_t reg_tl;
|
||||
uint8_t reg_ar;
|
||||
uint8_t reg_dr;
|
||||
uint8_t reg_sl;
|
||||
uint8_t reg_rr;
|
||||
uint8_t reg_wf;
|
||||
uint8_t key;
|
||||
uint32_t pg_reset;
|
||||
uint32_t pg_phase;
|
||||
uint16_t pg_phase_out;
|
||||
uint8_t slot_num;
|
||||
};
|
||||
|
||||
struct _opl3_channel {
|
||||
opl3_slot *slotz[2]; // Don't use "slots" keyword to avoid conflict with Qt applications
|
||||
opl3_channel *pair;
|
||||
opl3_chip *chip;
|
||||
int16_t *out[4];
|
||||
|
||||
typedef struct chan {
|
||||
opl3_slot *slotz[2]; // Don't use "slots" keyword to avoid conflict with Qt applications
|
||||
struct chan *pair;
|
||||
struct chip *chip;
|
||||
int16_t *out[4];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
int32_t leftpan;
|
||||
int32_t rightpan;
|
||||
int32_t leftpan;
|
||||
int32_t rightpan;
|
||||
#endif
|
||||
uint8_t chtype;
|
||||
uint16_t f_num;
|
||||
uint8_t block;
|
||||
uint8_t fb;
|
||||
uint8_t con;
|
||||
uint8_t alg;
|
||||
uint8_t ksv;
|
||||
uint16_t cha;
|
||||
uint16_t chb;
|
||||
uint16_t chc;
|
||||
uint16_t chd;
|
||||
uint8_t ch_num;
|
||||
} opl3_channel;
|
||||
|
||||
uint8_t chtype;
|
||||
uint16_t f_num;
|
||||
uint8_t block;
|
||||
uint8_t fb;
|
||||
uint8_t con;
|
||||
uint8_t alg;
|
||||
uint8_t ksv;
|
||||
uint16_t cha;
|
||||
uint16_t chb;
|
||||
uint16_t chc;
|
||||
uint16_t chd;
|
||||
uint8_t ch_num;
|
||||
};
|
||||
|
||||
typedef struct _opl3_writebuf {
|
||||
uint64_t time;
|
||||
@@ -91,7 +100,7 @@ typedef struct _opl3_writebuf {
|
||||
uint8_t data;
|
||||
} opl3_writebuf;
|
||||
|
||||
typedef struct chip {
|
||||
struct _opl3_chip {
|
||||
opl3_channel channel[18];
|
||||
opl3_slot slot[36];
|
||||
uint16_t timer;
|
||||
@@ -99,7 +108,7 @@ typedef struct chip {
|
||||
uint8_t eg_timerrem;
|
||||
uint8_t eg_state;
|
||||
uint8_t eg_add;
|
||||
uint64_t eg_timer_lo;
|
||||
uint8_t eg_timer_lo;
|
||||
uint8_t newm;
|
||||
uint8_t nts;
|
||||
uint8_t rhy;
|
||||
@@ -119,26 +128,26 @@ typedef struct chip {
|
||||
uint8_t rm_tc_bit5;
|
||||
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
uint8_t stereoext;
|
||||
uint8_t stereoext;
|
||||
#endif
|
||||
|
||||
// OPL3L
|
||||
int32_t rateratio;
|
||||
int32_t samplecnt;
|
||||
int32_t oldsamples[4];
|
||||
int32_t samples[4];
|
||||
int32_t rateratio;
|
||||
int32_t samplecnt;
|
||||
int32_t oldsamples[4];
|
||||
int32_t samples[4];
|
||||
|
||||
uint64_t writebuf_samplecnt;
|
||||
uint32_t writebuf_cur;
|
||||
uint32_t writebuf_last;
|
||||
uint64_t writebuf_lasttime;
|
||||
opl3_writebuf writebuf[OPL_WRITEBUF_SIZE];
|
||||
} opl3_chip;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
opl3_chip opl;
|
||||
int8_t flags;
|
||||
int8_t pad;
|
||||
int8_t flags;
|
||||
int8_t pad;
|
||||
|
||||
uint16_t port;
|
||||
uint8_t status;
|
||||
@@ -173,6 +182,19 @@ enum {
|
||||
CTRL_TMR1_START = 0x01
|
||||
};
|
||||
|
||||
void nuked_write_reg(void *priv, uint16_t reg, uint8_t val);
|
||||
void OPL3_Generate(opl3_chip *chip, int32_t *buf);
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, int32_t *buf);
|
||||
void OPL3_Reset(opl3_chip *chip, uint32_t samplerate);
|
||||
void OPL3_WriteReg(void *priv, uint16_t reg, uint8_t val);
|
||||
void OPL3_WriteRegBuffered(void *priv, uint16_t reg, uint8_t val);
|
||||
void OPL3_GenerateStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples);
|
||||
|
||||
static void OPL3_Generate4Ch(void *priv, int32_t *buf4);
|
||||
void OPL3_Generate4Ch_Resampled(opl3_chip *chip, int32_t *buf4);
|
||||
void OPL3_Generate4Ch_Stream(opl3_chip *chip, int32_t *sndptr1, int32_t *sndptr2, uint32_t numsamples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*SOUND_OPL_NUKED_H*/
|
||||
|
@@ -85,13 +85,6 @@ enum {
|
||||
egk_drum = 0x02
|
||||
};
|
||||
|
||||
enum envelope_gen_num {
|
||||
envelope_gen_num_attack = 0,
|
||||
envelope_gen_num_decay = 1,
|
||||
envelope_gen_num_sustain = 2,
|
||||
envelope_gen_num_release = 3
|
||||
};
|
||||
|
||||
#ifdef ENABLE_OPL_LOG
|
||||
int nuked_do_log = ENABLE_OPL_LOG;
|
||||
|
||||
@@ -230,7 +223,7 @@ typedef int16_t (*envelope_sinfunc)(uint16_t phase, uint16_t envelope);
|
||||
typedef void (*envelope_genfunc)(opl3_slot *slot);
|
||||
|
||||
static int16_t
|
||||
envelope_calc_exp(uint32_t level)
|
||||
OPL3_EnvelopeCalcExp(uint32_t level)
|
||||
{
|
||||
if (level > 0x1fff)
|
||||
level = 0x1fff;
|
||||
@@ -239,7 +232,7 @@ envelope_calc_exp(uint32_t level)
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin0(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin0(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
uint16_t neg = 0;
|
||||
@@ -254,11 +247,11 @@ envelope_calc_sin0(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[phase & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)) ^ neg);
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg);
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin1(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin1(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
|
||||
@@ -271,11 +264,11 @@ envelope_calc_sin1(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[phase & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)));
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin2(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin2(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
|
||||
@@ -286,11 +279,11 @@ envelope_calc_sin2(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[phase & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)));
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin3(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin3(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
|
||||
@@ -301,11 +294,11 @@ envelope_calc_sin3(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[phase & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)));
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin4(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin4(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
uint16_t neg = 0;
|
||||
@@ -322,11 +315,11 @@ envelope_calc_sin4(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[(phase << 1u) & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)) ^ neg);
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg);
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin5(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin5(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
|
||||
@@ -339,11 +332,11 @@ envelope_calc_sin5(uint16_t phase, uint16_t envelope)
|
||||
else
|
||||
out = logsinrom[(phase << 1u) & 0xffu];
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)));
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin6(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin6(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t neg = 0;
|
||||
|
||||
@@ -352,11 +345,11 @@ envelope_calc_sin6(uint16_t phase, uint16_t envelope)
|
||||
if (phase & 0x0200)
|
||||
neg = 0xffff;
|
||||
|
||||
return (envelope_calc_exp(envelope << 3) ^ neg);
|
||||
return (OPL3_EnvelopeCalcExp(envelope << 3) ^ neg);
|
||||
}
|
||||
|
||||
static int16_t
|
||||
envelope_calc_sin7(uint16_t phase, uint16_t envelope)
|
||||
OPL3_EnvelopeCalcSin7(uint16_t phase, uint16_t envelope)
|
||||
{
|
||||
uint16_t out = 0;
|
||||
uint16_t neg = 0;
|
||||
@@ -370,22 +363,29 @@ envelope_calc_sin7(uint16_t phase, uint16_t envelope)
|
||||
|
||||
out = phase << 3;
|
||||
|
||||
return (envelope_calc_exp(out + (envelope << 3)) ^ neg);
|
||||
return (OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg);
|
||||
}
|
||||
|
||||
static const envelope_sinfunc envelope_sin[8] = {
|
||||
envelope_calc_sin0,
|
||||
envelope_calc_sin1,
|
||||
envelope_calc_sin2,
|
||||
envelope_calc_sin3,
|
||||
envelope_calc_sin4,
|
||||
envelope_calc_sin5,
|
||||
envelope_calc_sin6,
|
||||
envelope_calc_sin7
|
||||
OPL3_EnvelopeCalcSin0,
|
||||
OPL3_EnvelopeCalcSin1,
|
||||
OPL3_EnvelopeCalcSin2,
|
||||
OPL3_EnvelopeCalcSin3,
|
||||
OPL3_EnvelopeCalcSin4,
|
||||
OPL3_EnvelopeCalcSin5,
|
||||
OPL3_EnvelopeCalcSin6,
|
||||
OPL3_EnvelopeCalcSin7
|
||||
};
|
||||
|
||||
enum envelope_gen_num {
|
||||
envelope_gen_num_attack = 0,
|
||||
envelope_gen_num_decay = 1,
|
||||
envelope_gen_num_sustain = 2,
|
||||
envelope_gen_num_release = 3
|
||||
};
|
||||
|
||||
static void
|
||||
envelope_update_ksl(opl3_slot *slot)
|
||||
OPL3_EnvelopeUpdateKSL(opl3_slot *slot)
|
||||
{
|
||||
int16_t ksl = (kslrom[slot->channel->f_num >> 6u] << 2)
|
||||
- ((0x08 - slot->channel->block) << 5);
|
||||
@@ -397,7 +397,7 @@ envelope_update_ksl(opl3_slot *slot)
|
||||
}
|
||||
|
||||
static void
|
||||
envelope_calc(opl3_slot *slot)
|
||||
OPL3_EnvelopeCalc(opl3_slot *slot)
|
||||
{
|
||||
uint8_t nonzero;
|
||||
uint8_t rate;
|
||||
@@ -531,33 +531,35 @@ envelope_calc(opl3_slot *slot)
|
||||
}
|
||||
|
||||
static void
|
||||
envelope_key_on(opl3_slot *slot, uint8_t type)
|
||||
OPL3_EnvelopeKeyOn(opl3_slot *slot, uint8_t type)
|
||||
{
|
||||
slot->key |= type;
|
||||
}
|
||||
|
||||
static void
|
||||
envelope_key_off(opl3_slot *slot, uint8_t type)
|
||||
OPL3_EnvelopeKeyOff(opl3_slot *slot, uint8_t type)
|
||||
{
|
||||
slot->key &= ~type;
|
||||
}
|
||||
|
||||
// Phase Generator
|
||||
static void
|
||||
phase_generate(opl3_slot *slot)
|
||||
OPL3_PhaseGenerate(opl3_slot *slot)
|
||||
{
|
||||
uint16_t f_num;
|
||||
uint32_t basefreq;
|
||||
uint8_t rm_xor;
|
||||
uint8_t n_bit;
|
||||
uint32_t noise;
|
||||
uint16_t phase;
|
||||
int8_t range;
|
||||
uint8_t vibpos;
|
||||
opl3_chip *chip;
|
||||
uint16_t f_num;
|
||||
uint32_t basefreq;
|
||||
uint8_t rm_xor;
|
||||
uint8_t n_bit;
|
||||
uint32_t noise;
|
||||
uint16_t phase;
|
||||
|
||||
chip = slot->chip;
|
||||
f_num = slot->channel->f_num;
|
||||
if (slot->reg_vib) {
|
||||
int8_t range;
|
||||
uint8_t vibpos;
|
||||
|
||||
range = (f_num >> 7) & 7;
|
||||
vibpos = chip->vibpos;
|
||||
|
||||
@@ -625,8 +627,9 @@ phase_generate(opl3_slot *slot)
|
||||
chip->noise = (noise >> 1) | (n_bit << 22);
|
||||
}
|
||||
|
||||
// Slot
|
||||
static void
|
||||
slot_write_20(opl3_slot *slot, uint8_t data)
|
||||
OPL3_SlotWrite20(opl3_slot *slot, uint8_t data)
|
||||
{
|
||||
if ((data >> 7) & 0x01)
|
||||
slot->trem = &slot->chip->tremolo;
|
||||
@@ -640,23 +643,23 @@ slot_write_20(opl3_slot *slot, uint8_t data)
|
||||
}
|
||||
|
||||
static void
|
||||
slot_write_40(opl3_slot *slot, uint8_t data)
|
||||
OPL3_SlotWrite40(opl3_slot *slot, uint8_t data)
|
||||
{
|
||||
slot->reg_ksl = (data >> 6) & 0x03;
|
||||
slot->reg_tl = data & 0x3f;
|
||||
|
||||
envelope_update_ksl(slot);
|
||||
OPL3_EnvelopeUpdateKSL(slot);
|
||||
}
|
||||
|
||||
static void
|
||||
slot_write_60(opl3_slot *slot, uint8_t data)
|
||||
OPL3_SlotWrite60(opl3_slot *slot, uint8_t data)
|
||||
{
|
||||
slot->reg_ar = (data >> 4) & 0x0f;
|
||||
slot->reg_dr = data & 0x0f;
|
||||
}
|
||||
|
||||
static void
|
||||
slot_write_80(opl3_slot *slot, uint8_t data)
|
||||
OPL3_SlotWrite80(opl3_slot *slot, uint8_t data)
|
||||
{
|
||||
slot->reg_sl = (data >> 4) & 0x0f;
|
||||
|
||||
@@ -667,7 +670,7 @@ slot_write_80(opl3_slot *slot, uint8_t data)
|
||||
}
|
||||
|
||||
static void
|
||||
slot_write_e0(opl3_slot *slot, uint8_t data)
|
||||
OPL3_SlotWriteE0(opl3_slot *slot, uint8_t data)
|
||||
{
|
||||
slot->reg_wf = data & 0x07;
|
||||
|
||||
@@ -676,14 +679,13 @@ slot_write_e0(opl3_slot *slot, uint8_t data)
|
||||
}
|
||||
|
||||
static void
|
||||
slot_generate(opl3_slot *slot)
|
||||
OPL3_SlotGenerate(opl3_slot *slot)
|
||||
{
|
||||
slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod,
|
||||
slot->eg_out);
|
||||
slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out);
|
||||
}
|
||||
|
||||
static void
|
||||
slot_calc_fb(opl3_slot *slot)
|
||||
OPL3_SlotCalcFB(opl3_slot *slot)
|
||||
{
|
||||
if (slot->channel->fb != 0x00)
|
||||
slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb);
|
||||
@@ -695,10 +697,10 @@ slot_calc_fb(opl3_slot *slot)
|
||||
|
||||
// Channel
|
||||
static void
|
||||
channel_setup_alg(opl3_channel *channel);
|
||||
OPL3_ChannelSetupAlg(opl3_channel *channel);
|
||||
|
||||
static void
|
||||
channel_update_rhythm(opl3_chip *chip, uint8_t data)
|
||||
OPL3_ChannelUpdateRhythm(opl3_chip *chip, uint8_t data)
|
||||
{
|
||||
opl3_channel *channel6;
|
||||
opl3_channel *channel7;
|
||||
@@ -726,55 +728,55 @@ channel_update_rhythm(opl3_chip *chip, uint8_t data)
|
||||
for (chnum = 6; chnum < 9; chnum++)
|
||||
chip->channel[chnum].chtype = ch_drum;
|
||||
|
||||
channel_setup_alg(channel6);
|
||||
channel_setup_alg(channel7);
|
||||
channel_setup_alg(channel8);
|
||||
OPL3_ChannelSetupAlg(channel6);
|
||||
OPL3_ChannelSetupAlg(channel7);
|
||||
OPL3_ChannelSetupAlg(channel8);
|
||||
|
||||
// hh
|
||||
if (chip->rhy & 0x01)
|
||||
envelope_key_on(channel7->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum);
|
||||
else
|
||||
envelope_key_off(channel7->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum);
|
||||
|
||||
// tc
|
||||
if (chip->rhy & 0x02)
|
||||
envelope_key_on(channel8->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum);
|
||||
else
|
||||
envelope_key_off(channel8->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum);
|
||||
|
||||
// tom
|
||||
if (chip->rhy & 0x04)
|
||||
envelope_key_on(channel8->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum);
|
||||
else
|
||||
envelope_key_off(channel8->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum);
|
||||
|
||||
// sd
|
||||
if (chip->rhy & 0x08)
|
||||
envelope_key_on(channel7->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum);
|
||||
else
|
||||
envelope_key_off(channel7->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum);
|
||||
|
||||
// bd
|
||||
if (chip->rhy & 0x10) {
|
||||
envelope_key_on(channel6->slotz[0], egk_drum);
|
||||
envelope_key_on(channel6->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum);
|
||||
} else {
|
||||
envelope_key_off(channel6->slotz[0], egk_drum);
|
||||
envelope_key_off(channel6->slotz[1], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum);
|
||||
}
|
||||
} else {
|
||||
for (chnum = 6; chnum < 9; chnum++) {
|
||||
chip->channel[chnum].chtype = ch_2op;
|
||||
|
||||
channel_setup_alg(&chip->channel[chnum]);
|
||||
envelope_key_off(chip->channel[chnum].slotz[0], egk_drum);
|
||||
envelope_key_off(chip->channel[chnum].slotz[1], egk_drum);
|
||||
OPL3_ChannelSetupAlg(&chip->channel[chnum]);
|
||||
OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum);
|
||||
OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
channel_write_a0(opl3_channel *channel, uint8_t data)
|
||||
OPL3_ChannelWriteA0(opl3_channel *channel, uint8_t data)
|
||||
{
|
||||
if (channel->chip->newm && channel->chtype == ch_4op2)
|
||||
return;
|
||||
@@ -783,20 +785,20 @@ channel_write_a0(opl3_channel *channel, uint8_t data)
|
||||
channel->ksv = (channel->block << 1)
|
||||
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
|
||||
|
||||
envelope_update_ksl(channel->slotz[0]);
|
||||
envelope_update_ksl(channel->slotz[1]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
|
||||
|
||||
if (channel->chip->newm && channel->chtype == ch_4op) {
|
||||
channel->pair->f_num = channel->f_num;
|
||||
channel->pair->ksv = channel->ksv;
|
||||
|
||||
envelope_update_ksl(channel->pair->slotz[0]);
|
||||
envelope_update_ksl(channel->pair->slotz[1]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
channel_write_b0(opl3_channel *channel, uint8_t data)
|
||||
OPL3_ChannelWriteB0(opl3_channel *channel, uint8_t data)
|
||||
{
|
||||
if (channel->chip->newm && channel->chtype == ch_4op2)
|
||||
return;
|
||||
@@ -806,21 +808,21 @@ channel_write_b0(opl3_channel *channel, uint8_t data)
|
||||
channel->ksv = (channel->block << 1)
|
||||
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
|
||||
|
||||
envelope_update_ksl(channel->slotz[0]);
|
||||
envelope_update_ksl(channel->slotz[1]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
|
||||
|
||||
if (channel->chip->newm && channel->chtype == ch_4op) {
|
||||
channel->pair->f_num = channel->f_num;
|
||||
channel->pair->block = channel->block;
|
||||
channel->pair->ksv = channel->ksv;
|
||||
|
||||
envelope_update_ksl(channel->pair->slotz[0]);
|
||||
envelope_update_ksl(channel->pair->slotz[1]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
|
||||
OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
channel_setup_alg(opl3_channel *channel)
|
||||
OPL3_ChannelSetupAlg(opl3_channel *channel)
|
||||
{
|
||||
if (channel->chtype == ch_drum) {
|
||||
if (channel->ch_num == 7 || channel->ch_num == 8) {
|
||||
@@ -929,30 +931,31 @@ channel_setup_alg(opl3_channel *channel)
|
||||
}
|
||||
|
||||
static void
|
||||
channel_update_alg(opl3_channel *channel)
|
||||
OPL3_ChannelUpdateAlg(opl3_channel *channel)
|
||||
{
|
||||
channel->alg = channel->con;
|
||||
|
||||
if (channel->chip->newm) {
|
||||
if (channel->chtype == ch_4op) {
|
||||
channel->pair->alg = 0x04 | (channel->con << 1) | channel->pair->con;
|
||||
channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con);
|
||||
channel->alg = 0x08;
|
||||
channel_setup_alg(channel->pair);
|
||||
OPL3_ChannelSetupAlg(channel->pair);
|
||||
} else if (channel->chtype == ch_4op2) {
|
||||
channel->alg = 0x04 | (channel->pair->con << 1) | channel->con;
|
||||
channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con);
|
||||
channel->pair->alg = 0x08;
|
||||
channel_setup_alg(channel);
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
} else
|
||||
channel_setup_alg(channel);
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
} else
|
||||
channel_setup_alg(channel);
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
|
||||
static void
|
||||
channel_write_c0(opl3_channel *channel, uint8_t data)
|
||||
OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
||||
{
|
||||
channel->fb = (data & 0x0e) >> 1;
|
||||
channel->con = data & 0x01;
|
||||
OPL3_ChannelUpdateAlg(channel);
|
||||
|
||||
if (channel->chip->newm) {
|
||||
channel->cha = ((data >> 4) & 0x01) ? ~0 : 0;
|
||||
@@ -975,7 +978,7 @@ channel_write_c0(opl3_channel *channel, uint8_t data)
|
||||
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
static void
|
||||
channel_write_d0(opl3_channel *channel, uint8_t data)
|
||||
OPL3_ChannelWriteD0(opl3_channel *channel, uint8_t data)
|
||||
{
|
||||
if (channel->chip->stereoext) {
|
||||
channel->leftpan = panpot_lut[data ^ 0xffu];
|
||||
@@ -985,45 +988,45 @@ channel_write_d0(opl3_channel *channel, uint8_t data)
|
||||
#endif
|
||||
|
||||
static void
|
||||
channel_key_on(opl3_channel *channel)
|
||||
OPL3_ChannelKeyOn(opl3_channel *channel)
|
||||
{
|
||||
if (channel->chip->newm) {
|
||||
if (channel->chtype == ch_4op) {
|
||||
envelope_key_on(channel->slotz[0], egk_norm);
|
||||
envelope_key_on(channel->slotz[1], egk_norm);
|
||||
envelope_key_on(channel->pair->slotz[0], egk_norm);
|
||||
envelope_key_on(channel->pair->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm);
|
||||
} else if (channel->chtype == ch_2op || channel->chtype == ch_drum) {
|
||||
envelope_key_on(channel->slotz[0], egk_norm);
|
||||
envelope_key_on(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
|
||||
}
|
||||
} else {
|
||||
envelope_key_on(channel->slotz[0], egk_norm);
|
||||
envelope_key_on(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
channel_key_off(opl3_channel *channel)
|
||||
OPL3_ChannelKeyOff(opl3_channel *channel)
|
||||
{
|
||||
if (channel->chip->newm) {
|
||||
if (channel->chtype == ch_4op) {
|
||||
envelope_key_off(channel->slotz[0], egk_norm);
|
||||
envelope_key_off(channel->slotz[1], egk_norm);
|
||||
envelope_key_off(channel->pair->slotz[0], egk_norm);
|
||||
envelope_key_off(channel->pair->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm);
|
||||
} else if (channel->chtype == ch_2op || channel->chtype == ch_drum) {
|
||||
envelope_key_off(channel->slotz[0], egk_norm);
|
||||
envelope_key_off(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
|
||||
}
|
||||
} else {
|
||||
envelope_key_off(channel->slotz[0], egk_norm);
|
||||
envelope_key_off(channel->slotz[1], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
|
||||
OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
channel_set_4op(opl3_chip *chip, uint8_t data)
|
||||
OPL3_ChannelSet4Op(opl3_chip *chip, uint8_t data)
|
||||
{
|
||||
uint8_t chnum;
|
||||
|
||||
@@ -1036,36 +1039,36 @@ channel_set_4op(opl3_chip *chip, uint8_t data)
|
||||
if ((data >> bit) & 0x01) {
|
||||
chip->channel[chnum].chtype = ch_4op;
|
||||
chip->channel[chnum + 3u].chtype = ch_4op2;
|
||||
channel_update_alg(&chip->channel[chnum]);
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
} else {
|
||||
chip->channel[chnum].chtype = ch_2op;
|
||||
chip->channel[chnum + 3u].chtype = ch_2op;
|
||||
channel_update_alg(&chip->channel[chnum]);
|
||||
channel_update_alg(&chip->channel[chnum + 3u]);
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum + 3u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_slot(opl3_slot *slot)
|
||||
OPL3_ProcessSlot(opl3_slot *slot)
|
||||
{
|
||||
slot_calc_fb(slot);
|
||||
envelope_calc(slot);
|
||||
phase_generate(slot);
|
||||
slot_generate(slot);
|
||||
OPL3_SlotCalcFB(slot);
|
||||
OPL3_EnvelopeCalc(slot);
|
||||
OPL3_PhaseGenerate(slot);
|
||||
OPL3_SlotGenerate(slot);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
OPL3_Generate4Ch(void *priv, int32_t *buf4)
|
||||
{
|
||||
opl3_chip *chip = (opl3_chip *) priv;
|
||||
opl3_channel *channel;
|
||||
opl3_writebuf *writebuf;
|
||||
int16_t **out;
|
||||
int32_t mix[2];
|
||||
int16_t accm;
|
||||
int16_t shift = 0;
|
||||
uint8_t i;
|
||||
int16_t accm;
|
||||
uint8_t shift = 0;
|
||||
|
||||
buf4[1] = chip->mixbuff[1];
|
||||
buf4[3] = chip->mixbuff[3];
|
||||
@@ -1075,7 +1078,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
#else
|
||||
for (i = 0; i < 36; i++)
|
||||
#endif
|
||||
process_slot(&chip->slot[i]);
|
||||
OPL3_ProcessSlot(&chip->slot[i]);
|
||||
|
||||
mix[0] = mix[1] = 0;
|
||||
|
||||
@@ -1084,11 +1087,11 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix[0] += (int32_t) ((accm * channel->leftpan) >> 16);
|
||||
mix[0] += (int16_t) ((accm * channel->leftpan) >> 16);
|
||||
#else
|
||||
mix[0] += (int32_t) (accm & channel->cha);
|
||||
mix[0] += (int16_t) (accm & channel->cha);
|
||||
#endif
|
||||
mix[1] += (int32_t) (accm & channel->chc);
|
||||
mix[1] += (int16_t) (accm & channel->chc);
|
||||
}
|
||||
|
||||
chip->mixbuff[0] = mix[0];
|
||||
@@ -1096,7 +1099,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (i = 15; i < 18; i++)
|
||||
process_slot(&chip->slot[i]);
|
||||
OPL3_ProcessSlot(&chip->slot[i]);
|
||||
#endif
|
||||
|
||||
buf4[0] = chip->mixbuff[0];
|
||||
@@ -1104,7 +1107,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (i = 18; i < 33; i++)
|
||||
process_slot(&chip->slot[i]);
|
||||
OPL3_ProcessSlot(&chip->slot[i]);
|
||||
#endif
|
||||
|
||||
mix[0] = mix[1] = 0;
|
||||
@@ -1112,13 +1115,13 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
for (i = 0; i < 18; i++) {
|
||||
channel = &chip->channel[i];
|
||||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix[0] += (int32_t) ((accm * channel->rightpan) >> 16);
|
||||
mix[0] += (int16_t) ((accm * channel->rightpan) >> 16);
|
||||
#else
|
||||
mix[0] += (int32_t) (accm & channel->chb);
|
||||
mix[0] += (int16_t) (accm & channel->chb);
|
||||
#endif
|
||||
mix[1] += (int32_t) (accm & channel->chd);
|
||||
mix[1] += (int16_t) (accm & channel->chd);
|
||||
}
|
||||
|
||||
chip->mixbuff[1] = mix[0];
|
||||
@@ -1126,7 +1129,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (i = 33; i < 36; i++)
|
||||
process_slot(&chip->slot[i]);
|
||||
OPL3_ProcessSlot(&chip->slot[i]);
|
||||
#endif
|
||||
|
||||
if ((chip->timer & 0x3f) == 0x3f)
|
||||
@@ -1166,13 +1169,13 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
|
||||
chip->eg_state ^= 1;
|
||||
|
||||
while (writebuf = &chip->writebuf[chip->writebuf_cur], writebuf->time <= chip->writebuf_samplecnt) {
|
||||
while ((writebuf = &chip->writebuf[chip->writebuf_cur]), writebuf->time <= chip->writebuf_samplecnt) {
|
||||
if (!(writebuf->reg & 0x200))
|
||||
break;
|
||||
|
||||
writebuf->reg &= 0x01ff;
|
||||
|
||||
nuked_write_reg(chip, writebuf->reg, writebuf->data);
|
||||
OPL3_WriteReg(chip, writebuf->reg, writebuf->data);
|
||||
|
||||
chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE;
|
||||
}
|
||||
@@ -1181,84 +1184,79 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate(opl3_chip *chip, int32_t *buf)
|
||||
OPL3_Generate(opl3_chip *chip, int32_t *buf)
|
||||
{
|
||||
int32_t samples[4];
|
||||
nuked_generate_4ch(chip, samples);
|
||||
OPL3_Generate4Ch(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_4ch_resampled(opl3_chip *chip, int32_t *buf4)
|
||||
OPL3_Generate4ChResampled(opl3_chip *chip, int32_t *buf4)
|
||||
{
|
||||
while (chip->samplecnt >= chip->rateratio) {
|
||||
chip->oldsamples[0] = chip->samples[0];
|
||||
chip->oldsamples[1] = chip->samples[1];
|
||||
chip->oldsamples[2] = chip->samples[2];
|
||||
chip->oldsamples[3] = chip->samples[3];
|
||||
nuked_generate_4ch(chip, chip->samples);
|
||||
OPL3_Generate4Ch(chip, chip->samples);
|
||||
chip->samplecnt -= chip->rateratio;
|
||||
}
|
||||
|
||||
buf4[0] = (int32_t) ((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt)
|
||||
/ chip->rateratio);
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[1] = (int32_t) ((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt)
|
||||
/ chip->rateratio);
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[2] = (int32_t) ((chip->oldsamples[2] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[2] * chip->samplecnt)
|
||||
/ chip->rateratio);
|
||||
+ chip->samples[2] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[3] = (int32_t) ((chip->oldsamples[3] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[3] * chip->samplecnt)
|
||||
/ chip->rateratio);
|
||||
+ chip->samples[3] * chip->samplecnt) / chip->rateratio);
|
||||
|
||||
chip->samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_resampled(opl3_chip *chip, int32_t *buf4)
|
||||
OPL3_GenerateResampled(opl3_chip *chip, int32_t *buf)
|
||||
{
|
||||
int32_t samples[4];
|
||||
nuked_generate_4ch_resampled(chip, samples);
|
||||
buf4[0] = samples[0];
|
||||
buf4[1] = samples[1];
|
||||
OPL3_Generate4ChResampled(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void
|
||||
nuked_init(opl3_chip *chip, uint32_t samplerate)
|
||||
OPL3_Reset(opl3_chip *chip, uint32_t samplerate)
|
||||
{
|
||||
opl3_slot *slot;
|
||||
opl3_channel *channel;
|
||||
uint8_t i;
|
||||
uint8_t local_ch_slot;
|
||||
|
||||
memset(chip, 0x00, sizeof(opl3_chip));
|
||||
|
||||
for (i = 0; i < 36; i++) {
|
||||
slot = &chip->slot[i];
|
||||
slot->chip = chip;
|
||||
slot->mod = &chip->zeromod;
|
||||
slot->eg_rout = 0x01ff;
|
||||
slot->eg_out = 0x01ff;
|
||||
slot->eg_gen = envelope_gen_num_release;
|
||||
slot->trem = (uint8_t *) &chip->zeromod;
|
||||
slot->slot_num = i;
|
||||
for (uint8_t slotnum = 0; slotnum < 36; slotnum++) {
|
||||
slot = &chip->slot[slotnum];
|
||||
slot->chip = chip;
|
||||
slot->mod = &chip->zeromod;
|
||||
slot->eg_rout = 0x01ff;
|
||||
slot->eg_out = 0x01ff;
|
||||
slot->eg_gen = envelope_gen_num_release;
|
||||
slot->trem = (uint8_t *) &chip->zeromod;
|
||||
slot->slot_num = slotnum;
|
||||
}
|
||||
|
||||
for (i = 0; i < 18; i++) {
|
||||
channel = &chip->channel[i];
|
||||
local_ch_slot = ch_slot[i];
|
||||
for (uint8_t channum = 0; channum < 18; channum++) {
|
||||
channel = &chip->channel[channum];
|
||||
local_ch_slot = ch_slot[channum];
|
||||
channel->slotz[0] = &chip->slot[local_ch_slot];
|
||||
channel->slotz[1] = &chip->slot[local_ch_slot + 3u];
|
||||
chip->slot[local_ch_slot].channel = channel;
|
||||
chip->slot[local_ch_slot + 3u].channel = channel;
|
||||
|
||||
if ((i % 9) < 3)
|
||||
channel->pair = &chip->channel[i + 3u];
|
||||
else if ((i % 9) < 6)
|
||||
channel->pair = &chip->channel[i - 3u];
|
||||
if ((channum % 9) < 3)
|
||||
channel->pair = &chip->channel[channum + 3u];
|
||||
else if ((channum % 9) < 6)
|
||||
channel->pair = &chip->channel[channum - 3u];
|
||||
|
||||
channel->chip = chip;
|
||||
channel->out[0] = &chip->zeromod;
|
||||
@@ -1272,9 +1270,9 @@ nuked_init(opl3_chip *chip, uint32_t samplerate)
|
||||
channel->leftpan = 0x10000;
|
||||
channel->rightpan = 0x10000;
|
||||
#endif
|
||||
channel->ch_num = i;
|
||||
channel->ch_num = channum;
|
||||
|
||||
channel_setup_alg(channel);
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
|
||||
chip->noise = 1;
|
||||
@@ -1291,15 +1289,6 @@ nuked_init(opl3_chip *chip, uint32_t samplerate)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_raw(opl3_chip *chip, int32_t *bufp)
|
||||
{
|
||||
nuked_generate(chip, chip->samples);
|
||||
|
||||
bufp[0] = (int32_t) chip->samples[0];
|
||||
bufp[1] = (int32_t) chip->samples[1];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
nuked_write_addr(void *priv, uint16_t port, uint8_t val)
|
||||
{
|
||||
@@ -1314,7 +1303,7 @@ nuked_write_addr(void *priv, uint16_t port, uint8_t val)
|
||||
}
|
||||
|
||||
void
|
||||
nuked_write_reg(void *priv, uint16_t reg, uint8_t val)
|
||||
OPL3_WriteReg(void *priv, uint16_t reg, uint8_t val)
|
||||
{
|
||||
opl3_chip *chip = (opl3_chip *) priv;
|
||||
uint8_t high = (reg >> 8) & 0x01;
|
||||
@@ -1325,7 +1314,7 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val)
|
||||
if (high)
|
||||
switch (regm & 0x0f) {
|
||||
case 0x04:
|
||||
channel_set_4op(chip, val);
|
||||
OPL3_ChannelSet4Op(chip, val);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
@@ -1352,72 +1341,72 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val)
|
||||
case 0x20:
|
||||
case 0x30:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
slot_write_20(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
OPL3_SlotWrite20(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
case 0x50:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
slot_write_40(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
OPL3_SlotWrite40(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
case 0x70:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
slot_write_60(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
OPL3_SlotWrite60(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
slot_write_80(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
OPL3_SlotWrite80(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
case 0xf0:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
OPL3_SlotWriteE0(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
case 0xa0:
|
||||
if ((regm & 0x0f) < 9)
|
||||
channel_write_a0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
OPL3_ChannelWriteA0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
break;
|
||||
|
||||
case 0xb0:
|
||||
if (regm == 0xbd && !high) {
|
||||
chip->tremoloshift = (((val >> 7) ^ 1) << 1) + 2;
|
||||
chip->vibshift = ((val >> 6) & 0x01) ^ 1;
|
||||
channel_update_rhythm(chip, val);
|
||||
OPL3_ChannelUpdateRhythm(chip, val);
|
||||
} else if ((regm & 0x0f) < 9) {
|
||||
channel_write_b0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
OPL3_ChannelWriteB0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
|
||||
if (val & 0x20)
|
||||
channel_key_on(&chip->channel[9u * high + (regm & 0x0fu)]);
|
||||
OPL3_ChannelKeyOn(&chip->channel[9u * high + (regm & 0x0fu)]);
|
||||
else
|
||||
channel_key_off(&chip->channel[9u * high + (regm & 0x0fu)]);
|
||||
OPL3_ChannelKeyOff(&chip->channel[9u * high + (regm & 0x0fu)]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
if ((regm & 0x0f) < 9)
|
||||
channel_write_c0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
OPL3_ChannelWriteC0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
break;
|
||||
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
case 0xd0:
|
||||
if ((regm & 0x0f) < 9)
|
||||
channel_write_d0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
OPL3_ChannelWriteD0(&chip->channel[9u * high + (regm & 0x0fu)], val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0xe0:
|
||||
case 0xf0:
|
||||
if (ad_slot[regm & 0x1fu] >= 0)
|
||||
slot_write_e0(&chip->slot[18u * high + ad_slot[regm & 0x1fu]], val);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val)
|
||||
OPL3_WriteRegBuffered(void *priv, uint16_t reg, uint8_t val)
|
||||
{
|
||||
opl3_chip *chip = (opl3_chip *) priv;
|
||||
uint64_t time1;
|
||||
@@ -1429,7 +1418,7 @@ nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val)
|
||||
writebuf = &chip->writebuf[writebuf_last];
|
||||
|
||||
if (writebuf->reg & 0x0200) {
|
||||
nuked_write_reg(chip, writebuf->reg & 0x01ff, writebuf->data);
|
||||
OPL3_WriteReg(chip, writebuf->reg & 0x01ff, writebuf->data);
|
||||
|
||||
chip->writebuf_cur = (writebuf_last + 1) % OPL_WRITEBUF_SIZE;
|
||||
chip->writebuf_samplecnt = writebuf->time;
|
||||
@@ -1449,12 +1438,12 @@ nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val)
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_4ch_stream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples)
|
||||
OPL3_Generate4ChStream(opl3_chip *chip, int32_t *sndptr1, int32_t *sndptr2, uint32_t numsamples)
|
||||
{
|
||||
int32_t samples[4];
|
||||
|
||||
for (uint_fast32_t i = 0; i < numsamples; i++) {
|
||||
nuked_generate_4ch_resampled(chip, samples);
|
||||
OPL3_Generate4Ch(chip, samples);
|
||||
sndptr1[0] = samples[0];
|
||||
sndptr1[1] = samples[1];
|
||||
sndptr2[0] = samples[2];
|
||||
@@ -1465,10 +1454,10 @@ nuked_generate_4ch_stream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, u
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_stream(opl3_chip *chip, int32_t *sndptr, uint32_t num)
|
||||
OPL3_GenerateStream(opl3_chip *chip, int32_t *sndptr, uint32_t numsamples)
|
||||
{
|
||||
for (uint_fast32_t i = 0; i < num; i++) {
|
||||
nuked_generate_resampled(chip, sndptr);
|
||||
for (uint_fast32_t i = 0; i < numsamples; i++) {
|
||||
OPL3_Generate(chip, sndptr);
|
||||
sndptr += 2;
|
||||
}
|
||||
}
|
||||
@@ -1549,7 +1538,7 @@ nuked_drv_init(const device_t *info)
|
||||
dev->status = 0x06;
|
||||
|
||||
/* Initialize the NukedOPL object. */
|
||||
nuked_init(&dev->opl, OPL_FREQ);
|
||||
OPL3_Reset(&dev->opl, OPL_FREQ);
|
||||
|
||||
timer_add(&dev->timers[0], nuked_timer_1, dev, 0);
|
||||
timer_add(&dev->timers[1], nuked_timer_2, dev, 0);
|
||||
@@ -1572,7 +1561,7 @@ nuked_drv_update(void *priv)
|
||||
if (dev->pos >= music_pos_global)
|
||||
return dev->buffer;
|
||||
|
||||
nuked_generate_stream(&dev->opl,
|
||||
OPL3_GenerateStream(&dev->opl,
|
||||
&dev->buffer[dev->pos * 2],
|
||||
music_pos_global - dev->pos);
|
||||
|
||||
@@ -1614,7 +1603,7 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv)
|
||||
nuked_drv_update(dev);
|
||||
|
||||
if ((port & 0x0001) == 0x0001) {
|
||||
nuked_write_reg_buffered(&dev->opl, dev->port, val);
|
||||
OPL3_WriteRegBuffered(&dev->opl, dev->port, val);
|
||||
|
||||
switch (dev->port) {
|
||||
case 0x002: /* Timer 1 */
|
||||
|
Reference in New Issue
Block a user