Spaces:
Sleeping
Sleeping
loop music
Browse files
app.py
CHANGED
@@ -2,11 +2,15 @@ import gradio as gr
|
|
2 |
import requests
|
3 |
import tempfile
|
4 |
import os
|
|
|
|
|
|
|
5 |
from langchain_openai import ChatOpenAI
|
6 |
from langchain_core.runnables import RunnablePassthrough
|
7 |
from langchain.prompts import PromptTemplate
|
|
|
8 |
|
9 |
-
#
|
10 |
MOOD_QUESTIONS = [
|
11 |
"On a scale of 1-5, how would you rate your current energy level?",
|
12 |
"On a scale of 1-5, how would you rate your current stress level?",
|
@@ -25,13 +29,11 @@ Based on the user's mood assessment:
|
|
25 |
- Happiness level: {happiness}
|
26 |
- Current emotions: {current_emotions}
|
27 |
- Desired mood: {desired_mood}
|
28 |
-
|
29 |
Musical preferences (if specified):
|
30 |
- Preferred genre: {genre}
|
31 |
- Preferred instruments: {instruments}
|
32 |
- Preferred tempo: {tempo}
|
33 |
- Preferred mood: {preferred_mood}
|
34 |
-
|
35 |
Generate a detailed music prompt that would help the user transition from their current emotional state to their desired mood.
|
36 |
The prompt should incorporate the user's musical preferences if provided, while focusing on therapeutic musical qualities.
|
37 |
Keep the description under 100 words and emphasize the healing aspects of the music.
|
@@ -45,26 +47,43 @@ prompt = PromptTemplate(
|
|
45 |
|
46 |
music_chain = RunnablePassthrough() | prompt | llm
|
47 |
|
48 |
-
def
|
49 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
try:
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
except Exception as e:
|
64 |
-
|
65 |
|
66 |
-
def generate_music(prompt, duration=
|
67 |
-
"""Generate music using the MusicGen API"""
|
68 |
API_URL = "https://api-inference.huggingface.co/models/facebook/musicgen-small"
|
69 |
headers = {"Authorization": f"Bearer {os.getenv('HF_API_KEY')}"}
|
70 |
|
@@ -77,14 +96,40 @@ def generate_music(prompt, duration=10):
|
|
77 |
if response.status_code != 200:
|
78 |
return None, f"Error: API returned status code {response.status_code}"
|
79 |
|
|
|
80 |
with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
|
81 |
tmp_file.write(response.content)
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
-
return
|
85 |
except Exception as e:
|
86 |
return None, f"Error: {str(e)}"
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
def gradio_interface(energy, stress, happiness, current_emotions, desired_mood,
|
89 |
genre, instruments, tempo, preferred_mood):
|
90 |
"""Main interface function that processes questionnaire and generates music"""
|
@@ -113,7 +158,7 @@ with gr.Blocks() as demo:
|
|
113 |
gr.Markdown("""
|
114 |
# Therapeutic Music Generator
|
115 |
Complete the mood assessment questionnaire and optionally specify your musical preferences to receive personalized music
|
116 |
-
that helps you achieve your desired emotional state.
|
117 |
""")
|
118 |
|
119 |
with gr.Row():
|
@@ -195,5 +240,4 @@ with gr.Blocks() as demo:
|
|
195 |
)
|
196 |
|
197 |
if __name__ == "__main__":
|
198 |
-
demo.launch()
|
199 |
-
|
|
|
2 |
import requests
|
3 |
import tempfile
|
4 |
import os
|
5 |
+
import numpy as np
|
6 |
+
import soundfile as sf
|
7 |
+
import librosa
|
8 |
from langchain_openai import ChatOpenAI
|
9 |
from langchain_core.runnables import RunnablePassthrough
|
10 |
from langchain.prompts import PromptTemplate
|
11 |
+
import math
|
12 |
|
13 |
+
# [Previous constants and LangChain setup remains the same...]
|
14 |
MOOD_QUESTIONS = [
|
15 |
"On a scale of 1-5, how would you rate your current energy level?",
|
16 |
"On a scale of 1-5, how would you rate your current stress level?",
|
|
|
29 |
- Happiness level: {happiness}
|
30 |
- Current emotions: {current_emotions}
|
31 |
- Desired mood: {desired_mood}
|
|
|
32 |
Musical preferences (if specified):
|
33 |
- Preferred genre: {genre}
|
34 |
- Preferred instruments: {instruments}
|
35 |
- Preferred tempo: {tempo}
|
36 |
- Preferred mood: {preferred_mood}
|
|
|
37 |
Generate a detailed music prompt that would help the user transition from their current emotional state to their desired mood.
|
38 |
The prompt should incorporate the user's musical preferences if provided, while focusing on therapeutic musical qualities.
|
39 |
Keep the description under 100 words and emphasize the healing aspects of the music.
|
|
|
47 |
|
48 |
music_chain = RunnablePassthrough() | prompt | llm
|
49 |
|
50 |
+
def loop_audio(input_path, target_duration=120):
|
51 |
+
"""
|
52 |
+
Loop the input audio file to reach the target duration using librosa
|
53 |
+
|
54 |
+
Args:
|
55 |
+
input_path (str): Path to the input audio file
|
56 |
+
target_duration (int): Desired duration in seconds
|
57 |
+
|
58 |
+
Returns:
|
59 |
+
str: Path to the looped audio file
|
60 |
+
"""
|
61 |
try:
|
62 |
+
# Load the audio file
|
63 |
+
y, sr = librosa.load(input_path, sr=None)
|
64 |
+
|
65 |
+
# Calculate current duration and required loops
|
66 |
+
current_duration = len(y) / sr
|
67 |
+
loops_needed = math.ceil(target_duration / current_duration)
|
68 |
+
|
69 |
+
# Create the looped audio
|
70 |
+
y_looped = np.tile(y, loops_needed)
|
71 |
+
|
72 |
+
# Trim to exact target duration if necessary
|
73 |
+
target_samples = int(target_duration * sr)
|
74 |
+
if len(y_looped) > target_samples:
|
75 |
+
y_looped = y_looped[:target_samples]
|
76 |
+
|
77 |
+
# Save to a new temporary file
|
78 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
|
79 |
+
sf.write(tmp_file.name, y_looped, sr)
|
80 |
+
return tmp_file.name
|
81 |
+
|
82 |
except Exception as e:
|
83 |
+
raise Exception(f"Error in audio looping: {str(e)}")
|
84 |
|
85 |
+
def generate_music(prompt, duration=120):
|
86 |
+
"""Generate music using the MusicGen API and loop it to the desired duration"""
|
87 |
API_URL = "https://api-inference.huggingface.co/models/facebook/musicgen-small"
|
88 |
headers = {"Authorization": f"Bearer {os.getenv('HF_API_KEY')}"}
|
89 |
|
|
|
96 |
if response.status_code != 200:
|
97 |
return None, f"Error: API returned status code {response.status_code}"
|
98 |
|
99 |
+
# Save the initial generated audio
|
100 |
with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
|
101 |
tmp_file.write(response.content)
|
102 |
+
initial_audio_path = tmp_file.name
|
103 |
+
|
104 |
+
# Loop the audio to reach target duration
|
105 |
+
final_audio_path = loop_audio(initial_audio_path, duration)
|
106 |
+
|
107 |
+
# Clean up the initial audio file
|
108 |
+
os.unlink(initial_audio_path)
|
109 |
|
110 |
+
return final_audio_path, "Music generated and looped successfully!"
|
111 |
except Exception as e:
|
112 |
return None, f"Error: {str(e)}"
|
113 |
|
114 |
+
# [Rest of the code remains the same...]
|
115 |
+
def analyze_mood_and_generate_prompt(responses, preferences):
|
116 |
+
"""Convert questionnaire responses and preferences into a music generation prompt using LangChain"""
|
117 |
+
try:
|
118 |
+
prompt_result = music_chain.invoke({
|
119 |
+
"energy": responses[0],
|
120 |
+
"stress": responses[1],
|
121 |
+
"happiness": responses[2],
|
122 |
+
"current_emotions": responses[3],
|
123 |
+
"desired_mood": responses[4],
|
124 |
+
"genre": preferences["genre"] or "any",
|
125 |
+
"instruments": preferences["instruments"] or "any",
|
126 |
+
"tempo": preferences["tempo"] or "any",
|
127 |
+
"preferred_mood": preferences["preferred_mood"] or "any"
|
128 |
+
})
|
129 |
+
return prompt_result.content
|
130 |
+
except Exception as e:
|
131 |
+
return f"Error generating prompt: {str(e)}"
|
132 |
+
|
133 |
def gradio_interface(energy, stress, happiness, current_emotions, desired_mood,
|
134 |
genre, instruments, tempo, preferred_mood):
|
135 |
"""Main interface function that processes questionnaire and generates music"""
|
|
|
158 |
gr.Markdown("""
|
159 |
# Therapeutic Music Generator
|
160 |
Complete the mood assessment questionnaire and optionally specify your musical preferences to receive personalized music
|
161 |
+
that helps you achieve your desired emotional state. Generated music will be 2 minutes long.
|
162 |
""")
|
163 |
|
164 |
with gr.Row():
|
|
|
240 |
)
|
241 |
|
242 |
if __name__ == "__main__":
|
243 |
+
demo.launch()
|
|