我已经用 Java 编写了一个 Sega Master System 仿真器(尽管这个问题不是 Java 特定的)并且除了 SN76489 声音芯片之外的所有东西都已经完成。该芯片如何发出声音很容易——我遇到的问题是将其转换为可通过 PC/笔记本电脑/运行 JVM 的任何设备播放的形式。
我已经确定了以下步骤;
由于 SN76489 以大约 221khz 的采样率运行 - 这意味着它输出的波的频率高达 110khz(尽管在实践中我怀疑任何东西都会如此之高)。因此,我需要在下采样之前实现一个低通滤波器。
然后我想将它下采样到 44.1khz,所以我可以通过音频线(在我的例子中是 Java 源数据线)输出它。
为此,我需要将低通滤波器设置为 22.05khz,但问题是我不知道(从数学上讲)低通滤波器实际上是如何工作的。我需要这个才能写一个。
目前,我的声音芯片创建了一个 0.2 秒的缓冲区,并将样本存储在其中,如上所述,频率为 221khz。据我了解,我可以进行下采样 - 但如果我在没有首先应用低通滤波器的情况下进行下采样,我知道我可能会在生成的声音流中出现混叠故障。
谁能推荐最简单的数学思维算法来做到这一点 - 由于涉及的变量,我意识到低通永远不是“精确的”,但我只需要一个对我的大脑来说足够简单的合理解释(这并不是真的之前处理过波形处理)来理解。
如果有帮助,具体如下:SN76489 同时输出三个方波和一个噪声通道。这些相加在一起,并输出到混频器/放大器 - 链中的这个阶段是我想要在下采样然后放大波之前运行低通滤波器的地方。非常感谢人们可以给我的任何帮助。我意识到需要背景阅读,但我想知道我需要阅读什么。非常感谢。
更新:我最后想出了一个更简单的方法——虽然还没有。SN76489 通过从寄存器值生成每个音调通道来工作 - 输出极性 1,值递减,等等 - 直到值为 0,然后重置值并将极性切换到 - 1,依此类推. 然后将该值乘以音量以获得该样本的最终幅度,并与其他通道相加。
我现在只是阻止产生一个超出我要求的奈奎斯特极限的方波的寄存器值。这给我留下了更好的信号,但它仍然有一些嗡嗡声/爆音 - 不知道为什么最大可能的频率应该是 18,473Hz。这种爆裂声/嗡嗡声是否是因为当芯片将通道从一个频率切换到下一个频率时,它不允许当前波形完全完成?例如,芯片输出 1111,然后是 00——而不是完整的四个零并切换到新的频率——这可能会导致混叠,不是吗?