Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import os | |
import matplotlib.pyplot as plt | |
import librosa | |
from src.predict import predict_emotion | |
DIRECTORY = "audios" | |
FILE_NAME = "audio.wav" | |
RATE = 16000 | |
def emotion_analysis(): | |
st.header("❤️ Emotion Analysis") | |
if st.session_state.audio_file is None: | |
st.info("Please, upload or record an audio file in the studio tab") | |
st.stop() | |
else: | |
audio_file = st.session_state.audio_file | |
start_inference = st.button("Start emotion recogniton","inf_on_upl_btn") | |
emotion_labels = ["colere", "neutre", "joie"] | |
colors = ['#f71c1c', '#cac8c8', '#f6d60a'] | |
if start_inference: | |
# Configuration Streamlit | |
with st.spinner("Real-time emotion analysis..."): | |
# uploaded_file = st.file_uploader("Choisissez un fichier audio", type=["wav", "mp3"]) | |
if audio_file is not None: | |
# Charger et rééchantillonner l'audio | |
audio, sr = librosa.load(audio_file, sr=RATE) | |
# chunk = audio_file | |
# Paramètres de la fenêtre glissante | |
window_size = 1 # 1 seconde de données | |
hop_length = 0.5 # 0.5 secondes de chevauchement | |
# Créer un graphique en temps réel | |
fig, ax = plt.subplots() | |
lines = [ax.plot([], [], label=emotion)[0] for emotion in emotion_labels] | |
ax.set_ylim(0, 1) | |
ax.set_xlim(0, len(audio) / sr) | |
ax.set_xlabel("Temps (s)") | |
ax.set_ylabel("Probabilité") | |
chart = st.pyplot(fig) | |
scores = [[],[],[]] # 3 émotions pour l'instant | |
# Traitement par fenêtre glissante | |
for i in range(0, len(audio), int(hop_length * sr)): | |
chunk = audio[i:i + int(window_size * sr)] | |
if len(chunk) < int(window_size * sr): | |
break | |
emotion_scores = predict_emotion(chunk, output_probs=True, sampling_rate=RATE) | |
# Mettre à jour le graphique | |
for emotion, line in zip(emotion_labels, lines): | |
xdata = list(line.get_xdata()) | |
ydata = list(line.get_ydata()) | |
colour = colors[list(emotion_scores).index(emotion)] | |
xdata.append(i / sr) | |
ydata.append(emotion_scores[emotion]) | |
scores[list(emotion_scores).index(emotion)].append(emotion_scores[emotion]) | |
line.set_data(xdata, ydata) | |
line.set_color(colour) | |
ax.relim() | |
ax.autoscale_view() | |
ax.legend() | |
chart.pyplot(fig, use_container_width=True) | |
# Prepare the styling | |
st.markdown(""" | |
<style> | |
.colored-box { | |
padding: 10px; | |
border-radius: 5px; | |
color: white; | |
font-weight: bold; | |
text-align: center; | |
} | |
</style> | |
""" | |
, unsafe_allow_html=True) | |
# Dynamically create the specified number of columns | |
columns = st.columns(len(emotion_scores)) | |
# emotion_scores_mean = [sum(sublist) / len(sublist) for sublist in scores] | |
emotion_scores_mean = {emotion:sum(sublist) / len(sublist) for emotion, sublist in zip(emotion_labels, scores)} | |
max_emo = max(emotion_scores_mean) | |
emotion_scores_sorted = dict(sorted(emotion_scores_mean.items(), key=lambda x: x[1], reverse=True)) | |
colors_sorted = [colors[list(emotion_scores_mean.keys()).index(key)] for key in list(emotion_scores_sorted.keys())] | |
# Add content to each column | |
for i, (col, emotion) in enumerate(zip(columns, emotion_scores_sorted)): | |
color = colors_sorted[i % len(colors_sorted)] # Cycle through colors if more columns than colors | |
col.markdown(f""" | |
<div class="colored-box" style="background-color: {color};"> | |
{emotion} : {100*emotion_scores_sorted[emotion]:.2f} % | |
</div> | |
""" | |
, unsafe_allow_html=True) | |
st.success("Analyse terminée !") | |
else: | |
st.warning("You need to load an audio file !") | |
if start_inference: | |
st.subheader("Feedback") | |
# Initialisation du fichier CSV | |
csv_file = os.path.join("src","predictions","feedback.csv") | |
# Vérifier si le fichier CSV existe, sinon le créer avec des colonnes appropriées | |
if not os.path.exists(csv_file): | |
df = pd.DataFrame(columns=["filepath", "prediction", "feedback"]) | |
df.to_csv(csv_file, index=False) | |
# Charger les données existantes du CSV | |
df = pd.read_csv(csv_file) | |
with st.form("feedback_form"): | |
st.write("What should have been the correct prediction ? (*Choose the same emotion if the prediction was correct*).") | |
feedback = st.selectbox("Your answer :", ['Sadness','Anger', 'Disgust', 'Fear', 'Surprise', 'Joy', 'Neutral']) | |
submit_button = st.form_submit_button("Submit") | |
st.write("En cliquant sur ce bouton, vous acceptez que votre audio soit sauvegardé dans notre base de données.") | |
if submit_button: | |
# Ajouter le feedback au DataFrame | |
new_entry = pd.DataFrame([{"filepath": audio_file.name, "prediction": max_emo, "feedback": feedback}]) | |
# df = df.append(new_entry, ignore_index=True) | |
df = pd.concat([df, new_entry], ignore_index=True) | |
# Sauvegarder les données mises à jour dans le fichier CSV | |
df.to_csv(csv_file, index=False) | |
# Sauvegarder le fichier audio | |
with open(os.path.join("src","predictions","data",audio_file.name), "wb") as f: | |
f.write(audio_file.getbuffer()) | |
# Confirmation pour l'utilisateur | |
st.success("Merci pour votre retour ! Vos données ont été sauvegardées.") |