Add voice messages
This commit is contained in:
@@ -27,10 +27,13 @@ def record() -> str:
|
|||||||
speaking_started = False
|
speaking_started = False
|
||||||
max_chunks = int(16000 / 1024 * MAX_DURATION)
|
max_chunks = int(16000 / 1024 * MAX_DURATION)
|
||||||
silence_chunks_needed = int(16000 / 1024 * SILENCE_DURATION)
|
silence_chunks_needed = int(16000 / 1024 * SILENCE_DURATION)
|
||||||
|
warmup_chunks = int(16000 / 1024 * 0.3) # 0.3 сек — эхо звука активации
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for _ in range(max_chunks):
|
for i in range(max_chunks):
|
||||||
data = stream.read(1024, exception_on_overflow=False)
|
data = stream.read(1024, exception_on_overflow=False)
|
||||||
|
if i < warmup_chunks:
|
||||||
|
continue # пропускаем эхо от звука активации
|
||||||
frames.append(data)
|
frames.append(data)
|
||||||
|
|
||||||
amplitude = np.abs(np.frombuffer(data, dtype=np.int16)).mean()
|
amplitude = np.abs(np.frombuffer(data, dtype=np.int16)).mean()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from datetime import date
|
|||||||
|
|
||||||
from .config import GATEWAY_URL, VOICE_MODEL, AGENT, AGENTS, log
|
from .config import GATEWAY_URL, VOICE_MODEL, AGENT, AGENTS, log
|
||||||
from .text import clean_for_speech, find_sentence_end
|
from .text import clean_for_speech, find_sentence_end
|
||||||
from .tts import speak
|
from .tts import speak, play_error_sound
|
||||||
|
|
||||||
SYSTEM_PROMPT = "Отвечай кратко, 1-2 предложения, без markdown, без эмодзи."
|
SYSTEM_PROMPT = "Отвечай кратко, 1-2 предложения, без markdown, без эмодзи."
|
||||||
MAX_HISTORY = int(__import__("os").getenv("MAX_HISTORY", "20"))
|
MAX_HISTORY = int(__import__("os").getenv("MAX_HISTORY", "20"))
|
||||||
@@ -79,18 +79,21 @@ def ask_agent_stream(text: str, conv: "Conversation | None" = None, agent_id: st
|
|||||||
log.exception("Gateway недоступен")
|
log.exception("Gateway недоступен")
|
||||||
msg = "Не могу связаться с сервером, попробуй ещё раз."
|
msg = "Не могу связаться с сервером, попробуй ещё раз."
|
||||||
print(f"⚠️ {msg}")
|
print(f"⚠️ {msg}")
|
||||||
|
#play_error_sound()
|
||||||
speak(msg, agent_id)
|
speak(msg, agent_id)
|
||||||
return msg
|
return msg
|
||||||
except requests.Timeout:
|
except requests.Timeout:
|
||||||
log.exception("Gateway таймаут")
|
log.exception("Gateway таймаут")
|
||||||
msg = "Сервер не ответил вовремя, попробуй ещё раз."
|
msg = "Сервер не ответил вовремя, попробуй ещё раз."
|
||||||
print(f"⚠️ {msg}")
|
print(f"⚠️ {msg}")
|
||||||
|
#play_error_sound()
|
||||||
speak(msg, agent_id)
|
speak(msg, agent_id)
|
||||||
return msg
|
return msg
|
||||||
except requests.HTTPError:
|
except requests.HTTPError:
|
||||||
log.exception(f"Gateway HTTP ошибка {resp.status_code}")
|
log.exception(f"Gateway HTTP ошибка {resp.status_code}")
|
||||||
msg = "Ошибка сервера, попробуй ещё раз."
|
msg = "Ошибка сервера, попробуй ещё раз."
|
||||||
print(f"⚠️ Gateway {resp.status_code}: {resp.text}")
|
print(f"⚠️ Gateway {resp.status_code}: {resp.text}")
|
||||||
|
#play_error_sound()
|
||||||
speak(msg, agent_id)
|
speak(msg, agent_id)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ def is_speaking() -> bool:
|
|||||||
|
|
||||||
def _mpv_cmd() -> list[str]:
|
def _mpv_cmd() -> list[str]:
|
||||||
"""Команда mpv для воспроизведения из stdin"""
|
"""Команда mpv для воспроизведения из stdin"""
|
||||||
cmd = ["mpv", "--no-video", "--really-quiet", "--no-terminal"]
|
mpv_bin = os.getenv("MPV_PATH", "mpv")
|
||||||
|
cmd = [mpv_bin, "--no-video", "--really-quiet", "--no-terminal"]
|
||||||
if AUDIO_SINK:
|
if AUDIO_SINK:
|
||||||
cmd.append(f"--audio-device=pulse/{AUDIO_SINK}")
|
cmd.append(f"--audio-device=pulse/{AUDIO_SINK}")
|
||||||
cmd.append("-")
|
cmd.append("-")
|
||||||
@@ -54,6 +55,7 @@ def speak(text: str, agent_id: str = "cosmo"):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception("TTS ошибка")
|
log.exception("TTS ошибка")
|
||||||
print(f"⚠️ Ошибка воспроизведения: {e}")
|
print(f"⚠️ Ошибка воспроизведения: {e}")
|
||||||
|
play_error_sound()
|
||||||
|
|
||||||
|
|
||||||
def _speak_elevenlabs(text: str, agent_id: str):
|
def _speak_elevenlabs(text: str, agent_id: str):
|
||||||
@@ -98,13 +100,33 @@ def _speak_elevenlabs(text: str, agent_id: str):
|
|||||||
_current_process = None
|
_current_process = None
|
||||||
|
|
||||||
|
|
||||||
|
def _play_sound_file(filename: str, wait: bool = False):
|
||||||
|
"""Воспроизводит файл из папки sounds/ через mpv.
|
||||||
|
wait=True — блокирует до конца воспроизведения."""
|
||||||
|
sounds_dir = os.path.join(os.path.dirname(__file__), "..", "sounds")
|
||||||
|
path = os.path.normpath(os.path.join(sounds_dir, filename))
|
||||||
|
mpv_bin = os.getenv("MPV_PATH", "mpv")
|
||||||
|
cmd = [mpv_bin, "--no-video", "--really-quiet", "--no-terminal", path]
|
||||||
|
if wait:
|
||||||
|
subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
else:
|
||||||
|
subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
|
||||||
def play_activation_sound():
|
def play_activation_sound():
|
||||||
"""Звук активации после wake word"""
|
"""Звук активации — неблокирующий"""
|
||||||
try:
|
try:
|
||||||
if sys.platform == "darwin":
|
_play_sound_file("Success_Cosmo.mp3", wait=False)
|
||||||
subprocess.run(["afplay", "/System/Library/Sounds/Glass.aiff"])
|
|
||||||
else:
|
|
||||||
subprocess.run(["paplay", "/usr/share/sounds/freedesktop/stereo/bell.oga"])
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception("Ошибка звука активации")
|
log.warning(f"Ошибка звука активации: {e}")
|
||||||
print(f"⚠️ Ошибка звука: {e}")
|
|
||||||
|
|
||||||
|
def play_error_sound():
|
||||||
|
"""Звук ошибки — 'не получилось'"""
|
||||||
|
import traceback
|
||||||
|
print("🔴 play_error_sound вызван из:")
|
||||||
|
traceback.print_stack()
|
||||||
|
try:
|
||||||
|
_play_sound_file("Error_Cosmo.mp3")
|
||||||
|
except Exception as e:
|
||||||
|
log.warning(f"Ошибка звука ошибки: {e}")
|
||||||
|
|||||||
BIN
sounds/Error_Cosmo.mp3
Normal file
BIN
sounds/Error_Cosmo.mp3
Normal file
Binary file not shown.
BIN
sounds/Success_Cosmo.mp3
Normal file
BIN
sounds/Success_Cosmo.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user