Fix ymfm timing issues by queuing register writes

Rapid register writes could cause audio glitches [1].
This introduces a queue to process one write per audio generation cycle.
This approach is the same as the one used in ymfm's vgmrender.cpp.

[1] https://github.com/aaronsgiles/ymfm/issues/1
This commit is contained in:
kichikuou
2025-11-27 08:11:18 +09:00
parent 257dc9c415
commit fe17265cfb
2 changed files with 16 additions and 3 deletions
+8 -3
View File
@@ -48,9 +48,8 @@ void MakoYmfm::Process(int16_t* stream, int len) {
}
void MakoYmfm::SetReg(RegType type, uint8_t addr, uint8_t val) {
uint32_t offset = type == OPNA_SLAVE ? 2 : 0;
opna.write(offset, addr);
opna.write(offset + 1, val);
uint8_t port = type == OPNA_SLAVE ? 2 : 0;
queue.push({port, addr, val});
}
void MakoYmfm::Generate(int16_t* buf, int samples) {
@@ -62,6 +61,12 @@ void MakoYmfm::Generate(int16_t* buf, int samples) {
// generate at the appropriate sample rate
assert(opna_pos <= output_pos);
while (opna_pos <= output_pos) {
if (!queue.empty()) {
auto w = queue.front();
opna.write(w.port, w.addr);
opna.write(w.port + 1, w.val);
queue.pop();
}
opna.generate(&opna_output);
opna_pos += opna_step;
}
+8
View File
@@ -1,6 +1,7 @@
#ifndef MAKOYMFM_H_
#define MAKOYMFM_H_
#include <queue>
#include <vector>
#include "ymfm_opn.h"
#include "makofm.h"
@@ -15,6 +16,12 @@ private:
// we use an int64_t as emulated time, as a 32.32 fixed point value
using emulated_time = int64_t;
struct RegWrite {
uint8_t port;
uint8_t addr;
uint8_t val;
};
void SetReg(RegType type, uint8_t addr, uint8_t val) override;
void Generate(int16_t* buf, int samples);
@@ -24,6 +31,7 @@ private:
emulated_time output_pos = 0;
int last_sync = 0;
int samples_left = 0;
std::queue<RegWrite> queue;
};
#endif // MAKOYMFM_H_