Создание спектрограммы matplotlib с частотой «маркер» и кнопкой «пауза» - PullRequest
1 голос
/ 17 февраля 2020

Я создаю простую спектрограмму в matplotlib

  1. Мне интересно, как (или с чего начать, чтобы научиться) создать простой трекер курсора, который сообщает мне значение частоты на пиках мой график Спектрограмма, которую я пытаюсь воспроизвести, приведена ниже. Я хочу достичь спектрального маркера красного цвета .

spectrogram

Я хотел бы создать простой подвижный вертикальный маркер, такой как выше, который говорит мне, на какой частоте воспроизводится мой звук (что измеряет значение x на моем графике в определенной точке).

Я также хочу знать , как вставить кнопку паузы , как показано выше. Это должно работать так, чтобы весь экран можно было приостановить в любое время

Текущее решение

На данный момент моя программа выглядит так, как показано ниже. Это простая спектрограмма, которую я сделал в python.

looks like

Мой код указан ниже. Пожалуйста, дайте мне знать, если есть какие-либо проблемы с ним, так как я очень плохо знаком со Stack Overflow, и использование этого сайта очень чуждо мне - мне есть чему поучиться!

Program: Spectrogram
"""

#preamble
import pyaudio, matplotlib.pyplot as plt, numpy as np, struct, sys
from scipy.fftpack import fft

#set constants
CHUNK = 1024 * 2    #samples per frame
FORMAT = pyaudio.paInt16    #audio format
CHANNELS = 1    #single channel for microphone
RATE = 44100    #samples per second

#create matplotlib figure and axes
fig, (ax, ax2) = plt.subplots(2, figsize=(10, 7))

p = pyaudio.PyAudio()
plt.ion()

#stream object to get data from microphone
stream = p.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    output=True,
    frames_per_buffer=CHUNK
)

# variables for plotting
x = np.arange(0, 2 * CHUNK, 2)  #samples for waveform
x_fft = np.linspace(0, RATE, CHUNK) #frequencies for spectrum

#create a line object with random data
line, = ax.plot(x, np.random.rand(CHUNK), 'b-', lw=1)

#create a semilog x line for spectrum
line_fft, = ax2.semilogx(x_fft, np.random.rand(CHUNK), 'b-', lw=1)

#axes formatting for waveform
ax.set_title('Audio Waveform')
ax.set_xlabel('Samples')
ax.set_ylabel('Volume')
ax.set_xlim(0, 2 * CHUNK)
ax.set_ylim(0, 255)
plt.setp(ax, xticks=[0, CHUNK, 2 * CHUNK], yticks=[0, 128, 255])

#axis formatting for spectrum
ax2.set_title('Audio Spectrum')
ax2.set_xlabel('Frequency (Hz)')
ax2.set_ylabel('Volume')
ax2.set_xlim(20, RATE/2)
ax2.set_ylim(0, 1.2)
#ax2.set_xticks(np.arange(50, 1000, 50))
#ax2.grid(True, which='both')

#show plot
plt.tight_layout()
plt.show(block=False)

# close stuff
def handle_close(evt):
    sys.exit()
fig.canvas.mpl_connect('close_event', handle_close)

while True:
    #binary data
    data = stream.read(CHUNK, False)

    #convert data to integers
    data_int = struct.unpack(str(2 * CHUNK) + 'B', data)

    #create np array and offset by 128
    data_np = np.array(data_int, dtype='b')[::2] + 128

    line.set_ydata(data_np)

    #compute FFT and update line
    y_fft = fft(data_int)
    line_fft.set_ydata(np.abs(y_fft[0:CHUNK]) / (128 * CHUNK))

    #update figure canvas
    plt.pause(.0001)
    plt.show()
...