Update app.py
Browse files
app.py
CHANGED
@@ -315,77 +315,58 @@ def create_interface():
|
|
315 |
return None
|
316 |
|
317 |
def analyze_voice(audio_path, state):
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
}
|
370 |
-
except Exception as e:
|
371 |
-
return {
|
372 |
-
"transcribed_text": f"오류 발생: {str(e)}",
|
373 |
-
"voice_emotion": "",
|
374 |
-
"text_emotion": "",
|
375 |
-
"prompt": ""
|
376 |
-
}
|
377 |
|
378 |
-
# 이벤트 연결 부분도 수정
|
379 |
-
analyze_btn.click(
|
380 |
-
fn=analyze_voice,
|
381 |
-
inputs=[voice_input, state],
|
382 |
-
outputs={
|
383 |
-
"transcribed_text": transcribed_text,
|
384 |
-
"voice_emotion": voice_emotion,
|
385 |
-
"text_emotion": text_emotion,
|
386 |
-
"final_prompt": final_prompt
|
387 |
-
}
|
388 |
-
)
|
389 |
|
390 |
set_baseline_btn.click(
|
391 |
fn=set_baseline,
|
|
|
315 |
return None
|
316 |
|
317 |
def analyze_voice(audio_path, state):
|
318 |
+
"""음성 분석"""
|
319 |
+
if audio_path is None:
|
320 |
+
return state, "음성을 먼저 녹음해주세요.", "", "", ""
|
321 |
+
|
322 |
+
try:
|
323 |
+
y, sr = librosa.load(audio_path, sr=16000)
|
324 |
+
|
325 |
+
acoustic_features = {
|
326 |
+
"energy": float(np.mean(librosa.feature.rms(y=y))),
|
327 |
+
"tempo": float(librosa.beat.tempo(y)[0]),
|
328 |
+
"pitch": float(np.mean(librosa.feature.zero_crossing_rate(y))),
|
329 |
+
"volume": float(np.mean(np.abs(y)))
|
330 |
+
}
|
331 |
+
|
332 |
+
# 기준점이 있는 경우 상대적 분석
|
333 |
+
baseline = state.get("baseline_features")
|
334 |
+
emotions = map_acoustic_to_emotion(acoustic_features, baseline)
|
335 |
+
|
336 |
+
# 음성-텍스트 변환
|
337 |
+
transcription = speech_recognizer(y)
|
338 |
+
text = transcription["text"]
|
339 |
+
text_sentiment = text_analyzer(text)[0]
|
340 |
+
|
341 |
+
voice_result = (
|
342 |
+
f"음성 감정: {emotions['primary']} "
|
343 |
+
f"(강도: {emotions['intensity']:.1f}%, 신뢰도: {emotions['confidence']:.2f})\n"
|
344 |
+
f"특징: {', '.join(emotions['characteristics'])}\n"
|
345 |
+
f"상세 분석:\n"
|
346 |
+
f"- 에너지 레벨: {emotions['details']['energy_level']}\n"
|
347 |
+
f"- 말하기 속도: {emotions['details']['speech_rate']}\n"
|
348 |
+
f"- 음높이 변화: {emotions['details']['pitch_variation']}\n"
|
349 |
+
f"- 음성 크기: {emotions['details']['voice_volume']}"
|
350 |
+
)
|
351 |
+
|
352 |
+
if baseline:
|
353 |
+
voice_result += "\n\n[기준점 대비 분석]\n"
|
354 |
+
voice_result += f"기준 상태와 비교한 감정 강도 변화: {emotions['intensity']-50:.1f}%"
|
355 |
+
|
356 |
+
text_result = f"텍스트 감정 분석 (1-5): {text_sentiment['score']}"
|
357 |
+
prompt = generate_detailed_prompt(text, emotions, text_sentiment)
|
358 |
+
|
359 |
+
return state, text, voice_result, text_result, prompt
|
360 |
+
except Exception as e:
|
361 |
+
return state, f"오류 발생: {str(e)}", "", "", ""
|
362 |
+
|
363 |
+
# 이벤트 연결 부분
|
364 |
+
analyze_btn.click(
|
365 |
+
fn=analyze_voice,
|
366 |
+
inputs=[voice_input, state],
|
367 |
+
outputs=[state, transcribed_text, voice_emotion, text_emotion, final_prompt]
|
368 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
set_baseline_btn.click(
|
372 |
fn=set_baseline,
|