PyAudio如何找到特定范围的声音频率的音量

时间:2019-12-08 21:20:30

标签: python fft pyaudio

我正在尝试用python制作一个程序,该程序将使用pyaudio接收声音频率,并使用乌龟将频率范围显示为横线向上和向下。我希望它看起来像这样:

Equalizer

我遵循了本教程,以fft格式获取和绘制声音数据: https://www.youtube.com/watch?v=aQKX3mrDFoY

我的代码被格式化为具有32个eq带。要将频率分为32组,我遍历pyaudio创建的频率列表,并以32组为单位添加列表的所有值,然后使列表中的每个值占最大值的百分比(这样输入音量无所谓)。在拆分之前,列表中有1024个不同的频率。这是我用来拆分这些值的函数:

def split_freq(freq): # splits given sound frequencies into groups of frequencies to feed into turtle
    freq_ranges = []
    for i in range(len(freq)-1): # split the frequencies into 32 groups
        if i % abs((len(freq)//32)) == 0:
            if len(freq_ranges) > 0:
                freq_ranges[len(freq_ranges)-2] = freq_ranges[len(freq_ranges)-2]
            freq_ranges.append(0)
        freq_ranges[len(freq_ranges)-1] = freq_ranges[len(freq_ranges)-1] + freq[i]
    for i in range(len(freq_ranges)):
        freq_ranges[i] = (freq_ranges[i] / np.array(freq_ranges).max())
    return [i * 400 for i in freq_ranges]

我将每个值最后都乘以400,这样乌龟就会在屏幕的很大一部分上绘制。

当我运行代码时,一行通常比其他所有行都高得多(这是可以预料的,因为每一行都是最大行的百分比)。问题是当我播放音乐甚至某些频率时,它根本不会改变。看起来总是这样(条形图随机移动):

Turtle Eq

有人知道这个问题是什么吗?这是我的完整代码:

import pyaudio
import struct
import numpy as np
from scipy.fftpack import fft
import turtle
import time

def update_graph(frequencies):
    for i in range(len(eq_bars)):

        eq_bars[i].penup()
        eq_bars[i].sety(-200)
        eq_bars[i].setx(-230+(i*15))
        eq_bars[i].setheading(90)
        eq_bars[i].pendown()
        eq_bars[i].fd(frequencies[i]) # go up by the amount of the current frequency
        eq_bars[i].penup()
        eq_bars[i].setx(1+(i*20))
    for eq_bar in eq_bars:
        eq_bar.clear()


def split_freq(freq): # splits given sound frequencies into groups of frequencies to feed into turtle
    freq_ranges = []
    for i in range(len(freq)-1): # split the frequencies into 32 groups
        if i % abs((len(freq)//32)) == 0:
            if len(freq_ranges) > 0:
                freq_ranges[len(freq_ranges)-2] = freq_ranges[len(freq_ranges)-2]
            freq_ranges.append(0)
        freq_ranges[len(freq_ranges)-1] = freq_ranges[len(freq_ranges)-1] + freq[i]
    for i in range(len(freq_ranges)):
        freq_ranges[i] = (freq_ranges[i] / np.array(freq_ranges).max())
    return [i * 400 for i in freq_ranges]


CHUNK = 2**10
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100

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

wn = turtle.Screen()
wn.bgcolor("black")
wn.setup(width = 600, height = 600)
wn.title("Audio Visualizer")
wn.delay(0)

eq_bars = []

for i in range(32):
    eq_bars.append(turtle.Turtle())

    eq_bars[i].hideturtle()

    eq_bars[i].speed(0)
    eq_bars[i].pensize(5)
    eq_bars[i].color("white")
    eq_bars[i].penup()
    eq_bars[i].sety(-200)
    eq_bars[i].setx(-230+(i*15))
    eq_bars[i].setheading(90)
    eq_bars[i].pendown()
    eq_bars[i].fd(100)
    eq_bars[i].penup()
    eq_bars[i].setx(1+(i*20))



x = np.arange(0, 2*CHUNK, 2)
x_fft = np.linspace(0, RATE, CHUNK)

while True:

    data = struct.unpack(str(CHUNK*CHANNELS) + 'h', stream.read(CHUNK))
    data = stream.read(CHUNK)
    data = np.array(struct.unpack(str(2*CHUNK) + 'B', data), dtype='b')[::2] + 127

    y_fft = fft(data)
    y_fft = np.abs(y_fft[:CHUNK]) * 2 / (256 * CHUNK)
    print(len(y_fft))
    turtle_data = split_freq(y_fft)
    update_graph(turtle_data)

0 个答案:

没有答案