Spaces:
Sleeping
Sleeping
Upload 8 files
Browse files- .gitattributes +2 -0
- about.py +39 -0
- app1.py +216 -0
- css.py +85 -0
- fevicon.png +3 -0
- logo.png +3 -0
- requirements.txt +8 -0
- tone.py +95 -0
- voice.py +41 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
fevicon.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
logo.png filter=lfs diff=lfs merge=lfs -text
|
about.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
def about_page():
|
| 4 |
+
st.title("π About VoiceBridge")
|
| 5 |
+
|
| 6 |
+
st.markdown("""
|
| 7 |
+
**VoiceBridge** is a smart and user-friendly app designed to help you **translate speech or text across multiple languages** and analyze the **emotional tone** of the message.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
### π What Can VoiceBridge Do?
|
| 11 |
+
- π£οΈ Convert **voice to text** using speech recognition
|
| 12 |
+
- π Translate text or speech into other languages using Deep Translator (Google Translate)
|
| 13 |
+
- π¬ Detect the **sentiment or tone** of the message using local and cloud-based models
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
### π§ Technologies Used
|
| 17 |
+
- **Speech Recognition**: `speech_recognition` library for converting audio to text
|
| 18 |
+
- **Translation**: `deep_translator` with Google Translate for accurate text translation
|
| 19 |
+
- **Sentiment Analysis**:
|
| 20 |
+
- For text: Hugging Face Transformer models (e.g., BERT-based sentiment classification)
|
| 21 |
+
- For voice: A local emotion detection model to analyze audio tone
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
### π― Why VoiceBridge?
|
| 25 |
+
VoiceBridge is created to:
|
| 26 |
+
- Break language barriers in real-time
|
| 27 |
+
- Help understand the emotional intent of communication
|
| 28 |
+
- Enable better interaction in global, multicultural environments
|
| 29 |
+
- Support accessibility and learning
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
### π¨βπ» Developer Info
|
| 33 |
+
**Developed by**: Ayush & Manav
|
| 34 |
+
π [GitHub](https://github.com/yourusername) | [LinkedIn](https://linkedin.com/in/yourprofile)
|
| 35 |
+
|
| 36 |
+
---
|
| 37 |
+
π VoiceBridge is open for collaboration and feedback. Let's bridge the gap between voices and languages! π¬π
|
| 38 |
+
""")
|
| 39 |
+
|
app1.py
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from deep_translator import GoogleTranslator
|
| 3 |
+
from gtts import gTTS
|
| 4 |
+
from pydub import AudioSegment
|
| 5 |
+
import tempfile
|
| 6 |
+
import os
|
| 7 |
+
import speech_recognition as sr
|
| 8 |
+
from transformers import pipeline as pl
|
| 9 |
+
from streamlit_option_menu import option_menu
|
| 10 |
+
import css
|
| 11 |
+
from st_audiorec import st_audiorec
|
| 12 |
+
import streamlit.components.v1 as components
|
| 13 |
+
from voice import transcribe,text_to_speech
|
| 14 |
+
from tone import tone
|
| 15 |
+
import about
|
| 16 |
+
|
| 17 |
+
os.environ["STREAMLIT_WATCHER_TYPE"] = "none"
|
| 18 |
+
st.session_state.translate=False
|
| 19 |
+
|
| 20 |
+
st.set_page_config(page_title="VoiceBridge",layout="wide",page_icon="fevicon.png")
|
| 21 |
+
Languages = {'afrikaans':'af','albanian':'sq','amharic':'am','arabic':'ar','armenian':'hy','azerbaijani':'az',
|
| 22 |
+
'basque':'eu','belarusian':'be','bengali':'bn','bosnian':'bs','bulgarian':'bg','catalan':'ca',
|
| 23 |
+
'cebuano':'ceb','chichewa':'ny','chinese (simplified)':'zh-cn','chinese (traditional)':'zh-tw',
|
| 24 |
+
'corsican':'co','croatian':'hr','czech':'cs','danish':'da','dutch':'nl','english':'en','esperanto':'eo',
|
| 25 |
+
'estonian':'et','filipino':'tl','finnish':'fi','french':'fr','frisian':'fy','galician':'gl','georgian':'ka',
|
| 26 |
+
'german':'de','greek':'el','gujarati':'gu','haitian creole':'ht','hausa':'ha','hawaiian':'haw','hebrew':'iw',
|
| 27 |
+
'hebrew':'he','hindi':'hi','hmong':'hmn','hungarian':'hu','icelandic':'is','igbo':'ig','indonesian':'id',
|
| 28 |
+
'irish':'ga','italian':'it','japanese':'ja','javanese':'jw','kannada':'kn','kazakh':'kk','khmer':'km',
|
| 29 |
+
'korean':'ko','kurdish (kurmanji)':'ku','kyrgyz':'ky','lao':'lo','latin':'la','latvian':'lv','lithuanian':'lt',
|
| 30 |
+
'luxembourgish':'lb','macedonian':'mk','malagasy':'mg','malay':'ms','malayalam':'ml','maltese':'mt','maori':'mi',
|
| 31 |
+
'marathi':'mr','mongolian':'mn','myanmar (burmese)':'my','nepali':'ne','norwegian':'no','odia':'or','pashto':'ps',
|
| 32 |
+
'persian':'fa','polish':'pl','portuguese':'pt','punjabi':'pa','romanian':'ro','russian':'ru','samoan':'sm',
|
| 33 |
+
'scots gaelic':'gd','serbian':'sr','sesotho':'st','shona':'sn','sindhi':'sd','sinhala':'si','slovak':'sk',
|
| 34 |
+
'slovenian':'sl','somali':'so','spanish':'es','sundanese':'su','swahili':'sw','swedish':'sv','tajik':'tg',
|
| 35 |
+
'tamil':'ta','telugu':'te','thai':'th','turkish':'tr','turkmen':'tk','ukrainian':'uk','urdu':'ur','uyghur':'ug',
|
| 36 |
+
'uzbek':'uz','vietnamese':'vi','welsh':'cy','xhosa':'xh','yiddish':'yi','yoruba':'yo','zulu':'zu'}
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
st.markdown(
|
| 41 |
+
"""
|
| 42 |
+
<style>
|
| 43 |
+
|
| 44 |
+
[alt="Logo"] {
|
| 45 |
+
height: 90px;
|
| 46 |
+
width: auto;
|
| 47 |
+
|
| 48 |
+
}
|
| 49 |
+
.block-container {
|
| 50 |
+
padding-top: 0rem;
|
| 51 |
+
}
|
| 52 |
+
header { visibility: hidden; }
|
| 53 |
+
</style>
|
| 54 |
+
""",
|
| 55 |
+
unsafe_allow_html=True
|
| 56 |
+
)
|
| 57 |
+
col1, col2 = st.columns([1, 6])
|
| 58 |
+
with col1:
|
| 59 |
+
st.markdown("""
|
| 60 |
+
<style>
|
| 61 |
+
@media only screen and (max-width: 959px) {
|
| 62 |
+
img {
|
| 63 |
+
max-width: 100px;
|
| 64 |
+
height: auto;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
</style>
|
| 68 |
+
""", unsafe_allow_html=True)
|
| 69 |
+
st.logo("logo.png")
|
| 70 |
+
with col2:
|
| 71 |
+
|
| 72 |
+
css.nev()
|
| 73 |
+
st.markdown('<div class="custom-navbar">', unsafe_allow_html=True)
|
| 74 |
+
selected = option_menu(
|
| 75 |
+
menu_title=None,
|
| 76 |
+
options=["Translate", "Tone", "About"],
|
| 77 |
+
icons=["bi-people-fill", "bi-soundwave", "gear"],
|
| 78 |
+
menu_icon="cast",
|
| 79 |
+
default_index=0,
|
| 80 |
+
orientation="horizontal",
|
| 81 |
+
styles={
|
| 82 |
+
"container": {"padding": "0!important", "background-color": "#0E1117"},
|
| 83 |
+
"icon": {"color": "white"},
|
| 84 |
+
"nav-link": {
|
| 85 |
+
"text-align": "center",
|
| 86 |
+
"margin": "0px",
|
| 87 |
+
"--hover-color": "#204044",
|
| 88 |
+
},
|
| 89 |
+
"nav-link-selected": {"background-color": "#1f6f78"},
|
| 90 |
+
}
|
| 91 |
+
)
|
| 92 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 93 |
+
with st.container():
|
| 94 |
+
st.markdown("""
|
| 95 |
+
<style>
|
| 96 |
+
.custom-container {
|
| 97 |
+
margin-top: 70px;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
@media (max-width: 767px) {
|
| 101 |
+
.custom-container {
|
| 102 |
+
margin-top: 0px;
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
</style>
|
| 106 |
+
<style>
|
| 107 |
+
.middle {
|
| 108 |
+
margin-top: 120px;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
@media (max-width: 767px) {
|
| 112 |
+
.middle {
|
| 113 |
+
margin-top: 0px;
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
</style>
|
| 117 |
+
""", unsafe_allow_html=True)
|
| 118 |
+
st.markdown('<div class="custom-container">', unsafe_allow_html=True)
|
| 119 |
+
|
| 120 |
+
left_col, st.session_state.mid_col, st.session_state.right_col = st.columns([3, 2, 3])
|
| 121 |
+
# left user input
|
| 122 |
+
# ------------------------------------------------------------------------------------------------------------------------------------------------
|
| 123 |
+
if (selected == "Translate" or selected == "Tone"):
|
| 124 |
+
with left_col:
|
| 125 |
+
with st.popover("", icon=":material/tune:"):
|
| 126 |
+
inp = st.selectbox('Choose Input Format', ("Text", "Audio_file", "MIC"))
|
| 127 |
+
st.session_state.inp = inp
|
| 128 |
+
with st.form("my_form"):
|
| 129 |
+
st.markdown("### ποΈ Input")
|
| 130 |
+
if st.session_state.inp == "Text":
|
| 131 |
+
st.session_state.text = st.text_area("Enter Text:", help="Type your text here...")
|
| 132 |
+
elif st.session_state.inp == "MIC":
|
| 133 |
+
st.session_state.uploaded_file = st.audio_input("Record a Voice Message")
|
| 134 |
+
else:
|
| 135 |
+
st.session_state.uploaded_file = st.file_uploader("Upload an Audio File", type=["mp3", "wav", "m4a"])
|
| 136 |
+
|
| 137 |
+
submitted = st.form_submit_button("Submit")
|
| 138 |
+
|
| 139 |
+
# ------------------------------------------------------------------------------------------------------------------------------------------------
|
| 140 |
+
if selected == "Translate":
|
| 141 |
+
|
| 142 |
+
# ------------------------------------------------------------------------------------------------------------------------------------------------
|
| 143 |
+
# center button
|
| 144 |
+
st.markdown('<div class="middle">', unsafe_allow_html=True)
|
| 145 |
+
with st.session_state.mid_col:
|
| 146 |
+
|
| 147 |
+
css.cicle_button()
|
| 148 |
+
|
| 149 |
+
if st.button("Translate"):
|
| 150 |
+
st.session_state.translate=False
|
| 151 |
+
st.session_state.translate=True
|
| 152 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
# ------------------------------------------------------------------------------------------------------------------------------------------------
|
| 156 |
+
# Right Output
|
| 157 |
+
with st.session_state.right_col:
|
| 158 |
+
|
| 159 |
+
with st.popover("", icon=":material/tune:"):
|
| 160 |
+
out_type = st.selectbox('Choose Input Format', ("Text", "Voice", "Both"))
|
| 161 |
+
st.session_state.out_type = out_type
|
| 162 |
+
with st.form("output"):
|
| 163 |
+
st.markdown("### π Voice Output")
|
| 164 |
+
option2 = st.selectbox('Select Output Language', list(Languages.keys()))
|
| 165 |
+
value2 = Languages[option2]
|
| 166 |
+
|
| 167 |
+
if st.session_state.translate:
|
| 168 |
+
c1,c2=st.columns(2)
|
| 169 |
+
if st.session_state.inp != "Text":
|
| 170 |
+
st.session_state.text = transcribe(st.session_state.uploaded_file)
|
| 171 |
+
|
| 172 |
+
translated_text = GoogleTranslator(target=value2).translate(st.session_state.text)
|
| 173 |
+
|
| 174 |
+
if st.session_state.out_type == "Text":
|
| 175 |
+
st.text_area("Translated Text:", translated_text, height=100)
|
| 176 |
+
|
| 177 |
+
elif st.session_state.out_type == "Voice":
|
| 178 |
+
if translated_text.strip():
|
| 179 |
+
audio_file = text_to_speech(translated_text, value2)
|
| 180 |
+
else:
|
| 181 |
+
c2.warning("Please enter text before converting.")
|
| 182 |
+
st.audio(audio_file, format='audio/mp3', autoplay=True)
|
| 183 |
+
|
| 184 |
+
else:
|
| 185 |
+
if translated_text.strip():
|
| 186 |
+
audio_file = text_to_speech(translated_text, value2)
|
| 187 |
+
else:
|
| 188 |
+
c2.warning("Please enter text before converting.")
|
| 189 |
+
with c1.popover("", icon=":material/library_books:"):
|
| 190 |
+
st.text_area("Translated Text:", translated_text, height=100)
|
| 191 |
+
c2.audio(audio_file, format='audio/mp3', autoplay=True)
|
| 192 |
+
|
| 193 |
+
reset = st.form_submit_button("Reset β» ")
|
| 194 |
+
if reset:
|
| 195 |
+
st.session_state.translate= False
|
| 196 |
+
# Optional: Add some styling
|
| 197 |
+
st.markdown("""
|
| 198 |
+
|
| 199 |
+
<style>
|
| 200 |
+
body {
|
| 201 |
+
background-color: #0e1117;
|
| 202 |
+
color: white;
|
| 203 |
+
}
|
| 204 |
+
.stButton>button {
|
| 205 |
+
background-color: teal;
|
| 206 |
+
color: white;
|
| 207 |
+
}
|
| 208 |
+
</style>
|
| 209 |
+
""", unsafe_allow_html=True)
|
| 210 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
if selected == "Tone":
|
| 214 |
+
tone()
|
| 215 |
+
if selected == "About":
|
| 216 |
+
about.about_page()
|
css.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
def nev():
|
| 4 |
+
st.markdown("""
|
| 5 |
+
<style>
|
| 6 |
+
/* Responsive icon and text size for option menu */
|
| 7 |
+
@media only screen and (max-width: 768px) {
|
| 8 |
+
.nav-link > span {
|
| 9 |
+
font-size: 14px !important; /* reduce label size */
|
| 10 |
+
}
|
| 11 |
+
.nav-link > i {
|
| 12 |
+
font-size: 16px !important; /* reduce icon size */
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
@media only screen and (max-width: 480px) {
|
| 17 |
+
.nav-link > span {
|
| 18 |
+
font-size: 12px !important;
|
| 19 |
+
}
|
| 20 |
+
.nav-link > i {
|
| 21 |
+
font-size: 14px !important;
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
@media only screen and (min-width: 769px) {
|
| 26 |
+
.nav-link > span {
|
| 27 |
+
font-size: 18px !important;
|
| 28 |
+
}
|
| 29 |
+
.nav-link > i {
|
| 30 |
+
font-size: 20px !important;
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
.custom-navbar {
|
| 35 |
+
margin-top: 0px;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
@media only screen and (max-width: 768px) {
|
| 39 |
+
.custom-navbar {
|
| 40 |
+
margin-top: 50px !important;
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
</style>
|
| 44 |
+
""", unsafe_allow_html=True)
|
| 45 |
+
|
| 46 |
+
def cicle_button():
|
| 47 |
+
st.markdown("""
|
| 48 |
+
<style>
|
| 49 |
+
/* Target the button using Streamlit's internal structure */
|
| 50 |
+
div[class^="stButton"] > button {
|
| 51 |
+
width: 80px;
|
| 52 |
+
height: 80px;
|
| 53 |
+
border-radius: 50%;
|
| 54 |
+
background-color: #008080;
|
| 55 |
+
color: white;
|
| 56 |
+
font-weight: bold;
|
| 57 |
+
font-size: 16px;
|
| 58 |
+
padding: 0;
|
| 59 |
+
border: none;
|
| 60 |
+
margin-left: 37%;
|
| 61 |
+
margin-top: 70px;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
@media (max-width: 640px) {
|
| 65 |
+
div[class^="stButton"] > button {
|
| 66 |
+
margin-top: 0px;
|
| 67 |
+
margin-left:43%;
|
| 68 |
+
|
| 69 |
+
}
|
| 70 |
+
div[class^="stButton"] > button:hover {
|
| 71 |
+
background-color: #009999;
|
| 72 |
+
margin-left: 90px;
|
| 73 |
+
}
|
| 74 |
+
@media (max-width: 767px) {
|
| 75 |
+
div[class^="stButton"] > button:hover{
|
| 76 |
+
margin-top: 0px;
|
| 77 |
+
margin-left:60px;
|
| 78 |
+
}
|
| 79 |
+
@media (max-width: 640px) {
|
| 80 |
+
div[class^="stButton"] > button:hover{
|
| 81 |
+
margin-top: 0px;
|
| 82 |
+
margin-left:43%;
|
| 83 |
+
}
|
| 84 |
+
</style>
|
| 85 |
+
""", unsafe_allow_html=True)
|
fevicon.png
ADDED
|
|
Git LFS Details
|
logo.png
ADDED
|
Git LFS Details
|
requirements.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
streamlit
|
| 2 |
+
deep-translator
|
| 3 |
+
gTTS
|
| 4 |
+
pydub
|
| 5 |
+
speechrecognition
|
| 6 |
+
transformers
|
| 7 |
+
streamlit-option-menu
|
| 8 |
+
st-audiorec
|
tone.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from deep_translator import GoogleTranslator
|
| 3 |
+
from gtts import gTTS
|
| 4 |
+
from pydub import AudioSegment
|
| 5 |
+
import tempfile
|
| 6 |
+
import os
|
| 7 |
+
import speech_recognition as sr
|
| 8 |
+
import css
|
| 9 |
+
from voice import transcribe
|
| 10 |
+
from transformers import pipeline as pl
|
| 11 |
+
# from speechbrain.pretrained import EncoderClassifier
|
| 12 |
+
|
| 13 |
+
# @st.cache_resource
|
| 14 |
+
# def load_emotion_model():
|
| 15 |
+
# return EncoderClassifier.from_hparams(
|
| 16 |
+
# source="emotion_model_local",
|
| 17 |
+
# savedir="tmp_emotion_model"
|
| 18 |
+
# )
|
| 19 |
+
|
| 20 |
+
# emotion_model = load_emotion_model()
|
| 21 |
+
|
| 22 |
+
# def detect_emotion(uploaded_file):
|
| 23 |
+
# # Save the uploaded file temporarily
|
| 24 |
+
# # Use a more robust way to handle the temporary file lifecycle
|
| 25 |
+
# with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file:
|
| 26 |
+
# tmp_file.write(uploaded_file.getvalue())
|
| 27 |
+
# raw_path = tmp_file.name
|
| 28 |
+
|
| 29 |
+
# try:
|
| 30 |
+
# audio = AudioSegment.from_file(raw_path)
|
| 31 |
+
# audio = audio.set_frame_rate(16000).set_channels(1)
|
| 32 |
+
# audio.export(raw_path, format="wav")
|
| 33 |
+
|
| 34 |
+
# # Predict emotion using the cleaned file
|
| 35 |
+
# # Ensure the path is passed as a standard string
|
| 36 |
+
# result = emotion_model.classify_file(str(raw_path))
|
| 37 |
+
# predicted_emotion = result[3][0]
|
| 38 |
+
# return predicted_emotion
|
| 39 |
+
# finally:
|
| 40 |
+
# # Clean up the temporary file
|
| 41 |
+
# if os.path.exists(raw_path):
|
| 42 |
+
# os.remove(raw_path)
|
| 43 |
+
def tone():
|
| 44 |
+
|
| 45 |
+
st.session_state.analyse=False
|
| 46 |
+
st.markdown('<div class="middle">', unsafe_allow_html=True)
|
| 47 |
+
with st.session_state.mid_col:
|
| 48 |
+
|
| 49 |
+
css.cicle_button()
|
| 50 |
+
|
| 51 |
+
if st.button("Translate"):
|
| 52 |
+
st.session_state.analyse=True
|
| 53 |
+
|
| 54 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
| 55 |
+
with st.session_state.right_col:
|
| 56 |
+
if st.session_state.analyse:
|
| 57 |
+
if st.session_state.inp != "Text":
|
| 58 |
+
st.session_state.text = transcribe(st.session_state.uploaded_file)
|
| 59 |
+
st.write(" ")
|
| 60 |
+
st.write(" ")
|
| 61 |
+
st.write(" ")
|
| 62 |
+
with st.form("Tone_form"):
|
| 63 |
+
if st.session_state.text !="" and st.session_state.text != " ":
|
| 64 |
+
pipe = pl("text-classification", model="tabularisai/multilingual-sentiment-analysis")
|
| 65 |
+
sentence = st.session_state.text
|
| 66 |
+
result = pipe(sentence)[0]
|
| 67 |
+
|
| 68 |
+
sentiment = result['label']
|
| 69 |
+
|
| 70 |
+
if sentiment == "Very Negative":
|
| 71 |
+
st.error('This is Very Negative', icon="π¨")
|
| 72 |
+
elif sentiment == "Negative":
|
| 73 |
+
st.error('This is Negative', icon="π")
|
| 74 |
+
elif sentiment == "Neutral":
|
| 75 |
+
st.warning('This is Neutral', icon="π")
|
| 76 |
+
elif sentiment == "Positive":
|
| 77 |
+
st.success('This is Positive', icon="π")
|
| 78 |
+
else:
|
| 79 |
+
st.success('This is Very Positive', icon="π")
|
| 80 |
+
else:
|
| 81 |
+
st.warning("write something first")
|
| 82 |
+
reset = st.form_submit_button("Reset β» ")
|
| 83 |
+
if reset:
|
| 84 |
+
st.session_state.analyse= False
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
# if st.session_state.inp != "Text":
|
| 92 |
+
# text = transcribe(st.session_state.uploaded_file)
|
| 93 |
+
# if text !="" and text != " ":
|
| 94 |
+
# emotion = detect_emotion(st.session_state.uploaded_file)
|
| 95 |
+
# st.write(f"π Detected Emotion: `{emotion}`")
|
voice.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from gtts import gTTS
|
| 3 |
+
from pydub import AudioSegment
|
| 4 |
+
import tempfile
|
| 5 |
+
import os
|
| 6 |
+
import speech_recognition as sr
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def text_to_speech(text, lang='en', c=0):
|
| 11 |
+
tts = gTTS(text=text, lang=lang)
|
| 12 |
+
audio_file = f"output{c}.mp3"
|
| 13 |
+
tts.save(audio_file)
|
| 14 |
+
return audio_file
|
| 15 |
+
|
| 16 |
+
def transcribe(uploaded_file):
|
| 17 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
|
| 18 |
+
file_path = tmpfile.name
|
| 19 |
+
tmpfile.write(uploaded_file.read())
|
| 20 |
+
|
| 21 |
+
audio = AudioSegment.from_file(file_path)
|
| 22 |
+
audio = audio.set_frame_rate(16000).set_channels(1)
|
| 23 |
+
audio.export(file_path, format="wav")
|
| 24 |
+
|
| 25 |
+
recognizer = sr.Recognizer()
|
| 26 |
+
with sr.AudioFile(file_path) as source:
|
| 27 |
+
trans=True
|
| 28 |
+
with st.spinner("Transcribing... Please wait!", show_time=True):
|
| 29 |
+
if trans:
|
| 30 |
+
audio_data = recognizer.record(source)
|
| 31 |
+
try:
|
| 32 |
+
text = recognizer.recognize_google(audio_data)
|
| 33 |
+
trans=False
|
| 34 |
+
return text
|
| 35 |
+
except sr.UnknownValueError:
|
| 36 |
+
st.error("β Could not understand the audio.")
|
| 37 |
+
except sr.RequestError:
|
| 38 |
+
st.error("β API error. Check internet connection.")
|
| 39 |
+
|
| 40 |
+
os.remove(file_path)
|
| 41 |
+
return ""
|