geethareddy commited on
Commit
f66fff5
·
verified ·
1 Parent(s): 1824d88

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -56
app.py CHANGED
@@ -7,7 +7,6 @@ from simple_salesforce import Salesforce
7
  import os
8
  from datetime import datetime
9
  import logging
10
- from scipy.io import wavfile
11
  import webrtcvad
12
 
13
  # Set up logging
@@ -85,11 +84,10 @@ def extract_health_features(audio, sr):
85
  logger.error(f"Feature extraction failed: {str(e)}")
86
  raise
87
 
88
- def transcribe_audio(audio_file):
89
  """Transcribe audio to text using Whisper."""
90
  try:
91
- audio, sr = librosa.load(audio_file, sr=16000)
92
- inputs = whisper_processor(audio, sampling_rate=sr, return_tensors="pt")
93
  with torch.no_grad():
94
  generated_ids = whisper_model.generate(inputs["input_features"])
95
  transcription = whisper_processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
@@ -105,21 +103,24 @@ def analyze_symptoms(text):
105
  feedback = []
106
  if "cough" in text or "difficulty breathing" in text:
107
  feedback.append("Symptoms like cough or difficulty breathing may indicate a respiratory condition, such as bronchitis or asthma. Consult a doctor.")
108
- if "tired" in text or "fatigue" in text:
109
- feedback.append("Reported fatigue may suggest conditions like anemia or chronic fatigue syndrome. Seek medical advice.")
110
  if not feedback:
111
  feedback.append("No specific conditions detected from reported symptoms.")
112
  return "\n".join(feedback)
113
 
114
- def analyze_voice(audio_file):
115
  """Analyze voice for health indicators."""
116
  try:
117
- # Validate input
118
- if not os.path.exists(audio_file):
119
- raise ValueError("Audio file not found")
120
- if not audio_file.lower().endswith((".wav", ".mp3", ".flac")):
121
- raise ValueError("Supported formats: WAV, MP3, FLAC")
122
- audio, sr = librosa.load(audio_file, sr=16000)
 
 
 
123
  if len(audio) < sr:
124
  raise ValueError("Audio too short (minimum 1 second)")
125
 
@@ -127,7 +128,7 @@ def analyze_voice(audio_file):
127
  features = extract_health_features(audio, sr)
128
 
129
  # Transcribe audio for symptom analysis
130
- transcription = transcribe_audio(audio_file)
131
  symptom_feedback = analyze_symptoms(transcription) if transcription else "No transcription available for symptom analysis."
132
 
133
  # Analyze voice features for health indicators
@@ -160,16 +161,9 @@ def analyze_voice(audio_file):
160
  feedback_str = "\n".join(feedback)
161
 
162
  # Store in Salesforce
163
- if sf:
164
  store_in_salesforce(audio_file, feedback_str, respiratory_score, mental_health_score, features, transcription)
165
 
166
- # Clean up
167
- try:
168
- os.remove(audio_file)
169
- logger.info(f"Deleted audio: {audio_file}")
170
- except Exception as e:
171
- logger.error(f"Failed to delete audio: {str(e)}")
172
-
173
  return feedback_str
174
  except Exception as e:
175
  logger.error(f"Audio processing failed: {str(e)}")
