You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

YM3812(OPL2) FM合成器反馈算法实现与预期不符问题咨询

YM3812 FM合成反馈算法实现问题

背景

我正在用C++和JavaScript开发一款小型软件合成器,参考Yamaha YM3812与YMF262技术手册,已完成JS版FM Tone Generator。

手册中的FM与反馈公式

根据YM3812手册第2页,基础FM公式:

F = Asin(wct + Isin(wmt))

反馈公式:

F = A*sin(wct + BF)

其中反馈系数B的取值来自手册第19页:

0, π/16, π/8, π/4, π/2, π, 2π, 4π

当前实现与问题

我在FM Tone Generator的“Output PCM Code”区域的实现代码如下:

let x2p = x*2.0*Math.PI;
let m1 = mWaveform(x2p*mFreq, A1);
let c1 = cWaveform(x2p*cFreq + m1, A2);
let f1 = cWaveform(x2p*cFreq + feedback*c1, A2);
if (feedback != 0) {
  value = f1;
}
else {
  value = c1;
}      

当调制器与载波均为正弦波、反馈值设为7(对应4π)时,等效代码为:

let value = A2*Math.sin(x*2.0*Math.PI*cFreq + A1*Math.sin(x*2.0*Math.PI*mFreq));
value = A2*Math.sin(x*2.0*Math.PI*cFreq + 4*Math.PI*value);

但这个实现的反馈效果和DosBox中AdLib tracker的预期不符——此时本应产生噪声,实际却没有。

尝试的临时方案

我尝试在调制器上执行10次反馈迭代后,效果更接近预期,但未找到任何文档提及此操作:

let x2p = x*2.0*Math.PI;
let m1 = mWaveform(x2p*mFreq, A1);
let iterations = 10;
if (feedback != 0) {
  for(let i = 0; i < iterations; i++) {
    m1 = mWaveform(x2p*mFreq + feedback*m1);
  }
}
let c1 = cWaveform(x2p*cFreq + m1, A2);
value = c1;

需求

我查看了Mame等模拟器源码,但它们采用查表法精确模拟YM3812,难以理解;而我开发的是支持脉冲、三角等多种波形的通用合成器,希望得到正确的反馈算法实现方案。

内容的提问来源于stack exchange,提问作者John Ernest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:52:43