CoolFace
Modelpublic

Prathmesh0001/interview-system

sourceHugging Facemitupdated 8mo agoView on Hugging Face
0likes
audio_handler.py253 linesDownload Raw Back to root
1"""
2Audio Handler Module
3Manages speech recognition (STT) and text-to-speech (TTS) functionality
4"""
5
6import speech_recognition as sr
7import pyttsx3
8from gtts import gTTS
9import os
10import tempfile
11from typing import Optional, Tuple
12import time
13
14
15class AudioHandler:
16    """Handle audio input/output for interview system"""
17    
18    def __init__(self, use_gtts: bool = False):
19        """
20        Initialize audio handler
21        
22        Args:
23            use_gtts: Use Google TTS instead of pyttsx3
24        """
25        self.recognizer = sr.Recognizer()
26        self.use_gtts = use_gtts
27        
28        # Initialize TTS engine
29        if not use_gtts:
30            try:
31                self.tts_engine = pyttsx3.init()
32                self.tts_engine.setProperty('rate', 150)  # Speed of speech
33                self.tts_engine.setProperty('volume', 0.9)  # Volume (0.0 to 1.0)
34            except Exception as e:
35                print(f"Error initializing pyttsx3: {e}")
36                print("Falling back to gTTS")
37                self.use_gtts = True
38    
39    def speak(self, text: str) -> bool:
40        """
41        Convert text to speech and play it
42        
43        Args:
44            text: Text to speak
45            
46        Returns:
47            True if successful, False otherwise
48        """
49        try:
50            if self.use_gtts:
51                return self._speak_gtts(text)
52            else:
53                return self._speak_pyttsx3(text)
54        except Exception as e:
55            print(f"Error in text-to-speech: {e}")
56            return False
57    
58    def _speak_pyttsx3(self, text: str) -> bool:
59        """Speak using pyttsx3 (offline)"""
60        try:
61            self.tts_engine.say(text)
62            self.tts_engine.runAndWait()
63            return True
64        except Exception as e:
65            print(f"pyttsx3 error: {e}")
66            return False
67    
68    def _speak_gtts(self, text: str) -> bool:
69        """Speak using Google TTS (online)"""
70        try:
71            tts = gTTS(text=text, lang='en', slow=False)
72            
73            # Create temporary file
74            with tempfile.NamedTemporaryFile(delete=False, suffix='.mp3') as fp:
75                temp_file = fp.name
76                tts.save(temp_file)
77            
78            # Play the audio file (platform-dependent)
79            if os.name == 'posix':  # Linux/Mac
80                os.system(f'mpg123 -q {temp_file} 2>/dev/null || afplay {temp_file} 2>/dev/null')
81            else:  # Windows
82                os.system(f'start {temp_file}')
83            
84            time.sleep(0.5)
85            
86            # Clean up
87            try:
88                os.remove(temp_file)
89            except:
90                pass
91            
92            return True
93        except Exception as e:
94            print(f"gTTS error: {e}")
95            return False
96    
97    def listen(self, timeout: int = 120, phrase_time_limit: int = 120) -> Tuple[Optional[str], dict]:
98        """
99        Listen to microphone and convert speech to text
100        
101        Args:
102            timeout: Maximum time to wait for phrase start
103            phrase_time_limit: Maximum time for phrase
104            
105        Returns:
106            Tuple of (transcribed text or None, audio analysis dict)
107        """
108        audio_analysis = {
109            'duration': 0,
110            'confidence': 0,
111            'error': None
112        }
113        
114        try:
115            with sr.Microphone() as source:
116                print("๐ŸŽค Listening... (speak now)")
117                
118                # Adjust for ambient noise
119                self.recognizer.adjust_for_ambient_noise(source, duration=1)
120                
121                # Record audio
122                start_time = time.time()
123                audio = self.recognizer.listen(
124                    source, 
125                    timeout=timeout,
126                    phrase_time_limit=phrase_time_limit
127                )
128                audio_analysis['duration'] = time.time() - start_time
129                
130                print("๐Ÿ”„ Processing your response...")
131                
132                # Recognize speech using Google Speech Recognition
133                text = self.recognizer.recognize_google(audio)
134                audio_analysis['confidence'] = 0.85  # Google doesn't provide confidence
135                
136                return text, audio_analysis
137                
138        except sr.WaitTimeoutError:
139            audio_analysis['error'] = 'timeout'
140            print("โฑ๏ธ No speech detected within timeout period")
141            return None, audio_analysis
142            
143        except sr.UnknownValueError:
144            audio_analysis['error'] = 'unclear'
145            print("โŒ Could not understand the audio")
146            return None, audio_analysis
147            
148        except sr.RequestError as e:
149            audio_analysis['error'] = 'service_error'
150            print(f"โŒ Could not request results from speech recognition service: {e}")
151            return None, audio_analysis
152            
153        except Exception as e:
154            audio_analysis['error'] = str(e)
155            print(f"โŒ Error during speech recognition: {e}")
156            return None, audio_analysis
157    
158    def analyze_voice_features(self, audio_data, text: str) -> dict:
159        """
160        Analyze voice features from audio
161        
162        Args:
163            audio_data: Audio data from speech recognition
164            text: Transcribed text
165            
166        Returns:
167            Dictionary with voice analysis metrics
168        """
169        # Basic analysis based on transcribed text
170        analysis = {
171            'word_count': len(text.split()),
172            'speaking_rate': 0,  # Words per minute
173            'volume_level': 'medium',  # Would need audio processing for actual value
174            'clarity_score': 0.7  # Default placeholder
175        }
176        
177        # Estimate speaking rate if we have duration
178        # This is a simplified version - would need actual audio processing for accuracy
179        if hasattr(audio_data, 'duration'):
180            duration_minutes = audio_data.duration / 60
181            if duration_minutes > 0:
182                analysis['speaking_rate'] = analysis['word_count'] / duration_minutes
183        
184        # Assess clarity based on word count and sentence structure
185        if analysis['word_count'] > 30:
186            analysis['clarity_score'] = 0.8
187        if analysis['word_count'] > 50:
188            analysis['clarity_score'] = 0.85
189        
190        return analysis
191    
192    def test_audio_setup(self) -> dict:
193        """
194        Test audio input/output setup
195        
196        Returns:
197            Dictionary with test results
198        """
199        results = {
200            'microphone': False,
201            'speakers': False,
202            'speech_recognition': False
203        }
204        
205        # Test speakers
206        print("\nTesting speakers...")
207        try:
208            self.speak("Testing audio output. Can you hear this?")
209            results['speakers'] = True
210            print("โœ… Speakers working")
211        except Exception as e:
212            print(f"โŒ Speaker test failed: {e}")
213        
214        # Test microphone
215        print("\nTesting microphone...")
216        try:
217            with sr.Microphone() as source:
218                self.recognizer.adjust_for_ambient_noise(source, duration=1)
219                results['microphone'] = True
220                print("โœ… Microphone detected")
221        except Exception as e:
222            print(f"โŒ Microphone test failed: {e}")
223        
224        # Test speech recognition
225        if results['microphone']:
226            print("\nTesting speech recognition...")
227            print("Please say: 'This is a test'")
228            try:
229                text, _ = self.listen(timeout=10, phrase_time_limit=10)
230                if text:
231                    results['speech_recognition'] = True
232                    print(f"โœ… Recognized: {text}")
233            except Exception as e:
234                print(f"โŒ Speech recognition test failed: {e}")
235        
236        return results
237
238
239if __name__ == "__main__":
240    # Test the audio handler
241    print("Audio Handler Module - Test Mode")
242    print("=" * 50)
243    
244    handler = AudioHandler()
245    
246    # Run audio setup test
247    test_results = handler.test_audio_setup()
248    
249    print("\n" + "=" * 50)
250    print("Test Results:")
251    for component, status in test_results.items():
252        status_symbol = "โœ…" if status else "โŒ"
253        print(f"{status_symbol} {component.replace('_', ' ').title()}: {'Working' if status else 'Failed'}")