尝试获取Python中.wav文件的频率 [英] Trying to get the frequencies of a .wav file in Python

查看:405
本文介绍了尝试获取Python中.wav文件的频率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有关Python中.wav文件的问题已被殴打致死,但由于没有人的答案似乎对我有用,我感到非常沮丧.我想做的事情对我来说似乎相对简单:我想确切地知道在给定时间.wav文件中的频率.我想知道,例如,从时间 n 毫秒到 n + 10 毫秒,声音的平均频率为 x 赫兹".我见过一些人在谈论傅立叶变换和Goertzel算法以及各种模块,但我似乎无法弄清楚如何去完成我所描述的事情.我尝试查找诸如在python中查找wav文件的频率"之类的内容大约二十次,但无济于事.有人可以帮我吗?

I know that questions about .wav files in Python have been just about beaten to death, but I am extremely frustrated as no one's answer seems to be working for me. What I'm trying to do seems relatively simple to me: I want to know exactly what frequencies there are in a .wav file at given times. I want to know, for example, "from the time n milliseconds to n + 10 milliseconds, the average frequency of the sound was x hertz". I have seen people talking about Fourier transforms and Goertzel algorithms, as well as various modules, that I can't seem to figure out how to get to do what I've described. I've tried looking up such things as "find frequency of a wav file in python" about twenty times to no avail. Can someone please help me?

我正在寻找的是一种类似于此伪代码的解决方案,或者至少是一种可以实现类似于伪代码的解决方案的解决方案:

What I'm looking for is a solution like this pseudocode, or at least one that will do something like what the pseudocode is getting at:

import some_module_that_can_help_me_do_this as freq

file = 'output.wav'
start_time = 1000  # Start 1000 milliseconds into the file
end_time = 1010  # End 10 milliseconds thereafter

print("Average frequency = " + str(freq.average(start_time, end_time)) + " hz")

请确保(我敢肯定,您会说)我是数学的白痴.这是我的第一个问题,请保持柔和

Please assume (as I'm sure you can tell) that I'm an idiot at math. This is my first question here so be gentle

推荐答案

如果您要检测音调(似乎确实如此),那么就Python库而言,最好的选择是 aubio .请参阅此示例进行实施.

If you'd like to detect pitch of a sound (and it seems you do), then in terms of Python libraries your best bet is aubio. Please consult this example for implementation.

import sys
from aubio import source, pitch

win_s = 4096
hop_s = 512 

s = source(your_file, samplerate, hop_s)
samplerate = s.samplerate

tolerance = 0.8

pitch_o = pitch("yin", win_s, hop_s, samplerate)
pitch_o.set_unit("midi")
pitch_o.set_tolerance(tolerance)

pitches = []
confidences = []

total_frames = 0
while True:
    samples, read = s()
    pitch = pitch_o(samples)[0]
    pitches += [pitch]
    confidence = pitch_o.get_confidence()
    confidences += [confidence]
    total_frames += read
    if read < hop_s: break

print("Average frequency = " + str(np.array(pitches).mean()) + " hz")

请务必检查文档有关音高检测方法.

Be sure to check docs on pitch detection methods.

我还认为您可能对不使用任何特殊库的平均频率和其他一些音频参数的估计感兴趣.让我们只使用numpy吧!这样可以使您更好地了解如何计算此类音频功能.它基于

I also thought you might be interested in estimation of mean frequency and some other audio parameters without using any special libraries. Let's just use numpy! This should give you much better insight into how such audio features can be calculated. It's based off specprop from seewave package. Check docs for meaning of computed features.

import numpy as np

def spectral_properties(y: np.ndarray, fs: int) -> dict:
    spec = np.abs(np.fft.rfft(y))
    freq = np.fft.rfftfreq(len(y), d=1 / fs)
    spec = np.abs(spec)
    amp = spec / spec.sum()
    mean = (freq * amp).sum()
    sd = np.sqrt(np.sum(amp * ((freq - mean) ** 2)))
    amp_cumsum = np.cumsum(amp)
    median = freq[len(amp_cumsum[amp_cumsum <= 0.5]) + 1]
    mode = freq[amp.argmax()]
    Q25 = freq[len(amp_cumsum[amp_cumsum <= 0.25]) + 1]
    Q75 = freq[len(amp_cumsum[amp_cumsum <= 0.75]) + 1]
    IQR = Q75 - Q25
    z = amp - amp.mean()
    w = amp.std()
    skew = ((z ** 3).sum() / (len(spec) - 1)) / w ** 3
    kurt = ((z ** 4).sum() / (len(spec) - 1)) / w ** 4

    result_d = {
        'mean': mean,
        'sd': sd,
        'median': median,
        'mode': mode,
        'Q25': Q25,
        'Q75': Q75,
        'IQR': IQR,
        'skew': skew,
        'kurt': kurt
    }

    return result_d

这篇关于尝试获取Python中.wav文件的频率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