有哪些方法可以改进我用 Python 编写的节拍器?

如何解决有哪些方法可以改进我用 Python 编写的节拍器?

我正在尝试使用 librosa 和 sounddevice 编写基于 Python 的节拍器,但我遇到了一些准确性问题。代码如下:

from time import sleep,perf_counter
import librosa
import sounddevice as sd

    bpm = 200
    delay = 60/bpm
    tone = librosa.tone(440,sr=22050,length=1000)
    
    try:
        while True:
            sd.play(tone,22050)
            sleep(delay)
    except KeyboardInterrupt:
        pass

首先,节拍器功能正常的上限似乎在 180bpm 左右 - 如果您将 bpm 设置为高于 200bpm,则不会产生声音。在较慢的速度下,我可以听到节拍器不像点击之间的间距那样一致。我已经运行了 the script from this topic 并且与这个答案的作者相比,我的结果非常糟糕(它使用“旧的单核 32 位 2GHz 机器”对我的六核 3.9GHz 64 位 Windows 运行):

150.0 bpm
+0.007575200
+0.006221200
-0.012907700
+0.001935400
+0.002982700
+0.006840000
-0.009625400
+0.003260200
+0.005553100
+0.000668100
-0.010895100
+0.017142500
-0.012933300
+0.001465200
+0.004203100
+0.004769100
-0.012183100
+0.002174500
+0.002301000
-0.001611100 

所以我想知道我的节拍器问题是否与这些糟糕的结果有关,以及我能做些什么来解决它。 我遇到的第二个问题是节拍器关闭的方式 - 我希望它一直运行到用户输入特定按钮的点,或者在我的情况下(没有 GUI)从键盘输入特定值 -让我们说空格键。所以你现在可以看到它只适用于 ctrl + c,但我不知道如何使用指定的键实现中断。

解决方法

在 Mac 上运行您的代码,时间不一致很明显,但节奏与设定的 bpm 相差甚远。

这主要是因为 sleep() 不是那么准确,还因为您必须考虑自上次事件以来已经过去的时间。例如调用 sd.play()

需要多长时间

我不知道你在什么操作系统上运行了这个,但大多数操作系统都有一个用于精确回调的特殊计时器(例如 Windows 上的多媒体计时器)。如果您不希望使用特定于平台的解决方案来改善计时,您可以在 sleep() 上进行“忙等待”。为此,您可以延迟睡眠,然后进入一个循环,不断检查已用时间。

lastTime = perf_counter()
while True:
    currentTime = perf_counter()
    delta = abs(lastTime - currentTime)
    sleep(delay / 2.0)

    while True:
        currentTime = perf_counter()
        if (currentTime - lastTime >= delay):
            sd.play(tone,22050)
            lastTime = currentTime
            break

不是一个完美的解决方案,但它会让你更接近。

您可以进一步优化用于睡眠以承担 CPU 负载的延迟部分。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?