Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- import numpy as np
- import pyaudio
- if __name__ == "__main__":
- 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
- # widocznosc dokumentacji dla numpy.rfftfreq()
- 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 rozdzielczoscia', 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
- 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))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement