Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 47 additions & 26 deletions recording.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import pyaudio
from random import *
import sys
import time
from itertools import chain
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from scipy.fftpack import fft

CHUNK = 1024
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
INTERVAL = 0.75 # in s
MIN = 0.1 # Sensitivity
SIZE = INTERVAL * RATE
T = 1 / RATE
SPACE = np.linspace(0.0, 1.0 / (2 * T), int(SIZE / 2))
SENSITIVITY = 0.003 # which amplitudes get evaluated

p = pyaudio.PyAudio()

Expand All @@ -23,40 +24,37 @@
input=True,
frames_per_buffer=CHUNK)

T = 1 / RATE
x = np.linspace(0.0, 1.0 / (2 * T), int(SIZE / 2))


def gen_scale():

pitches = [65.4064]
root = 65.4064

for Tone in range(47):
for Tone in range(55):
root = root * 2 ** (1 / 12)
pitches.append(round(root, 1))

rootnotes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
names = []

for line in range(4):
for line in range(5):
for e in rootnotes:
if line > 0:
names.append(e + str(line - 1))
else:
names.append(e)
return pitches, names


class Notes:
def __init__(self, pitches, notes):
self.pitches = pitches
self.notes = notes

def find_closest(self, freq):
closest = min(self.pitches, key=lambda x: abs(x - freq))
Index = self.pitches.index(closest)
closest = min(self.pitches, key=lambda x: abs(x - freq))
index = self.pitches.index(closest)

return closest, self.notes[Index]
return closest, self.notes[index]


note = Notes(gen_scale()[0], gen_scale()[1])
Expand All @@ -73,23 +71,46 @@ def interval_fft():
yr = fft(frames) # raw Fourier Transform
y = 2 / SIZE * np.abs(yr[0:np.int(SIZE / 2)]) # only positive values

return dict(zip(x, y)) # map freqs to amplitude
return dict(zip(y, SPACE)) # map freqs to amplitude


while True:
freqs = interval_fft()
loudestFreq = max(freqs, key=freqs.get)
def picknote():
rand_pitch = note.pitches[randint(0, len(note.pitches))]
rand_note = note.find_closest(rand_pitch)
return rand_pitch, rand_note

if loudestFreq > 20:
print(round(max(freqs, key=freqs.get), 2))
else:
print("-")

def listen():
fftvals = interval_fft()
loudestfreq = 0
maxamp = max(fftvals)
if maxamp > SENSITIVITY:
loudestfreq = fftvals[maxamp]

if loudestfreq > 25:
freq = round(loudestfreq, 2)
n = note.find_closest(freq)

# plt.plot(x,y)
# plt.show()
return freq
else:
return 0


def quiz():
while True:
playednote = ""
notepick = picknote()
print("Play " + str(notepick[1][1]) + " @ " + str(notepick[1][0]) + "Hz")
while playednote != notepick[1][1]:
rawlisten = listen()
playednote = note.find_closest(rawlisten)[1]
# print(playednote, end="\r")
if rawlisten > 25:
sys.stdout.write('\r' + "You most likely played: " + playednote + " @ " + str(rawlisten) + "Hz")
else:
sys.stdout.write('\r' + "You most likely played: nothing")
print("\nGood, now next one\n------------------")


stream.stop_stream()
stream.close()
p.terminate()
if __name__ == "__main__":
quiz()