简体   繁体   English

用于 Pitch Class Profiling 的 Python 代码

[英]Python Code for Pitch Class Profiling

I'm working on a the Pitch Class Profile as proposed by Takuya Fujishima.我正在制定由 Takuy​​a Fujishima 提出的 Pitch Class Profile。 I've done my best to implement this equation (using scipy and numpy);我已尽力实现这个等式(使用 scipy 和 numpy); however, I've been getting some rather odd results.然而,我得到了一些相当奇怪的结果。 I've debated on putting this on DSP, but figured this is more of a coding problem than an equation understanding problem.我曾就将其放在 DSP 上进行过辩论,但认为这更像是一个编码问题,而不是方程理解问题。

In any case, here is my code.无论如何,这是我的代码。

import scipy.io.wavfile
import numpy as np
import math
import sys

class PCP:

    def __init__(self):
        self.note_references = [16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50, 29.14, 30.87]
        self.results = {}


    def create_fft(self, filename):
        self.rate, self.data = scipy.io.wavfile.read('fmin.wav')
        print "Data from the File: \n", self.data

        self.frames = self.data.size
        print "Number of Frames: ", self.frames

        print "Rate: ", self.rate

        self.fft_results = np.fft.rfft(self.data) ##fft computing and normalization
        print "Results from the FFT: \n", self.fft_results


    # The work of the following classes was almost entirely based on a
    # thread in DSP.  Here is the link to the particular article
    # http://dsp.stackexchange.com/questions/13722/pitch-class-profiling
    # This function returns the values of the notes given the spectrograph
    def m_func(self, l, p):
        #M(l) = round(12 * log_2( (f_s*l)/(N*f_ref) ) ) % 12
        #print "L: ", l
        #print "Note: ", p
        a = self.rate * l
        b = self.frames * self.note_references[p]
        c = 12 * np.log2(a/b)
        d = np.round(c)
        e = np.mod(d.all(), 12)
        #print "Result: ", e
        #raw_input()
        return e


    def pcp(self, p):
        r = 0
        for l in self.fft_results:
            result = self.m_func(l[0], p)
            #print "actual returned result", result
            if result == p:
                r+=1
                #print "There was a match!  Add it!"
        return r


    def calculate_PCP(self):
        for p in range(0,11): #for all 12 notes
            self.results[p] = self.pcp(p)


    def print_results(self):
        for i in self.results.keys():
            print i , ":" , self.results[i]


def main():
    m = PCP()
    m.create_fft("fmin.wav")
    m.calculate_PCP()
    m.print_results()


if __name__ == '__main__':
    main()

Here are the outputs:以下是输出:

Data from the File: 
[[16 15]
 [ 9  9]
 [15 15]
 ..., 
 [ 0  0]
 [ 0  0]
 [ 0  0]]
Number of Frames:  352800
Rate:  44100
Results from the FFT: 
[[ 31.+0.j   1.+0.j]
 [ 18.+0.j   0.+0.j]
 [ 30.+0.j   0.+0.j]
 ..., 
 [  0.+0.j   0.+0.j]
 [  0.+0.j   0.+0.j]
 [  0.+0.j   0.+0.j]]
PCP.py:36: RuntimeWarning: divide by zero encountered in log2
  c = 12 * np.log2(a/b)
PCP.py:36: RuntimeWarning: invalid value encountered in cdouble_scalars
  c = 12 * np.log2(a/b)
0 : 143
1 : 176263
2 : 0
3 : 0
4 : 0
5 : 0
6 : 0
7 : 0
8 : 0
9 : 0
10 : 0

The file contains a piano playing an F-minor chord (responding with 0, 5, and 7 in the results dictionary).该文件包含演奏 F 小调和弦的钢琴(在结果字典中以 0、5 和 7 响应)。 The results, however, indicate a very strong presence for C#/Db, and I can certainly verify there is no C# in the recording.然而,结果表明 C#/Db 的存在非常强烈,我当然可以验证录音中没有 C#。 I'd appreciate any and all help!我将不胜感激任何帮助!

Pitch frequency is different from spectral frequency, and thus not equal to the content of every 12th fft magnitude result bin (especially for recordings of actual musical sounds).音高频率不同于频谱频率,因此不等于每 12 个 fft 幅度结果箱的内容(特别是对于实际音乐声音的录音)。 If nothing else, any strong odd harmonics, which aren't powers of two, will end up in the wrong pitch class bin.如果不出意外,任何不是 2 次幂的强奇次谐波最终都会出现在错误的音级箱中。

The algorithm referenced only works for a restricted class of waveforms, which are likely not representative of live music audio.所引用的算法仅适用于有限类别的波形,这些波形可能不代表现场音乐音频。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM