NAudio算法播放正弦波,其频率可以实时平滑改变

发布于 2024-11-28 23:27:40 字数 1468 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

轻拂→两袖风尘 2024-12-05 23:27:40

您需要避免输出波形的不连续性(这些是您听到的喀哒声)。最简单的方法是使用基于 LUT 的波形发生器 - 这适用于任何周期波形(即不仅仅是纯正弦波)。通常,您使用定点相位累加器,该累加器对于每个新样本都会增加一个与当前输出频率相对应的增量值。您可以根据自己的喜好安全地修改增量,并且波形仍然是连续的。

伪代码(针对一个输出样本):

const int LUT_SIZE;
const int LUT[LUT_SIZE];  // waveform lookup table (typically 2^N, N >= 8)
Fixed index; // current index into LUT (integer + fraction)
Fixed delta; // delta controls output frequency

output_value = LUT[(int)index];
    // NB: for higher quality use the fractional part of index to interpolate
    //     between LUT[(int)index] and LUT[(int)index + 1], rather than just
    //     truncating the index and using LUT[(int)index] only. Depends on both
    //     LUT_SIZE and required output quality.
index = (index + delta) % LUT_SIZE;


Note: to calculate delta for a given output frequency f and a sample rate Fs:

delta = FloatToFixed(LUT_SIZE * f / Fs);

You need to avoid discontinuities in the output waveform (these are the clicks you are hearing). The easiest way to do this is with a LUT-based waveform generator - this works for any periodic waveform (i.e. not just pure sine waves). Typically you use a fixed point phase accumulator, which is incremented for each new sample by a delta value which corresponds to the current output frequency. You can safely modify delta however you like and the waveform will still be continuous.

Pseudo code (for one output sample):

const int LUT_SIZE;
const int LUT[LUT_SIZE];  // waveform lookup table (typically 2^N, N >= 8)
Fixed index; // current index into LUT (integer + fraction)
Fixed delta; // delta controls output frequency

output_value = LUT[(int)index];
    // NB: for higher quality use the fractional part of index to interpolate
    //     between LUT[(int)index] and LUT[(int)index + 1], rather than just
    //     truncating the index and using LUT[(int)index] only. Depends on both
    //     LUT_SIZE and required output quality.
index = (index + delta) % LUT_SIZE;


Note: to calculate delta for a given output frequency f and a sample rate Fs:

delta = FloatToFixed(LUT_SIZE * f / Fs);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文