1. ホーム
  2. python

[解決済み] Pythonによるピッチ検出

2022-02-10 16:48:44

質問

私が取り組んでいるプログラムのコンセプトは、特定の周波数(人間の音声周波数80-300hz)を検出し、データベースからチェックすることによって、文章のイントネーションを表示するPythonモジュールです。SciPyを使って音声ファイルの周波数をプロットしているのですが、ピッチを分析するために特定の周波数を設定することができません。どうすればよいでしょうか?

より詳しく 音声のパターン(例:上昇、下降)を設定し、プログラムがサウンドファイルが特定のパターンに従っているかどうかを検出できるようにしたいのですが、可能でしょうか?

どのように解決するのですか?

次のことを試してみてはいかがでしょうか。人間の声にも300Hzをはるかに超える倍音があることはご存じだと思います。それでも、オーディオファイルにウィンドウを移動させ、最大パワー(下図)の変化や、ウィンドウ内の周波数のセットを見ることができます。以下のコードは、直感的に理解するためのものです。

import scipy.fftpack as sf
import numpy as np
def maxFrequency(X, F_sample, Low_cutoff=80, High_cutoff= 300):
        """ Searching presence of frequencies on a real signal using FFT
        Inputs
        =======
        X: 1-D numpy array, the real time domain audio signal (single channel time series)
        Low_cutoff: float, frequency components below this frequency will not pass the filter (physical frequency in unit of Hz)
        High_cutoff: float, frequency components above this frequency will not pass the filter (physical frequency in unit of Hz)
        F_sample: float, the sampling frequency of the signal (physical frequency in unit of Hz)
        """        

        M = X.size # let M be the length of the time series
        Spectrum = sf.rfft(X, n=M) 
        [Low_cutoff, High_cutoff, F_sample] = map(float, [Low_cutoff, High_cutoff, F_sample])

        #Convert cutoff frequencies into points on spectrum
        [Low_point, High_point] = map(lambda F: F/F_sample * M, [Low_cutoff, High_cutoff])

        maximumFrequency = np.where(Spectrum == np.max(Spectrum[Low_point : High_point])) # Calculating which frequency has max power.

        return maximumFrequency

voiceVector = []
for window in fullAudio: # Run a window of appropriate length across the audio file
    voiceVector.append (maxFrequency( window, samplingRate))

さて、声のイントネーションによって、最大出力周波数が変化することがありますが、これを登録し、あるイントネーションに対応させることができます。これは必ずしも常に正しいとは限りませんし、多くの周波数のシフトを一緒に監視する必要があるかもしれませんが、これで始めることができるはずです。