2011-12-26 27 views
10

Tôi tham gia vào một dự án yêu cầu tôi trích xuất các tính năng bài hát như nhịp mỗi phút (BPM), tiến độ, v.v. Tuy nhiên, tôi chưa tìm thấy thư viện Python phù hợp phát hiện chính xác các tính năng này.Làm thế nào để có được các tính năng âm thanh BPM và tiến độ trong Python

Có ai có lời khuyên nào không?

(Trong Matlab, tôi biết một dự án có tên Mirtoolbox, có thể cung cấp thông tin BPM và tiến độ sau khi xử lý các tập tin mp3 địa phương.)

+0

định dạng mã hóa là gì? Tôi chưa bao giờ nghe nói về một thư viện âm thanh trăn ... Sau đó, một lần nữa, tôi ở xa sự toàn năng và tất cả đều biết. Go crank bắt đầu máy google của bạn và cho nó "thư viện âm thanh python" –

Trả lời

5

Echo Nest API là những gì bạn đang tìm kiếm:

http://echonest.github.io/remix/

Ràng buộc Python rất phong phú, mặc dù cài đặt Echo Nest có thể gây đau khi nhóm dường như không thể xây dựng trình cài đặt vững chắc.

Tuy nhiên, nó không xử lý cục bộ. Thay vào đó, nó tính toán vân tay âm thanh và tải lên bài hát cho các máy chủ Echo Nest để trích xuất thông tin bằng các thuật toán mà chúng không hiển thị.

+3

là có dự án xử lý cục bộ có thể trích xuất các tính năng bpm chỉ dựa trên tệp mp3/wav cục bộ. – MaiTiano

+1

Tôi đã thực hiện một số nghiên cứu về vấn đề này khoảng một năm trước và Echo Nest là giải pháp dễ nhất cho Python. Tôi không chắc liệu có các thư viện khác hiện có hay không - vui lòng cho họ nghe câu trả lời nếu bạn tìm thấy chúng –

+1

Tôi có cùng một kết quả tìm kiếm với bạn. Không có thư viện có thể sử dụng nào có thể trích xuất các tính năng âm nhạc. – MaiTiano

10

Câu trả lời này xuất hiện một năm sau đó, tuy nhiên, để ghi lại. Tôi tìm thấy ba thư viện âm thanh với các ràng buộc python trích xuất các tính năng từ âm thanh. Họ không phải là dễ dàng để cài đặt vì chúng là thực sự trong C và bạn cần phải biên dịch đúng bindings python và thêm chúng vào đường dẫn đến nhập khẩu, nhưng ở đây đó là:

+0

Bây giờ tôi sẽ khuyên bạn nên sử dụng Essentia (http://essentia.upf.edu/), nó là một thư viện tuyệt vời mà tôi đã đóng góp một thời gian trước đây. – wizbcn

-1

Gần đây tôi đã xem qua Vampy là trình bao bọc cho phép bạn sử dụng plugin Vamp được viết bằng Python trong bất kỳ máy chủ Vamp nào. Vamp là hệ thống plugin xử lý âm thanh cho các plugin trích xuất thông tin mô tả từ dữ liệu âm thanh. Hy vọng nó giúp.

+0

Trang web Vamp nó không rõ ràng về cách cài đặt Vampy, họ đề nghị sử dụng một công cụ như SonicAnnotator, nhưng trang web dường như bị ... http://www.omras2.org/SonicAnnotator Viễn hữu ích hơn sẽ là nếu Vampy là một gói python có thể dễ dàng cài đặt với pip/conda hoặc nhân bản qua git với một cách đơn giản để sử dụng nó như một công cụ dòng lệnh. – alexvicegrab

0

Librosa có phương thức librosa.beat.beat_track(), nhưng bạn cần cung cấp ước tính BMP làm thông số "start_bpm". Không chắc nó chính xác như thế nào, nhưng có lẽ đáng để bắn.

0

tôi đã tìm thấy mã này bằng cách @scaperot here có thể giúp bạn:

import wave, array, math, time, argparse, sys 
import numpy, pywt 
from scipy import signal 
import pdb 
import matplotlib.pyplot as plt 

def read_wav(filename): 

    #open file, get metadata for audio 
    try: 
     wf = wave.open(filename,'rb') 
    except IOError, e: 
     print e 
     return 

    # typ = choose_type(wf.getsampwidth()) #TODO: implement choose_type 
    nsamps = wf.getnframes(); 
    assert(nsamps > 0); 

    fs = wf.getframerate() 
    assert(fs > 0) 

    # read entire file and make into an array 
    samps = list(array.array('i',wf.readframes(nsamps))) 
    #print 'Read', nsamps,'samples from', filename 
    try: 
     assert(nsamps == len(samps)) 
    except AssertionError, e: 
     print nsamps, "not equal to", len(samps) 

    return samps, fs 

# print an error when no data can be found 
def no_audio_data(): 
    print "No audio data for sample, skipping..." 
    return None, None 

# simple peak detection 
def peak_detect(data): 
    max_val = numpy.amax(abs(data)) 
    peak_ndx = numpy.where(data==max_val) 
    if len(peak_ndx[0]) == 0: #if nothing found then the max must be negative 
     peak_ndx = numpy.where(data==-max_val) 
    return peak_ndx 

def bpm_detector(data,fs): 
    cA = [] 
    cD = [] 
    correl = [] 
    cD_sum = [] 
    levels = 4 
    max_decimation = 2**(levels-1); 
    min_ndx = 60./ 220 * (fs/max_decimation) 
    max_ndx = 60./ 40 * (fs/max_decimation) 

    for loop in range(0,levels): 
     cD = [] 
     # 1) DWT 
     if loop == 0: 
      [cA,cD] = pywt.dwt(data,'db4'); 
      cD_minlen = len(cD)/max_decimation+1; 
      cD_sum = numpy.zeros(cD_minlen); 
     else: 
      [cA,cD] = pywt.dwt(cA,'db4'); 
     # 2) Filter 
     cD = signal.lfilter([0.01],[1 -0.99],cD); 

     # 4) Subtractargs.filename out the mean. 

     # 5) Decimate for reconstruction later. 
     cD = abs(cD[::(2**(levels-loop-1))]); 
     cD = cD - numpy.mean(cD); 
     # 6) Recombine the signal before ACF 
     # essentially, each level I concatenate 
     # the detail coefs (i.e. the HPF values) 
     # to the beginning of the array 
     cD_sum = cD[0:cD_minlen] + cD_sum; 

    if [b for b in cA if b != 0.0] == []: 
     return no_audio_data() 
    # adding in the approximate data as well...  
    cA = signal.lfilter([0.01],[1 -0.99],cA); 
    cA = abs(cA); 
    cA = cA - numpy.mean(cA); 
    cD_sum = cA[0:cD_minlen] + cD_sum; 

    # ACF 
    correl = numpy.correlate(cD_sum,cD_sum,'full') 

    midpoint = len(correl)/2 
    correl_midpoint_tmp = correl[midpoint:] 
    peak_ndx = peak_detect(correl_midpoint_tmp[min_ndx:max_ndx]); 
    if len(peak_ndx) > 1: 
     return no_audio_data() 

    peak_ndx_adjusted = peak_ndx[0]+min_ndx; 
    bpm = 60./ peak_ndx_adjusted * (fs/max_decimation) 
    print bpm 
    return bpm,correl 


if __name__ == '__main__': 
    parser = argparse.ArgumentParser(description='Process .wav file to determine the Beats Per Minute.') 
    parser.add_argument('--filename', required=True, 
        help='.wav file for processing') 
    parser.add_argument('--window', type=float, default=3, 
        help='size of the the window (seconds) that will be scanned to determine the bpm. Typically less than 10 seconds. [3]') 

    args = parser.parse_args() 
    samps,fs = read_wav(args.filename) 

    data = [] 
    correl=[] 
    bpm = 0 
    n=0; 
    nsamps = len(samps) 
    window_samps = int(args.window*fs)   
    samps_ndx = 0; #first sample in window_ndx 
    max_window_ndx = nsamps/window_samps; 
    bpms = numpy.zeros(max_window_ndx) 

    #iterate through all windows 
    for window_ndx in xrange(0,max_window_ndx): 

     #get a new set of samples 
     #print n,":",len(bpms),":",max_window_ndx,":",fs,":",nsamps,":",samps_ndx 
     data = samps[samps_ndx:samps_ndx+window_samps] 
     if not ((len(data) % window_samps) == 0): 
      raise AssertionError(str(len(data))) 

     bpm, correl_temp = bpm_detector(data,fs) 
     if bpm == None: 
      continue 
     bpms[window_ndx] = bpm 
     correl = correl_temp 

     #iterate at the end of the loop 
     samps_ndx = samps_ndx+window_samps; 
     n=n+1; #counter for debug... 

    bpm = numpy.median(bpms) 
    print 'Completed. Estimated Beats Per Minute:', bpm 

    n = range(0,len(correl)) 
    plt.plot(n,abs(correl)); 
    plt.show(False); #plot non-blocking 
    time.sleep(10); 
plt.close(); 
Các vấn đề liên quan