@@ -183,7 +177,7 @@ def store_in_salesforce(audio_file, feedback, respiratory_score, mental_health_s
183
  "Feedback__c": feedback,
184
  "RespiratoryScore__c": float(respiratory_score),
185
  "MentalHealthScore__c": float(mental_health_score),
186
- "AudioFileName__c": os.path.basename(audio_file),
187
  "Pitch__c": float(features["pitch"]),
188
  "Jitter__c": float(features["jitter"]),
189
  "Shimmer__c": float(features["shimmer"]),
@@ -195,38 +189,22 @@ def store_in_salesforce(audio_file, feedback, respiratory_score, mental_health_s
195
  logger.error(f"Salesforce storage failed: {str(e)}")
196
 
197
  def test_with_sample_audio():
198
- """Test with sample or dummy audio simulating a user's voice."""
199
- sample_audio_path = "audio_samples/sample.wav"
200
- if not os.path.exists(sample_audio_path):
201
- logger.warning("Sample audio not found; generating dummy audio to simulate user voice saying 'I have a cough'")
202
- # Generate synthetic audio: 150 Hz base frequency to mimic human voice
203
- sr = 16000
204
- t = np.linspace(0, 2, 2 * sr)
205
- freq_mod = 150 + 20 * np.sin(2 * np.pi * 0.5 * t) # Increased frequency variation
206
- amplitude_mod = 0.5 + 0.2 * np.sin(2 * np.pi * 0.3 * t) # Increased amplitude variation
207
- noise = 0.05 * np.random.normal(0, 1, len(t)) # Moderate noise for realism
208
- dummy_audio = amplitude_mod * np.sin(2 * np.pi * freq_mod * t) + noise
209
- # Ensure dummy_audio is a 1D NumPy array
210
- dummy_audio = np.asarray(dummy_audio, dtype=np.float32).flatten()
211
- if not isinstance(dummy_audio, np.ndarray) or dummy_audio.ndim != 1:
212
- logger.error(f"Invalid dummy_audio: type={type(dummy_audio)}, shape={dummy_audio.shape if hasattr(dummy_audio, 'shape') else 'N/A'}")
213
- raise ValueError("Generated audio is not a 1D NumPy array")
214
- # Normalize to int16 for scipy.io.wavfile
215
- dummy_audio = (dummy_audio * 32767).astype(np.int16)
216
- logger.info(f"Dummy audio shape: {dummy_audio.shape}, type: {type(dummy_audio)}, dtype: {dummy_audio.dtype}")
217
- sample_audio_path = "audio_samples/dummy_test.wav"
218
- os.makedirs("audio_samples", exist_ok=True)
219
- try:
220
- # Write audio using scipy.io.wavfile
221
- wavfile.write(sample_audio_path, sr, dummy_audio)
222
- logger.info(f"Generated dummy audio at: {sample_audio_path}")
223
- # Verify file exists
224
- if not os.path.exists(sample_audio_path):
225
- raise ValueError(f"Audio file not created: {sample_audio_path}")
226
- except Exception as e:
227
- logger.error(f"Failed to write dummy audio: {str(e)}")
228
- raise
229
- return analyze_voice(sample_audio_path)
230
 
231
  # Gradio interface
232
  iface = gr.Interface(
@@ -238,6 +216,6 @@ iface = gr.Interface(
238
  )
239
 
240
  if __name__ == "__main__":
241
- logger.info("Starting Voice Health Analyzer")
242
  print(test_with_sample_audio())
243
  iface.launch(server_name="0.0.0.0", server_port=7860)
 
7
  import os
8
  from datetime import datetime
9
  import logging
 
10
  import webrtcvad
11
 
12
  # Set up logging
 
84
  logger.error(f"Feature extraction failed: {str(e)}")
85
  raise
86
 
87
+ def transcribe_audio(audio):
88
  """Transcribe audio to text using Whisper."""
89
  try:
90
+ inputs = whisper_processor(audio, sampling_rate=16000, return_tensors="pt")
 
91
  with torch.no_grad():
92
  generated_ids = whisper_model.generate(inputs["input_features"])
93
  transcription = whisper_processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
 
103
  feedback = []
104
  if "cough" in text or "difficulty breathing" in text:
105
  feedback.append("Symptoms like cough or difficulty breathing may indicate a respiratory condition, such as bronchitis or asthma. Consult a doctor.")
106
+ if "stressed" in text or "stress" in text or "fatigue" in text:
107
+ feedback.append("Reported stress or fatigue may suggest conditions like anxiety or chronic fatigue syndrome. Seek medical advice.")
108
  if not feedback:
109
  feedback.append("No specific conditions detected from reported symptoms.")
110
  return "\n".join(feedback)
111
 
112
+ def analyze_voice(audio_file=None, audio_data=None):
113
  """Analyze voice for health indicators."""
114
  try:
115
+ # Use provided audio file or in-memory audio data
116
+ if audio_file and os.path.exists(audio_file):
117
+ audio, sr = librosa.load(audio_file, sr=16000)
118
+ elif audio_data is not None:
119
+ audio = audio_data
120
+ sr = 16000
121
+ else:
122
+ raise ValueError("No audio input provided")
123
+
124
  if len(audio) < sr:
125
  raise ValueError("Audio too short (minimum 1 second)")
126
 
 
128
  features = extract_health_features(audio, sr)
129
 
130
  # Transcribe audio for symptom analysis
131
+ transcription = transcribe_audio(audio)
132
  symptom_feedback = analyze_symptoms(transcription) if transcription else "No transcription available for symptom analysis."
133
 
134
  # Analyze voice features for health indicators
 
161
  feedback_str = "\n".join(feedback)
162
 
163
  # Store in Salesforce
164
+ if sf and audio_file:
165
  store_in_salesforce(audio_file, feedback_str, respiratory_score, mental_health_score, features, transcription)
166
 
 
 
 
 
 
 
 
167
  return feedback_str
168
  except Exception as e:
169
  logger.error(f"Audio processing failed: {str(e)}")
 
177
  "Feedback__c": feedback,
178
  "RespiratoryScore__c": float(respiratory_score),
179
  "MentalHealthScore__c": float(mental_health_score),
180
+ "AudioFileName__c": os.path.basename(audio_file) if audio_file else "in_memory_audio",
181
  "Pitch__c": float(features["pitch"]),
182
  "Jitter__c": float(features["jitter"]),
183
  "Shimmer__c": float(features["shimmer"]),
 
189
  logger.error(f"Salesforce storage failed: {str(e)}")
190
 
191
  def test_with_sample_audio():
192
+ """Test with dummy audio simulating a user's voice saying 'I have a cough and feel stressed'."""
193
+ logger.info("Starting test with in-memory audio simulation")
194
+ # Generate synthetic audio: 150 Hz base frequency with variations to mimic a stressed voice with cough
195
+ sr = 16000
196
+ t = np.linspace(0, 2, 2 * sr)
197
+ freq_mod = 150 + 25 * np.sin(2 * np.pi * 0.5 * t) # Increased jitter for respiratory hint
198
+ amplitude_mod = 0.5 + 0.25 * np.sin(2 * np.pi * 0.3 * t) # Increased shimmer for stress hint
199
+ noise = 0.05 * np.random.normal(0, 1, len(t)) # Moderate noise
200
+ dummy_audio = amplitude_mod * np.sin(2 * np.pi * freq_mod * t) + noise
201
+ # Ensure dummy_audio is a 1D NumPy array
202
+ dummy_audio = np.asarray(dummy_audio, dtype=np.float32).flatten()
203
+ if not isinstance(dummy_audio, np.ndarray) or dummy_audio.ndim != 1:
204
+ logger.error(f"Invalid dummy_audio: type={type(dummy_audio)}, shape={dummy_audio.shape if hasattr(dummy_audio, 'shape') else 'N/A'}")
205
+ raise ValueError("Generated audio is not a 1D NumPy array")
206
+ logger.info(f"Dummy audio shape: {dummy_audio.shape}, type: {type(dummy_audio)}, dtype: {dummy_audio.dtype}")
207
+ return analyze_voice(audio_data=dummy_audio)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
209
  # Gradio interface
210
  iface = gr.Interface(
 
216
  )
217
 
218
  if __name__ == "__main__":
219
+ logger.info("Starting Voice Health Analyzer at 10:31 AM IST, June 23, 2025")
220
  print(test_with_sample_audio())
221
  iface.launch(server_name="0.0.0.0", server_port=7860)