2017-12-26 55 views
3

다음과 같이 만든 노래 (wav 형식의 오디오 파일, 약 3 분 길이)에 대해 FFT를 수행하려고합니다. $1파이썬 : 음악 파일에 FFT 수행

ffmpeg -i "$1" -vn -ab 128k -ar 44100 -y -ac 1 "${1%.webm}.wav" 

는 WEBM 파일의 이름입니다.

import numpy as np 
import matplotlib.pyplot as plt 

# presume file already converted to wav. 
file = os.path.join(temp_folder, file_name) 

rate, aud_data = scipy.io.wavfile.read(file) 

# wav file is mono. 
channel_1 = aud_data[:] 

fourier = np.fft.fft(channel_1) 

plt.figure(1) 
plt.plot(fourier) 
plt.xlabel('n') 
plt.ylabel('amplitude') 
plt.show() 

문제는, 그것은 영원히 취

는 주어진 파일의 FFT를 표시하도록되어 코드입니다. 너무 오랜 시간이 걸리므로 결과를 표시 할 수 없습니다.이 게시물을 연구하고 쓸 시간이 충분하고 아직 완성되지 않았기 때문에.

나는 파일이 너무 길다는 가정,

이후
print (aud_data.shape) 

출력 (9218368,), 그러나 이것은 현실 세계의 문제처럼 보이는, 그래서 어떻게 든 오디오 파일의 FFT를 얻을 수있는 방법이 있기를 바랍니다.

내가 뭘 잘못하고 있니? 고맙습니다.

편집

문제의 더 나은 공식은 다음과 같습니다 음악 처리에서 좋은의 FFT는? 예를 들어 2 조각의 유사성.

의견에서 지적한대로 내 일반적인 접근 방식은 너무 느립니다.

감사합니다.

+0

[오디오 분석 플롯 스펙트로]의 가능한 복제 (https://stackoverflow.com/questions/47954034/plotting-spectrogram-in-audio-analysis) – Pavel

+2

음 : 상기 방법을 이용하여 몇 정현파 , FFT는 O (nlogn) 시간에 실행되며 ~ 10^8 sa가 있습니다. mples, 그래, 네가 뭘 기대 했니? –

+0

@Pavel. 밀접하게 관련되어 있지만 완전히 동일하지는 않습니다. 나는 속임수 표가 여기에서 보증 받았다고 생각하지 않는다. –

답변

1

상당히 분석의 fft 부분을 가속화하기 위해 2의 거듭 제곱에 데이터 아웃 패드 제로 수 여기

import numpy as np 
import matplotlib.pyplot as plt 

# rate, aud_data = scipy.io.wavfile.read(file) 
rate, aud_data = 44000, np.random.random((9218368,)) 

len_data = len(aud_data) 

channel_1 = np.zeros(2**(int(np.ceil(np.log2(len_data))))) 
channel_1[0:len_data] = aud_data 

fourier = np.fft.fft(channel_1) 

은의 푸리에 변환의 실수 성분을 플롯의 일례이다

import numpy as np 
import matplotlib.pyplot as plt 

# rate, aud_data = scipy.io.wavfile.read(file) 
rate = 44000 
ii = np.arange(0, 9218368) 
t = ii/rate 
aud_data = np.zeros(len(t)) 
for w in [1000, 5000, 10000, 15000]: 
    aud_data += np.cos(2 * np.pi * w * t) 

# From here down, everything else can be the same 
len_data = len(aud_data) 

channel_1 = np.zeros(2**(int(np.ceil(np.log2(len_data))))) 
channel_1[0:len_data] = aud_data 

fourier = np.fft.fft(channel_1) 
w = np.linspace(0, 44000, len(fourier)) 

# First half is the real component, second half is imaginary 
fourier_to_plot = fourier[0:len(fourier)//2] 
w = w[0:len(fourier)//2] 

plt.figure(1) 

plt.plot(w, fourier_to_plot) 
plt.xlabel('frequency') 
plt.ylabel('amplitude') 
plt.show()