Skip to content

Instantly share code, notes, and snippets.

@st1vms
Last active July 31, 2025 13:41
Show Gist options
  • Save st1vms/8f8eb91de26423031d15e2d5f39f1e04 to your computer and use it in GitHub Desktop.
Save st1vms/8f8eb91de26423031d15e2d5f39f1e04 to your computer and use it in GitHub Desktop.
Frequency estimation
import pyaudio
import numpy as np
import scipy.signal
import time
import sounddevice as sd
RATE = 44100
CHUNK = 2048
DURATION = 10 # seconds to record
def record_audio(duration, rate, chunk):
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16,
channels=1,
rate=rate,
input=True,
frames_per_buffer=chunk)
print("Recording...")
frames = []
for _ in range(0, int(rate / chunk * duration)):
data = stream.read(chunk)
frames.append(np.frombuffer(data, dtype=np.int16))
print("Done.")
stream.stop_stream()
stream.close()
p.terminate()
audio = np.hstack(frames)
return audio
# Estimate frequency using autocorrelation
def estimate_frequency(signal, rate):
# Apply a Hamming window
signal = signal * np.hamming(len(signal))
# Autocorrelation
corr = np.correlate(signal, signal, mode='full')
corr = corr[len(corr)//2:]
# Find first minimum then maximum after it
d = np.diff(corr)
start = np.where(d > 0)[0][0]
peak = np.argmax(corr[start:]) + start
fundamental_freq = rate / peak
return fundamental_freq
def play_tone(frequency, duration=2.0, rate=44100):
t = np.linspace(0, duration, int(rate * duration), False)
tone = 0.5 * np.sin(2 * np.pi * frequency * t)
sd.play(tone, rate)
sd.wait()
if __name__ == "__main__":
audio = record_audio(DURATION, RATE, CHUNK)
freq = estimate_frequency(audio, RATE)
print(f"Estimated frequency: {freq:.2f} Hz")
play_tone(freq, duration=2.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment