datbkpro commited on
Commit
06ce176
·
verified ·
1 Parent(s): 8289f9b

Update services/streaming_voice_service.py

Browse files
Files changed (1) hide show
  1. services/streaming_voice_service.py +93 -2
services/streaming_voice_service.py CHANGED
@@ -4,10 +4,11 @@ import soundfile as sf
4
  import time
5
  import traceback
6
  from groq import Groq
7
- from typing import Optional, Dict, Any
8
  from config.settings import settings
9
  from core.rag_system import EnhancedRAGSystem
10
  from core.tts_service import EnhancedTTSService
 
11
 
12
 
13
  class StreamingVoiceService:
@@ -16,12 +17,93 @@ class StreamingVoiceService:
16
  self.rag_system = rag_system
17
  self.tts_service = tts_service
18
 
 
 
 
 
 
19
  # Conversation context
20
  self.conversation_history = []
21
  self.current_transcription = ""
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def process_streaming_audio(self, audio_data: tuple) -> Dict[str, Any]:
24
- """Xử lý audio streaming từ Gradio microphone component"""
25
  if not audio_data:
26
  return {
27
  'transcription': "❌ Không có dữ liệu âm thanh",
@@ -61,6 +143,14 @@ class StreamingVoiceService:
61
  'tts_audio': None
62
  }
63
 
 
 
 
 
 
 
 
 
64
  # Chuyển đổi thành văn bản
65
  transcription = self._transcribe_audio(audio_array, sample_rate)
66
 
@@ -269,6 +359,7 @@ Thông tin tham khảo:
269
  def get_conversation_state(self) -> dict:
270
  """Lấy trạng thái hội thoại"""
271
  return {
 
272
  'history_length': len(self.conversation_history),
273
  'current_transcription': self.current_transcription,
274
  'last_update': time.strftime("%H:%M:%S")
 
4
  import time
5
  import traceback
6
  from groq import Groq
7
+ from typing import Optional, Dict, Any, Callable
8
  from config.settings import settings
9
  from core.rag_system import EnhancedRAGSystem
10
  from core.tts_service import EnhancedTTSService
11
+ from core.speechbrain_vad import SpeechBrainVAD
12
 
13
 
14
  class StreamingVoiceService:
 
17
  self.rag_system = rag_system
18
  self.tts_service = tts_service
19
 
20
+ # Khởi tạo VAD
21
+ self.vad_processor = SpeechBrainVAD()
22
+ self.is_listening = False
23
+ self.speech_callback = None
24
+
25
  # Conversation context
26
  self.conversation_history = []
27
  self.current_transcription = ""
28
 
29
+ def start_listening(self, speech_callback: Callable) -> bool:
30
+ """Bắt đầu lắng nghe với VAD"""
31
+ if self.is_listening:
32
+ return False
33
+
34
+ self.speech_callback = speech_callback
35
+ success = self.vad_processor.start_stream(self._on_speech_detected)
36
+ if success:
37
+ self.is_listening = True
38
+ print("🎙️ Đã bắt đầu lắng nghe với VAD")
39
+ return success
40
+
41
+ def stop_listening(self):
42
+ """Dừng lắng nghe"""
43
+ self.vad_processor.stop_stream()
44
+ self.is_listening = False
45
+ self.speech_callback = None
46
+ print("🛑 Đã dừng lắng nghe")
47
+
48
+ def process_audio_chunk(self, audio_data: tuple) -> Dict[str, Any]:
49
+ """Xử lý audio chunk với VAD (dùng cho real-time streaming)"""
50
+ if not audio_data or not self.is_listening:
51
+ return {
52
+ 'transcription': "",
53
+ 'response': "",
54
+ 'tts_audio': None
55
+ }
56
+
57
+ try:
58
+ sample_rate, audio_array = audio_data
59
+
60
+ # Xử lý với VAD
61
+ self.vad_processor.process_stream(audio_array, sample_rate)
62
+
63
+ return {
64
+ 'transcription': "Đang lắng nghe...",
65
+ 'response': "",
66
+ 'tts_audio': None
67
+ }
68
+
69
+ except Exception as e:
70
+ print(f"❌ Lỗi xử lý audio chunk: {e}")
71
+ return {
72
+ 'transcription': "",
73
+ 'response': "",
74
+ 'tts_audio': None
75
+ }
76
+
77
+ def _on_speech_detected(self, speech_audio: np.ndarray, sample_rate: int):
78
+ """Callback khi VAD phát hiện speech"""
79
+ print(f"🎯 VAD phát hiện speech segment: {len(speech_audio)/sample_rate:.2f}s")
80
+
81
+ # Chuyển đổi speech thành text
82
+ transcription = self._transcribe_audio(speech_audio, sample_rate)
83
+
84
+ if not transcription or len(transcription.strip()) < 2:
85
+ print("⚠️ Transcription quá ngắn hoặc trống")
86
+ return
87
+
88
+ print(f"📝 VAD Transcription: {transcription}")
89
+ self.current_transcription = transcription
90
+
91
+ # Tạo phản hồi AI
92
+ response = self._generate_ai_response(transcription)
93
+
94
+ # Tạo TTS
95
+ tts_audio_path = self._text_to_speech(response)
96
+
97
+ # Gửi kết quả đến callback
98
+ if self.speech_callback:
99
+ self.speech_callback({
100
+ 'transcription': transcription,
101
+ 'response': response,
102
+ 'tts_audio': tts_audio_path
103
+ })
104
+
105
  def process_streaming_audio(self, audio_data: tuple) -> Dict[str, Any]:
106
+ """Xử lý audio streaming (phương thức cho compatibility)"""
107
  if not audio_data:
108
  return {
109
  'transcription': "❌ Không có dữ liệu âm thanh",
 
143
  'tts_audio': None
144
  }
145
 
146
+ # Sử dụng VAD để kiểm tra speech
147
+ if not self.vad_processor.is_speech(audio_array, sample_rate):
148
+ return {
149
+ 'transcription': "❌ Không phát hiện giọng nói",
150
+ 'response': "Vui lòng nói rõ hơn",
151
+ 'tts_audio': None
152
+ }
153
+
154
  # Chuyển đổi thành văn bản
155
  transcription = self._transcribe_audio(audio_array, sample_rate)
156
 
 
359
  def get_conversation_state(self) -> dict:
360
  """Lấy trạng thái hội thoại"""
361
  return {
362
+ 'is_listening': self.is_listening,
363
  'history_length': len(self.conversation_history),
364
  'current_transcription': self.current_transcription,
365
  'last_update': time.strftime("%H:%M:%S")