Как массив FFT генерирует спектральный граф? - PullRequest
0 голосов
/ 26 мая 2019

Итак, мой код такой:


from scipy.io import wavfile
import numpy as np
import matplotlib.pyplot as plt
from skimage import util
import os


rate, audio = wavfile.read('scale_a_lydian.wav')

audio = np.mean(audio, axis=1)

N = audio.shape[0]
L = N / rate

print('L', L)

f, ax = plt.subplots()
ax.plot(np.arange(N) / rate, audio)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Amplitude [unknown]');
#plt.show()

M = 1024

#Audio is 44.1 Khz, or ~44100 samples / second
#window function takes 1024 samples or 0.02 seconds of audio (1024 / 44100 = ~0.02 seconds)
# and shifts the window 100 over each time
# so there would end up being (total_samplesize - 1024)/(100) total steps done (or slices)

slices = util.view_as_windows(audio, window_shape=(M,), step=100) #slices overlap

win = np.hanning(M + 1)[:-1]
slices = slices * win #each slice is 1024 samples (0.02 seconds of audio)


slices = slices.T #transpose matrix -> make each column 1024 samples (ie. make each column one slice)


spectrum = np.fft.fft(slices, axis=0)[:M // 2 + 1:-1] #perform fft on each slice and then take the first half of each slice, and reverse

spectrum = np.abs(spectrum) #take absolute value of slices


# take SampleSize * Slices
# transpose into slices * samplesize
# Take the first row -> slice * samplesize
# transpose back to samplesize * slice (essentially get 0.01s of spectrum)

spectrum2 = spectrum.T


spectrum2 = spectrum2[0:1]

spectrum2 = spectrum2.T

N = spectrum2.shape[0]
L = N / rate

#for i in range(1, int(L*10)):
f, ax = plt.subplots(figsize=(2, 10))

S = np.abs(spectrum)
S = 20 * np.log10(S / np.max(S))

ax.imshow(S, origin='lower', cmap='viridis',
          extent=(0,L,0, 4.5 ))
ax.axis('tight')

ax.set_ylabel('Frequency [kHz]')
ax.set_xlabel('Time [s]');

plt.show()

Итак, я пытаюсь понять, как на самом деле работает созданный график.Насколько я понимаю, форма 'spectrum2' (510,1) означает, что это 510 сэмплов или 0,01 с аудио.Но откуда берутся различные оттенки желтого (указывающие на амплитуду)?

Я предполагаю, что я почему-то неправильно понимаю, как работает NumPy или как устроены данные.Вот пример графика, который будет генерировать мой код:

fft spectrum

...