首页 文章

加快声音处理算法

提问于
浏览
0

我使用以下代码进行一些即时声音处理/分析 . 它工作,但真的很慢(与计划的速度相比) . 我添加了一些时间标记来找出问题所在,并根据它们不应该有任何问题 . 所有三个计算时间的典型持续时间(见下文)<0.01 s,但完成循环仍需要大约一秒钟 . 问题出在哪儿?

Edit: 请注意,时间测量不是真正的问题 . 为了证明: MyPeaks 基本上只找到相当短的FFT的最大值 - 没什么代价 . 即使这些例程被注释掉,问题仍然存在 .

  • 我应该使用与lambda函数不同的东西来制作循环吗?

  • 启动和录制流时是否犯了一些错误?

import pyaudio
import struct
import mute_alsa
import time
import numpy as np
from Tkinter import *


def snd_process(k=0):
 if k<1000:
  t0=time.clock()

  data = stream.read(CHUNK)

  t1=time.clock()

  fl=CHUNK
  int_data = struct.unpack("%sh" %str(fl),data)
  ft=np.fft.fft(int_data)
  ft=np.fft.fftshift(ft)
  ft=np.abs(ft)     

  t2=time.clock()

  pks=MyPeaks(np.log(ft))

  freq_out.configure(text=str(pks))

  t3=time.clock()

  print t1-t0, t2-t1, t3-t2     

  master.after(1, lambda: snd_process(k+1))

CHUNK = 8000
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 4000

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
            channels=CHANNELS,
            rate=RATE,
            input=True,
            frames_per_buffer=CHUNK)

#Tkinter stuff
master=Tk()
button_play=Button(master, command=snd_process, bg="yellow", text="Analyze")
button_play.grid(row=0, column=0)
freq_out = Label(master)
freq_out.grid(row=0, column=1)
freq_out.configure(text='base')
mainloop()

3 回答

  • 2

    您正在tk主线程中安排1000个回调;对于每个回调,你使用1毫秒延迟( after() 的第一个参数) . 这意味着最后一个循环将在第一个循环1000毫秒(1秒)后开始 .

    也许这就是循环仍然需要大约一秒才能完成的方式 .

    所以,尝试使用 after_idle() . 我认为你真的不需要加速声音处理算法,因为 np 已经非常有效 .

    [EDIT] 惊喜!!你在每次迭代时从音频通道读取1秒8000字节,16位格式,4000帧速率 . 你需要一秒钟才能拥有它 .

  • 4

    像往常一样将I / O和计算压缩到主循环中是经典的解决方案 . 但也有其他选择 .

    • 在第二个线程中进行音频采集和计算 . 由于I / O和numpy都应该释放GIL,因此它可能是一个很好的选择 . 这里有一个警告 . 由于像TKinter这样的GUI工具包通常不是多线程安全的,所以不应该从第二个线程进行Tkinter调用 . 但是你可以设置一个用 after 调用的函数来检查计算的进度,并且每100毫秒更新一次UI .

    • 在不同的 multiprocessing.Process 中进行音频采集和计算 . 这使它与GUI完全分离 . 您必须设置一个通信渠道,例如: a Queuepks 发送回主进程 . 您应该使用 after 函数来检查 Queue 是否有可用数据,如果是,则更新显示 .

  • -1

    根据操作系统,您需要're running at you might nog be measuring actual '挂钟时间 . 有关详细信息,请参见http://pythoncentral.io/measure-time-in-python-time-time-vs-time-clock/ . 请注意,对于python 3.3,不推荐使用time.clock,建议使用time.process_time()或time.perf_counter() .

相关问题