This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
computers-sound-music-portf.../code/tuner/main.py
David Westgate 839411b1fd tuner code
2024-11-15 15:50:44 -08:00

86 lines
2.1 KiB
Python

import string
from typing import Any
from scipy.io import wavfile as wav
import numpy as np
import sounddevice as sd
import math
import sys
print("Tuner exercise")
SAMPLE_RATE = 44100
CHUNK = 2048
QUIET_THRESHOLD = 0.01
A4 = 440
DEBUG = True
NOTES = "A B♭/A♯ B C D♭/C♯ D E♭/D♯ E F F♯/G♭ G A♭/G♯".split()
def calculate_note(frequency):
if frequency > 0:
note_num = round(math.log2(frequency / 440) * 12)
octave = math.floor(4 + note_num / 12)
rel_note = note_num % 12
note = NOTES[rel_note]
return f"{note}{octave}"
return 0
def dominant_frequency(data, samplerate):
windowed_data = data * np.hanning(len(data))
fft_result = np.fft.rfft(windowed_data)
fft_magnitude = np.abs(fft_result)
freqs = np.fft.rfftfreq(len(windowed_data), 1 / samplerate)
peak_idx = np.argmax(fft_magnitude)
dominant_freq = freqs[peak_idx]
return dominant_freq
def calculate_rms(data):
return np.sqrt(np.mean(data**2))
def audio_callback(indata: np.ndarray, frames: int, time: Any, status: Any):
if status:
print(f"Status: {status}")
rms = calculate_rms(indata)
if rms > QUIET_THRESHOLD:
mono_data = np.mean(indata, axis=1)
frequency = dominant_frequency(mono_data, SAMPLE_RATE)
out = f"\r{calculate_note(frequency)}"
if DEBUG: out += f" Dominant Frequency: {frequency:.2f} Hz (RMS: {rms:.3f})"
sys.stdout.write(out)
sys.stdout.flush()
else:
pass
if DEBUG:
print(sd.query_devices())
try:
stream = sd.InputStream(
device=15,
callback=audio_callback,
samplerate=SAMPLE_RATE,
channels=1,
blocksize=CHUNK,
)
stream.start()
if DEBUG:
print("channels? ", stream.channels)
print("device? ", stream.device)
print("active? ", stream.active)
while True:
pass
except KeyboardInterrupt:
print("Audio recording stopped.")
finally:
print("Stream closed.")
# https://python-sounddevice.readthedocs.io/en/0.5.1/examples.html#plot-microphone-signal-s-in-real-time
# https://github.com/mzucker/python-tuner/blob/master/tuner.py