From 6a109a308e95401bd47fa4094bddeb02ab619461 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 26 Jan 2023 15:38:39 +0800 Subject: [PATCH] Add OPL3_WriteRegDelayed() to buffer with a custom delay Currently, OPL3_WriteRegBuffered() will delay any write by 2 (non-resampled) samples. It's possible that we might want to delay writes by some other (possibly variable) amount. OPL3_WriteRegDelayed() accepts an additional 'delay' argument, which contains the number of 49,716Hz samples to delay the write by. --- opl3.c | 29 +++++++++++++++++++++++++++++ opl3.h | 1 + 2 files changed, 30 insertions(+) diff --git a/opl3.c b/opl3.c index 9128ba8..09a9731 100644 --- a/opl3.c +++ b/opl3.c @@ -1469,6 +1469,35 @@ void OPL3_WriteReg(opl3_chip *chip, uint16_t reg, uint8_t v) } } +void OPL3_WriteRegDelayed(opl3_chip *chip, uint16_t reg, uint8_t v, uint64_t delay) +{ + uint64_t currentTime; + opl3_writebuf *writebuf = &chip->writebuf[chip->writebuf_last]; + + currentTime = chip->writebuf_lasttime; + + /* If we've overflowed the ringbuffer, process the next event early */ + if (writebuf->reg & 0x200) + { + OPL3_WriteReg(chip, writebuf->reg & 0x1ff, writebuf->data); + } + + /* If the previous write was in the past... */ + if (currentTime < chip->writebuf_samplecnt) + { + currentTime = chip->writebuf_samplecnt; + } + + /* Schedule the write. */ + writebuf->time = currentTime + delay; + writebuf->reg = reg | 0x200; + writebuf->data = v; + + /* Advance the writebuf ringbuffer. */ + chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; + chip->writebuf_lasttime = writebuf->time; +} + void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v) { uint64_t time1, time2; diff --git a/opl3.h b/opl3.h index 3977f80..2c73ddc 100644 --- a/opl3.h +++ b/opl3.h @@ -159,6 +159,7 @@ void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf); void OPL3_Reset(opl3_chip *chip, uint32_t samplerate); 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_WriteRegDelayed(opl3_chip *chip, uint16_t reg, uint8_t v, uint64_t delay); void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples); void OPL3_Generate4Ch(opl3_chip *chip, int16_t *buf4);