Python 如何使用aubio找到.wav的节奏?

Python 如何使用aubio找到.wav的节奏?,python,audio,analysis,tempo,aubio,Python,Audio,Analysis,Tempo,Aubio,我希望在Python3.6中检测音频文件的节奏,但我并不真正理解关于aubio的文档。有人能告诉我如何使用aubio或其他库提取节拍吗?我找到了Paul Brossier的这篇文章,可以帮助你,这是: #! /usr/bin/env python from aubio import source, tempo from numpy import median, diff def get_file_bpm(path, params = None): """ Calculate the

我希望在Python3.6中检测音频文件的节奏,但我并不真正理解关于aubio的文档。有人能告诉我如何使用aubio或其他库提取节拍吗?

我找到了Paul Brossier的这篇文章,可以帮助你,这是:

#! /usr/bin/env python

from aubio import source, tempo
from numpy import median, diff

def get_file_bpm(path, params = None):
    """ Calculate the beats per minute (bpm) of a given file.
        path: path to the file
        param: dictionary of parameters
    """
    if params is None:
        params = {}
    try:
        win_s = params['win_s']
        samplerate = params['samplerate']
        hop_s = params['hop_s']
    except KeyError:
        """
        # super fast
        samplerate, win_s, hop_s = 4000, 128, 64 
        # fast
        samplerate, win_s, hop_s = 8000, 512, 128
        """
        # default:
        samplerate, win_s, hop_s = 44100, 1024, 512

    s = source(path, samplerate, hop_s)
    samplerate = s.samplerate
    o = tempo("specdiff", win_s, hop_s, samplerate)
    # List of beats, in samples
    beats = []
    # Total number of frames read
    total_frames = 0

    while True:
        samples, read = s()
        is_beat = o(samples)
        if is_beat:
            this_beat = o.get_last_s()
            beats.append(this_beat)
            #if o.get_confidence() > .2 and len(beats) > 2.:
            #    break
        total_frames += read
        if read < hop_s:
            break

    # Convert to periods and to bpm 
    if len(beats) > 1:
        if len(beats) < 4:
            print("few beats found in {:s}".format(path))
        bpms = 60./diff(beats)
        b = median(bpms)
    else:
        b = 0
        print("not enough beats found in {:s}".format(path))
    return b

if __name__ == '__main__':
    import sys
    for f in sys.argv[1:]:
        bpm = get_file_bpm(f)
print("{:6s} {:s}".format("{:2f}".format(bpm), f))

已更新

此命令将为您提供整个文件的速度估计值(在中提供):


在的
python/demos
中有一个简单的演示:

最重要的部分是以下两行,它们计算每个连续节拍之间的周期(
np.diff
),将这些周期转换为bpm(
60./
),并将中位数(
np.median
)作为这一系列节拍最可能的bpm候选值:

#!/usr/bin/env python
import numpy as np
bpms = 60./np.diff(beats)
median_bpm = np.median(bpms)

请注意,中位数如何比这里的平均值更合适,因为它总是给出原始总体中存在的估计值
bpms

您看到了吗?在Python中,这里已经有一个这样的例子,名为demo_bpm_extract.py:您忘了提到源代码,缩进不知怎么搞砸了。;-)在这里,指向原始资源似乎更合适。此外,我还添加了一些关于从beat位置到bpm转换的见解。由于我是上游作者,所以被否决感觉有些讽刺。谢谢你的回答,我投了你一票。但无论如何,aubio似乎并不擅长检测节奏/bpm。我只是试了几首歌,但值相差甚远,例如它给出的
smokeyrobinson-Cruisin'
bpm分数为168.3,这不可能是真的。任何带有现场音乐或环境噪音的歌曲也是非常错误的。对备选库有什么建议吗?@supersan你找到好的备选库了吗?我也经历过同样的事情,结果并不理想。@Patrick抱歉,我从来没有这样做过,尽管我几乎记不起任何细节,因为那是很久以前的事了。如果我现在就做,我可能会尝试使用机器学习。第一步是找到准确的bpm数据集和歌曲,您可以使用它们来训练模型。也许这对我来说是个不错的周末计划。如果有机会,我会告诉你最新消息。不用担心,谢谢你回复我@supersan
aubio tempo foo.wav
#!/usr/bin/env python
import numpy as np
bpms = 60./np.diff(beats)
median_bpm = np.median(bpms)