前提・実現したいこと
FFTしたものを一定の周波数ごとに周波数軸を区切り、それぞれの区間の最大値を求める。
発生している問題・エラーメッセージ
category = pd.cut(data, bins=np.arange(0, 23100, 100), right=False)を使ってやろうとしたのですが、分類まではできてもその周波数域を指定の仕方が分からず最大値を求めることが出来ませんでした。途中までのプログラムを下に載せます。
該当のソースコード
Python
1import numpy as np 2import matplotlib.pyplot as plt 3import soundfile as sf 4import sys 5import pandas as pd 6 7def nextpow2(n): 8 # 入力nの絶対値以上の最小の2のべき乗の指数を計算する 9 m_f = np.log2(n) 10 m_i = np.ceil(m_f) 11 return int(np.log2(2 ** m_i)) 12 13 14 15# ファイル読み込み 16filename = "bass.wav" 17 18wave, fs = sf.read(filename) #filename音データと周波数 19print("サンプリング周波数は{}[Hz]".format(fs)) 20 21# ステレオ2chの場合、LchとRchに分割 22wav_l = wave[:, 0] 23wav_r = wave[:, 1] 24 25# 入力をモノラル化 26xs = (0.5 * wav_l) + (0.5 * wav_r) 27 28 29print('wave',xs) 30print('fs',fs) 31 32 33# データのパラメータ 34f = xs # 音データ 35N = 20000 # サンプル数 36dt = 0.01 # サンプリング間隔 37t = np.arange(0, N*dt, dt) # 時間軸 38 39n = 2**nextpow2(N) # Transform length 40print(n) 41freq = np.arange(0,n)*(fs/n) # Frequency range 42print(freq) 43 44# フーリエ変換 45F = np.fft.fft(f, n) # 高速フーリエ変換 46power = F*np.conj(F)/n # Power of the DFT 47F_abs = np.abs(F) # 振幅スペクトルを計算 48 49 50# shift 51# 周波数範囲の前半 (0 からナイキスト周波数 fs/2 まで) は、残りの半分がその鏡映となるため、データの周波数成分を識別するのに十分です。 52F0 = np.fft.fftshift(F) # Rearrange y values 53freq0 = np.arange(-n/2,n/2)*(fs/n) # Frequency range 54power0 = F0*np.conj(F0)/n # Power of the DFT 55power0 = np.abs(F0)/(N/2) 56 57 58 59# 離散フーリエ変換+正規化 60yf = np.fft.fft(f)/(N/2) 61# 直流成分の振幅を揃える(実用上は不要) 62 63 64# 周波数スケール作成 65# t/dt/dt/N で作成しても良い 66freq = np.fft.fftfreq(N, dt) 67 68print("最大のピークの周波数は{:.2f}Hz".format(np.abs(freq0[np.argmax(power0)]))) 69 70 71category = pd.cut(freq0, bins=np.arange(0, 23100, 100), right=False) 72print("データとそれが所属する区間") 73for d, c in zip(freq0, category): 74 print(d, "・・・", c) 75print(d,c) 76 77sys.exit() 78
試したこと
配列を使って指定できないかと試したのですが、表示できませんでした。
補足情報(FW/ツールのバージョンなど)
PyCharmを利用しています。
あなたの回答
tips
プレビュー