PRANJAL KAR
Enhance app.py and utils.py with improved variant selection and logging features; update final_arrangement.json to include volume automation and curve types for sections; modify .gitignore to exclude .env files and additional log patterns.
611a504
import gradio as gr | |
import plotly.graph_objects as go | |
import numpy as np | |
import logging | |
import json | |
logger = logging.getLogger(__name__) | |
logger.setLevel(logging.INFO) | |
file_handler = logging.FileHandler('temp_choose.log') | |
file_handler.setLevel(logging.INFO) | |
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) | |
logger.addHandler(file_handler) | |
# Three base arrangements | |
arrangements = { | |
"High Energy Flow": [ | |
(1, 16, "Intro", 16, "Linear"), | |
(17, 48, "Verse 1", 32, "Flat"), | |
(49, 64, "Build-Up", 16, "Linear"), | |
(65, 100, "Drop 1", 64, "Flat"), | |
(129, 40, "Breakdown", 16, "-ve Linear"), | |
(145, 60, "Bridge", 32, "Flat"), | |
(177, 64, "Build-Up", 16, "Linear"), | |
(193, 100, "Drop 2", 64, "Flat"), | |
(257, 40, "Outro/Fade", 16, "-ve Linear"), | |
], | |
"Festival Vibes": [ | |
(1, 20, "Intro", 8, "Linear"), | |
(9, 40, "Verse 1", 32, "Flat"), | |
(41, 60, "Pre-Chorus", 16, "Linear"), | |
(57, 100, "Drop 1", 64, "Flat"), | |
(121, 40, "Breakdown", 16, "-ve Linear"), | |
(137, 60, "Bridge", 32, "Flat"), | |
(169, 64, "Build-Up", 16, "Linear"), | |
(185, 100, "Drop 2", 64, "Flat"), | |
(249, 40, "Outro/Fade", 16, "-ve Linear"), | |
], | |
"Underground Pulse": [ | |
(1, 20, "Intro", 16, "Linear"), | |
(17, 40, "Verse 1", 32, "Flat"), | |
(49, 40, "Breakdown", 16, "-ve Linear"), | |
(65, 60, "Build-Up", 16, "Linear"), | |
(81, 100, "Drop 1", 64, "Flat"), | |
(145, 40, "Bridge", 16, "-ve Linear"), | |
(161, 60, "Pre-Chorus", 32, "Linear"), | |
(193, 100, "Drop 2", 64, "Flat"), | |
(257, 40, "Outro", 16, "-ve Linear"), | |
], | |
} | |
arrangement = arrangements["High Energy Flow"].copy() | |
def shift_arrangement(start_index): | |
for i in range(start_index + 1, len(arrangement)): | |
prev_start, _, _, prev_length, _ = arrangement[i - 1] | |
arrangement[i] = (prev_start + prev_length, *arrangement[i][1:]) | |
def editable_diagram(section_data): | |
fig = go.Figure() | |
total_bars = 0 | |
for bar, tempo, name, length, curve in section_data: | |
x = np.arange(bar, bar + length + 1) | |
if curve == "Linear": | |
y = np.linspace(tempo * 0.6, tempo, len(x)) | |
elif curve == "-ve Linear": | |
y = np.linspace(tempo, tempo * 0.6, len(x)) | |
else: | |
y = np.full(len(x), tempo) | |
fig.add_trace( | |
go.Scatter( | |
x=x, y=y, fill="tozeroy", name=name, mode="lines", line_shape="hv", | |
text=[name] * len(x), textposition="top center" | |
) | |
) | |
total_bars = max(total_bars, bar + length) | |
fig.update_layout( | |
title="EDM Arrangement Energy Curve", | |
xaxis_title="Bar", | |
yaxis_title="Volume (Energy)", | |
xaxis=dict( | |
range=[0, total_bars + 4], | |
tickmode='linear', | |
tick0=0, | |
dtick=4 | |
), | |
yaxis=dict(range=[0, 100]), | |
height=400, | |
) | |
return fig | |
def update_section(index, bar, tempo, length, curve): | |
global arrangement | |
current = arrangement[index] | |
arrangement[index] = (int(bar), int(tempo), current[2], int(length), curve) | |
shift_arrangement(index) | |
return editable_diagram(arrangement) | |
def insert_section(index, name="New Section", bar=0, tempo=50, length=8, curve="Flat"): | |
global arrangement | |
arrangement.insert(index, (bar, tempo, name, length, curve)) | |
shift_arrangement(index) | |
return editable_diagram(arrangement) | |
def load_variation(variation_name): | |
global arrangement | |
arrangement = arrangements[variation_name].copy() | |
return editable_diagram(arrangement) | |
def finalise(): | |
# Map from display names to keys | |
section_key_map = { | |
"Intro": "intro", | |
"Build-Up": "buildup", | |
"Breakdown": "breakdown", | |
"Drop 1": "drop", | |
"Drop 2": "drop2", | |
"Outro": "outro", | |
"Outro/Fade": "outro", | |
"Verse 1": "verse1", | |
"Pre-Chorus": "pre_chorus", | |
"Bridge": "bridge", | |
"Pre-Verse": "pre_verse", | |
# Add more mappings as needed | |
} | |
# Example default values for bpm, bars, p (customize as needed) | |
default_section_params = { | |
"intro": {"bpm": 120, "bars": 8, "p": 0.3}, | |
"buildup": {"bpm": 120, "bars": 16, "p": 0.4}, | |
"breakdown": {"bpm": 120, "bars": 16, "p": 0.6}, | |
"drop": {"bpm": 120, "bars": 16, "p": 0.7}, | |
"outro": {"bpm": 120, "bars": 8, "p": 0.3}, | |
# Add more as needed | |
} | |
result = {} | |
logger.info(f"Arrangement: {arrangement}") | |
print(f"Arrangement: {arrangement}") | |
for starting_bar, tempo, name, length, curve in arrangement: | |
key = section_key_map.get(name, name.lower().replace(' ', '_')) | |
params = default_section_params.get(key, {"bpm": tempo, "bars": length, "p": 0.5}) | |
# Volume automation logic | |
if curve.lower() == "flat": | |
volume_automation = [tempo, tempo] | |
elif curve.lower() == "linear": | |
volume_automation = [round(tempo * 0.6, 2), tempo] | |
elif curve.lower() in ["-ve linear", "negative linear"]: | |
volume_automation = [tempo, round(tempo * 0.6, 2)] | |
else: | |
volume_automation = [tempo, tempo] # default to flat | |
params["volume_automation"] = volume_automation | |
params["curve"] = curve # Optionally save the curve type too | |
result[key] = params | |
with open("final_arrangement.json", "w") as f: | |
json.dump(result, f, indent=2) | |
return json.dumps(result, indent=2) | |
# To be commented, as UI is in different file | |
# Commented out for now | |
# with gr.Blocks() as iface: | |
# gr.Markdown("# π Interactive EDM Arrangement Tool") | |
# with gr.Row(): | |
# variation = gr.Radio( | |
# choices=list(arrangements.keys()), | |
# value="High Energy Flow", | |
# label="Choose Arrangement Variation", | |
# ) | |
# out_plot = gr.Plot(label="Arrangement Diagram", value=load_variation("High Energy Flow")) | |
# variation.change(fn=load_variation, inputs=variation, outputs=out_plot) | |
# iface.load(fn=load_variation, inputs=[variation], outputs=[out_plot]) | |
# with gr.Accordion("π» Edit Section Parameters", open=False): | |
# for i, (bar, tempo, name, length, curve) in enumerate(arrangement): | |
# with gr.Row(): | |
# gr.Markdown(f"**{name}**") | |
# bar_slider = gr.Slider( | |
# minimum=0, maximum=300, value=bar, label="Start Bar" | |
# ) | |
# tempo_slider = gr.Slider( | |
# minimum=20, maximum=100, value=tempo, label="Volume" | |
# ) | |
# length_slider = gr.Slider( | |
# minimum=1, maximum=64, value=length, label="Length" | |
# ) | |
# curve_selector = gr.Radio( | |
# choices=["Flat", "Linear", "-ve Linear"], | |
# value=curve, | |
# label="Curve Type", | |
# ) | |
# update_btn = gr.Button("Update") | |
# update_btn.click( | |
# fn=update_section, | |
# inputs=[ | |
# gr.Number(value=i, visible=False), | |
# bar_slider, | |
# tempo_slider, | |
# length_slider, | |
# curve_selector, | |
# ], | |
# outputs=[out_plot], | |
# ) | |
# with gr.Accordion("β Insert New Section", open=False): | |
# new_index = gr.Number(value=0, label="Insert At Index") | |
# new_name = gr.Textbox(label="Section Name", value="New Section") | |
# new_bar = gr.Slider(minimum=0, maximum=300, value=0, label="Start Bar") | |
# new_tempo = gr.Slider(minimum=20, maximum=100, value=50, label="Volume") | |
# new_length = gr.Slider(minimum=1, maximum=64, value=8, label="Length") | |
# new_curve = gr.Radio( | |
# choices=["Flat", "Linear", "-ve Linear"], value="Flat", label="Curve Type" | |
# ) | |
# insert_btn = gr.Button("Insert Section") | |
# insert_btn.click( | |
# fn=insert_section, | |
# inputs=[new_index, new_name, new_bar, new_tempo, new_length, new_curve], | |
# outputs=[out_plot], | |
# ) | |
# gr.Markdown("## β Finalise Your Arrangement") | |
# final_btn = gr.Button("Finalise and Export JSON") | |
# final_output = gr.Textbox(label="Final Arrangement JSON", lines=15) | |
# final_btn.click(fn=finalise, outputs=final_output) | |
# iface.launch() | |