Nuked: Last of the update

This commit is contained in:
Jasmine Iwanek
2024-07-14 15:16:17 -04:00
parent 8056c1bc9a
commit b5c7e59ab7
2 changed files with 287 additions and 276 deletions

View File

@@ -20,6 +20,12 @@
#ifndef SOUND_OPL_NUKED_H #ifndef SOUND_OPL_NUKED_H
#define SOUND_OPL_NUKED_H #define SOUND_OPL_NUKED_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#ifndef OPL_ENABLE_STEREOEXT #ifndef OPL_ENABLE_STEREOEXT
#define OPL_ENABLE_STEREOEXT 0 #define OPL_ENABLE_STEREOEXT 0
#endif #endif
@@ -27,63 +33,66 @@
#define OPL_WRITEBUF_SIZE 1024 #define OPL_WRITEBUF_SIZE 1024
#define OPL_WRITEBUF_DELAY 2 #define OPL_WRITEBUF_DELAY 2
struct chan; typedef struct _opl3_slot opl3_slot;
struct chip; typedef struct _opl3_channel opl3_channel;
typedef struct _opl3_chip opl3_chip;
typedef struct slot { struct _opl3_slot {
struct chan *channel; opl3_channel *channel;
struct chip *chip; opl3_chip *chip;
int16_t out; int16_t out;
int16_t fbmod; int16_t fbmod;
int16_t *mod; int16_t *mod;
int16_t prout; int16_t prout;
int16_t eg_rout; uint16_t eg_rout;
int16_t eg_out; uint16_t eg_out;
uint8_t eg_inc; uint8_t eg_inc;
uint8_t eg_gen; uint8_t eg_gen;
uint8_t eg_rate; uint8_t eg_rate;
uint8_t eg_ksl; uint8_t eg_ksl;
uint8_t *trem; uint8_t *trem;
uint8_t reg_vib; uint8_t reg_vib;
uint8_t reg_type; uint8_t reg_type;
uint8_t reg_ksr; uint8_t reg_ksr;
uint8_t reg_mult; uint8_t reg_mult;
uint8_t reg_ksl; uint8_t reg_ksl;
uint8_t reg_tl; uint8_t reg_tl;
uint8_t reg_ar; uint8_t reg_ar;
uint8_t reg_dr; uint8_t reg_dr;
uint8_t reg_sl; uint8_t reg_sl;
uint8_t reg_rr; uint8_t reg_rr;
uint8_t reg_wf; uint8_t reg_wf;
uint8_t key; uint8_t key;
uint32_t pg_reset; uint32_t pg_reset;
uint32_t pg_phase; uint32_t pg_phase;
uint16_t pg_phase_out; uint16_t pg_phase_out;
uint8_t slot_num; uint8_t slot_num;
} opl3_slot; };
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 #if OPL_ENABLE_STEREOEXT
int32_t leftpan; int32_t leftpan;
int32_t rightpan; int32_t rightpan;
#endif #endif
uint8_t chtype;
uint16_t f_num; uint8_t chtype;
uint8_t block; uint16_t f_num;
uint8_t fb; uint8_t block;
uint8_t con; uint8_t fb;
uint8_t alg; uint8_t con;
uint8_t ksv; uint8_t alg;
uint16_t cha; uint8_t ksv;
uint16_t chb; uint16_t cha;
uint16_t chc; uint16_t chb;
uint16_t chd; uint16_t chc;
uint8_t ch_num; uint16_t chd;
} opl3_channel; uint8_t ch_num;
};
typedef struct _opl3_writebuf { typedef struct _opl3_writebuf {
uint64_t time; uint64_t time;
@@ -91,7 +100,7 @@ typedef struct _opl3_writebuf {
uint8_t data; uint8_t data;
} opl3_writebuf; } opl3_writebuf;
typedef struct chip { struct _opl3_chip {
opl3_channel channel[18]; opl3_channel channel[18];
opl3_slot slot[36]; opl3_slot slot[36];
uint16_t timer; uint16_t timer;
@@ -99,7 +108,7 @@ typedef struct chip {
uint8_t eg_timerrem; uint8_t eg_timerrem;
uint8_t eg_state; uint8_t eg_state;
uint8_t eg_add; uint8_t eg_add;
uint64_t eg_timer_lo; uint8_t eg_timer_lo;
uint8_t newm; uint8_t newm;
uint8_t nts; uint8_t nts;
uint8_t rhy; uint8_t rhy;
@@ -119,26 +128,26 @@ typedef struct chip {
uint8_t rm_tc_bit5; uint8_t rm_tc_bit5;
#if OPL_ENABLE_STEREOEXT #if OPL_ENABLE_STEREOEXT
uint8_t stereoext; uint8_t stereoext;
#endif #endif
// OPL3L // OPL3L
int32_t rateratio; int32_t rateratio;
int32_t samplecnt; int32_t samplecnt;
int32_t oldsamples[4]; int32_t oldsamples[4];
int32_t samples[4]; int32_t samples[4];
uint64_t writebuf_samplecnt; uint64_t writebuf_samplecnt;
uint32_t writebuf_cur; uint32_t writebuf_cur;
uint32_t writebuf_last; uint32_t writebuf_last;
uint64_t writebuf_lasttime; uint64_t writebuf_lasttime;
opl3_writebuf writebuf[OPL_WRITEBUF_SIZE]; opl3_writebuf writebuf[OPL_WRITEBUF_SIZE];
} opl3_chip; };
typedef struct { typedef struct {
opl3_chip opl; opl3_chip opl;
int8_t flags; int8_t flags;
int8_t pad; int8_t pad;
uint16_t port; uint16_t port;
uint8_t status; uint8_t status;
@@ -173,6 +182,19 @@ enum {
CTRL_TMR1_START = 0x01 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*/ #endif /*SOUND_OPL_NUKED_H*/

View File

@@ -85,13 +85,6 @@ enum {
egk_drum = 0x02 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 #ifdef ENABLE_OPL_LOG
int nuked_do_log = 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); typedef void (*envelope_genfunc)(opl3_slot *slot);
static int16_t static int16_t
envelope_calc_exp(uint32_t level) OPL3_EnvelopeCalcExp(uint32_t level)
{ {
if (level > 0x1fff) if (level > 0x1fff)
level = 0x1fff; level = 0x1fff;
@@ -239,7 +232,7 @@ envelope_calc_exp(uint32_t level)
} }
static int16_t 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 out = 0;
uint16_t neg = 0; uint16_t neg = 0;
@@ -254,11 +247,11 @@ envelope_calc_sin0(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[phase & 0xffu]; out = logsinrom[phase & 0xffu];
return (envelope_calc_exp(out + (envelope << 3)) ^ neg); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg);
} }
static int16_t static int16_t
envelope_calc_sin1(uint16_t phase, uint16_t envelope) OPL3_EnvelopeCalcSin1(uint16_t phase, uint16_t envelope)
{ {
uint16_t out = 0; uint16_t out = 0;
@@ -271,11 +264,11 @@ envelope_calc_sin1(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[phase & 0xffu]; out = logsinrom[phase & 0xffu];
return (envelope_calc_exp(out + (envelope << 3))); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
} }
static int16_t static int16_t
envelope_calc_sin2(uint16_t phase, uint16_t envelope) OPL3_EnvelopeCalcSin2(uint16_t phase, uint16_t envelope)
{ {
uint16_t out = 0; uint16_t out = 0;
@@ -286,11 +279,11 @@ envelope_calc_sin2(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[phase & 0xffu]; out = logsinrom[phase & 0xffu];
return (envelope_calc_exp(out + (envelope << 3))); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
} }
static int16_t static int16_t
envelope_calc_sin3(uint16_t phase, uint16_t envelope) OPL3_EnvelopeCalcSin3(uint16_t phase, uint16_t envelope)
{ {
uint16_t out = 0; uint16_t out = 0;
@@ -301,11 +294,11 @@ envelope_calc_sin3(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[phase & 0xffu]; out = logsinrom[phase & 0xffu];
return (envelope_calc_exp(out + (envelope << 3))); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
} }
static int16_t 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 out = 0;
uint16_t neg = 0; uint16_t neg = 0;
@@ -322,11 +315,11 @@ envelope_calc_sin4(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[(phase << 1u) & 0xffu]; out = logsinrom[(phase << 1u) & 0xffu];
return (envelope_calc_exp(out + (envelope << 3)) ^ neg); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg);
} }
static int16_t static int16_t
envelope_calc_sin5(uint16_t phase, uint16_t envelope) OPL3_EnvelopeCalcSin5(uint16_t phase, uint16_t envelope)
{ {
uint16_t out = 0; uint16_t out = 0;
@@ -339,11 +332,11 @@ envelope_calc_sin5(uint16_t phase, uint16_t envelope)
else else
out = logsinrom[(phase << 1u) & 0xffu]; out = logsinrom[(phase << 1u) & 0xffu];
return (envelope_calc_exp(out + (envelope << 3))); return (OPL3_EnvelopeCalcExp(out + (envelope << 3)));
} }
static int16_t static int16_t
envelope_calc_sin6(uint16_t phase, uint16_t envelope) OPL3_EnvelopeCalcSin6(uint16_t phase, uint16_t envelope)
{ {
uint16_t neg = 0; uint16_t neg = 0;
@@ -352,11 +345,11 @@ envelope_calc_sin6(uint16_t phase, uint16_t envelope)
if (phase & 0x0200) if (phase & 0x0200)
neg = 0xffff; neg = 0xffff;
return (envelope_calc_exp(envelope << 3) ^ neg); return (OPL3_EnvelopeCalcExp(envelope << 3) ^ neg);
} }
static int16_t 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 out = 0;
uint16_t neg = 0; uint16_t neg = 0;
@@ -370,22 +363,29 @@ envelope_calc_sin7(uint16_t phase, uint16_t envelope)
out = phase << 3; 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] = { static const envelope_sinfunc envelope_sin[8] = {
envelope_calc_sin0, OPL3_EnvelopeCalcSin0,
envelope_calc_sin1, OPL3_EnvelopeCalcSin1,
envelope_calc_sin2, OPL3_EnvelopeCalcSin2,
envelope_calc_sin3, OPL3_EnvelopeCalcSin3,
envelope_calc_sin4, OPL3_EnvelopeCalcSin4,
envelope_calc_sin5, OPL3_EnvelopeCalcSin5,
envelope_calc_sin6, OPL3_EnvelopeCalcSin6,
envelope_calc_sin7 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 static void
envelope_update_ksl(opl3_slot *slot) OPL3_EnvelopeUpdateKSL(opl3_slot *slot)
{ {
int16_t ksl = (kslrom[slot->channel->f_num >> 6u] << 2) int16_t ksl = (kslrom[slot->channel->f_num >> 6u] << 2)
- ((0x08 - slot->channel->block) << 5); - ((0x08 - slot->channel->block) << 5);
@@ -397,7 +397,7 @@ envelope_update_ksl(opl3_slot *slot)
} }
static void static void
envelope_calc(opl3_slot *slot) OPL3_EnvelopeCalc(opl3_slot *slot)
{ {
uint8_t nonzero; uint8_t nonzero;
uint8_t rate; uint8_t rate;
@@ -531,33 +531,35 @@ envelope_calc(opl3_slot *slot)
} }
static void static void
envelope_key_on(opl3_slot *slot, uint8_t type) OPL3_EnvelopeKeyOn(opl3_slot *slot, uint8_t type)
{ {
slot->key |= type; slot->key |= type;
} }
static void static void
envelope_key_off(opl3_slot *slot, uint8_t type) OPL3_EnvelopeKeyOff(opl3_slot *slot, uint8_t type)
{ {
slot->key &= ~type; slot->key &= ~type;
} }
// Phase Generator
static void 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; 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; chip = slot->chip;
f_num = slot->channel->f_num; f_num = slot->channel->f_num;
if (slot->reg_vib) { if (slot->reg_vib) {
int8_t range;
uint8_t vibpos;
range = (f_num >> 7) & 7; range = (f_num >> 7) & 7;
vibpos = chip->vibpos; vibpos = chip->vibpos;
@@ -625,8 +627,9 @@ phase_generate(opl3_slot *slot)
chip->noise = (noise >> 1) | (n_bit << 22); chip->noise = (noise >> 1) | (n_bit << 22);
} }
// Slot
static void static void
slot_write_20(opl3_slot *slot, uint8_t data) OPL3_SlotWrite20(opl3_slot *slot, uint8_t data)
{ {
if ((data >> 7) & 0x01) if ((data >> 7) & 0x01)
slot->trem = &slot->chip->tremolo; slot->trem = &slot->chip->tremolo;
@@ -640,23 +643,23 @@ slot_write_20(opl3_slot *slot, uint8_t data)
} }
static void 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_ksl = (data >> 6) & 0x03;
slot->reg_tl = data & 0x3f; slot->reg_tl = data & 0x3f;
envelope_update_ksl(slot); OPL3_EnvelopeUpdateKSL(slot);
} }
static void 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_ar = (data >> 4) & 0x0f;
slot->reg_dr = data & 0x0f; slot->reg_dr = data & 0x0f;
} }
static void 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; slot->reg_sl = (data >> 4) & 0x0f;
@@ -667,7 +670,7 @@ slot_write_80(opl3_slot *slot, uint8_t data)
} }
static void static void
slot_write_e0(opl3_slot *slot, uint8_t data) OPL3_SlotWriteE0(opl3_slot *slot, uint8_t data)
{ {
slot->reg_wf = data & 0x07; slot->reg_wf = data & 0x07;
@@ -676,14 +679,13 @@ slot_write_e0(opl3_slot *slot, uint8_t data)
} }
static void 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->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out);
slot->eg_out);
} }
static void static void
slot_calc_fb(opl3_slot *slot) OPL3_SlotCalcFB(opl3_slot *slot)
{ {
if (slot->channel->fb != 0x00) if (slot->channel->fb != 0x00)
slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb);
@@ -695,10 +697,10 @@ slot_calc_fb(opl3_slot *slot)
// Channel // Channel
static void static void
channel_setup_alg(opl3_channel *channel); OPL3_ChannelSetupAlg(opl3_channel *channel);
static void static void
channel_update_rhythm(opl3_chip *chip, uint8_t data) OPL3_ChannelUpdateRhythm(opl3_chip *chip, uint8_t data)
{ {
opl3_channel *channel6; opl3_channel *channel6;
opl3_channel *channel7; opl3_channel *channel7;
@@ -726,55 +728,55 @@ channel_update_rhythm(opl3_chip *chip, uint8_t data)
for (chnum = 6; chnum < 9; chnum++) for (chnum = 6; chnum < 9; chnum++)
chip->channel[chnum].chtype = ch_drum; chip->channel[chnum].chtype = ch_drum;
channel_setup_alg(channel6); OPL3_ChannelSetupAlg(channel6);
channel_setup_alg(channel7); OPL3_ChannelSetupAlg(channel7);
channel_setup_alg(channel8); OPL3_ChannelSetupAlg(channel8);
// hh // hh
if (chip->rhy & 0x01) if (chip->rhy & 0x01)
envelope_key_on(channel7->slotz[0], egk_drum); OPL3_EnvelopeKeyOn(channel7->slotz[0], egk_drum);
else else
envelope_key_off(channel7->slotz[0], egk_drum); OPL3_EnvelopeKeyOff(channel7->slotz[0], egk_drum);
// tc // tc
if (chip->rhy & 0x02) if (chip->rhy & 0x02)
envelope_key_on(channel8->slotz[1], egk_drum); OPL3_EnvelopeKeyOn(channel8->slotz[1], egk_drum);
else else
envelope_key_off(channel8->slotz[1], egk_drum); OPL3_EnvelopeKeyOff(channel8->slotz[1], egk_drum);
// tom // tom
if (chip->rhy & 0x04) if (chip->rhy & 0x04)
envelope_key_on(channel8->slotz[0], egk_drum); OPL3_EnvelopeKeyOn(channel8->slotz[0], egk_drum);
else else
envelope_key_off(channel8->slotz[0], egk_drum); OPL3_EnvelopeKeyOff(channel8->slotz[0], egk_drum);
// sd // sd
if (chip->rhy & 0x08) if (chip->rhy & 0x08)
envelope_key_on(channel7->slotz[1], egk_drum); OPL3_EnvelopeKeyOn(channel7->slotz[1], egk_drum);
else else
envelope_key_off(channel7->slotz[1], egk_drum); OPL3_EnvelopeKeyOff(channel7->slotz[1], egk_drum);
// bd // bd
if (chip->rhy & 0x10) { if (chip->rhy & 0x10) {
envelope_key_on(channel6->slotz[0], egk_drum); OPL3_EnvelopeKeyOn(channel6->slotz[0], egk_drum);
envelope_key_on(channel6->slotz[1], egk_drum); OPL3_EnvelopeKeyOn(channel6->slotz[1], egk_drum);
} else { } else {
envelope_key_off(channel6->slotz[0], egk_drum); OPL3_EnvelopeKeyOff(channel6->slotz[0], egk_drum);
envelope_key_off(channel6->slotz[1], egk_drum); OPL3_EnvelopeKeyOff(channel6->slotz[1], egk_drum);
} }
} else { } else {
for (chnum = 6; chnum < 9; chnum++) { for (chnum = 6; chnum < 9; chnum++) {
chip->channel[chnum].chtype = ch_2op; chip->channel[chnum].chtype = ch_2op;
channel_setup_alg(&chip->channel[chnum]); OPL3_ChannelSetupAlg(&chip->channel[chnum]);
envelope_key_off(chip->channel[chnum].slotz[0], egk_drum); OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[0], egk_drum);
envelope_key_off(chip->channel[chnum].slotz[1], egk_drum); OPL3_EnvelopeKeyOff(chip->channel[chnum].slotz[1], egk_drum);
} }
} }
} }
static void 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) if (channel->chip->newm && channel->chtype == ch_4op2)
return; return;
@@ -783,20 +785,20 @@ channel_write_a0(opl3_channel *channel, uint8_t data)
channel->ksv = (channel->block << 1) channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
envelope_update_ksl(channel->slotz[0]); OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
envelope_update_ksl(channel->slotz[1]); OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op) { if (channel->chip->newm && channel->chtype == ch_4op) {
channel->pair->f_num = channel->f_num; channel->pair->f_num = channel->f_num;
channel->pair->ksv = channel->ksv; channel->pair->ksv = channel->ksv;
envelope_update_ksl(channel->pair->slotz[0]); OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
envelope_update_ksl(channel->pair->slotz[1]); OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
} }
} }
static void 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) if (channel->chip->newm && channel->chtype == ch_4op2)
return; return;
@@ -806,21 +808,21 @@ channel_write_b0(opl3_channel *channel, uint8_t data)
channel->ksv = (channel->block << 1) channel->ksv = (channel->block << 1)
| ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
envelope_update_ksl(channel->slotz[0]); OPL3_EnvelopeUpdateKSL(channel->slotz[0]);
envelope_update_ksl(channel->slotz[1]); OPL3_EnvelopeUpdateKSL(channel->slotz[1]);
if (channel->chip->newm && channel->chtype == ch_4op) { if (channel->chip->newm && channel->chtype == ch_4op) {
channel->pair->f_num = channel->f_num; channel->pair->f_num = channel->f_num;
channel->pair->block = channel->block; channel->pair->block = channel->block;
channel->pair->ksv = channel->ksv; channel->pair->ksv = channel->ksv;
envelope_update_ksl(channel->pair->slotz[0]); OPL3_EnvelopeUpdateKSL(channel->pair->slotz[0]);
envelope_update_ksl(channel->pair->slotz[1]); OPL3_EnvelopeUpdateKSL(channel->pair->slotz[1]);
} }
} }
static void static void
channel_setup_alg(opl3_channel *channel) OPL3_ChannelSetupAlg(opl3_channel *channel)
{ {
if (channel->chtype == ch_drum) { if (channel->chtype == ch_drum) {
if (channel->ch_num == 7 || channel->ch_num == 8) { if (channel->ch_num == 7 || channel->ch_num == 8) {
@@ -929,30 +931,31 @@ channel_setup_alg(opl3_channel *channel)
} }
static void static void
channel_update_alg(opl3_channel *channel) OPL3_ChannelUpdateAlg(opl3_channel *channel)
{ {
channel->alg = channel->con; channel->alg = channel->con;
if (channel->chip->newm) { if (channel->chip->newm) {
if (channel->chtype == ch_4op) { 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->alg = 0x08;
channel_setup_alg(channel->pair); OPL3_ChannelSetupAlg(channel->pair);
} else if (channel->chtype == ch_4op2) { } 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->pair->alg = 0x08;
channel_setup_alg(channel); OPL3_ChannelSetupAlg(channel);
} else } else
channel_setup_alg(channel); OPL3_ChannelSetupAlg(channel);
} else } else
channel_setup_alg(channel); OPL3_ChannelSetupAlg(channel);
} }
static void 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->fb = (data & 0x0e) >> 1;
channel->con = data & 0x01; channel->con = data & 0x01;
OPL3_ChannelUpdateAlg(channel);
if (channel->chip->newm) { if (channel->chip->newm) {
channel->cha = ((data >> 4) & 0x01) ? ~0 : 0; channel->cha = ((data >> 4) & 0x01) ? ~0 : 0;
@@ -975,7 +978,7 @@ channel_write_c0(opl3_channel *channel, uint8_t data)
#if OPL_ENABLE_STEREOEXT #if OPL_ENABLE_STEREOEXT
static void static void
channel_write_d0(opl3_channel *channel, uint8_t data) OPL3_ChannelWriteD0(opl3_channel *channel, uint8_t data)
{ {
if (channel->chip->stereoext) { if (channel->chip->stereoext) {
channel->leftpan = panpot_lut[data ^ 0xffu]; channel->leftpan = panpot_lut[data ^ 0xffu];
@@ -985,45 +988,45 @@ channel_write_d0(opl3_channel *channel, uint8_t data)
#endif #endif
static void static void
channel_key_on(opl3_channel *channel) OPL3_ChannelKeyOn(opl3_channel *channel)
{ {
if (channel->chip->newm) { if (channel->chip->newm) {
if (channel->chtype == ch_4op) { if (channel->chtype == ch_4op) {
envelope_key_on(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
envelope_key_on(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
envelope_key_on(channel->pair->slotz[0], egk_norm); OPL3_EnvelopeKeyOn(channel->pair->slotz[0], egk_norm);
envelope_key_on(channel->pair->slotz[1], egk_norm); OPL3_EnvelopeKeyOn(channel->pair->slotz[1], egk_norm);
} else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) {
envelope_key_on(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
envelope_key_on(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
} }
} else { } else {
envelope_key_on(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[0], egk_norm);
envelope_key_on(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOn(channel->slotz[1], egk_norm);
} }
} }
static void static void
channel_key_off(opl3_channel *channel) OPL3_ChannelKeyOff(opl3_channel *channel)
{ {
if (channel->chip->newm) { if (channel->chip->newm) {
if (channel->chtype == ch_4op) { if (channel->chtype == ch_4op) {
envelope_key_off(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
envelope_key_off(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
envelope_key_off(channel->pair->slotz[0], egk_norm); OPL3_EnvelopeKeyOff(channel->pair->slotz[0], egk_norm);
envelope_key_off(channel->pair->slotz[1], egk_norm); OPL3_EnvelopeKeyOff(channel->pair->slotz[1], egk_norm);
} else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) {
envelope_key_off(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
envelope_key_off(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
} }
} else { } else {
envelope_key_off(channel->slotz[0], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[0], egk_norm);
envelope_key_off(channel->slotz[1], egk_norm); OPL3_EnvelopeKeyOff(channel->slotz[1], egk_norm);
} }
} }
static void static void
channel_set_4op(opl3_chip *chip, uint8_t data) OPL3_ChannelSet4Op(opl3_chip *chip, uint8_t data)
{ {
uint8_t chnum; uint8_t chnum;
@@ -1036,36 +1039,36 @@ channel_set_4op(opl3_chip *chip, uint8_t data)
if ((data >> bit) & 0x01) { if ((data >> bit) & 0x01) {
chip->channel[chnum].chtype = ch_4op; chip->channel[chnum].chtype = ch_4op;
chip->channel[chnum + 3u].chtype = ch_4op2; chip->channel[chnum + 3u].chtype = ch_4op2;
channel_update_alg(&chip->channel[chnum]); OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
} else { } else {
chip->channel[chnum].chtype = ch_2op; chip->channel[chnum].chtype = ch_2op;
chip->channel[chnum + 3u].chtype = ch_2op; chip->channel[chnum + 3u].chtype = ch_2op;
channel_update_alg(&chip->channel[chnum]); OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
channel_update_alg(&chip->channel[chnum + 3u]); OPL3_ChannelUpdateAlg(&chip->channel[chnum + 3u]);
} }
} }
} }
static void static void
process_slot(opl3_slot *slot) OPL3_ProcessSlot(opl3_slot *slot)
{ {
slot_calc_fb(slot); OPL3_SlotCalcFB(slot);
envelope_calc(slot); OPL3_EnvelopeCalc(slot);
phase_generate(slot); OPL3_PhaseGenerate(slot);
slot_generate(slot); OPL3_SlotGenerate(slot);
} }
static inline void 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_chip *chip = (opl3_chip *) priv;
opl3_channel *channel; opl3_channel *channel;
opl3_writebuf *writebuf; opl3_writebuf *writebuf;
int16_t **out; int16_t **out;
int32_t mix[2]; int32_t mix[2];
int16_t accm;
int16_t shift = 0;
uint8_t i; uint8_t i;
int16_t accm;
uint8_t shift = 0;
buf4[1] = chip->mixbuff[1]; buf4[1] = chip->mixbuff[1];
buf4[3] = chip->mixbuff[3]; buf4[3] = chip->mixbuff[3];
@@ -1075,7 +1078,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
#else #else
for (i = 0; i < 36; i++) for (i = 0; i < 36; i++)
#endif #endif
process_slot(&chip->slot[i]); OPL3_ProcessSlot(&chip->slot[i]);
mix[0] = mix[1] = 0; mix[0] = mix[1] = 0;
@@ -1084,11 +1087,11 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
out = channel->out; 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 #if OPL_ENABLE_STEREOEXT
mix[0] += (int32_t) ((accm * channel->leftpan) >> 16); mix[0] += (int16_t) ((accm * channel->leftpan) >> 16);
#else #else
mix[0] += (int32_t) (accm & channel->cha); mix[0] += (int16_t) (accm & channel->cha);
#endif #endif
mix[1] += (int32_t) (accm & channel->chc); mix[1] += (int16_t) (accm & channel->chc);
} }
chip->mixbuff[0] = mix[0]; chip->mixbuff[0] = mix[0];
@@ -1096,7 +1099,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
#if OPL_QUIRK_CHANNELSAMPLEDELAY #if OPL_QUIRK_CHANNELSAMPLEDELAY
for (i = 15; i < 18; i++) for (i = 15; i < 18; i++)
process_slot(&chip->slot[i]); OPL3_ProcessSlot(&chip->slot[i]);
#endif #endif
buf4[0] = chip->mixbuff[0]; buf4[0] = chip->mixbuff[0];
@@ -1104,7 +1107,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
#if OPL_QUIRK_CHANNELSAMPLEDELAY #if OPL_QUIRK_CHANNELSAMPLEDELAY
for (i = 18; i < 33; i++) for (i = 18; i < 33; i++)
process_slot(&chip->slot[i]); OPL3_ProcessSlot(&chip->slot[i]);
#endif #endif
mix[0] = mix[1] = 0; mix[0] = mix[1] = 0;
@@ -1112,13 +1115,13 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
for (i = 0; i < 18; i++) { for (i = 0; i < 18; i++) {
channel = &chip->channel[i]; channel = &chip->channel[i];
out = channel->out; 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 #if OPL_ENABLE_STEREOEXT
mix[0] += (int32_t) ((accm * channel->rightpan) >> 16); mix[0] += (int16_t) ((accm * channel->rightpan) >> 16);
#else #else
mix[0] += (int32_t) (accm & channel->chb); mix[0] += (int16_t) (accm & channel->chb);
#endif #endif
mix[1] += (int32_t) (accm & channel->chd); mix[1] += (int16_t) (accm & channel->chd);
} }
chip->mixbuff[1] = mix[0]; chip->mixbuff[1] = mix[0];
@@ -1126,7 +1129,7 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
#if OPL_QUIRK_CHANNELSAMPLEDELAY #if OPL_QUIRK_CHANNELSAMPLEDELAY
for (i = 33; i < 36; i++) for (i = 33; i < 36; i++)
process_slot(&chip->slot[i]); OPL3_ProcessSlot(&chip->slot[i]);
#endif #endif
if ((chip->timer & 0x3f) == 0x3f) if ((chip->timer & 0x3f) == 0x3f)
@@ -1166,13 +1169,13 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
chip->eg_state ^= 1; 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)) if (!(writebuf->reg & 0x200))
break; break;
writebuf->reg &= 0x01ff; 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; chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE;
} }
@@ -1181,84 +1184,79 @@ nuked_generate_4ch(void *priv, int32_t *buf4)
} }
void void
nuked_generate(opl3_chip *chip, int32_t *buf) OPL3_Generate(opl3_chip *chip, int32_t *buf)
{ {
int32_t samples[4]; int32_t samples[4];
nuked_generate_4ch(chip, samples); OPL3_Generate4Ch(chip, samples);
buf[0] = samples[0]; buf[0] = samples[0];
buf[1] = samples[1]; buf[1] = samples[1];
} }
void void
nuked_generate_4ch_resampled(opl3_chip *chip, int32_t *buf4) OPL3_Generate4ChResampled(opl3_chip *chip, int32_t *buf4)
{ {
while (chip->samplecnt >= chip->rateratio) { while (chip->samplecnt >= chip->rateratio) {
chip->oldsamples[0] = chip->samples[0]; chip->oldsamples[0] = chip->samples[0];
chip->oldsamples[1] = chip->samples[1]; chip->oldsamples[1] = chip->samples[1];
chip->oldsamples[2] = chip->samples[2]; chip->oldsamples[2] = chip->samples[2];
chip->oldsamples[3] = chip->samples[3]; chip->oldsamples[3] = chip->samples[3];
nuked_generate_4ch(chip, chip->samples); OPL3_Generate4Ch(chip, chip->samples);
chip->samplecnt -= chip->rateratio; chip->samplecnt -= chip->rateratio;
} }
buf4[0] = (int32_t) ((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) buf4[0] = (int32_t) ((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
+ chip->samples[0] * chip->samplecnt) + chip->samples[0] * chip->samplecnt) / chip->rateratio);
/ chip->rateratio);
buf4[1] = (int32_t) ((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) buf4[1] = (int32_t) ((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
+ chip->samples[1] * chip->samplecnt) + chip->samples[1] * chip->samplecnt) / chip->rateratio);
/ chip->rateratio);
buf4[2] = (int32_t) ((chip->oldsamples[2] * (chip->rateratio - chip->samplecnt) buf4[2] = (int32_t) ((chip->oldsamples[2] * (chip->rateratio - chip->samplecnt)
+ chip->samples[2] * chip->samplecnt) + chip->samples[2] * chip->samplecnt) / chip->rateratio);
/ chip->rateratio);
buf4[3] = (int32_t) ((chip->oldsamples[3] * (chip->rateratio - chip->samplecnt) buf4[3] = (int32_t) ((chip->oldsamples[3] * (chip->rateratio - chip->samplecnt)
+ chip->samples[3] * chip->samplecnt) + chip->samples[3] * chip->samplecnt) / chip->rateratio);
/ chip->rateratio);
chip->samplecnt += 1 << RSM_FRAC; chip->samplecnt += 1 << RSM_FRAC;
} }
void void
nuked_generate_resampled(opl3_chip *chip, int32_t *buf4) OPL3_GenerateResampled(opl3_chip *chip, int32_t *buf)
{ {
int32_t samples[4]; int32_t samples[4];
nuked_generate_4ch_resampled(chip, samples); OPL3_Generate4ChResampled(chip, samples);
buf4[0] = samples[0]; buf[0] = samples[0];
buf4[1] = samples[1]; buf[1] = samples[1];
} }
void void
nuked_init(opl3_chip *chip, uint32_t samplerate) OPL3_Reset(opl3_chip *chip, uint32_t samplerate)
{ {
opl3_slot *slot; opl3_slot *slot;
opl3_channel *channel; opl3_channel *channel;
uint8_t i;
uint8_t local_ch_slot; uint8_t local_ch_slot;
memset(chip, 0x00, sizeof(opl3_chip)); memset(chip, 0x00, sizeof(opl3_chip));
for (i = 0; i < 36; i++) { for (uint8_t slotnum = 0; slotnum < 36; slotnum++) {
slot = &chip->slot[i]; slot = &chip->slot[slotnum];
slot->chip = chip; slot->chip = chip;
slot->mod = &chip->zeromod; slot->mod = &chip->zeromod;
slot->eg_rout = 0x01ff; slot->eg_rout = 0x01ff;
slot->eg_out = 0x01ff; slot->eg_out = 0x01ff;
slot->eg_gen = envelope_gen_num_release; slot->eg_gen = envelope_gen_num_release;
slot->trem = (uint8_t *) &chip->zeromod; slot->trem = (uint8_t *) &chip->zeromod;
slot->slot_num = i; slot->slot_num = slotnum;
} }
for (i = 0; i < 18; i++) { for (uint8_t channum = 0; channum < 18; channum++) {
channel = &chip->channel[i]; channel = &chip->channel[channum];
local_ch_slot = ch_slot[i]; local_ch_slot = ch_slot[channum];
channel->slotz[0] = &chip->slot[local_ch_slot]; channel->slotz[0] = &chip->slot[local_ch_slot];
channel->slotz[1] = &chip->slot[local_ch_slot + 3u]; channel->slotz[1] = &chip->slot[local_ch_slot + 3u];
chip->slot[local_ch_slot].channel = channel; chip->slot[local_ch_slot].channel = channel;
chip->slot[local_ch_slot + 3u].channel = channel; chip->slot[local_ch_slot + 3u].channel = channel;
if ((i % 9) < 3) if ((channum % 9) < 3)
channel->pair = &chip->channel[i + 3u]; channel->pair = &chip->channel[channum + 3u];
else if ((i % 9) < 6) else if ((channum % 9) < 6)
channel->pair = &chip->channel[i - 3u]; channel->pair = &chip->channel[channum - 3u];
channel->chip = chip; channel->chip = chip;
channel->out[0] = &chip->zeromod; channel->out[0] = &chip->zeromod;
@@ -1272,9 +1270,9 @@ nuked_init(opl3_chip *chip, uint32_t samplerate)
channel->leftpan = 0x10000; channel->leftpan = 0x10000;
channel->rightpan = 0x10000; channel->rightpan = 0x10000;
#endif #endif
channel->ch_num = i; channel->ch_num = channum;
channel_setup_alg(channel); OPL3_ChannelSetupAlg(channel);
} }
chip->noise = 1; chip->noise = 1;
@@ -1291,15 +1289,6 @@ nuked_init(opl3_chip *chip, uint32_t samplerate)
#endif #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 uint16_t
nuked_write_addr(void *priv, uint16_t port, uint8_t val) 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 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; opl3_chip *chip = (opl3_chip *) priv;
uint8_t high = (reg >> 8) & 0x01; uint8_t high = (reg >> 8) & 0x01;
@@ -1325,7 +1314,7 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val)
if (high) if (high)
switch (regm & 0x0f) { switch (regm & 0x0f) {
case 0x04: case 0x04:
channel_set_4op(chip, val); OPL3_ChannelSet4Op(chip, val);
break; break;
case 0x05: case 0x05:
@@ -1352,72 +1341,72 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val)
case 0x20: case 0x20:
case 0x30: case 0x30:
if (ad_slot[regm & 0x1fu] >= 0) 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; break;
case 0x40: case 0x40:
case 0x50: case 0x50:
if (ad_slot[regm & 0x1fu] >= 0) 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; break;
case 0x60: case 0x60:
case 0x70: case 0x70:
if (ad_slot[regm & 0x1fu] >= 0) 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; break;
case 0x80: case 0x80:
case 0x90: case 0x90:
if (ad_slot[regm & 0x1fu] >= 0) 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; break;
case 0xa0: case 0xa0:
if ((regm & 0x0f) < 9) if ((regm & 0x0f) < 9)
channel_write_a0(&chip->channel[9u * high + (regm & 0x0fu)], val); OPL3_ChannelWriteA0(&chip->channel[9u * high + (regm & 0x0fu)], val);
break; break;
case 0xb0: case 0xb0:
if (regm == 0xbd && !high) { if (regm == 0xbd && !high) {
chip->tremoloshift = (((val >> 7) ^ 1) << 1) + 2; chip->tremoloshift = (((val >> 7) ^ 1) << 1) + 2;
chip->vibshift = ((val >> 6) & 0x01) ^ 1; chip->vibshift = ((val >> 6) & 0x01) ^ 1;
channel_update_rhythm(chip, val); OPL3_ChannelUpdateRhythm(chip, val);
} else if ((regm & 0x0f) < 9) { } 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) if (val & 0x20)
channel_key_on(&chip->channel[9u * high + (regm & 0x0fu)]); OPL3_ChannelKeyOn(&chip->channel[9u * high + (regm & 0x0fu)]);
else else
channel_key_off(&chip->channel[9u * high + (regm & 0x0fu)]); OPL3_ChannelKeyOff(&chip->channel[9u * high + (regm & 0x0fu)]);
} }
break; break;
case 0xc0: case 0xc0:
if ((regm & 0x0f) < 9) if ((regm & 0x0f) < 9)
channel_write_c0(&chip->channel[9u * high + (regm & 0x0fu)], val); OPL3_ChannelWriteC0(&chip->channel[9u * high + (regm & 0x0fu)], val);
break; break;
#if OPL_ENABLE_STEREOEXT #if OPL_ENABLE_STEREOEXT
case 0xd0: case 0xd0:
if ((regm & 0x0f) < 9) if ((regm & 0x0f) < 9)
channel_write_d0(&chip->channel[9u * high + (regm & 0x0fu)], val); OPL3_ChannelWriteD0(&chip->channel[9u * high + (regm & 0x0fu)], val);
break; break;
#endif #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: default:
break; break;
} }
} }
void 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; opl3_chip *chip = (opl3_chip *) priv;
uint64_t time1; uint64_t time1;
@@ -1429,7 +1418,7 @@ nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val)
writebuf = &chip->writebuf[writebuf_last]; writebuf = &chip->writebuf[writebuf_last];
if (writebuf->reg & 0x0200) { 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_cur = (writebuf_last + 1) % OPL_WRITEBUF_SIZE;
chip->writebuf_samplecnt = writebuf->time; chip->writebuf_samplecnt = writebuf->time;
@@ -1449,12 +1438,12 @@ nuked_write_reg_buffered(void *priv, uint16_t reg, uint8_t val)
} }
void 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]; int32_t samples[4];
for (uint_fast32_t i = 0; i < numsamples; i++) { for (uint_fast32_t i = 0; i < numsamples; i++) {
nuked_generate_4ch_resampled(chip, samples); OPL3_Generate4Ch(chip, samples);
sndptr1[0] = samples[0]; sndptr1[0] = samples[0];
sndptr1[1] = samples[1]; sndptr1[1] = samples[1];
sndptr2[0] = samples[2]; sndptr2[0] = samples[2];
@@ -1465,10 +1454,10 @@ nuked_generate_4ch_stream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, u
} }
void 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++) { for (uint_fast32_t i = 0; i < numsamples; i++) {
nuked_generate_resampled(chip, sndptr); OPL3_Generate(chip, sndptr);
sndptr += 2; sndptr += 2;
} }
} }
@@ -1549,7 +1538,7 @@ nuked_drv_init(const device_t *info)
dev->status = 0x06; dev->status = 0x06;
/* Initialize the NukedOPL object. */ /* 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[0], nuked_timer_1, dev, 0);
timer_add(&dev->timers[1], nuked_timer_2, 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) if (dev->pos >= music_pos_global)
return dev->buffer; return dev->buffer;
nuked_generate_stream(&dev->opl, OPL3_GenerateStream(&dev->opl,
&dev->buffer[dev->pos * 2], &dev->buffer[dev->pos * 2],
music_pos_global - dev->pos); music_pos_global - dev->pos);
@@ -1614,7 +1603,7 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv)
nuked_drv_update(dev); nuked_drv_update(dev);
if ((port & 0x0001) == 0x0001) { if ((port & 0x0001) == 0x0001) {
nuked_write_reg_buffered(&dev->opl, dev->port, val); OPL3_WriteRegBuffered(&dev->opl, dev->port, val);
switch (dev->port) { switch (dev->port) {
case 0x002: /* Timer 1 */ case 0x002: /* Timer 1 */