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}")