File size: 7,146 Bytes
644d52a
db865fa
 
 
 
8a2791f
a7c706c
 
 
 
db865fa
abc0e8f
a7c706c
644d52a
8a2791f
a7c706c
db865fa
644d52a
abc0e8f
db865fa
 
 
644d52a
abc0e8f
db865fa
 
 
 
 
21c5c47
a7c706c
8a2791f
21c5c47
 
8a2791f
21c5c47
8a2791f
21c5c47
 
a7c706c
8a2791f
 
 
 
 
a7c706c
21c5c47
01296a1
 
 
 
92ed364
 
01296a1
92ed364
01296a1
 
 
8a2791f
21c5c47
 
01296a1
21c5c47
 
 
8a2791f
 
 
 
92ed364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a2791f
 
 
 
 
 
 
92ed364
 
 
 
 
 
 
 
 
 
 
8a2791f
 
21c5c47
 
 
a7c706c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21c5c47
8a2791f
21c5c47
 
 
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
167
168
169
170

import streamlit as st
from transformers import pipeline
from pydub import AudioSegment
import os
import re
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from datetime import datetime

# Page config
st.set_page_config(page_title="Atma.ai - Session Summarizer + Export", layout="wide")

st.title("🧠 Atma.ai – Advanced Mental Health Session Summarizer")
st.markdown("Upload a therapy session audio (Tamil-English mix) to view the transcript, summary, emotional analysis, and export everything to Word!")

# Upload audio
uploaded_file = st.file_uploader("πŸŽ™οΈ Upload audio file", type=["wav", "mp3", "m4a"])

if uploaded_file:
    st.audio(uploaded_file)

    # Convert audio to required format
    audio_path = "temp_audio.wav"
    audio = AudioSegment.from_file(uploaded_file)
    audio = audio.set_channels(1).set_frame_rate(16000)
    audio.export(audio_path, format="wav")

    try:
        # Transcribe
        st.info("πŸ”„ Transcribing with Whisper (mixed-language support)...")
        asr = pipeline("automatic-speech-recognition", model="openai/whisper-large")
        result = asr(audio_path, return_timestamps=True, generate_kwargs={"language": "<|en|>"})
        raw_transcript = result.get("text", "")

        if not raw_transcript:
            st.error("❌ Could not generate a transcript. Please try a different audio.")
        else:
            # Simulated Speaker Diarization
            st.info("πŸ—£οΈ Simulating speaker separation...")
            sentences = re.split(r'(?<=[.?!])\s+', raw_transcript)
            diarized_transcript = ""
            for idx, sentence in enumerate(sentences):
                speaker = "Speaker 1" if idx % 2 == 0 else "Speaker 2"
                diarized_transcript += f"{speaker}: {sentence}\n\n"

            
            # Static Session Context Recall
            st.info("πŸ” Loading previous session context...")
            past_sessions = [
                {"date": "2024-04-15", "coping": "walking", "emotion": "anxiety", "notes": "high workload"},
                {"date": "2024-04-22", "coping": "journaling", "emotion": "stress", "notes": "difficulty sleeping"}
            ]
            rag_context = "\n".join([f"Session {i+1}: {s['coping']}, {s['emotion']}, {s['notes']}" for i, s in enumerate(past_sessions)])

            prompt_input = f"""Previous session context:\n{rag_context}\n\nCurrent session:\n{raw_transcript}"""

            # Summarization
            st.info("πŸ“‹ Summarizing conversation...")
            summarizer = pipeline("summarization", model="philschmid/bart-large-cnn-samsum")
            summary = summarizer(prompt_input, max_length=256, min_length=60, do_sample=False)

            # Emotion tagging
            st.info("🎭 Extracting emotional tones...")
            emotion_model = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", return_all_scores=True)
            emotion_scores = emotion_model(raw_transcript)

            # Layout with Tabs
            
import matplotlib.pyplot as plt

# Add trends tab to UI
tab1, tab2, tab3, tab4 = st.tabs(["πŸ“ Transcript", "πŸ“‹ Summary", "πŸ’¬ Emotions", "πŸ“ˆ Trends"])

# Plot session trend (static mock data)
with tab4:
    st.subheader("πŸ“ˆ Emotional Trends Over Time")

    session_dates = ["2024-04-01", "2024-04-08", "2024-04-15", "2024-04-22"]
    anxiety_scores = [70, 65, 55, 40]
    sadness_scores = [30, 20, 25, 15]

    fig, ax = plt.subplots()
    ax.plot(session_dates, anxiety_scores, label='Anxiety', marker='o')
    ax.plot(session_dates, sadness_scores, label='Sadness', marker='o')
    ax.set_title("Emotional Trends Over Time")
    ax.set_ylabel("Score (%)")
    ax.set_xlabel("Session Date")
    ax.legend()
    st.pyplot(fig)


            with tab1:
                st.subheader("πŸ“ Speaker-Simulated Transcript")
                st.markdown(diarized_transcript, unsafe_allow_html=True)

            with tab2:
                st.subheader("πŸ“‹ Contextual Summary")
                
            # Insight Tracking based on previous sessions
            insights = []
            if "music" in raw_transcript.lower():
                if any("walking" in s["coping"] for s in past_sessions):
                    insights.append("Patient previously mentioned walking as a helpful coping mechanism. This time, music is highlighted instead.")
            if "sleep" in raw_transcript.lower():
                insights.append("Sleep continues to be a recurring theme across sessions.")
            final_output = f"{summary[0]['summary_text']}\n\nContextual Observations:\n" + "\n".join(insights)
            st.write(final_output)
    

            with tab3:
                st.subheader("πŸ’¬ Emotional Insights (Overall)")
                for emo in emotion_scores[0]:
                    st.write(f"{emo['label']}: {round(emo['score']*100, 2)}%")

            # Export Button
            st.subheader("πŸ“₯ Export Session Report")

            def generate_docx(transcript, summary_text, emotions):
                doc = Document()

                # Title
                title = doc.add_heading('Session Summary - Atma.ai', 0)
                title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

                # Date
                date_paragraph = doc.add_paragraph(f"Date: {datetime.now().strftime('%Y-%m-%d')}")
                date_paragraph.runs[0].italic = True

                doc.add_paragraph("\n")

                # Transcript
                doc.add_heading('πŸ“ Transcript', level=1)
                transcript_para = doc.add_paragraph(transcript)
                transcript_para.runs[0].font.size = Pt(12)

                doc.add_paragraph("\n")

                # Summary
                doc.add_heading('πŸ“‹ Summary', level=1)
                summary_para = doc.add_paragraph(summary_text)
                summary_para.runs[0].font.size = Pt(12)

                doc.add_paragraph("\n")

                # Emotional Insights
                doc.add_heading('πŸ’¬ Emotional Insights', level=1)
                for emo in emotions[0]:
                    emotion_para = doc.add_paragraph(f"{emo['label']}: {round(emo['score']*100, 2)}%")
                    emotion_para.runs[0].font.size = Pt(12)

                # Footer
                doc.add_paragraph("\n\n---\nGenerated by Atma.ai – Confidential", style="Intense Quote")

                output_path = "session_summary.docx"
                doc.save(output_path)
                return output_path

            if st.button("Generate and Download Report (.docx)"):
                output_file = generate_docx(diarized_transcript, summary[0]["summary_text"], emotion_scores)
                with open(output_file, "rb") as f:
                    st.download_button(label="πŸ“₯ Download Report", data=f, file_name="session_summary.docx", mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document")

    except Exception as err:
        st.error(f"❌ Processing failed: {err}")
    finally:
        if os.path.exists(audio_path):
            os.remove(audio_path)