如何使用python触发特定频率的事件

问题描述 投票:1回答:2

我想以某个频率触发事件,例如44100hz。我希望下面的代码每秒执行“打印” 44100次,但不会。

import time

frequency = 44100
desired_interval = 1 / frequency

events = 0

time_now = time.time()
time_end = time_now +1

while time_now < time_end:

    events += 1
    print(events)

    # some time has passed, sleep for desired interval less passed time
    if( desired_interval > ( time.time() - time_now ) ):
        time.sleep( desired_interval - ( time.time() - time_now ) )

    time_now = time.time()    
python frequency
2个回答
0
投票

这很接近,即使很有可能(肯定)事件“ print”没有按常规频率触发。

import time

frequency = 44100
desired_interval = 1 / frequency

events = 0

time_now = time.time()
time_start = time_now
time_end = time_now +1

while time_now < time_end:

    events += 1
    print(events)

    if( desired_interval * events > ( time.time() - time_start ) ):
        # abs mitigate the fact that sometime the result is negative.
        time.sleep( abs( desired_interval * events - ( time.time() - time_start ) ) )


    time_now = time.time()

0
投票

要了解为什么花费比您认为更长的时间,我们必须使用profiler

将您的代码另存为timer.py,我运行了以下代码;

python3 -m cProfile -s tottime timer.py

结果是:

37621
37622
37623
37624
37625
37626
         188134 function calls in 1.000 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    37626    0.840    0.000    0.840    0.000 {built-in method time.sleep}
    37626    0.104    0.000    0.104    0.000 {built-in method builtins.print}
        1    0.045    0.045    1.000    1.000 timer.py:1(<module>)
   112879    0.012    0.000    0.012    0.000 {built-in method time.time}
        1    0.000    0.000    1.000    1.000 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

所以,在我的机器上,它每秒运行37626次。大部分时间都花在了time.sleep()上。

事实是,在计算延迟时,您没有考虑python代码运行的时间。它也没有考虑到Python在运行其他程序的操作系统上运行。

让我们将程序简化为:

import time

frequency = 44100
desired_interval = 1 / frequency * 0.72
events = 0
time_now = time.time()
time_end = time_now + 1
while time_now < time_end:
    events += 1
    print(events)
    time.sleep(desired_interval)
    time_now = time.time()

在我的系统上,每秒打印大约 44100次。如您所见,考虑到开销,我不得不将睡眠时间减少了大约30%。这只是一个玩具程序。

查看所需的频率,您似乎想实时进行CD质量的音频处理。老实说,Python可能不是正确的选择。

您应该做的是将要执行的实际工作包装在一个函数中,然后在该函数上运行探查器。分析的结果将告诉您是否可以在所需的时间内完成所需的工作。

如果不能,则有一些选项可以加快它的速度;

  • 使用numpy
  • 使用cython
  • 使用pypy
© www.soinside.com 2019 - 2024. All rights reserved.