代码之家  ›  专栏  ›  技术社区  ›  Tom Dalling

利用软件合成器制作实时音频应用程序

  •  3
  • Tom Dalling  · 技术社区  · 16 年前

    我正在研究制作一些软件,使键盘像钢琴一样工作(例如,用户按“w”键,扬声器播放d音符)。我可能会用Openal。我了解数字音频的基本知识,但在按键时播放实时音频会带来一些我难以解决的问题。

    问题是: 假设我有10个音频缓冲区,每个缓冲区保存一秒钟的音频数据。如果我必须在通过扬声器播放缓冲区之前填充缓冲区,那么我将在播放缓冲区之前一到两秒填充缓冲区。这意味着,每当用户尝试播放一个音符时,按键和正在播放的音符之间会有一到两秒钟的延迟。

    你如何解决这个问题?你只是让缓冲区尽可能小,并尽可能晚地填充它们吗?我错过了什么把戏吗?

    3 回复  |  直到 13 年前
        1
  •  6
  •   Nils Pipenbrinck    16 年前

    大多数软件合成器根本不使用多个缓冲区。

    他们只使用一个不断播放的小铃声缓冲器。

    高优先级线程将尽可能经常检查当前播放位置,并用声音数据填充环形缓冲区的空闲部分(例如,自上次线程运行以来已播放的部分)。

    这将给您一个恒定的延迟,它只受您的环缓冲区大小和声卡输出延迟的限制(通常不会太大)。

    您可以进一步降低延迟:

    如果要播放新的音符(例如,用户刚按了一个键),您可以检查环缓冲区中的当前播放位置,添加一些安全示例,然后使用新的声音设置重新渲染声音数据。

    如果运行基于时间的效果(延迟线、混响等),这会变得很棘手,但它是可行的。只需每毫秒左右跟踪你的基于时间的效果的最后10个状态。这样可以在10毫秒内返回。

        2
  •  1
  •   Stefan Monov    15 年前

    使用winapi,您只能在延迟方面做到这一点。通常你不能低于40-50毫秒,这是相当讨厌的。解决方案是在应用程序中实现ASIO支持,并让用户在后台运行类似ASIO4all的程序。这将延迟降低到5毫秒,但代价是:其他应用程序不能同时播放声音。

    我知道这是因为我是一个佛罗里达的工作室用户。

        3
  •  0
  •   marko    13 年前

    解决方案是小的缓冲区,经常由实时线程填充。缓冲区的大小(或者使用环形缓冲区使缓冲区变满的程度)受到操作系统调度延迟的限制。你可能会发现10毫秒是可以接受的。

    这里有一些针对未入门者的棘手问题,特别是在软件架构和线程安全方面。

    你可以试试看 Juce -这是一个用于编写音频软件的跨平台框架,尤其是音频插件,如SoftSynths和Effects。它包括用于示例插件和主机的软件。主要是在主机中处理线程问题。

    推荐文章