OPL: quad output
now that we have this new dispatch output method
This commit is contained in:
parent
6c834524aa
commit
fd9b1dd0f5
|
@ -946,10 +946,8 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
|
|||
}
|
||||
}
|
||||
|
||||
static void OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
||||
static void OPL3_ChannelUpdateAlg(opl3_channel *channel)
|
||||
{
|
||||
channel->fb = (data & 0x0e) >> 1;
|
||||
channel->con = data & 0x01;
|
||||
channel->alg = channel->con;
|
||||
if (channel->chip->newm)
|
||||
{
|
||||
|
@ -974,14 +972,25 @@ static void OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
|||
{
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void 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;
|
||||
channel->chb = ((data >> 5) & 0x01) ? ~0 : 0;
|
||||
channel->chc = ((data >> 6) & 0x01) ? ~0 : 0;
|
||||
channel->chd = ((data >> 7) & 0x01) ? ~0 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->cha = channel->chb = (uint16_t)~0;
|
||||
// TODO: Verify on real chip if DAC2 output is disabled in compat mode
|
||||
channel->chc = channel->chd = 0;
|
||||
}
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
if (!channel->chip->stereoext)
|
||||
|
@ -1066,11 +1075,14 @@ static void OPL3_ChannelSet4Op(opl3_chip *chip, uint8_t data)
|
|||
{
|
||||
chip->channel[chnum].chtype = ch_4op;
|
||||
chip->channel[chnum + 3].chtype = ch_4op2;
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->channel[chnum].chtype = ch_2op;
|
||||
chip->channel[chnum + 3].chtype = ch_2op;
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum+3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1096,17 +1108,18 @@ static void OPL3_ProcessSlot(opl3_slot *slot)
|
|||
OPL3_SlotGenerate(slot);
|
||||
}
|
||||
|
||||
void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
||||
inline void OPL3_Generate4Ch(opl3_chip *chip, int16_t *buf4)
|
||||
{
|
||||
opl3_channel *channel;
|
||||
opl3_writebuf *writebuf;
|
||||
int16_t **out;
|
||||
int32_t mix;
|
||||
int32_t mix[2];
|
||||
uint8_t ii;
|
||||
int16_t accm;
|
||||
uint8_t shift = 0;
|
||||
|
||||
buf[1] = OPL3_ClipSample(chip->mixbuff[1]);
|
||||
buf4[1] = OPL3_ClipSample(chip->mixbuff[1]);
|
||||
buf4[3] = OPL3_ClipSample(chip->mixbuff[3]);
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 0; ii < 15; ii++)
|
||||
|
@ -1117,7 +1130,7 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
OPL3_ProcessSlot(&chip->slot[ii]);
|
||||
}
|
||||
|
||||
mix = 0;
|
||||
mix[0] = mix[1] = 0;
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
channel = &chip->channel[ii];
|
||||
|
@ -1125,12 +1138,14 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix += (int16_t)((accm * channel->leftpan) >> 16);
|
||||
mix[0] += (int16_t)((accm * channel->leftpan) >> 16);
|
||||
#else
|
||||
mix += (int16_t)(accm & channel->cha);
|
||||
#endif
|
||||
mix[0] += (int16_t)(accm & channel->cha);
|
||||
#endif
|
||||
mix[1] += (int16_t)(accm & channel->chc);
|
||||
}
|
||||
chip->mixbuff[0] = mix;
|
||||
chip->mixbuff[0] = mix[0];
|
||||
chip->mixbuff[2] = mix[1];
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 15; ii < 18; ii++)
|
||||
|
@ -1139,7 +1154,8 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
buf[0] = OPL3_ClipSample(chip->mixbuff[0]);
|
||||
buf4[0] = OPL3_ClipSample(chip->mixbuff[0]);
|
||||
buf4[2] = OPL3_ClipSample(chip->mixbuff[2]);
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 18; ii < 33; ii++)
|
||||
|
@ -1148,7 +1164,7 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
mix = 0;
|
||||
mix[0] = mix[1] = 0;
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
channel = &chip->channel[ii];
|
||||
|
@ -1156,12 +1172,14 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix += (int16_t)((accm * channel->rightpan) >> 16);
|
||||
mix[0] += (int16_t)((accm * channel->rightpan) >> 16);
|
||||
#else
|
||||
mix += (int16_t)(accm & channel->chb);
|
||||
#endif
|
||||
mix[0] += (int16_t)(accm & channel->chb);
|
||||
#endif
|
||||
mix[1] += (int16_t)(accm & channel->chd);
|
||||
}
|
||||
chip->mixbuff[1] = mix;
|
||||
chip->mixbuff[1] = mix[0];
|
||||
chip->mixbuff[3] = mix[1];
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 33; ii < 36; ii++)
|
||||
|
@ -1236,22 +1254,44 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
chip->writebuf_samplecnt++;
|
||||
}
|
||||
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf)
|
||||
void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
||||
{
|
||||
int16_t samples[4];
|
||||
OPL3_Generate4Ch(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void OPL3_Generate4ChResampled(opl3_chip *chip, int16_t *buf4)
|
||||
{
|
||||
while (chip->samplecnt >= chip->rateratio)
|
||||
{
|
||||
chip->oldsamples[0] = chip->samples[0];
|
||||
chip->oldsamples[1] = chip->samples[1];
|
||||
OPL3_Generate(chip, chip->samples);
|
||||
chip->oldsamples[2] = chip->samples[2];
|
||||
chip->oldsamples[3] = chip->samples[3];
|
||||
OPL3_Generate4Ch(chip, chip->samples);
|
||||
chip->samplecnt -= chip->rateratio;
|
||||
}
|
||||
buf[0] = (int16_t)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf[1] = (int16_t)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[0] = (int16_t)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[1] = (int16_t)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[2] = (int16_t)((chip->oldsamples[2] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[2] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[3] = (int16_t)((chip->oldsamples[3] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[3] * chip->samplecnt) / chip->rateratio);
|
||||
chip->samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf)
|
||||
{
|
||||
int16_t samples[4];
|
||||
OPL3_Generate4ChResampled(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void OPL3_Reset(opl3_chip *chip, uint32_t samplerate)
|
||||
{
|
||||
opl3_slot *slot;
|
||||
|
@ -1464,9 +1504,26 @@ void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v)
|
|||
chip->writebuf_last = (writebuf_last + 1) % OPL_WRITEBUF_SIZE;
|
||||
}
|
||||
|
||||
void OPL3_Generate4ChStream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples)
|
||||
{
|
||||
uint_fast32_t i;
|
||||
int16_t samples[4];
|
||||
|
||||
for(i = 0; i < numsamples; i++)
|
||||
{
|
||||
OPL3_Generate4ChResampled(chip, samples);
|
||||
sndptr1[0] = samples[0];
|
||||
sndptr1[1] = samples[1];
|
||||
sndptr2[0] = samples[2];
|
||||
sndptr2[1] = samples[3];
|
||||
sndptr1 += 2;
|
||||
sndptr2 += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples)
|
||||
{
|
||||
uint32_t i;
|
||||
uint_fast32_t i;
|
||||
|
||||
for(i = 0; i < numsamples; i++)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,7 @@ struct _opl3_channel {
|
|||
uint8_t alg;
|
||||
uint8_t ksv;
|
||||
uint16_t cha, chb;
|
||||
uint16_t chc, chd;
|
||||
uint8_t ch_num;
|
||||
uint8_t muted;
|
||||
};
|
||||
|
@ -129,7 +130,7 @@ struct _opl3_chip {
|
|||
uint8_t tremoloshift;
|
||||
uint32_t noise;
|
||||
int16_t zeromod;
|
||||
int32_t mixbuff[2];
|
||||
int32_t mixbuff[4];
|
||||
uint8_t rm_hh_bit2;
|
||||
uint8_t rm_hh_bit3;
|
||||
uint8_t rm_hh_bit7;
|
||||
|
@ -144,8 +145,8 @@ struct _opl3_chip {
|
|||
/* OPL3L */
|
||||
int32_t rateratio;
|
||||
int32_t samplecnt;
|
||||
int16_t oldsamples[2];
|
||||
int16_t samples[2];
|
||||
int16_t oldsamples[4];
|
||||
int16_t samples[4];
|
||||
|
||||
uint64_t writebuf_samplecnt;
|
||||
uint32_t writebuf_cur;
|
||||
|
@ -161,6 +162,10 @@ void OPL3_WriteReg(opl3_chip *chip, uint16_t reg, uint8_t v);
|
|||
void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v);
|
||||
void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples);
|
||||
|
||||
void OPL3_Generate4Ch(opl3_chip *chip, int16_t *buf4);
|
||||
void OPL3_Generate4ChResampled(opl3_chip *chip, int16_t *buf4);
|
||||
void OPL3_Generate4ChStream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -160,12 +160,12 @@ const int orderedOpsL[4]={
|
|||
#define ADDR_LR_FB_ALG 0xc0
|
||||
|
||||
void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
||||
static short o[2];
|
||||
static int os[2];
|
||||
static short o[4];
|
||||
static int os[4];
|
||||
static ymfm::ymfm_output<2> aOut;
|
||||
|
||||
for (size_t h=0; h<len; h++) {
|
||||
os[0]=0; os[1]=0;
|
||||
os[0]=0; os[1]=0; os[2]=0; os[3]=0;
|
||||
if (!writes.empty() && --delay<0) {
|
||||
delay=1;
|
||||
QueuedWrite& w=writes.front();
|
||||
|
@ -194,11 +194,14 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
|||
}
|
||||
|
||||
if (downsample) {
|
||||
OPL3_GenerateResampled(&fm,o);
|
||||
OPL3_Generate4ChResampled(&fm,o);
|
||||
} else {
|
||||
OPL3_Generate(&fm,o);
|
||||
OPL3_Generate4Ch(&fm,o);
|
||||
}
|
||||
os[0]+=o[0]; os[1]+=o[1];
|
||||
os[0]+=o[0];
|
||||
os[1]+=o[1];
|
||||
os[2]+=o[2];
|
||||
os[3]+=o[3];
|
||||
|
||||
if (adpcmChan>=0) {
|
||||
adpcmB->clock();
|
||||
|
@ -225,6 +228,12 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
|||
if (fm.channel[i].out[1]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
|
||||
}
|
||||
if (fm.channel[i].out[2]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
|
||||
}
|
||||
if (fm.channel[i].out[3]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
|
||||
}
|
||||
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
|
||||
oscBuf[i]->needle++;
|
||||
}
|
||||
|
@ -244,6 +253,12 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
|||
if (fm.channel[i].out[1]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
|
||||
}
|
||||
if (fm.channel[i].out[2]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
|
||||
}
|
||||
if (fm.channel[i].out[3]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
|
||||
}
|
||||
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
|
||||
oscBuf[i]->needle++;
|
||||
}
|
||||
|
@ -254,10 +269,18 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
|||
|
||||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
if (os[2]<-32768) os[2]=-32768;
|
||||
if (os[2]>32767) os[2]=32767;
|
||||
|
||||
if (os[3]<-32768) os[3]=-32768;
|
||||
if (os[3]>32767) os[3]=32767;
|
||||
|
||||
buf[0][h]=os[0];
|
||||
if (oplType==3 || oplType==759) {
|
||||
buf[1][h]=os[1];
|
||||
buf[2][h]=os[2];
|
||||
buf[3][h]=os[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue