Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -61,15 +61,21 @@ def extract_health_features(audio, sr):
|
|
61 |
raise ValueError("No voiced segments detected")
|
62 |
voiced_audio = np.concatenate(voiced_frames)
|
63 |
|
64 |
-
# Pitch (F0)
|
65 |
-
pitches, magnitudes = librosa.piptrack(y=voiced_audio, sr=sr, fmin=
|
66 |
-
valid_pitches = [p for p in pitches[magnitudes > 0] if p
|
67 |
pitch = np.mean(valid_pitches) if valid_pitches else 0
|
68 |
jitter = np.std(valid_pitches) / pitch if pitch and valid_pitches else 0
|
|
|
|
|
|
|
69 |
|
70 |
# Shimmer (amplitude variation)
|
71 |
amplitudes = librosa.feature.rms(y=voiced_audio, frame_length=2048, hop_length=512)[0]
|
72 |
shimmer = np.std(amplitudes) / np.mean(amplitudes) if np.mean(amplitudes) else 0
|
|
|
|
|
|
|
73 |
|
74 |
# Energy
|
75 |
energy = np.mean(librosa.feature.rms(y=voiced_audio, frame_length=2048, hop_length=512)[0])
|
@@ -102,11 +108,11 @@ def analyze_symptoms(text):
|
|
102 |
text = text.lower()
|
103 |
feedback = []
|
104 |
if "cough" in text or "difficulty breathing" in text:
|
105 |
-
feedback.append("
|
106 |
-
|
107 |
-
feedback.append("
|
108 |
-
|
109 |
-
feedback.append("
|
110 |
return "\n".join(feedback)
|
111 |
|
112 |
def analyze_voice(audio_file=None):
|
@@ -126,7 +132,7 @@ def analyze_voice(audio_file=None):
|
|
126 |
|
127 |
# Transcribe audio for symptom analysis
|
128 |
transcription = transcribe_audio(audio)
|
129 |
-
symptom_feedback = analyze_symptoms(transcription) if transcription else "No transcription available
|
130 |
|
131 |
# Analyze voice features for health indicators
|
132 |
feedback = []
|
@@ -135,17 +141,17 @@ def analyze_voice(audio_file=None):
|
|
135 |
|
136 |
# Rule-based analysis (thresholds from voice pathology studies)
|
137 |
if respiratory_score > 1.0:
|
138 |
-
feedback.append(f"
|
139 |
if mental_health_score > 5.0:
|
140 |
-
feedback.append(f"
|
141 |
if features["energy"] < 0.01:
|
142 |
-
feedback.append(f"
|
143 |
|
144 |
-
if not feedback:
|
145 |
-
feedback.append("
|
146 |
|
147 |
# Combine voice and symptom feedback
|
148 |
-
feedback.append("\n**Symptom
|
149 |
feedback.append(symptom_feedback)
|
150 |
feedback.append("\n**Voice Analysis Details**:")
|
151 |
feedback.append(f"Pitch: {features['pitch']:.2f} Hz (average fundamental frequency)")
|
@@ -191,9 +197,9 @@ iface = gr.Interface(
|
|
191 |
inputs=gr.Audio(type="filepath", label="Record or Upload Your Voice (WAV, MP3, FLAC, 1+ sec)", format="wav"),
|
192 |
outputs=gr.Textbox(label="Health Assessment Results"),
|
193 |
title="Voice Health Analyzer",
|
194 |
-
description="Record or upload your voice (minimum 1 second) to receive preliminary health insights. Speak clearly in English about your symptoms."
|
195 |
)
|
196 |
|
197 |
if __name__ == "__main__":
|
198 |
-
logger.info("Starting Voice Health Analyzer at 12:
|
199 |
iface.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
61 |
raise ValueError("No voiced segments detected")
|
62 |
voiced_audio = np.concatenate(voiced_frames)
|
63 |
|
64 |
+
# Pitch (F0) with range validation
|
65 |
+
pitches, magnitudes = librosa.piptrack(y=voiced_audio, sr=sr, fmin=75, fmax=300) # Adult pitch range
|
66 |
+
valid_pitches = [p for p in pitches[magnitudes > 0] if 75 <= p <= 300]
|
67 |
pitch = np.mean(valid_pitches) if valid_pitches else 0
|
68 |
jitter = np.std(valid_pitches) / pitch if pitch and valid_pitches else 0
|
69 |
+
if jitter > 10: # Cap extreme jitter (possible noise)
|
70 |
+
jitter = 10
|
71 |
+
logger.warning("Jitter exceeds 10%, likely due to noise or distortion")
|
72 |
|
73 |
# Shimmer (amplitude variation)
|
74 |
amplitudes = librosa.feature.rms(y=voiced_audio, frame_length=2048, hop_length=512)[0]
|
75 |
shimmer = np.std(amplitudes) / np.mean(amplitudes) if np.mean(amplitudes) else 0
|
76 |
+
if shimmer > 10: # Cap extreme shimmer (possible noise)
|
77 |
+
shimmer = 10
|
78 |
+
logger.warning("Shimmer exceeds 10%, likely due to noise or distortion")
|
79 |
|
80 |
# Energy
|
81 |
energy = np.mean(librosa.feature.rms(y=voiced_audio, frame_length=2048, hop_length=512)[0])
|
|
|
108 |
text = text.lower()
|
109 |
feedback = []
|
110 |
if "cough" in text or "difficulty breathing" in text:
|
111 |
+
feedback.append("Your voice suggests possible respiratory issues, such as bronchitis or asthma. Please consult a doctor.")
|
112 |
+
elif "stressed" in text or "stress" in text or "tired" in text or "fatigue" in text:
|
113 |
+
feedback.append("Your voice and words indicate possible stress or fatigue, which may relate to anxiety or exhaustion. Consider seeking medical advice.")
|
114 |
+
else:
|
115 |
+
feedback.append("Your input didn’t specify clear symptoms. For a comprehensive health check, please describe any issues (e.g., cough, stress) and consult a healthcare provider.")
|
116 |
return "\n".join(feedback)
|
117 |
|
118 |
def analyze_voice(audio_file=None):
|
|
|
132 |
|
133 |
# Transcribe audio for symptom analysis
|
134 |
transcription = transcribe_audio(audio)
|
135 |
+
symptom_feedback = analyze_symptoms(transcription) if transcription else "No transcription available. Please record again with clear speech."
|
136 |
|
137 |
# Analyze voice features for health indicators
|
138 |
feedback = []
|
|
|
141 |
|
142 |
# Rule-based analysis (thresholds from voice pathology studies)
|
143 |
if respiratory_score > 1.0:
|
144 |
+
feedback.append(f"Your voice shows elevated jitter ({respiratory_score:.2f}%), which may indicate respiratory issues like vocal cord irregularities. Consult a doctor.")
|
145 |
if mental_health_score > 5.0:
|
146 |
+
feedback.append(f"Your voice exhibits elevated shimmer ({mental_health_score:.2f}%), suggesting possible stress or emotional strain. Consider a health check.")
|
147 |
if features["energy"] < 0.01:
|
148 |
+
feedback.append(f"Your vocal energy is low ({features['energy']:.4f}), which might suggest fatigue. Seek medical advice if persistent.")
|
149 |
|
150 |
+
if not feedback and not symptom_feedback.startswith("No transcription"):
|
151 |
+
feedback.append("Your voice shows no significant health indicators based on current analysis.")
|
152 |
|
153 |
# Combine voice and symptom feedback
|
154 |
+
feedback.append("\n**Symptom Feedback (from your words)**:")
|
155 |
feedback.append(symptom_feedback)
|
156 |
feedback.append("\n**Voice Analysis Details**:")
|
157 |
feedback.append(f"Pitch: {features['pitch']:.2f} Hz (average fundamental frequency)")
|
|
|
197 |
inputs=gr.Audio(type="filepath", label="Record or Upload Your Voice (WAV, MP3, FLAC, 1+ sec)", format="wav"),
|
198 |
outputs=gr.Textbox(label="Health Assessment Results"),
|
199 |
title="Voice Health Analyzer",
|
200 |
+
description="Record or upload your voice (minimum 1 second) to receive preliminary health insights. Speak clearly in English about your symptoms (e.g., 'I have a cough' or 'I feel stressed')."
|
201 |
)
|
202 |
|
203 |
if __name__ == "__main__":
|
204 |
+
logger.info("Starting Voice Health Analyzer at 12:21 PM IST, June 23, 2025")
|
205 |
iface.launch(server_name="0.0.0.0", server_port=7860)
|