File size: 4,200 Bytes
2391729
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import streamlit as st
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import urllib.parse

# Set Streamlit page configuration
st.set_page_config(
    page_title="Text-to-Music Generator 🎡",
    page_icon="🎡",
    layout="wide",
    initial_sidebar_state="expanded",
)

# Add custom CSS for styling
st.markdown("""
    <style>
        body {
            background-color: #eaf6fb;
            color: #003366;
            font-family: 'Arial', sans-serif;
        }
        .stButton>button {
            background-color: #4dabf5;
            color: white;
            font-weight: bold;
            border-radius: 12px;
            padding: 10px 20px;
        }
        .stButton>button:hover {
            background-color: #007bb5;
        }
        .stTextArea textarea {
            border: 2px solid #4dabf5;
            border-radius: 8px;
        }
        iframe {
            border: 2px solid #4dabf5;
            border-radius: 8px;
        }
        .title {
            text-align: center;
            font-size: 36px;
            font-weight: bold;
            color: #003366;
        }
        .description {
            text-align: center;
            font-size: 18px;
            color: #005792;
        }
    </style>
""", unsafe_allow_html=True)

# Initialize the Hugging Face model and tokenizer
@st.cache_resource
def load_model():
    tokenizer = AutoTokenizer.from_pretrained('sander-wood/text-to-music')
    model = AutoModelForSeq2SeqLM.from_pretrained('sander-wood/text-to-music')
    return tokenizer, model

# Load model and tokenizer
tokenizer, model = load_model()

# Streamlit App UI
st.markdown("<div class='title'>🎡 Text-to-Music Generator 🎡</div>", unsafe_allow_html=True)
st.markdown("""
<div class='description'>
Enter a textual description, and the model will generate music in ABC notation.  
You can use tools like [abc2midi](http://abc.sourceforge.net/abcMIDI/) to convert the notation into a playable file.
</div>
""", unsafe_allow_html=True)

# Input Fields
with st.container():
    text_input = st.text_area(
        "Enter a description for the music:",
        placeholder="e.g., This is a traditional Irish dance music.",
    )
    max_length = st.slider(
        "Maximum Length of Generated Music:", min_value=128, max_value=2048, value=1024, step=128
    )
    top_p = st.slider(
        "Top-p (Nucleus Sampling):", min_value=0.1, max_value=1.0, value=0.9, step=0.05
    )
    temperature = st.slider(
        "Temperature (Sampling Diversity):", min_value=0.1, max_value=2.0, value=1.0, step=0.1
    )

# Generate Music Button
if st.button("Generate Music 🎢"):
    if not text_input.strip():
        st.error("Please enter a valid description!")
    else:
        st.info("Generating music... This might take a few seconds.")

        try:
            # Tokenize input
            input_ids = tokenizer(text_input, return_tensors='pt', truncation=True, max_length=max_length)['input_ids']

            # Generate music using efficient beam search sampling
            generated_ids = model.generate(
                input_ids,
                max_length=max_length,
                do_sample=True,
                top_p=top_p,
                temperature=temperature,
                eos_token_id=tokenizer.eos_token_id,
            )

            # Decode generated music
            tune = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
            tune = "X:1\n" + tune

            st.success("Music generated successfully!")

            # Display raw generated music in the app
            st.text_area("Generated Music (ABC Notation):", value=tune, height=300)

            # Encode tune for URL and embed ABCJS Editor
            encoded_tune = urllib.parse.quote(tune)
            editor_url = f"https://www.abcjs.net/abcjs-editor?abc={encoded_tune}"
            st.markdown(f"""
            ### ABCJS Editor Preview
            You can edit or play the music below:
            <iframe src="{editor_url}" width="100%" height="500" style="border:none;"></iframe>
            """, unsafe_allow_html=True)
        except Exception as e:
            st.error(f"An error occurred: {e}")