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
相关产品推荐
相关产品推荐

