File size: 6,176 Bytes
bb63470
 
 
 
00ada4a
db42dba
bb63470
9d47e7f
 
 
 
db42dba
9d47e7f
00ada4a
7ec9920
 
9d47e7f
7ec9920
00ada4a
9d47e7f
 
7ec9920
db42dba
9d47e7f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
db42dba
9d47e7f
 
 
 
db42dba
 
9d47e7f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
db42dba
7ec9920
9d47e7f
 
 
 
 
 
 
 
 
 
 
 
7ec9920
9d47e7f
 
 
 
 
 
 
 
 
 
 
 
db42dba
9d47e7f
 
 
 
 
 
 
 
 
 
 
db42dba
 
 
 
9f7512d
9d47e7f
 
 
 
 
 
 
 
9f7512d
db42dba
9d47e7f
 
 
 
db42dba
9d47e7f
7ec9920
9d47e7f
 
db42dba
7ec9920
9d47e7f
db42dba
9d47e7f
 
db42dba
9d47e7f
 
7ec9920
db42dba
7ec9920
 
9d47e7f
db42dba
 
 
9d47e7f
db42dba
 
7ec9920
9f7512d
9d47e7f
bb63470
9d47e7f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import gradio as gr
import numpy as np
import librosa
from transformers import pipeline
from datetime import datetime
import os

# 전역 변수 설정
SAMPLE_RATE = 16000  # 샘플링 레이트 고정
N_MELS = 64  # mel 필터 수 조정

# AI 모델 초기화
text_analyzer = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")

def create_interface():
    with gr.Blocks(theme=gr.themes.Soft()) as app:
        # 상태 변수
        state = gr.State({
            "reflections": [],
            "user_name": "",
            "analyses": []
        })

        # 헤더
        header = gr.Markdown("# 디지털 굿판")
        user_display = gr.Markdown("")

        with gr.Tabs() as tabs:
            # 입장 탭
            with gr.Tab("입장") as intro_tab:
                gr.Markdown("""
                # 디지털 굿판에 오신 것을 환영합니다
                온천천의 디지털 치유 공간으로 들어가보세요.
                """)
                name_input = gr.Textbox(label="이름을 알려주세요")
                start_btn = gr.Button("여정 시작하기")

            # 청신 탭
            with gr.Tab("청신") as cleansing_tab:
                with gr.Row():
                    # 음악 플레이어
                    audio = gr.Audio(
                        value="assets/main_music.mp3",
                        type="filepath",
                        label="온천천의 소리",
                        interactive=True
                    )
                    
                    with gr.Column():
                        reflection_input = gr.Textbox(
                            label="현재 순간의 감상을 적어주세요",
                            lines=3
                        )
                        save_btn = gr.Button("감상 저장하기")
                        reflections_display = gr.Dataframe(
                            headers=["시간", "감상", "감정"],
                            label="기록된 감상들"
                        )

            # 기원 탭
            with gr.Tab("기원") as prayer_tab:
                with gr.Row():
                    voice_input = gr.Audio(
                        label="나누고 싶은 이야기를 들려주세요",
                        sources=["microphone"],
                        type="filepath"
                    )
                    
                    with gr.Column():
                        text_output = gr.Textbox(label="인식된 텍스트")
                        emotion_output = gr.Textbox(label="감정 분석")
                        audio_features = gr.JSON(label="음성 특성 분석")

            # 송신 탭
            with gr.Tab("송신") as sharing_tab:
                prompt_display = gr.Textbox(label="생성된 프롬프트")
                gallery = gr.Gallery(label="시각화 결과")

        # 함수 정의
        def start_journey(name):
            """여정 시작"""
            if name.strip():
                welcome_text = f"# 환영합니다, {name}님"
                return welcome_text, gr.update(selected="청신")
            return "이름을 입력해주세요", gr.update(selected="입장")

        def save_reflection(text, state_data):
            """감상 저장"""
            if not text.strip():
                return state_data, []
            
            try:
                current_time = datetime.now().strftime("%H:%M:%S")
                sentiment = text_analyzer(text)[0]
                new_reflection = [current_time, text, sentiment["label"]]
                
                if "reflections" not in state_data:
                    state_data["reflections"] = []
                
                state_data["reflections"].append(new_reflection)
                return state_data, state_data["reflections"]
            except Exception as e:
                print(f"Error in save_reflection: {str(e)}")
                return state_data, []

        def analyze_voice(audio_path, state_data):
            """음성 분석"""
            if audio_path is None:
                return None, None, None, state_data
                
            try:
                # 오디오 로드 및 리샘플링
                y, sr = librosa.load(audio_path, sr=SAMPLE_RATE)
                
                # 기본 특성 추출
                features = {
                    "energy": float(np.mean(librosa.feature.rms(y=y))),
                    "tempo": float(librosa.beat.tempo(y)[0]),
                    "zero_crossing_rate": float(np.mean(librosa.feature.zero_crossing_rate(y)))
                }
                
                # MFCC 계산 (파라미터 조정)
                mfccs = librosa.feature.mfcc(
                    y=y, 
                    sr=sr,
                    n_mfcc=13,
                    n_mels=N_MELS
                )
                features["mfcc_mean"] = np.mean(mfccs, axis=1).tolist()
                
                return (
                    "음성이 성공적으로 분석되었습니다.",  # 텍스트 출력
                    f"에너지: {features['energy']:.2f}\n템포: {features['tempo']:.2f}",  # 감정 출력
                    features,  # JSON 출력
                    state_data  # 상태 업데이트
                )
                
            except Exception as e:
                print(f"Error in analyze_voice: {str(e)}")
                return f"오류 발생: {str(e)}", None, None, state_data

        # 이벤트 연결
        start_btn.click(
            fn=start_journey,
            inputs=[name_input],
            outputs=[user_display, tabs]
        )
        
        save_btn.click(
            fn=save_reflection,
            inputs=[reflection_input, state],
            outputs=[state, reflections_display]
        )
        
        voice_input.change(
            fn=analyze_voice,
            inputs=[voice_input, state],
            outputs=[text_output, emotion_output, audio_features, state]
        )

    return app

# 앱 실행
if __name__ == "__main__":
    demo = create_interface()
    demo.launch()