Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from transformers import pipeline
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
import numpy as np
|
| 5 |
+
import torch, librosa, soundfile as sf
|
| 6 |
+
|
| 7 |
+
# --------- INIT MODELS ----------
|
| 8 |
+
musicgen = pipeline("text-to-audio", model="facebook/musicgen-small")
|
| 9 |
+
sentiment = pipeline("sentiment-analysis")
|
| 10 |
+
|
| 11 |
+
# --------- UTILITIES ----------
|
| 12 |
+
def detect_mood(text, mic_audio=None):
|
| 13 |
+
"""Combine user text + voice tone → mood keyword."""
|
| 14 |
+
if mic_audio is not None:
|
| 15 |
+
# rough energy check from mic input
|
| 16 |
+
y, sr = librosa.load(mic_audio, sr=16000)
|
| 17 |
+
rms = np.mean(librosa.feature.rms(y=y))
|
| 18 |
+
energy = "calm" if rms < 0.01 else "energetic"
|
| 19 |
+
else:
|
| 20 |
+
energy = "neutral"
|
| 21 |
+
|
| 22 |
+
base = sentiment(text)[0]["label"].lower()
|
| 23 |
+
if "neg" in base:
|
| 24 |
+
mood = "melancholic"
|
| 25 |
+
elif "pos" in base:
|
| 26 |
+
mood = "uplifting"
|
| 27 |
+
else:
|
| 28 |
+
mood = "reflective"
|
| 29 |
+
|
| 30 |
+
if energy == "energetic" and mood == "uplifting":
|
| 31 |
+
mood = "joyous"
|
| 32 |
+
return mood
|
| 33 |
+
|
| 34 |
+
# --------- CORE GENERATION ----------
|
| 35 |
+
def generate_music(prompt, mic_input=None):
|
| 36 |
+
mood = detect_mood(prompt, mic_input)
|
| 37 |
+
hour = datetime.now().hour
|
| 38 |
+
time_tag = (
|
| 39 |
+
"morning calm"
|
| 40 |
+
if 5 <= hour < 12
|
| 41 |
+
else "evening glow"
|
| 42 |
+
if 17 <= hour < 22
|
| 43 |
+
else "midnight dream"
|
| 44 |
+
)
|
| 45 |
+
|
| 46 |
+
full_prompt = f"{prompt}, {mood} atmosphere, {time_tag} tone"
|
| 47 |
+
print(f"[EchoBloom] prompt → {full_prompt}")
|
| 48 |
+
|
| 49 |
+
audio_out = musicgen(full_prompt, forward_params={"do_sample": True, "max_new_tokens": 256})[0]
|
| 50 |
+
sf.write("out.wav", audio_out["audio"], audio_out["sampling_rate"])
|
| 51 |
+
return "out.wav", f"Mood: {mood} | Scene: {time_tag}"
|
| 52 |
+
|
| 53 |
+
# --------- GRADIO UI ----------
|
| 54 |
+
with gr.Blocks(title="EchoBloom: Adaptive Listener Companion") as demo:
|
| 55 |
+
gr.Markdown("## 🌱 EchoBloom — Adaptive Listener\nWhisper a mood, hum a phrase, or let silence bloom into sound.")
|
| 56 |
+
|
| 57 |
+
with gr.Row():
|
| 58 |
+
text_in = gr.Textbox(label="Your Whisper / Mood Prompt", placeholder="e.g., 'Drifting through starlit fields'")
|
| 59 |
+
mic_in = gr.Audio(source="microphone", type="filepath", label="Voice Tone (optional)")
|
| 60 |
+
|
| 61 |
+
generate_btn = gr.Button("🌸 Bloom Soundscape")
|
| 62 |
+
audio_out = gr.Audio(label="Generated Music", type="filepath")
|
| 63 |
+
mood_info = gr.Textbox(label="Mood State", interactive=False)
|
| 64 |
+
|
| 65 |
+
generate_btn.click(fn=generate_music, inputs=[text_in, mic_in], outputs=[audio_out, mood_info])
|
| 66 |
+
|
| 67 |
+
gr.Markdown(
|
| 68 |
+
"Tip: Try whispering something happy vs. calm, and watch how the soundtrack changes with your voice energy!"
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
if __name__ == "__main__":
|
| 72 |
+
demo.launch()
|