Created
April 6, 2024 01:29
-
-
Save Defozo/c93f8ea7292a3339830d38e4bb00ff44 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Displays graph amplitudes x decibels from selected microphone | |
import pyaudio | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from matplotlib.animation import FuncAnimation | |
# Constants | |
FORMAT = pyaudio.paInt16 # Audio format (16-bit PCM) | |
CHANNELS = 1 # Mono audio | |
RATE = 96000 # Adjusted sample rate, e.g., 96kHz | |
CHUNK = 2048 # Adjusted chunk size, may need tuning based on performance | |
FREQ_RANGE = (14000, 24000) | |
# Initialize PyAudio | |
p = pyaudio.PyAudio() | |
# List all available microphones | |
print("Available audio input devices:") | |
info = p.get_host_api_info_by_index(0) | |
numdevices = info.get('deviceCount') | |
for i in range(0, numdevices): | |
if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0: | |
print(f"Device ID {i} - {p.get_device_info_by_host_api_device_index(0, i).get('name')}") | |
# Let user select a microphone | |
mic_index = int(input("Enter the device ID of the microphone you wish to use: ")) | |
# Open stream with the selected microphone | |
stream = p.open(format=FORMAT, | |
channels=CHANNELS, | |
rate=RATE, | |
input=True, | |
input_device_index=mic_index, | |
frames_per_buffer=CHUNK) | |
# Initialize the plot | |
fig, ax = plt.subplots() | |
x = np.linspace(FREQ_RANGE[0], FREQ_RANGE[1], CHUNK // 2) | |
line, = ax.plot(x, np.random.rand(CHUNK // 2)) | |
ax.set_ylim(0, 250) # Decibel range | |
ax.set_xlim(FREQ_RANGE[0], FREQ_RANGE[1]) | |
ax.set_xlabel('Frequency (Hz)') | |
ax.set_ylabel('Decibel (dB)') | |
# Global variables to track the threshold state | |
threshold_exceeded = False | |
message_displayed = False | |
def update(frame): | |
global threshold_exceeded, message_displayed | |
data = np.frombuffer(stream.read(CHUNK), dtype=np.int16) | |
fft = np.abs(np.fft.fft(data)[0:CHUNK // 2]) | |
db = 20 * np.log10(np.clip(fft, 1e-20, 1e100)) | |
# Frequency indices for 22-23 kHz, assuming linear spacing | |
idx_start = int((22_000 - FREQ_RANGE[0]) / (FREQ_RANGE[1] - FREQ_RANGE[0]) * (CHUNK // 2)) | |
idx_end = int((23_000 - FREQ_RANGE[0]) / (FREQ_RANGE[1] - FREQ_RANGE[0]) * (CHUNK // 2)) | |
# Check if any dB value in the 22-23 kHz range exceeds 60 | |
if np.any(db[idx_start:idx_end] > 60): | |
threshold_exceeded = True | |
if not message_displayed: | |
from datetime import datetime | |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
print(f"{current_time} - Amplitude in the 22-23 kHz range exceeded 60 dB!") | |
message_displayed = True | |
else: | |
# Reset the message flag if the condition is no longer true | |
threshold_exceeded = False | |
message_displayed = False | |
line.set_ydata(db) | |
return line, | |
ani = FuncAnimation(fig, update, blit=True) | |
plt.show() | |
# Close the stream and PyAudio | |
stream.stop_stream() | |
stream.close() | |
p.terminate() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment