Spaces:
Running
Running
import streamlit as st | |
import requests | |
import numpy as np | |
import os | |
import base64 | |
from streamlit import session_state as st_state | |
import streamlit_vertical_slider as svs | |
import librosa | |
import soundfile as sf | |
from scipy.signal import butter, sosfilt | |
from wordpress_xmlrpc.compat import xmlrpc_client | |
from io import BytesIO | |
import soundfile as sf | |
from datetime import datetime | |
from wordpress_xmlrpc import Client | |
from wordpress_xmlrpc.methods import media | |
from xmlrpc.client import Binary | |
from woocommerce import API | |
from wordpress_xmlrpc.compat import xmlrpc_client | |
from io import BytesIO | |
import soundfile as sf # This library is used for saving audio data as WAV file | |
from datetime import datetime | |
import uuid | |
def save_to_wordpress(audio, sample_rate): | |
# Define your WordPress site URL and authentication credentials | |
wordpress_url = 'https://songlabai.com/xmlrpc.php' | |
woocommerce_url = 'https://songlabai.com' | |
consumer_key = 'ck_93d516ba12289a6fd0eced56bbc0b05ecbf98735' | |
consumer_secret = 'cs_9d5eb716d631db408a4c47796b5d18b0313d8559' | |
username = 'admin_h2ibbgql' | |
password = 'um^VdaNK0H8Vw2*KNJlYABkh' | |
# Authenticate with WordPress XML-RPC API | |
wav_bytes = BytesIO() | |
sf.write(wav_bytes, audio, samplerate=sample_rate, format='WAV') | |
title = f"generated_audio_{datetime.now().timestamp()}.wav" | |
file_data = { | |
'name': title, | |
'type': 'audio/x-wav', # Change the MIME type according to your file type | |
'bits': xmlrpc_client.Binary(wav_bytes.getvalue()), | |
} | |
wp_client = Client(wordpress_url, username, password) | |
for _ in range(4): | |
try: | |
# Upload the file to WordPress Media Library | |
media_response = wp_client.call(media.UploadFile(file_data)) | |
# Handle the response | |
if media_response: | |
print("File successfully uploaded to WordPress with attachment ID:", media_response) | |
# Create product data for WooCommerce | |
product_data = { | |
'status':'pending', | |
'name': title, | |
'type': 'simple', | |
'regular_price': '1.00', # Set the price as needed | |
'sku': str(uuid.uuid4()), | |
'downloadable': True, | |
'download_limit': -1, | |
'download_expiry': -1, | |
} | |
# Authenticate with WooCommerce API | |
wc_api = API( | |
url=woocommerce_url, | |
consumer_key=consumer_key, | |
consumer_secret=consumer_secret, | |
version="wc/v3" | |
) | |
# Create the product | |
response = wc_api.post("products", product_data) | |
# Handle the response | |
if response.status_code == 201: | |
print("Product successfully created in WooCommerce:", response.json()) | |
# Update product to add downloadable file URL | |
product_update_data = { | |
'downloads': [{ | |
'name': media_response['title'], | |
'file': media_response['link'] | |
}] | |
} | |
product_id = response.json().get('id') | |
response = wc_api.put(f"products/{product_id}", product_update_data) | |
if response.status_code == 200: | |
print("Downloadable file URL added to product:", response.json()) | |
return response.json()['permalink'] | |
else: | |
print("Error adding downloadable file URL to product:", response.text) | |
else: | |
print("Error creating product in WooCommerce:", response.text) | |
else: | |
print("Error uploading file to WordPress.") | |
break | |
except Exception as e: | |
print("Error:", e) | |
# Try to get API_URL from environment variables, if not found set to a default value | |
try: | |
API_URL = os.environ["API_URL"] | |
except KeyError: | |
st.error("API_URL environment variable is not set.") | |
st.stop() | |
# Try to get the Bearer token from environment variables, if not found set to a default value | |
try: | |
BEARER_TOKEN = os.environ["ACCESS_TOKEN"] | |
except KeyError: | |
st.error("BEARER_TOKEN environment variable is not set.") | |
st.stop() | |
headers = { | |
"Authorization": f"Bearer {BEARER_TOKEN}", | |
"Content-Type": "application/json" | |
} | |
# Initialize session state variables | |
if 'audio' not in st_state: | |
st_state.audio = None | |
if 'augmented_audio' not in st_state: | |
st_state.augmented_audio = None | |
# Streamlit app title | |
st.title("Songlabai") | |
# Initialize session state variables | |
if 'vocal_audio' not in st_state: | |
st_state.vocal_audio = None | |
if 'audio' not in st_state: | |
st_state.audio = None | |
if 'augmented_audio' not in st_state: | |
st_state.augmented_audio = None | |
genres = [ | |
"Pop", "Rock", "Hip Hop", "Jazz", "Blues", | |
"Country", "Classical", "Electronic", "Reggae", | |
"Folk", "R&B", "Metal", "Punk", "Indie", | |
"Dance", "World", "Gospel", "Soul", "Funk", | |
"Ambient", "Techno", "Disco", "House", "Trance", | |
"Dubstep" | |
] | |
genre = st.selectbox("Select Genre:", genres) | |
energy_levels = ["Low", "Medium", "High"] | |
energy_level = st.radio("Energy Level:", energy_levels, horizontal=True) | |
description = st.text_input("Description:", "") | |
tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5) | |
# Duration input | |
duration = st.slider("Duration (in seconds):", min_value=15, max_value=90, value=30, step=1) | |
# Generate audio based on the user's prompt | |
if st.button("Generate Audio") and genre and energy_level and description and tempo: | |
prompt = f"{genre} ,{energy_level}, {tempo}, {description}" | |
payload = {"inputs": {"prompt": prompt, "duration": duration}} | |
st.text("Generating audio...") | |
response = requests.post(API_URL, headers=headers, json=payload) | |
response = response.json()[0] | |
audio = np.array(response['generated_audio'], dtype=np.float32) | |
sample_rate = response['sample_rate'] | |
st_state.audio = audio | |
permalink = save_to_wordpress(audio, sample_rate) | |
st.audio(st_state.audio, format="audio/wav", sample_rate=sample_rate, start_time=0) | |
st.text(f"For downloading/publishing please contact the administrator, from your loged in accout. Remember to send the following link:\n{permalink}") | |
# Post-processing options | |
st.header("Post-processing Options") | |
vocal_file = st.file_uploader("Upload Vocal File", type=["wav", "wav"]) | |
if vocal_file: | |
st_state.vocal_audio = vocal_file.read() | |
# Mixing | |
mix_vocals = st.checkbox("Mix Vocals") | |
if mix_vocals and st_state.vocal_audio is not None: | |
# Load the vocal audio | |
vocal_audio, _ = librosa.load(vocal_file.read(), mono=False) | |
# Adjust the vocal audio length to match the generated audio | |
vocal_audio = librosa.util.fix_length(vocal_audio, len(st_state.audio)) | |
# Mix the vocal audio with the generated audio | |
st_state.augmented_audio = (st_state.audio + vocal_audio) / 2 | |
# Mastering | |
st.subheader("Mastering") | |
# Volume Balance, Compression Ratio, and Reverb Amount | |
vol_col, comp_col, reverb_col = st.columns(3) | |
with vol_col: | |
volume_balance = svs.vertical_slider( | |
"Volume Balance", min_value=-10.0, max_value=10.0, default_value=0.0, step=0.1, | |
slider_color="green", track_color="lightgray", thumb_color="red" | |
) | |
vol_button = st.button("Apply Volume Balance") | |
with comp_col: | |
compression_ratio = svs.vertical_slider( | |
"Compression Ratio", min_value=1.0, max_value=10.0, default_value=3.0, step=0.1, | |
slider_color="blue", track_color="lightgray", thumb_color="navy" | |
) | |
comp_button = st.button("Apply Compression") | |
with reverb_col: | |
reverb_amount = svs.vertical_slider( | |
"Reverb Amount", min_value=1.0, max_value=10.0, default_value=3.0, step=0.1, | |
slider_color="orange", track_color="lightgray", thumb_color="darkorange" | |
) | |
reverb_button = st.button("Apply Reverb") | |
if vol_button: | |
if st_state.augmented_audio is None: | |
st_state.augmented_audio = st_state.audio | |
st_state.augmented_audio *= 10 ** (volume_balance / 20) | |
if comp_button: | |
if st_state.augmented_audio is None: | |
st_state.augmented_audio = st_state.audio | |
# Apply compression using a simple soft-knee compressor | |
threshold = -20 # dBFS | |
ratio = compression_ratio | |
knee = 10 # dB | |
max_gain = 20 # dB | |
def compress(x, threshold, ratio, knee, max_gain): | |
over = np.maximum(x - threshold, 0) | |
gain = over / (over + knee) * (1 - (1 / ratio)) + 1 | |
gain = np.maximum(gain, 1 - max_gain) | |
return x * gain | |
st_state.augmented_audio = compress(st_state.augmented_audio, threshold, ratio, knee, max_gain) | |
if reverb_button: | |
if st_state.augmented_audio is None: | |
st_state.augmented_audio = st_state.audio | |
# Apply a simple reverb effect using convolution | |
ir_length = int(sample_rate * 2.5) # 2.5 seconds | |
ir = np.zeros(ir_length) | |
ir[0] = 1 | |
ir = np.append(ir, np.zeros(len(st_state.augmented_audio) - ir_length)) | |
reverb = np.convolve(st_state.augmented_audio, ir, mode='full')[:len(st_state.augmented_audio)] | |
st_state.augmented_audio = st_state.augmented_audio + reverb_amount * reverb | |
# Create two main columns | |
col1, col2 = st.columns(2) | |
# EQ Controls | |
with col1: | |
eq_cols1 = st.columns(3) | |
with eq_cols1[0]: | |
eq_low = svs.vertical_slider( | |
"Low", default_value=0.0, step=0.1, min_value=-10.0, max_value=10.0, | |
slider_color="green", track_color="lightgray", thumb_color="red" | |
) | |
with eq_cols1[1]: | |
eq_mid = svs.vertical_slider( | |
"Medium", default_value=0.0, step=0.1, min_value=-10.0, max_value=10.0, | |
slider_color="green", track_color="lightgray", thumb_color="red" | |
) | |
with eq_cols1[2]: | |
eq_high = svs.vertical_slider( | |
"High", default_value=0.0, step=0.1, min_value=-10.0, max_value=10.0, | |
slider_color="green", track_color="lightgray", thumb_color="red" | |
) | |
eq_cols2 = st.columns(3) | |
with eq_cols2[0]: | |
pass | |
with eq_cols2[1]: | |
eq_button = st.button("Apply EQ") | |
with eq_cols2[2]: | |
pass | |
# Delay Controls | |
with col2: | |
delay_cols1 = st.columns(2) | |
with delay_cols1[0]: | |
delay_amount = svs.vertical_slider( | |
"Value", default_value=25, step=1, min_value=0, max_value=100, | |
slider_color="#6A5ACD", track_color="#F5F5F5", thumb_color="#4B0082" | |
) | |
with delay_cols1[1]: | |
delay_time = svs.vertical_slider( | |
"Time", default_value=75, step=1, min_value=0, max_value=100, | |
slider_color="#3CB371", track_color="#F5F5F5", thumb_color="#2E8B57" | |
) | |
delay_cols2 = st.columns(3) | |
with delay_cols2[0]: | |
pass | |
with delay_cols2[1]: | |
delay_button = st.button("Delay") | |
with delay_cols2[2]: | |
pass | |
if eq_button: | |
if st_state.augmented_audio is None: | |
st_state.augmented_audio = st_state.audio | |
# Apply a simple 3-band EQ using a butterworth filter | |
nyquist = sample_rate / 2 | |
low_cutoff = 200 / nyquist | |
mid_cutoff = 2000 / nyquist | |
high_cutoff = 8000 / nyquist | |
low_sos = butter(4, low_cutoff, btype='low', output='sos', analog=False) | |
mid_sos = butter(4, [low_cutoff, mid_cutoff], btype='band', output='sos', analog=False) | |
high_sos = butter(4, high_cutoff, btype='high', output='sos', analog=False) | |
st_state.augmented_audio = sosfilt(np.dstack((low_sos, mid_sos, high_sos)), st_state.augmented_audio, np.stack((eq_low, eq_mid, eq_high))) | |
# Add delay logic here if needed | |
if delay_button: | |
if st_state.augmented_audio is None: | |
st_state.augmented_audio = st_state.audio | |
# Apply a simple delay effect | |
delay_samples = int(delay_time / 1000 * sample_rate) | |
delay = np.zeros(len(st_state.augmented_audio) + delay_samples) | |
delay[delay_samples:] = st_state.augmented_audio | |
delay[:len(st_state.augmented_audio)] += delay_amount * delay[:-delay_samples] | |
st_state.augmented_audio = delay[:len(st_state.augmented_audio)] | |
# Display the final audio | |
if st_state.augmented_audio is not None: | |
st.audio(st_state.augmented_audio, format="audio/wav", sample_rate=sample_rate, start_time=0) | |
# Redirect Button for subscribe | |
st.link_button("Download/Save", "https://songlabai.com/subcribe/") | |