translator но без озвучивания слов на английском
This commit is contained in:
94
wakeword.py
94
wakeword.py
@@ -15,6 +15,7 @@ class WakeWordDetector:
|
||||
self.porcupine = None
|
||||
self.audio_stream = None
|
||||
self.pa = None
|
||||
self._stream_closed = True # Track state explicitly
|
||||
|
||||
def initialize(self):
|
||||
"""Initialize Porcupine and audio stream."""
|
||||
@@ -24,6 +25,19 @@ class WakeWordDetector:
|
||||
)
|
||||
|
||||
self.pa = pyaudio.PyAudio()
|
||||
self._open_stream()
|
||||
print("🎤 Ожидание wake word 'Alexandr'...")
|
||||
|
||||
def _open_stream(self):
|
||||
"""Open the audio stream."""
|
||||
if self.audio_stream and not self._stream_closed:
|
||||
return
|
||||
|
||||
if self.audio_stream:
|
||||
try:
|
||||
self.audio_stream.close()
|
||||
except: pass
|
||||
|
||||
self.audio_stream = self.pa.open(
|
||||
rate=self.porcupine.sample_rate,
|
||||
channels=1,
|
||||
@@ -31,44 +45,47 @@ class WakeWordDetector:
|
||||
input=True,
|
||||
frames_per_buffer=self.porcupine.frame_length
|
||||
)
|
||||
print("🎤 Ожидание wake word 'Alexandr'...")
|
||||
|
||||
def wait_for_wakeword(self) -> bool:
|
||||
self._stream_closed = False
|
||||
|
||||
def stop_monitoring(self):
|
||||
"""Explicitly stop and close the stream."""
|
||||
if self.audio_stream and not self._stream_closed:
|
||||
try:
|
||||
self.audio_stream.stop_stream()
|
||||
self.audio_stream.close()
|
||||
except: pass
|
||||
self._stream_closed = True
|
||||
|
||||
def wait_for_wakeword(self, timeout: float = None) -> bool:
|
||||
"""
|
||||
Blocks until wake word is detected.
|
||||
Returns True when wake word is detected.
|
||||
Blocks until wake word is detected or timeout expires.
|
||||
|
||||
Args:
|
||||
timeout: Maximum seconds to wait. None = infinite.
|
||||
|
||||
Returns:
|
||||
True if wake word detected, False if timeout.
|
||||
"""
|
||||
import time
|
||||
if not self.porcupine:
|
||||
self.initialize()
|
||||
|
||||
# Ensure stream is open and active
|
||||
if self.audio_stream is None or not self.audio_stream.is_active():
|
||||
# If closed or None, we might need to recreate it.
|
||||
# PyAudio streams once closed cannot be reopened usually?
|
||||
# We should probably recreate it.
|
||||
if self.audio_stream:
|
||||
try:
|
||||
self.audio_stream.close()
|
||||
except: pass
|
||||
|
||||
self.audio_stream = self.pa.open(
|
||||
rate=self.porcupine.sample_rate,
|
||||
channels=1,
|
||||
format=pyaudio.paInt16,
|
||||
input=True,
|
||||
frames_per_buffer=self.porcupine.frame_length
|
||||
)
|
||||
# Ensure stream is open
|
||||
self._open_stream()
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
while True:
|
||||
if timeout and (time.time() - start_time > timeout):
|
||||
return False
|
||||
|
||||
pcm = self.audio_stream.read(self.porcupine.frame_length, exception_on_overflow=False)
|
||||
pcm = struct.unpack_from("h" * self.porcupine.frame_length, pcm)
|
||||
|
||||
keyword_index = self.porcupine.process(pcm)
|
||||
if keyword_index >= 0:
|
||||
print("✅ Wake word обнаружен!")
|
||||
# Stop and CLOSE stream to release mic for STT
|
||||
self.audio_stream.stop_stream()
|
||||
self.audio_stream.close()
|
||||
self.stop_monitoring()
|
||||
return True
|
||||
|
||||
def check_wakeword_once(self) -> bool:
|
||||
@@ -80,20 +97,8 @@ class WakeWordDetector:
|
||||
self.initialize()
|
||||
|
||||
try:
|
||||
# Ensure stream is open/active
|
||||
if self.audio_stream is None or not self.audio_stream.is_active():
|
||||
# Re-open if needed (similar to wait_for_wakeword logic)
|
||||
if self.audio_stream:
|
||||
try:
|
||||
self.audio_stream.close()
|
||||
except: pass
|
||||
self.audio_stream = self.pa.open(
|
||||
rate=self.porcupine.sample_rate,
|
||||
channels=1,
|
||||
format=pyaudio.paInt16,
|
||||
input=True,
|
||||
frames_per_buffer=self.porcupine.frame_length
|
||||
)
|
||||
# Ensure stream is open
|
||||
self._open_stream()
|
||||
|
||||
pcm = self.audio_stream.read(self.porcupine.frame_length, exception_on_overflow=False)
|
||||
pcm = struct.unpack_from("h" * self.porcupine.frame_length, pcm)
|
||||
@@ -108,8 +113,7 @@ class WakeWordDetector:
|
||||
|
||||
def cleanup(self):
|
||||
"""Release resources."""
|
||||
if self.audio_stream:
|
||||
self.audio_stream.close()
|
||||
self.stop_monitoring()
|
||||
if self.pa:
|
||||
self.pa.terminate()
|
||||
if self.porcupine:
|
||||
@@ -128,10 +132,14 @@ def get_detector() -> WakeWordDetector:
|
||||
return _detector
|
||||
|
||||
|
||||
def wait_for_wakeword() -> bool:
|
||||
def wait_for_wakeword(timeout: float = None) -> bool:
|
||||
"""Wait for wake word detection."""
|
||||
return get_detector().wait_for_wakeword()
|
||||
return get_detector().wait_for_wakeword(timeout)
|
||||
|
||||
def stop_monitoring():
|
||||
"""Stop monitoring for wake word."""
|
||||
if _detector:
|
||||
_detector.stop_monitoring()
|
||||
|
||||
def cleanup():
|
||||
"""Cleanup detector resources."""
|
||||
|
||||
Reference in New Issue
Block a user