python - 在audiomath中创建播放器需要可变时间-可以加快速度吗?
问题描述
我在 Windows 10 上的 Python 3.7 下使用audiomath。我想Player
在实时应用程序期间的不同时间临时创建实例以播放Sound
已加载到内存中的实例。似乎这些有时可以非常快速地构建(不到一毫秒),但有时需要几百毫秒(这可能会干扰我的应用程序的时间)。我认为这反映了初始化 PortAudio 和/或打开流的开销,但我不清楚这种情况何时发生和不发生。有没有办法提前初始化所有内容和/或优化事物,以便Player
构建总是快速进行?
解决方案
确实需要时间来初始化库和流。如果您不跟踪Player
您拥有的实例数量,这种开销(至少是流打开部分)可能会在意想不到的时间发生,这也是事实。默认情况下,当您创建第一个流时,它会隐式自动创建/打开/启动,当没有更多实例使用它Player
时,它会自动停止/关闭/删除。Player
因此,当您的最后一个Player
实例被垃圾收集时,流将关闭:然后如果您随后创建另一个实例,您将再次获得流初始化成本。也许这可以解释您观察到它“有时”缓慢而有时不是?以下结果来自 IPython 的%timeit
工具说明了它是如何工作的(audiomath 1.5.1、Python 3.7.3、Windows 10):
import audiomath as am
s = am.TestSound('12')
timeit -n1 -r1 am.Player(s)
# 722 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# First-ever Player: it took 722 ms to initialize the PortAudio
# library and opening a stream
timeit -n1 -r1 am.Player(s)
# 281 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# The previous player was garbage-collected, so we're working off a
# blank slate, but the library is already initialized, so 281 is
# just the stream-opening overhead.
timeit -n1 -r1 am.Player(s)
# 283 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# Same again.
p = am.Player(s) # now, let's keep a reference to an active Player
timeit -n1 -r1 am.Player(s)
# 52.3 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# With p still alive, creating another Player is really fast (although
# on some implementations such as macOS, even this can spend some tens
# of milliseconds just deciding which device should be used)
最干净的方法是Stream
显式创建一个实例,在整个会话期间保持它的活动状态,并通过它们的构造函数参数显式告诉新Player
实例使用它:stream=
import audiomath as am
s = am.TestSound('12')
f = am.Stream()
timeit -n1 -r1 am.Player(s, stream=f)
# 50.3 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# All Players, even the first, are initialized lightning-fast
就像 一样Player
,Stream
该类由audiomath.PortAudioInterface
后端导出,并且在加载该后端时(默认情况下)在顶级命名空间中可用。它没有很好的文档记录,但是值得了解的输入参数(用于指定要使用的 API 和设备)与audiomath.PortAudioInterface.FindDevices
推荐阅读
- javascript - 打字稿:以属性为字符串的接口的访问属性
- php - PHP-fpm session_start() 在 ptero 容器中不受保护
- javascript - 如何将代码从代码沙盒传输到 Visual Studio Code?
- python - Python在列表列表中迭代和追加中级
- java - IllegalArgumentException: Bound 必须是正数?
- reactjs - 多次调度函数以便使用不同的参数执行它
- https - 您如何配置 JBOSS 以通过 HTTPS 允许端口 8080?
- macros - Nim 宏:如何命名正文参数
- amazon-web-services - 为前端和后端(Godaddy、AWS 和 Firebase)添加单独的子域路由
- node.js - 在 NodeJS 中生成 PDF 并使用 react-pdf 在 React 中打开