Drodzy,
wykonałem kod, którego obliczenia działają w pętli.
Próbowałem różnymi metodami (to, co wyświetla się w konsoli, wrzucić do okna metody ScrolledText);
Przy pomocy:
- insert
- dataframe
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import fig as fig
import numpy as np
import pyaudio
import os
from matplotlib import pyplot as plt
from matplotlib import animation
from tkinter import scrolledtext
from tkinter import *
from PIL import ImageTk, Image
import pandas as pd
if __name__ == "__main__":
window = Tk()
window.title('Tuner Gitarowy')
window.geometry('1380x855')
img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
window = Label(window, background='NavajoWhite3', image=img)
window.pack(side='right', fill='both', expand='yes')
txt = scrolledtext.ScrolledText(window, width=60, height=53)
txt.grid(column=0, row=1)
window.mainloop()
FSAMP = 22050 # czestotliwosc probkowania w Hz
ROZMIAR_PROB = 2048 # ilosc probek
KLATEK_NA_FFT = 16 # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
NOTKA_MIN = 40 # E2
NOTKA_MAX = 64 # E4
# dla wyswietlenia nazw dzwieku:
NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()
# nowe dzwieki:
PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT
def nazwa_notki(n):
return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))
def czestotliwosc_na_numer(f):
return 64 + 12 * np.log2(f / 329.63)
def numer_na_czestotliwosc(n):
return 329.63 * 2.0 ** ((n - 64) / 12.0)
# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera:
def notka_do_fftbin(n):
return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI
imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))
# Przydzial przestrzeni aby uruchomic szybka transformate fouriera:
buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
numer_klatki = 0
# inicjalizacja dzwieku:
stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
stream.start_stream()
# tworzenie funkcji Hanninga:
window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))
# wypisanie poczatkowego tekstu:
print('pobieranie probek w:', FSAMP, 'Hz z maksymalna czestotliwoscia', KROK_CZESTOTLIWOSCI, 'Hz')
# otrzymywane dane w czasie:
while stream.is_active():
# przesuwanie bufora i wprowadzenie nowych danych
buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)
# Uruchom szybka transformate fouriera na okiennym buforze
fft = np.fft.rfft(buf * window)
# pobierz czestotliwosc maksymalnej wartosci z zakresu
czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI
# pobierz numer notatki i najblizsza notatke
n = czestotliwosc_na_numer(czestotliwosc)
n0 = int(round(n))
# dane wyjsciowe konsoli, gdy mamy pelny bufor
numer_klatki += 1
nameCol = ('n', 'czestotliwosc', 'nazwa_notki(n0)', 'n - n0')
x = n
y = czestotliwosc
z = nazwa_notki(n)
v = (n - n0)
data = pd.DataFrame(columns=nameCol)
if numer_klatki >= KLATEK_NA_FFT:
print('Numer {:7.2f} Wysokosc: {:7.2f} Hz Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))
# najpierw ustaw figure, os i element wykresu, ktory chcemy animowac
def Okno(w):
fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)
# funkcja inicjalizacji: wykresla tlo kazdej ramki
def init():
czestotliwosc.set_data([], [])
return czestotliwosc,
# funkcja animacji. Nazywa sie to sekwencyjnie
def oblicz(i):
x = np.linspace(0, 2, 1000)
y = np.sin(2 * np.pi * (x - 0.01 * i))
czestotliwosc.set_data(x, y)
return czestotliwosc,
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
dataLoop = pd.DataFrame(columns=nameCol)
dataLoop['n'] = (x)
dataLoop['czestotliwosc'] = (y)
dataLoop['nazwa_notki(n0)'] = (z)
dataLoop['n - n0'] = (v)
print(dataLoop)
data = data.append(dataLoop, ignore_index=True)
Przypisałem zmienne do innym zmiennych, które realizują obliczenia.
Gdzieś robię błąd, bo nie wyrzuca tych wyników do okna.
Udostępniam cały kod, aktualny: https://megawrzuta.pl/download/6c42fee8422bc1dcfe07336af85658c6.html
i wyświetlający okno, a po jego zamknięciu printowanie wyników w konsoli: https://megawrzuta.pl/download/d7f580e8f1c06c9653f6ace83b08c1ff.html
Może czegoś się dopatrzycie.
Bardzo proszę o pomoc.