Spaces:
Running
Running
Phoenixak99
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -7,6 +7,8 @@ from datetime import datetime
|
|
7 |
from io import BytesIO
|
8 |
from tempfile import NamedTemporaryFile
|
9 |
from xmlrpc.client import Binary
|
|
|
|
|
10 |
import numpy as np
|
11 |
import requests
|
12 |
import scipy
|
@@ -21,35 +23,24 @@ from wordpress_xmlrpc import Client
|
|
21 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
22 |
from wordpress_xmlrpc.methods import media
|
23 |
|
24 |
-
# Function to extract nonce from URL parameters
|
25 |
-
def get_nonce_from_url():
|
26 |
-
params = st.experimental_get_query_params()
|
27 |
-
if 'nonce' in params:
|
28 |
-
return params['nonce'][0] # Extract the nonce from the query parameters
|
29 |
-
return None
|
30 |
-
|
31 |
-
nonce = get_nonce_from_url()
|
32 |
-
|
33 |
-
# API URLs and Tokens
|
34 |
-
API_URL = os.getenv("API_URL", None)
|
35 |
-
BEARER_TOKEN = os.getenv("BEARER_TOKEN", None)
|
36 |
|
37 |
-
if not
|
|
|
|
|
|
|
38 |
st.error("API_URL environment variable is not set.")
|
39 |
st.stop()
|
40 |
|
41 |
-
if not
|
|
|
|
|
|
|
42 |
st.error("BEARER_TOKEN environment variable is not set.")
|
43 |
st.stop()
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
"Authorization": f"Bearer {BEARER_TOKEN}",
|
48 |
-
"Content-Type": "application/json",
|
49 |
-
"X-WP-Nonce": nonce # Include nonce in the headers
|
50 |
-
}
|
51 |
|
52 |
-
# Add background image for Streamlit app
|
53 |
page_bg_img = '''
|
54 |
<style>
|
55 |
.stApp {
|
@@ -60,30 +51,111 @@ background-size: cover;
|
|
60 |
'''
|
61 |
st.markdown(page_bg_img, unsafe_allow_html=True)
|
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 |
st.title("Songlab AI")
|
88 |
|
89 |
# Initialize session state variables
|
@@ -91,12 +163,14 @@ if "vocal_audio" not in st_state:
|
|
91 |
st_state.vocal_audio = None
|
92 |
if "vocal_sample_rate" not in st_state:
|
93 |
st_state.vocal_sample_rate = None
|
|
|
94 |
if "audio" not in st_state:
|
95 |
st_state.audio = None
|
96 |
if "audio_pydub" not in st_state:
|
97 |
st_state.audio_pydub = None
|
98 |
if "audio_sample_rate" not in st_state:
|
99 |
st_state.audio_sample_rate = None
|
|
|
100 |
if "augmented_audio" not in st_state:
|
101 |
st_state.augmented_audio = None
|
102 |
if "augmented_audio_pydub" not in st_state:
|
@@ -104,71 +178,314 @@ if "augmented_audio_pydub" not in st_state:
|
|
104 |
if "augmented_audio_sample_rate" not in st_state:
|
105 |
st_state.augmented_audio_sample_rate = None
|
106 |
|
107 |
-
|
108 |
-
genres = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
genre = st.selectbox("Select Genre:", genres)
|
110 |
energy_levels = ["Low", "Medium", "High"]
|
111 |
energy_level = st.radio("Energy Level:", energy_levels, horizontal=True)
|
112 |
-
|
113 |
-
# Input for description and tempo
|
114 |
description = st.text_input("Description:", "")
|
115 |
tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
def time_post_request(api_url, headers=None, payload=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
start_time = time.time()
|
135 |
response = requests.post(api_url, headers=headers, json=payload)
|
136 |
-
|
|
|
|
|
137 |
print(f"Execution time: {execution_time} seconds")
|
|
|
138 |
return response
|
139 |
|
140 |
-
# Function to generate audio
|
141 |
def generate_audio(genre, energy_level, tempo, description, duration):
|
142 |
-
|
|
|
143 |
payload = {"inputs": {"prompt": prompt, "duration": duration}}
|
144 |
with st.spinner("Generating audio ..."):
|
145 |
-
response = time_post_request(API_URL, headers
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
else:
|
152 |
-
|
|
|
|
|
|
|
153 |
|
154 |
-
# Function to load and play the generated audio
|
155 |
def load_and_play_generated_audio(response):
|
|
|
156 |
response_eval = json.loads(response.content)
|
157 |
-
channel1 =
|
158 |
-
channel2 =
|
159 |
with NamedTemporaryFile() as f1:
|
160 |
-
scipy.io.wavfile.write(
|
|
|
|
|
161 |
channel1_temp = AudioSegment.from_file(f1.name)
|
162 |
with NamedTemporaryFile() as f2:
|
163 |
-
scipy.io.wavfile.write(
|
|
|
|
|
164 |
channel2_temp = AudioSegment.from_file(f2.name)
|
165 |
audio_pydub = AudioSegment.from_mono_audiosegments(channel1_temp, channel2_temp)
|
166 |
st_state.audio_pydub = audio_pydub
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
-
# Generate audio button
|
170 |
if st.button("Generate Audio"):
|
171 |
-
if description:
|
172 |
generate_audio(genre, energy_level, tempo, description, duration)
|
173 |
-
|
|
|
174 |
st.info("Description field is required.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
from io import BytesIO
|
8 |
from tempfile import NamedTemporaryFile
|
9 |
from xmlrpc.client import Binary
|
10 |
+
import jwt
|
11 |
+
|
12 |
import numpy as np
|
13 |
import requests
|
14 |
import scipy
|
|
|
23 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
24 |
from wordpress_xmlrpc.methods import media
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
+
# Try to get API_URL from environment variables, if not found set to a default value
|
28 |
+
try:
|
29 |
+
API_URL = os.environ["API_URL"]
|
30 |
+
except KeyError:
|
31 |
st.error("API_URL environment variable is not set.")
|
32 |
st.stop()
|
33 |
|
34 |
+
# Try to get the Bearer token from environment variables, if not found set to a default value
|
35 |
+
try:
|
36 |
+
BEARER_TOKEN = os.environ["BEARER_TOKEN"]
|
37 |
+
except KeyError:
|
38 |
st.error("BEARER_TOKEN environment variable is not set.")
|
39 |
st.stop()
|
40 |
|
41 |
+
print("API_URL:", os.environ["API_URL"])
|
42 |
+
print("BEARER_TOKEN:", os.environ["BEARER_TOKEN"])
|
|
|
|
|
|
|
|
|
43 |
|
|
|
44 |
page_bg_img = '''
|
45 |
<style>
|
46 |
.stApp {
|
|
|
51 |
'''
|
52 |
st.markdown(page_bg_img, unsafe_allow_html=True)
|
53 |
|
54 |
+
def save_to_wordpress(channel1, channel2, sample_rate):
|
55 |
+
|
56 |
+
channel1 = np.array(channel1).astype(np.float32)
|
57 |
+
channel2 = np.array(channel2).astype(np.float32)
|
58 |
+
stereo_audio = np.column_stack((channel1, channel2))
|
59 |
+
|
60 |
+
# Define your WordPress site URL and authentication credentials
|
61 |
+
wordpress_url = "https://songlabai.com/xmlrpc.php"
|
62 |
+
woocommerce_url = "https://songlabai.com"
|
63 |
+
consumer_key = "ck_93d516ba12289a6fd0eced56bbc0b05ecbf98735"
|
64 |
+
consumer_secret = "cs_9d5eb716d631db408a4c47796b5d18b0313d8559"
|
65 |
+
username = "admin_h2ibbgql"
|
66 |
+
password = "um^VdaNK0H8Vw2*KNJlYABkh"
|
67 |
+
|
68 |
+
# Authenticate with WordPress XML-RPC API
|
69 |
+
wav_bytes = BytesIO()
|
70 |
+
sf.write(wav_bytes, stereo_audio, samplerate=sample_rate, format="WAV")
|
71 |
+
title = f"generated_audio_{datetime.now().timestamp()}.wav"
|
72 |
+
file_data = {
|
73 |
+
"name": title,
|
74 |
+
"type": "audio/x-wav", # Change the MIME type according to your file type
|
75 |
+
"bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
|
76 |
+
}
|
77 |
+
wp_client = Client(wordpress_url, username, password)
|
78 |
+
for _ in range(4):
|
79 |
+
try:
|
80 |
+
# Upload the file to WordPress Media Library
|
81 |
+
|
82 |
+
media_response = wp_client.call(media.UploadFile(file_data))
|
83 |
+
|
84 |
+
# Handle the response
|
85 |
+
if media_response:
|
86 |
+
print(
|
87 |
+
"File successfully uploaded to WordPress with attachment ID:",
|
88 |
+
media_response,
|
89 |
+
)
|
90 |
+
|
91 |
+
# Create product data for WooCommerce
|
92 |
+
product_data = {
|
93 |
+
"status": "pending",
|
94 |
+
"name": title,
|
95 |
+
"type": "simple",
|
96 |
+
"regular_price": "1.00", # Set the price as needed
|
97 |
+
"sku": str(uuid.uuid4()),
|
98 |
+
"downloadable": True,
|
99 |
+
"download_limit": -1,
|
100 |
+
"download_expiry": -1,
|
101 |
+
}
|
102 |
|
103 |
+
# Authenticate with WooCommerce API
|
104 |
+
wc_api = API(
|
105 |
+
url=woocommerce_url,
|
106 |
+
consumer_key=consumer_key,
|
107 |
+
consumer_secret=consumer_secret,
|
108 |
+
version="wc/v3",
|
109 |
+
)
|
110 |
+
|
111 |
+
# Create the product
|
112 |
+
response = wc_api.post("products", product_data)
|
113 |
+
|
114 |
+
# Handle the response
|
115 |
+
if response.status_code == 201:
|
116 |
+
print(
|
117 |
+
"Product successfully created in WooCommerce:", response.json()
|
118 |
+
)
|
119 |
+
# Update product to add downloadable file URL
|
120 |
+
product_update_data = {
|
121 |
+
"downloads": [
|
122 |
+
{
|
123 |
+
"name": media_response["title"],
|
124 |
+
"file": media_response["link"],
|
125 |
+
}
|
126 |
+
]
|
127 |
+
}
|
128 |
+
product_id = response.json().get("id")
|
129 |
+
response = wc_api.put(f"products/{product_id}", product_update_data)
|
130 |
+
|
131 |
+
if response.status_code == 200:
|
132 |
+
print(
|
133 |
+
"Downloadable file URL added to product:", response.json()
|
134 |
+
)
|
135 |
+
return (
|
136 |
+
response.json()["permalink"],
|
137 |
+
response.json()["permalink"].split("p=")[-1],
|
138 |
+
)
|
139 |
+
else:
|
140 |
+
print(
|
141 |
+
"Error adding downloadable file URL to product:",
|
142 |
+
response.text,
|
143 |
+
)
|
144 |
+
else:
|
145 |
+
print("Error creating product in WooCommerce:", response.text)
|
146 |
+
else:
|
147 |
+
print("Error uploading file to WordPress.")
|
148 |
+
break
|
149 |
+
except Exception as e:
|
150 |
+
print("Error:", e)
|
151 |
+
|
152 |
+
|
153 |
+
headers = {
|
154 |
+
"Authorization": f"Bearer {BEARER_TOKEN}",
|
155 |
+
"Content-Type": "application/json",
|
156 |
+
}
|
157 |
+
|
158 |
+
# Streamlit app title
|
159 |
st.title("Songlab AI")
|
160 |
|
161 |
# Initialize session state variables
|
|
|
163 |
st_state.vocal_audio = None
|
164 |
if "vocal_sample_rate" not in st_state:
|
165 |
st_state.vocal_sample_rate = None
|
166 |
+
|
167 |
if "audio" not in st_state:
|
168 |
st_state.audio = None
|
169 |
if "audio_pydub" not in st_state:
|
170 |
st_state.audio_pydub = None
|
171 |
if "audio_sample_rate" not in st_state:
|
172 |
st_state.audio_sample_rate = None
|
173 |
+
|
174 |
if "augmented_audio" not in st_state:
|
175 |
st_state.augmented_audio = None
|
176 |
if "augmented_audio_pydub" not in st_state:
|
|
|
178 |
if "augmented_audio_sample_rate" not in st_state:
|
179 |
st_state.augmented_audio_sample_rate = None
|
180 |
|
181 |
+
|
182 |
+
genres = [
|
183 |
+
"Pop",
|
184 |
+
"Rock",
|
185 |
+
"Hip Hop",
|
186 |
+
"Jazz",
|
187 |
+
"Blues",
|
188 |
+
"Country",
|
189 |
+
"Classical",
|
190 |
+
"Electronic",
|
191 |
+
"Reggae",
|
192 |
+
"Folk",
|
193 |
+
"R&B",
|
194 |
+
"Metal",
|
195 |
+
"Punk",
|
196 |
+
"Indie",
|
197 |
+
"Dance",
|
198 |
+
"World",
|
199 |
+
"Gospel",
|
200 |
+
"Soul",
|
201 |
+
"Funk",
|
202 |
+
"Ambient",
|
203 |
+
"Techno",
|
204 |
+
"Disco",
|
205 |
+
"House",
|
206 |
+
"Trance",
|
207 |
+
"Dubstep",
|
208 |
+
]
|
209 |
+
|
210 |
genre = st.selectbox("Select Genre:", genres)
|
211 |
energy_levels = ["Low", "Medium", "High"]
|
212 |
energy_level = st.radio("Energy Level:", energy_levels, horizontal=True)
|
|
|
|
|
213 |
description = st.text_input("Description:", "")
|
214 |
tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
|
215 |
+
|
216 |
+
# Duration input
|
217 |
+
duration = st.slider(
|
218 |
+
"Duration (in seconds):", min_value=15, max_value=300, value=30, step=1
|
219 |
+
)
|
220 |
+
|
221 |
+
prompt2 = "Classical ,Low, 40, slow calm"
|
222 |
+
|
223 |
+
|
224 |
+
def convert_audio_segment_to_float_array(audio_pydub):
|
225 |
+
"""
|
226 |
+
Convert a pydub AudioSegment to a NumPy array of type float32.
|
227 |
+
|
228 |
+
Args:
|
229 |
+
audio_pydub (AudioSegment): The AudioSegment object to be converted.
|
230 |
+
|
231 |
+
Returns:
|
232 |
+
np.ndarray: A NumPy array containing the audio data as float32.
|
233 |
+
"""
|
234 |
+
# Get the raw audio data as a sequence of samples
|
235 |
+
samples = audio_pydub.get_array_of_samples()
|
236 |
+
|
237 |
+
# Convert the samples to a NumPy array and normalize to float32
|
238 |
+
audio_array = np.array(samples).astype(np.float32)
|
239 |
+
|
240 |
+
# Normalize the audio array to range between -1.0 and 1.0
|
241 |
+
max_val = 2**15 # Assuming 16-bit audio, modify this if using different bit depths
|
242 |
+
audio_array /= max_val
|
243 |
+
return audio_array
|
244 |
+
|
245 |
def time_post_request(api_url, headers=None, payload=None):
|
246 |
+
"""
|
247 |
+
Times the execution of a POST request.
|
248 |
+
|
249 |
+
Parameters:
|
250 |
+
- api_url (str): The URL to which the POST request is sent.
|
251 |
+
- headers (dict): The headers to include in the POST request.
|
252 |
+
- payload (dict): The payload to include in the POST request.
|
253 |
+
|
254 |
+
Returns:
|
255 |
+
- response (requests.Response): The response object returned by the POST request.
|
256 |
+
- execution_time (float): The time it took to execute the POST request.
|
257 |
+
"""
|
258 |
start_time = time.time()
|
259 |
response = requests.post(api_url, headers=headers, json=payload)
|
260 |
+
end_time = time.time()
|
261 |
+
|
262 |
+
execution_time = end_time - start_time
|
263 |
print(f"Execution time: {execution_time} seconds")
|
264 |
+
|
265 |
return response
|
266 |
|
|
|
267 |
def generate_audio(genre, energy_level, tempo, description, duration):
|
268 |
+
count_down = 300
|
269 |
+
prompt = f"Genre: {genre}, Energy Level: {energy_level}, Tempo: {tempo}, Description: {description},"
|
270 |
payload = {"inputs": {"prompt": prompt, "duration": duration}}
|
271 |
with st.spinner("Generating audio ..."):
|
272 |
+
response = time_post_request(API_URL, headers, payload)
|
273 |
+
placeholder1 = st.empty()
|
274 |
+
if response.status_code != 200:
|
275 |
+
# Temp Jay Start
|
276 |
+
print(f"Request Headers: {response.request.headers}")
|
277 |
+
print(f"Request Body: {response.request.body}")
|
278 |
+
print(f"Response Code: {response.status_code}")
|
279 |
+
print(f"Response Body: {response.text}")
|
280 |
+
# Temp Jay End
|
281 |
+
|
282 |
+
|
283 |
+
print(str(response.content))
|
284 |
+
count_down_placeholder = st.empty()
|
285 |
+
for seconds in range(count_down):
|
286 |
+
count_down_placeholder.info(
|
287 |
+
f"The server is currently loading. Retrying in ⏳ {count_down - seconds} seconds."
|
288 |
+
)
|
289 |
+
time.sleep(1)
|
290 |
+
count_down_placeholder.empty()
|
291 |
+
with st.spinner("Generating audio ..."):
|
292 |
+
response = time_post_request(API_URL, headers, payload)
|
293 |
+
if response.status_code != 200:
|
294 |
+
count_down_placeholder = st.empty()
|
295 |
+
for seconds in range(count_down):
|
296 |
+
count_down_placeholder.info(
|
297 |
+
f"2nd attempt failed. trying again one more time in ⏳ {count_down - seconds} seconds."
|
298 |
+
)
|
299 |
+
time.sleep(1)
|
300 |
+
count_down_placeholder.empty()
|
301 |
+
with st.spinner("Generating audio ..."):
|
302 |
+
response = time_post_request(API_URL, headers, payload)
|
303 |
+
if response.status_code != 200:
|
304 |
+
placeholder1.error(
|
305 |
+
"Failed to generate audio after multiple attempts. Please try again later."
|
306 |
+
)
|
307 |
+
else:
|
308 |
+
placeholder1.success(f"✔️ Audio Generated, Loading...")
|
309 |
+
load_and_play_generated_audio(response)
|
310 |
+
placeholder1.empty()
|
311 |
+
else:
|
312 |
+
placeholder1.success(f"✔️ Audio Generated, Loading...")
|
313 |
+
load_and_play_generated_audio(response)
|
314 |
+
placeholder1.empty()
|
315 |
else:
|
316 |
+
placeholder1.success(f"✔️ Audio Generated, Loading...")
|
317 |
+
load_and_play_generated_audio(response)
|
318 |
+
placeholder1.empty()
|
319 |
+
|
320 |
|
|
|
321 |
def load_and_play_generated_audio(response):
|
322 |
+
|
323 |
response_eval = json.loads(response.content)
|
324 |
+
channel1 = response_eval[0]["generated_audio"][0]
|
325 |
+
channel2 = response_eval[0]["generated_audio"][1]
|
326 |
with NamedTemporaryFile() as f1:
|
327 |
+
scipy.io.wavfile.write(
|
328 |
+
f1.name, rate=32000, data=np.array(channel1).astype(np.float32)
|
329 |
+
)
|
330 |
channel1_temp = AudioSegment.from_file(f1.name)
|
331 |
with NamedTemporaryFile() as f2:
|
332 |
+
scipy.io.wavfile.write(
|
333 |
+
f2.name, rate=32000, data=np.array(channel2).astype(np.float32)
|
334 |
+
)
|
335 |
channel2_temp = AudioSegment.from_file(f2.name)
|
336 |
audio_pydub = AudioSegment.from_mono_audiosegments(channel1_temp, channel2_temp)
|
337 |
st_state.audio_pydub = audio_pydub
|
338 |
+
st_state.audio_pydub_sample_rate = audio_pydub.frame_rate
|
339 |
+
|
340 |
+
st_state.audio = np.array(st_state.audio_pydub.get_array_of_samples()).astype(np.float32)
|
341 |
+
sample_rate = response_eval[0]["sample_rate"]
|
342 |
+
perm_link, product_code = save_to_wordpress(
|
343 |
+
channel1, channel2, 32000
|
344 |
+
)
|
345 |
+
|
346 |
+
st_state.audio_sample_rate = sample_rate
|
347 |
+
st_state.augmented_audio_pydub = st_state.audio_pydub
|
348 |
+
st.audio(st_state.audio_pydub.export().read())
|
349 |
+
col_btn, col_text = st.columns([2,4])
|
350 |
+
|
351 |
+
with col_btn:
|
352 |
+
st.link_button("Publish your Song", "https://songlabai.com/contact_us/")
|
353 |
+
st.link_button("Download Song", "https://songlabai.com/download-music/")
|
354 |
+
|
355 |
+
with col_text:
|
356 |
+
st.write(
|
357 |
+
f"To Publish, please contact the admin by sending the following link: {perm_link}"
|
358 |
+
)
|
359 |
+
st.write(f"To download use the following product code: {product_code}")
|
360 |
+
|
361 |
|
|
|
362 |
if st.button("Generate Audio"):
|
363 |
+
if genre and energy_level and description and tempo:
|
364 |
generate_audio(genre, energy_level, tempo, description, duration)
|
365 |
+
|
366 |
+
if description == "":
|
367 |
st.info("Description field is required.")
|
368 |
+
|
369 |
+
# Post-processing options
|
370 |
+
st.header("Post-processing Options")
|
371 |
+
|
372 |
+
vocal_file = st.file_uploader(
|
373 |
+
"Upload Vocal File", type=["mp3", "wav", "ogg", "flac", "aac"]
|
374 |
+
)
|
375 |
+
if vocal_file:
|
376 |
+
st_state.vocal_audio = vocal_file.read()
|
377 |
+
# st.audio(st_state.vocal_audio, format="audio/wav")
|
378 |
+
|
379 |
+
# Mixing
|
380 |
+
mix_vocals = st.checkbox("Mix Vocals")
|
381 |
+
|
382 |
+
if mix_vocals and st_state.vocal_audio is not None:
|
383 |
+
with NamedTemporaryFile() as f:
|
384 |
+
f.write(st_state.vocal_audio)
|
385 |
+
st_state.vocal_audio = AudioSegment.from_file(f.name)
|
386 |
+
st_state.augmented_audio_pydub = st_state.augmented_audio_pydub.overlay(
|
387 |
+
st_state.vocal_audio, position=100
|
388 |
+
)
|
389 |
+
# st.audio(st_state.augmented_audio_pydub.export().read())
|
390 |
+
st_state.augmented_audio = convert_audio_segment_to_float_array(
|
391 |
+
st_state.augmented_audio_pydub
|
392 |
+
)
|
393 |
+
st_state.augmented_audio_sample_rate = st_state.augmented_audio_pydub.frame_rate
|
394 |
+
elif not mix_vocals and st_state.vocal_audio is not None:
|
395 |
+
st_state.augmented_audio_pydub = st_state.audio_pydub
|
396 |
+
st_state.augmented_audio_sample_rate = st_state.audio_pydub.frame_rate
|
397 |
+
# Mastering
|
398 |
+
st.header("Mastering")
|
399 |
+
st.markdown("")
|
400 |
+
# Volume Balance, Compression Ratio, and Reverb Amount
|
401 |
+
vol_col, pitch_shift,buttons_col = st.columns([2, 2, 2.5,])
|
402 |
+
with buttons_col:
|
403 |
+
with st.container(height=371, border=True):
|
404 |
+
st.markdown("")
|
405 |
+
apply_stereo = st.button("Apply Stereo Effect")
|
406 |
+
st.markdown("")
|
407 |
+
reverse = st.button("Apply Audio Reverse ")
|
408 |
+
st.markdown("")
|
409 |
+
reset_post_processing = st.button("Undo All Post-processings")
|
410 |
+
st.markdown("")
|
411 |
+
|
412 |
+
with vol_col:
|
413 |
+
with st.container(border=True):
|
414 |
+
volume_balance = svs.vertical_slider(
|
415 |
+
"Volume Balance",
|
416 |
+
min_value=-10.0,
|
417 |
+
max_value=10.0,
|
418 |
+
default_value=0.0,
|
419 |
+
step=0.1,
|
420 |
+
slider_color="green",
|
421 |
+
track_color="lightgray",
|
422 |
+
thumb_color="red",
|
423 |
+
thumb_shape="pill",
|
424 |
+
)
|
425 |
+
vol_button = st.button("Apply Vol-Balance")
|
426 |
+
|
427 |
+
|
428 |
+
# Pitch shifting
|
429 |
+
with pitch_shift:
|
430 |
+
with st.container(border=True):
|
431 |
+
pitch_semitones = svs.vertical_slider(
|
432 |
+
label="Pitch (semitones)",
|
433 |
+
min_value=-12,
|
434 |
+
max_value=12,
|
435 |
+
default_value=0,
|
436 |
+
step=1,
|
437 |
+
slider_color="red",
|
438 |
+
track_color="lightgray",
|
439 |
+
thumb_color="red",
|
440 |
+
thumb_shape="pill",
|
441 |
+
)
|
442 |
+
pitch_shift_button = st.button(
|
443 |
+
"Apply Pitch Shift",
|
444 |
+
)
|
445 |
+
|
446 |
+
|
447 |
+
if st_state.augmented_audio_pydub is not None:
|
448 |
+
if vol_button:
|
449 |
+
st_state.augmented_audio_pydub = st_state.augmented_audio_pydub + volume_balance
|
450 |
+
|
451 |
+
if apply_stereo:
|
452 |
+
st_state.augmented_audio_pydub = st_state.augmented_audio_pydub.pan(
|
453 |
+
-0.5
|
454 |
+
).overlay(st_state.augmented_audio_pydub.pan(0.5))
|
455 |
+
if reverse:
|
456 |
+
st_state.augmented_audio_pydub = st_state.augmented_audio_pydub.reverse()
|
457 |
+
if pitch_shift_button:
|
458 |
+
st_state.augmented_audio_pydub = st_state.augmented_audio_pydub._spawn(
|
459 |
+
st_state.augmented_audio_pydub.raw_data,
|
460 |
+
overrides={
|
461 |
+
"frame_rate": int(
|
462 |
+
st_state.augmented_audio_pydub.frame_rate
|
463 |
+
* (2 ** (pitch_semitones / 12.0))
|
464 |
+
)
|
465 |
+
},
|
466 |
+
)
|
467 |
+
|
468 |
+
# Display the final audio
|
469 |
+
if st_state.augmented_audio_pydub is not None:
|
470 |
+
st.audio(st_state.augmented_audio_pydub.export().read())
|
471 |
+
# sample_rate = st_state.augmented_audio_sample_rate
|
472 |
+
# st.audio(st_state.augmented_audio, format="audio/wav", sample_rate=sample_rate*2, start_time=0)
|
473 |
+
|
474 |
+
st.link_button(
|
475 |
+
label="⬇️ Download/Save",
|
476 |
+
url="https://songlabai.com/subcribe/",
|
477 |
+
type="primary",
|
478 |
+
use_container_width=True,
|
479 |
+
)
|
480 |
+
# m = st.markdown("""
|
481 |
+
# <style>
|
482 |
+
# div.stButton > button:first-child {
|
483 |
+
# # color: rgb(204, 49, 49);
|
484 |
+
# # background-color: ;
|
485 |
+
# # border-radius: 5%;
|
486 |
+
# backgroud-color: #00ff00;
|
487 |
+
# }
|
488 |
+
# # </style>""", unsafe_allow_html=True)
|
489 |
+
|
490 |
+
if reset_post_processing and st_state.audio_pydub is not None:
|
491 |
+
st_state.augmented_audio_pydub = st_state.audio_pydub
|