geethareddy commited on
Commit
9c963a6
·
verified ·
1 Parent(s): 0dc01e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -15
app.py CHANGED
@@ -1,8 +1,9 @@
 
1
  import gradio as gr
2
  import librosa
3
  import numpy as np
4
  import torch
5
- from transformers import Wav2Vec2Processor, Wav2Vec2Model
6
  from simple_salesforce import Salesforce
7
  import os
8
  from datetime import datetime
@@ -36,9 +37,10 @@ try:
36
  except Exception as e:
37
  logger.error(f"Salesforce connection failed: {str(e)}")
38
 
39
- # Load Wav2Vec2 model (optional context features)
40
- processor = Wav2Vec2Processor.from_pretrained("facebook/wav2vec2-base-960h")
41
- model = Wav2Vec2Model.from_pretrained("facebook/wav2vec2-base-960h")
 
42
 
43
  # Initialize VAD
44
  vad = webrtcvad.Vad(mode=2) # Moderate mode for balanced voice detection
@@ -84,6 +86,33 @@ def extract_health_features(audio, sr):
84
  logger.error(f"Feature extraction failed: {str(e)}")
85
  raise
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  def analyze_voice(audio_file):
88
  """Analyze voice for health indicators."""
89
  try:
@@ -96,10 +125,14 @@ def analyze_voice(audio_file):
96
  if len(audio) < sr:
97
  raise ValueError("Audio too short (minimum 1 second)")
98
 
99
- # Extract features
100
  features = extract_health_features(audio, sr)
101
 
102
- # Analyze for health indicators
 
 
 
 
103
  feedback = []
104
  respiratory_score = features["jitter"]
105
  mental_health_score = features["shimmer"]
@@ -113,21 +146,24 @@ def analyze_voice(audio_file):
113
  feedback.append(f"Low vocal energy ({features['energy']:.4f}) may indicate fatigue or reduced vocal effort, potentially linked to physical or mental exhaustion.")
114
 
115
  if not feedback:
116
- feedback.append("No significant health indicators detected. Your voice appears stable based on the analyzed features.")
117
 
118
- # Debug info
119
- feedback.append("\n**Analysis Details**:")
 
 
120
  feedback.append(f"Pitch: {features['pitch']:.2f} Hz (average fundamental frequency)")
121
  feedback.append(f"Jitter: {respiratory_score:.2f}% (pitch variation, higher values may indicate respiratory issues)")
122
  feedback.append(f"Shimmer: {mental_health_score:.2f}% (amplitude variation, higher values may indicate stress)")
123
  feedback.append(f"Energy: {features['energy']:.4f} (vocal intensity, lower values may indicate fatigue)")
 
124
  feedback.append("\n**Disclaimer**: This is a preliminary analysis, not a medical diagnosis. Always consult a healthcare provider for professional evaluation.")
125
 
126
  feedback_str = "\n".join(feedback)
127
 
128
  # Store in Salesforce
129
  if sf:
130
- store_in_salesforce(audio_file, feedback_str, respiratory_score, mental_health_score, features)
131
 
132
  # Clean up
133
  try:
@@ -141,7 +177,7 @@ def analyze_voice(audio_file):
141
  logger.error(f"Audio processing failed: {str(e)}")
142
  return f"Error: {str(e)}"
143
 
144
- def store_in_salesforce(audio_file, feedback, respiratory_score, mental_health_score, features):
145
  """Store results in Salesforce."""
146
  try:
147
  sf.HealthAssessment__c.create({
@@ -153,7 +189,8 @@ def store_in_salesforce(audio_file, feedback, respiratory_score, mental_health_s
153
  "Pitch__c": float(features["pitch"]),
154
  "Jitter__c": float(features["jitter"]),
155
  "Shimmer__c": float(features["shimmer"]),
156
- "Energy__c": float(features["energy"])
 
157
  })
158
  logger.info("Stored in Salesforce")
159
  except Exception as e:
@@ -163,7 +200,7 @@ def test_with_sample_audio():
163
  """Test with sample or dummy audio simulating a user's voice."""
164
  sample_audio_path = "audio_samples/sample.wav"
165
  if not os.path.exists(sample_audio_path):
166
- logger.warning("Sample audio not found; generating dummy audio to simulate user voice")
167
  # Generate synthetic audio: 150 Hz base frequency to mimic human voice
168
  sr = 16000
169
  t = np.linspace(0, 2, 2 * sr)
@@ -172,16 +209,20 @@ def test_with_sample_audio():
172
  noise = 0.05 * np.random.normal(0, 1, len(t)) # Moderate noise for realism
173
  dummy_audio = amplitude_mod * np.sin(2 * np.pi * freq_mod * t) + noise
174
  # Ensure dummy_audio is a 1D NumPy array
175
- dummy_audio = np.asarray(dummy_audio, dtype=np.float64).flatten()
176
  if not isinstance(dummy_audio, np.ndarray) or dummy_audio.ndim != 1:
177
  logger.error(f"Invalid dummy_audio: type={type(dummy_audio)}, shape={dummy_audio.shape if hasattr(dummy_audio, 'shape') else 'N/A'}")
178
  raise ValueError("Generated audio is not a 1D NumPy array")
179
- logger.info(f"Dummy audio shape: {dummy_audio.shape}, type: {type(dummy_audio)}")
180
  sample_audio_path = "audio_samples/dummy_test.wav"
181
  os.makedirs("audio_samples", exist_ok=True)
182
  try:
 
183
  soundfile.write(dummy_audio, sr, sample_audio_path)
184
  logger.info(f"Generated dummy audio at: {sample_audio_path}")
 
 
 
185
  except Exception as e:
186
  logger.error(f"Failed to write dummy audio: {str(e)}")
187
  raise
@@ -200,3 +241,4 @@ if __name__ == "__main__":
200
  logger.info("Starting Voice Health Analyzer")
201
  print(test_with_sample_audio())
202
  iface.launch(server_name="0.0.0.0", server_port=7860)
 
 
1
+ ```python
2
  import gradio as gr
3
  import librosa
4
  import numpy as np
5
  import torch
6
+ from transformers import WhisperProcessor, WhisperForConditionalGeneration, pipeline
7
  from simple_salesforce import Salesforce
8
  import os
9
  from datetime import datetime
 
37
  except Exception as e:
38
  logger.error(f"Salesforce connection failed: {str(e)}")
39
 
40
+ # Load Whisper model for speech-to-text
41
+ whisper_processor = WhisperProcessor.from_pretrained("openai/whisper-tiny")
42
+ whisper_model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny")
43
+ whisper_model.config.forced_decoder_ids = whisper_processor.get_decoder_prompt_ids(language="english", task="transcribe")
44
 
45
  # Initialize VAD
46
  vad = webrtcvad.Vad(mode=2) # Moderate mode for balanced voice detection
 
86
  logger.error(f"Feature extraction failed: {str(e)}")
87
  raise
88
 
89
+ def transcribe_audio(audio_file):
90
+ """Transcribe audio to text using Whisper."""
91
+ try:
92
+ audio, sr = librosa.load(audio_file, sr=16000)
93
+ inputs = whisper_processor(audio, sampling_rate=sr, return_tensors="pt")
94
+ with torch.no_grad():
95
+ generated_ids = whisper_model.generate(inputs["input_features"])
96
+ transcription = whisper_processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
97
+ logger.info(f"Transcription: {transcription}")
98
+ return transcription
99
+ except Exception as e:
100
+ logger.error(f"Transcription failed: {str(e)}")
101
+ return ""
102
+
103
+ def analyze_symptoms(text):
104
+ """Mock symptom-to-disease analysis (placeholder for symptom-2-disease-net)."""
105
+ # Since abhirajeshbhai/symptom-2-disease-net is not locally available, use rule-based analysis
106
+ text = text.lower()
107
+ feedback = []
108
+ if "cough" in text or "difficulty breathing" in text:
109
+ feedback.append("Symptoms like cough or difficulty breathing may indicate a respiratory condition, such as bronchitis or asthma. Consult a doctor.")
110
+ if "tired" in text or "fatigue" in text:
111
+ feedback.append("Reported fatigue may suggest conditions like anemia or chronic fatigue syndrome. Seek medical advice.")
112
+ if not feedback:
113
+ feedback.append("No specific conditions detected from reported symptoms.")
114
+ return "\n".join(feedback)
115
+
116
  def analyze_voice(audio_file):
117
  """Analyze voice for health indicators."""
118
  try:
 
125
  if len(audio) < sr:
126
  raise ValueError("Audio too short (minimum 1 second)")
127
 
128
+ # Extract voice features
129
  features = extract_health_features(audio, sr)
130
 
131
+ # Transcribe audio for symptom analysis
132
+ transcription = transcribe_audio(audio_file)
133
+ symptom_feedback = analyze_symptoms(transcription) if transcription else "No transcription available for symptom analysis."
134
+
135
+ # Analyze voice features for health indicators
136
  feedback = []
137
  respiratory_score = features["jitter"]
138
  mental_health_score = features["shimmer"]
 
146
  feedback.append(f"Low vocal energy ({features['energy']:.4f}) may indicate fatigue or reduced vocal effort, potentially linked to physical or mental exhaustion.")
147
 
148
  if not feedback:
149
+ feedback.append("No significant health indicators detected from voice features.")
150
 
151
+ # Combine voice and symptom feedback
152
+ feedback.append("\n**Symptom Analysis (from transcription)**:")
153
+ feedback.append(symptom_feedback)
154
+ feedback.append("\n**Voice Analysis Details**:")
155
  feedback.append(f"Pitch: {features['pitch']:.2f} Hz (average fundamental frequency)")
156
  feedback.append(f"Jitter: {respiratory_score:.2f}% (pitch variation, higher values may indicate respiratory issues)")
157
  feedback.append(f"Shimmer: {mental_health_score:.2f}% (amplitude variation, higher values may indicate stress)")
158
  feedback.append(f"Energy: {features['energy']:.4f} (vocal intensity, lower values may indicate fatigue)")
159
+ feedback.append(f"Transcription: {transcription if transcription else 'None'}")
160
  feedback.append("\n**Disclaimer**: This is a preliminary analysis, not a medical diagnosis. Always consult a healthcare provider for professional evaluation.")
161
 
162
  feedback_str = "\n".join(feedback)
163
 
164
  # Store in Salesforce
165
  if sf:
166
+ store_in_salesforce(audio_file, feedback_str, respiratory_score, mental_health_score, features, transcription)
167
 
168
  # Clean up
169
  try:
 
177
  logger.error(f"Audio processing failed: {str(e)}")
178
  return f"Error: {str(e)}"
179
 
180
+ def store_in_salesforce(audio_file, feedback, respiratory_score, mental_health_score, features, transcription):
181
  """Store results in Salesforce."""
182
  try:
183
  sf.HealthAssessment__c.create({
 
189
  "Pitch__c": float(features["pitch"]),
190
  "Jitter__c": float(features["jitter"]),
191
  "Shimmer__c": float(features["shimmer"]),
192
+ "Energy__c": float(features["energy"]),
193
+ "Transcription__c": transcription
194
  })
195
  logger.info("Stored in Salesforce")
196
  except Exception as e:
 
200
  """Test with sample or dummy audio simulating a user's voice."""
201
  sample_audio_path = "audio_samples/sample.wav"
202
  if not os.path.exists(sample_audio_path):
203
+ logger.warning("Sample audio not found; generating dummy audio to simulate user voice saying 'I have a cough'")
204
  # Generate synthetic audio: 150 Hz base frequency to mimic human voice
205
  sr = 16000
206
  t = np.linspace(0, 2, 2 * sr)
 
209
  noise = 0.05 * np.random.normal(0, 1, len(t)) # Moderate noise for realism
210
  dummy_audio = amplitude_mod * np.sin(2 * np.pi * freq_mod * t) + noise
211
  # Ensure dummy_audio is a 1D NumPy array
212
+ dummy_audio = np.asarray(dummy_audio, dtype=np.float32).flatten()
213
  if not isinstance(dummy_audio, np.ndarray) or dummy_audio.ndim != 1:
214
  logger.error(f"Invalid dummy_audio: type={type(dummy_audio)}, shape={dummy_audio.shape if hasattr(dummy_audio, 'shape') else 'N/A'}")
215
  raise ValueError("Generated audio is not a 1D NumPy array")
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
+ # Test audio writing
221
  soundfile.write(dummy_audio, sr, sample_audio_path)
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
 
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)
244
+ ```