Update pages/ai_buddy.py
Browse files- pages/ai_buddy.py +173 -4
pages/ai_buddy.py
CHANGED
@@ -8,11 +8,14 @@ import pandas as pd
|
|
8 |
from datetime import datetime
|
9 |
import plotly.express as px
|
10 |
import json
|
|
|
11 |
import time
|
|
|
12 |
import threading
|
13 |
from playsound import playsound
|
14 |
import pygame
|
15 |
-
|
|
|
16 |
|
17 |
pygame.mixer.init()
|
18 |
|
@@ -240,6 +243,165 @@ def show_personalized_recommendations():
|
|
240 |
for rec in additional_recs:
|
241 |
st.markdown(f"- {rec}")
|
242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
def main():
|
244 |
st.set_page_config(page_title="S.H.E.R.L.O.C.K. AI Buddy", page_icon="🕵️", layout="wide")
|
245 |
|
@@ -361,13 +523,15 @@ def main():
|
|
361 |
with st.chat_message(message["role"]):
|
362 |
st.markdown(message["content"])
|
363 |
|
|
|
|
|
|
|
364 |
# Clear chat history button
|
365 |
if st.button("Clear Chat History"):
|
366 |
st.session_state.messages = []
|
367 |
st.experimental_rerun()
|
368 |
|
369 |
-
|
370 |
-
if prompt := st.chat_input("What's on your mind?"):
|
371 |
st.session_state.messages.append({"role": "user", "content": prompt})
|
372 |
with st.chat_message("user"):
|
373 |
st.markdown(prompt)
|
@@ -387,12 +551,17 @@ def main():
|
|
387 |
message_placeholder.markdown(full_response)
|
388 |
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
389 |
|
|
|
|
|
|
|
390 |
with tab2:
|
391 |
-
tool_choice = st.selectbox("Select a tool", ["Meditation Timer", "Recommendations"])
|
392 |
if tool_choice == "Meditation Timer":
|
393 |
show_meditation_timer()
|
394 |
elif tool_choice == "Recommendations":
|
395 |
show_personalized_recommendations()
|
|
|
|
|
396 |
|
397 |
# Mood tracker
|
398 |
st.sidebar.markdown("---")
|
|
|
8 |
from datetime import datetime
|
9 |
import plotly.express as px
|
10 |
import json
|
11 |
+
import tempfile
|
12 |
import time
|
13 |
+
import numpy as np
|
14 |
import threading
|
15 |
from playsound import playsound
|
16 |
import pygame
|
17 |
+
import sounddevice as sd
|
18 |
+
from scipy.io import wavfile
|
19 |
|
20 |
pygame.mixer.init()
|
21 |
|
|
|
243 |
for rec in additional_recs:
|
244 |
st.markdown(f"- {rec}")
|
245 |
|
246 |
+
def generate_binaural_beat(freq1, freq2, duration_seconds, sample_rate=44100):
|
247 |
+
t = np.linspace(0, duration_seconds, int(sample_rate * duration_seconds), False)
|
248 |
+
left_channel = np.sin(2 * np.pi * freq1 * t)
|
249 |
+
right_channel = np.sin(2 * np.pi * freq2 * t)
|
250 |
+
stereo_audio = np.vstack((left_channel, right_channel)).T
|
251 |
+
return (stereo_audio * 32767).astype(np.int16)
|
252 |
+
|
253 |
+
def get_binary_file_downloader_html(bin_file, file_label='File'):
|
254 |
+
b64 = base64.b64encode(bin_file).decode()
|
255 |
+
return f'<a href="data:application/octet-stream;base64,{b64}" download="{file_label}.wav" class="download-link">Download {file_label}</a>'
|
256 |
+
|
257 |
+
def show_binaural_beats():
|
258 |
+
st.subheader("🎵 Binaural Beats Generator")
|
259 |
+
|
260 |
+
st.markdown("""
|
261 |
+
<style>
|
262 |
+
.stButton>button {
|
263 |
+
background-color: #4CAF50;
|
264 |
+
color: white;
|
265 |
+
font-weight: bold;
|
266 |
+
}
|
267 |
+
.download-link {
|
268 |
+
background-color: #008CBA;
|
269 |
+
color: white;
|
270 |
+
padding: 10px 15px;
|
271 |
+
text-align: center;
|
272 |
+
text-decoration: none;
|
273 |
+
display: inline-block;
|
274 |
+
font-size: 16px;
|
275 |
+
margin: 4px 2px;
|
276 |
+
cursor: pointer;
|
277 |
+
border-radius: 4px;
|
278 |
+
}
|
279 |
+
.stop-button {
|
280 |
+
background-color: #f44336;
|
281 |
+
color: white;
|
282 |
+
font-weight: bold;
|
283 |
+
}
|
284 |
+
</style>
|
285 |
+
""", unsafe_allow_html=True)
|
286 |
+
|
287 |
+
st.write("Binaural beats are created when two slightly different frequencies are played in each ear, potentially influencing brainwave activity.")
|
288 |
+
|
289 |
+
preset_beats = {
|
290 |
+
"Deep Relaxation (Delta)": {"base": 100, "beat": 2},
|
291 |
+
"Meditation (Theta)": {"base": 150, "beat": 6},
|
292 |
+
"Relaxation (Alpha)": {"base": 200, "beat": 10},
|
293 |
+
"Light Focus (Low Beta)": {"base": 250, "beat": 14},
|
294 |
+
"High Focus (Mid Beta)": {"base": 300, "beat": 20},
|
295 |
+
"Alertness (High Beta)": {"base": 350, "beat": 30},
|
296 |
+
"Gamma Consciousness": {"base": 400, "beat": 40},
|
297 |
+
"Lucid Dreaming": {"base": 180, "beat": 3},
|
298 |
+
"Memory Enhancement": {"base": 270, "beat": 12},
|
299 |
+
"Creativity Boost": {"base": 220, "beat": 8},
|
300 |
+
"Pain Relief": {"base": 130, "beat": 4},
|
301 |
+
"Mood Elevation": {"base": 315, "beat": 18}
|
302 |
+
}
|
303 |
+
|
304 |
+
col1, col2 = st.columns(2)
|
305 |
+
|
306 |
+
with col1:
|
307 |
+
beat_type = st.selectbox("Choose a preset or custom:", ["Custom"] + list(preset_beats.keys()))
|
308 |
+
|
309 |
+
with col2:
|
310 |
+
duration = st.slider("Duration (minutes):", 1, 60, 15)
|
311 |
+
|
312 |
+
if beat_type == "Custom":
|
313 |
+
col3, col4 = st.columns(2)
|
314 |
+
with col3:
|
315 |
+
base_freq = st.slider("Base Frequency (Hz):", 100, 500, 200)
|
316 |
+
with col4:
|
317 |
+
beat_freq = st.slider("Desired Beat Frequency (Hz):", 1, 40, 10)
|
318 |
+
else:
|
319 |
+
base_freq = preset_beats[beat_type]["base"]
|
320 |
+
beat_freq = preset_beats[beat_type]["beat"]
|
321 |
+
st.info(f"Base Frequency: {base_freq} Hz, Beat Frequency: {beat_freq} Hz")
|
322 |
+
|
323 |
+
if 'audio_playing' not in st.session_state:
|
324 |
+
st.session_state.audio_playing = False
|
325 |
+
|
326 |
+
if 'start_time' not in st.session_state:
|
327 |
+
st.session_state.start_time = None
|
328 |
+
|
329 |
+
if 'end_time' not in st.session_state:
|
330 |
+
st.session_state.end_time = None
|
331 |
+
|
332 |
+
# Create persistent placeholders for UI elements
|
333 |
+
progress_bar = st.empty()
|
334 |
+
status_text = st.empty()
|
335 |
+
stop_button = st.empty()
|
336 |
+
|
337 |
+
generate_button = st.button("Generate and Play Binaural Beat")
|
338 |
+
|
339 |
+
if generate_button:
|
340 |
+
try:
|
341 |
+
# Stop any currently playing audio
|
342 |
+
if st.session_state.audio_playing:
|
343 |
+
pygame.mixer.music.stop()
|
344 |
+
st.session_state.audio_playing = False
|
345 |
+
|
346 |
+
audio_data = generate_binaural_beat(base_freq, base_freq + beat_freq, duration * 60)
|
347 |
+
|
348 |
+
# Save the generated audio to a temporary file
|
349 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as temp_file:
|
350 |
+
temp_filename = temp_file.name
|
351 |
+
wavfile.write(temp_filename, 44100, audio_data)
|
352 |
+
|
353 |
+
# Initialize pygame mixer
|
354 |
+
pygame.mixer.init(frequency=44100, size=-16, channels=2)
|
355 |
+
|
356 |
+
# Load and play the audio
|
357 |
+
pygame.mixer.music.load(temp_filename)
|
358 |
+
pygame.mixer.music.play()
|
359 |
+
st.session_state.audio_playing = True
|
360 |
+
|
361 |
+
st.session_state.start_time = time.time()
|
362 |
+
st.session_state.end_time = st.session_state.start_time + (duration * 60)
|
363 |
+
|
364 |
+
except Exception as e:
|
365 |
+
st.error(f"An error occurred: {str(e)}")
|
366 |
+
st.info("Please try again or contact support if the issue persists.")
|
367 |
+
|
368 |
+
if st.session_state.audio_playing:
|
369 |
+
stop_button_active = stop_button.button("Stop Binaural Beat", key="stop_binaural", type="primary")
|
370 |
+
current_time = time.time()
|
371 |
+
|
372 |
+
if stop_button_active:
|
373 |
+
pygame.mixer.music.stop()
|
374 |
+
st.session_state.audio_playing = False
|
375 |
+
st.session_state.start_time = None
|
376 |
+
st.session_state.end_time = None
|
377 |
+
|
378 |
+
elif current_time < st.session_state.end_time:
|
379 |
+
elapsed_time = current_time - st.session_state.start_time
|
380 |
+
progress = elapsed_time / (st.session_state.end_time - st.session_state.start_time)
|
381 |
+
progress_bar.progress(progress)
|
382 |
+
|
383 |
+
remaining_time = st.session_state.end_time - current_time
|
384 |
+
mins, secs = divmod(int(remaining_time), 60)
|
385 |
+
status_text.text(f"Time remaining: {mins:02d}:{secs:02d}")
|
386 |
+
else:
|
387 |
+
pygame.mixer.music.stop()
|
388 |
+
st.session_state.audio_playing = False
|
389 |
+
st.session_state.start_time = None
|
390 |
+
st.session_state.end_time = None
|
391 |
+
progress_bar.empty()
|
392 |
+
status_text.text("Binaural beat session complete!")
|
393 |
+
|
394 |
+
# Offer download of the generated audio
|
395 |
+
if not st.session_state.audio_playing and 'audio_data' in locals():
|
396 |
+
with io.BytesIO() as buffer:
|
397 |
+
wavfile.write(buffer, 44100, audio_data)
|
398 |
+
st.markdown(get_binary_file_downloader_html(buffer.getvalue(), f"binaural_beat_{base_freq}_{beat_freq}Hz"), unsafe_allow_html=True)
|
399 |
+
|
400 |
+
# Ensure the app updates every second
|
401 |
+
if st.session_state.audio_playing:
|
402 |
+
time.sleep(1)
|
403 |
+
st.experimental_rerun()
|
404 |
+
|
405 |
def main():
|
406 |
st.set_page_config(page_title="S.H.E.R.L.O.C.K. AI Buddy", page_icon="🕵️", layout="wide")
|
407 |
|
|
|
523 |
with st.chat_message(message["role"]):
|
524 |
st.markdown(message["content"])
|
525 |
|
526 |
+
# User input
|
527 |
+
prompt = st.chat_input("What's on your mind?")
|
528 |
+
|
529 |
# Clear chat history button
|
530 |
if st.button("Clear Chat History"):
|
531 |
st.session_state.messages = []
|
532 |
st.experimental_rerun()
|
533 |
|
534 |
+
if prompt:
|
|
|
535 |
st.session_state.messages.append({"role": "user", "content": prompt})
|
536 |
with st.chat_message("user"):
|
537 |
st.markdown(prompt)
|
|
|
551 |
message_placeholder.markdown(full_response)
|
552 |
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
553 |
|
554 |
+
# Force a rerun to update the chat history immediately
|
555 |
+
st.experimental_rerun()
|
556 |
+
|
557 |
with tab2:
|
558 |
+
tool_choice = st.selectbox("Select a tool", ["Meditation Timer", "Binaural Beats", "Recommendations"])
|
559 |
if tool_choice == "Meditation Timer":
|
560 |
show_meditation_timer()
|
561 |
elif tool_choice == "Recommendations":
|
562 |
show_personalized_recommendations()
|
563 |
+
elif tool_choice == "Binaural Beats":
|
564 |
+
show_binaural_beats()
|
565 |
|
566 |
# Mood tracker
|
567 |
st.sidebar.markdown("---")
|