Track_Arrangement_V2 / temp_choose.py
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()