如何将方法调用与 alsa 播放同步?
Posted
技术标签:
【中文标题】如何将方法调用与 alsa 播放同步?【英文标题】:How can I synchronize a method call with alsa playback? 【发布时间】:2016-02-10 03:24:28 【问题描述】:我正在尝试编写一个程序,将灯光与基本 wav 文件的播放同步。我在所有的 alsa 文档、ffplay.c 的来源和互联网上进行了搜索,但很难弄清楚如何执行看似常见且简单的任务。
基本上我想做两件事,第一件事是在音频播放时读取按键事件并将偏移量存储在文件中。第二个是获取这些队列文件并稍后加载它们,这次是在树莓派等不同的音频设备上。
我正在努力解决如何首先考虑偏移位置的初始捕获中的延迟,然后在完全不同的硬件设备上播放时如何处理该延迟。
我知道 ffmpeg 套件使用snd_pcm_delay()
来处理其中的一些问题,但我什至在基本技术方面都在苦苦挣扎。这不是复杂的播放机制,只是循环中的阻塞写入。
我会发布一些代码,但我现在没有它,而且它只是当前的一堆乱七八糟的 hacks 不起作用。
【问题讨论】:
写入阻塞时如何获得按键? @CL 我有点不确定这到底是如何工作的,但写入很快就会返回 【参考方案1】:所以最终这变得有些容易,但要弄清楚却并不容易。使用snd_pcm_delay
是正确的路径。
当前正在播放的实际音频样本是写入的帧数 - snd_pcm_delay
,这为您提供了一个相对准确的当前播放帧(您现在应该听到的帧)。这应该用于计算时间戳的位置,并作为应用程序等待当前位置领先或与下一个提示事件相同的位置索引。
这是 GStreamer 以更多文档和更可扩展的方式所做的事情,构建了一个更复杂的同步算法,允许音频在单独的线程上运行,同时避免每次需要位置时钟时锁定。如果可能的话,我会使用 GStreamer 来实现任何类似的应用程序。
但是如果你不需要 GStreamer 的所有复杂性并且想要减少你的依赖,基本的方法就是我上面描述的那个。
【讨论】:
以上是关于如何将方法调用与 alsa 播放同步?的主要内容,如果未能解决你的问题,请参考以下文章
Unity UNET - 在播放器对象之外调用 [Command]