61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
import sys
|
||
import numpy as np
|
||
import sounddevice as sd
|
||
|
||
# Настройки
|
||
DURATION = 0.2 # Увеличили буфер для стабильности на Raspberry Pi
|
||
SAMPLE_RATE = 44100 # Частота дискретизации
|
||
|
||
|
||
def audio_callback(indata, frames, time, status):
|
||
# Игнорируем input overflow, чтобы не засорять вывод,
|
||
# но выводим другие критические ошибки, если они будут
|
||
if status and not status.input_overflow:
|
||
print(f"\nСтатус: {status}", file=sys.stderr)
|
||
|
||
# Вычисляем среднеквадратичное значение (RMS)
|
||
rms = np.sqrt(np.mean(indata**2))
|
||
|
||
# Переводим в проценты.
|
||
# Коэффициент 250 хорошо подходит для стандартных микрофонов
|
||
volume_percent = min(int(rms * 250), 100)
|
||
|
||
# Рисуем текстовый индикатор
|
||
bar_length = int(volume_percent / 2) # Шкала из 50 символов max
|
||
bar = "█" * bar_length + "-" * (50 - bar_length)
|
||
|
||
# Выводим в консоль с очисткой конца строки (\033[K), чтобы убрать артефакты
|
||
sys.stdout.write(f"\rУровень: {volume_percent:3}% | [{bar}]\033[K")
|
||
sys.stdout.flush()
|
||
|
||
|
||
print("Поиск аудиоустройств...")
|
||
|
||
device_id = None
|
||
devices = sd.query_devices()
|
||
for idx, dev in enumerate(devices):
|
||
# Ищем устройство без учета регистра
|
||
if "pcm2902" in dev["name"].lower() and dev["max_input_channels"] > 0:
|
||
device_id = idx
|
||
print(f"Найдено устройство: {dev['name']} (ID: {idx})")
|
||
break
|
||
|
||
if device_id is None:
|
||
print("Используем аудиоустройство по умолчанию.")
|
||
|
||
print("Запуск мониторинга уровня звука. Для выхода нажмите Ctrl+C\n")
|
||
|
||
try:
|
||
with sd.InputStream(
|
||
device=device_id,
|
||
channels=1,
|
||
samplerate=SAMPLE_RATE,
|
||
blocksize=int(SAMPLE_RATE * DURATION),
|
||
callback=audio_callback,
|
||
):
|
||
while True:
|
||
sd.sleep(100)
|
||
except KeyboardInterrupt:
|
||
print("\nМониторинг остановлен.")
|
||
except Exception as e:
|
||
print(f"\nОшибка: {e}") |