PRANJAL KAR commited on
Commit
611a504
Β·
1 Parent(s): 22652b6

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.

Browse files
Files changed (5) hide show
  1. .gitignore +4 -1
  2. app.py +120 -94
  3. final_arrangement.json +51 -16
  4. temp_choose.py +40 -6
  5. utils.py +39 -27
.gitignore CHANGED
@@ -1,5 +1,6 @@
1
  .log*
2
  __pycache__/
 
3
  *.log
4
  *.log.*
5
  *.log.*.*
@@ -8,4 +9,6 @@ __pycache__/
8
  .env
9
  *.log.*.*.*.*.*
10
  __pycache__/
11
- log.txt
 
 
 
1
  .log*
2
  __pycache__/
3
+ .env
4
  *.log
5
  *.log.*
6
  *.log.*.*
 
9
  .env
10
  *.log.*.*.*.*.*
11
  __pycache__/
12
+ log.txt
13
+ *.log.*.*.*.*.*
14
+ __pycache__/
app.py CHANGED
@@ -133,6 +133,8 @@ def generate_section_variants_handler(
133
  descriptions = {key: data["description"] for key, data in variants.items()}
134
  descriptions_json = json.dumps(descriptions, indent=2)
135
 
 
 
136
  logger.info(f"S3: DESCRIPTIONS of section {section_type} : {descriptions_json}")
137
 
138
  progress(1.0, desc="Complete!")
@@ -144,108 +146,79 @@ def generate_section_variants_handler(
144
  variant3_audio,
145
  variant4_audio,
146
  descriptions_json,
 
147
  )
148
 
149
  except Exception as e:
150
- return f"Error generating variants: {str(e)}", None, None, None, None, None
151
 
152
 
153
  def select_variant(section_type, variant_num, append):
154
- """Select a variant for a specific section, with an option to append. Retry up to 5 times on error."""
155
  global ALL_VARIANTS, SELECTED_VARIANTS
156
 
157
- max_retries = 5
158
- for attempt in range(1, max_retries + 1):
159
- try:
160
- if section_type not in ALL_VARIANTS:
161
- msg = f"No variants generated for {section_type} yet"
162
- if attempt == max_retries:
163
- return msg
164
- continue
165
 
166
- variant_key = f"variant{variant_num}"
167
- if variant_key not in ALL_VARIANTS[section_type]:
168
- msg = f"Variant {variant_num} not found for {section_type}"
169
- if attempt == max_retries:
170
- return msg
171
- continue
172
 
173
- # If appending, add to the list of selected variants
174
- if append:
175
- # For now, just overwrite with the latest selection (no append logic)
176
- SELECTED_VARIANTS[section_type] = ALL_VARIANTS[section_type][variant_key]["config"]
177
- else:
178
- # Otherwise, replace the selection
179
- SELECTED_VARIANTS[section_type] = ALL_VARIANTS[section_type][variant_key]["config"]
 
180
 
181
- return f"Selected variant {variant_num} for {section_type} (Append: {append})"
182
- except Exception as e:
183
- msg = f"Error selecting variant (attempt {attempt}): {str(e)}"
184
- if attempt == max_retries:
185
- return msg
186
- continue
187
 
188
 
189
  def generate_full_track(
190
  crossfade_ms,
191
  output_track_name,
192
- include_intro,
193
- include_buildup,
194
- include_breakdown,
195
- include_drop,
196
- include_outro,
197
  progress=gr.Progress(),
198
  ):
199
  """Generate the full track from selected variants"""
200
- global TEMP_DIR, SELECTED_VARIANTS, UPLOADED_STEMS
201
 
202
  if not TEMP_DIR or not os.path.exists(TEMP_DIR):
203
- return "Error: No stems loaded", None, None
204
 
205
  try:
206
  progress(0.1, desc="Preparing to generate full track...")
207
 
208
- # Check which sections to include based on user selections and available variants
 
 
 
209
  sections_to_include = {}
210
- logger.info(f"SELECTED_VARIANTS: {SELECTED_VARIANTS}")
211
-
212
- if include_intro and "intro" in SELECTED_VARIANTS:
213
- sections_to_include["intro"] = SELECTED_VARIANTS["intro"]
214
-
215
- if include_buildup and "buildup" in SELECTED_VARIANTS:
216
- sections_to_include["buildup"] = SELECTED_VARIANTS["buildup"]
217
-
218
- # We always include the full loop if it exists
219
- if "full_loop" in SELECTED_VARIANTS:
220
- sections_to_include["full_loop"] = SELECTED_VARIANTS["full_loop"]
221
-
222
- if include_breakdown and "breakdown" in SELECTED_VARIANTS:
223
- sections_to_include["breakdown"] = SELECTED_VARIANTS["breakdown"]
224
-
225
- if include_drop and "drop" in SELECTED_VARIANTS:
226
- sections_to_include["drop"] = SELECTED_VARIANTS["drop"]
227
-
228
- if include_outro and "outro" in SELECTED_VARIANTS:
229
- sections_to_include["outro"] = SELECTED_VARIANTS["outro"]
230
 
231
  if not sections_to_include:
232
- return "Error: No sections selected or available", None, None
233
 
234
  progress(0.3, desc="Creating track structure...")
235
 
236
  # Create the final track
237
  final_track = None
238
 
239
- # Define the order of sections
240
- section_order = ["intro", "buildup", "full_loop", "breakdown", "drop", "outro"]
241
-
242
- # Process each section in order
243
- for section_name in section_order:
244
  if section_name not in sections_to_include:
245
  continue
246
 
247
  progress(
248
- 0.4 + 0.1 * section_order.index(section_name) / len(section_order),
249
  desc=f"Processing {section_name}...",
250
  )
251
 
@@ -257,7 +230,6 @@ def generate_full_track(
257
 
258
  # Create audio for this section
259
  from utils import create_section_from_json
260
-
261
  section_audio = create_section_from_json(variant_config, stems_copy)
262
 
263
  # Add to final track
@@ -281,6 +253,15 @@ def generate_full_track(
281
  "Total sections": len(sections_list),
282
  "Duration": f"{int(track_duration // 60)}:{int(track_duration % 60):02d}",
283
  "Crossfade": f"{crossfade_ms} ms",
 
 
 
 
 
 
 
 
 
284
  }
285
 
286
  progress(1.0, desc="Complete!")
@@ -302,27 +283,34 @@ def generate_full_loop_variants(bpm_value, bars_value, p_value, progress=gr.Prog
302
  )
303
 
304
 
305
- def create_section_ui(section_name, bpm_default, bars_default, p_default):
306
  """Helper function to create UI elements for a section."""
307
  with gr.Accordion(f"Generate {section_name.capitalize()} Variants", open=False):
308
  with gr.Row():
309
  with gr.Column(scale=1):
310
  gr.Markdown(f"### {section_name.capitalize()} Parameters")
 
 
 
311
  bpm_slider = gr.Slider(
312
  label="BPM (Beats Per Minute)",
313
  minimum=60,
314
  maximum=180,
315
- value=bpm_default,
316
  step=1,
317
  )
318
  bars_slider = gr.Slider(
319
- label="Number of Bars", minimum=4, maximum=64, value=bars_default, step=4
 
 
 
 
320
  )
321
  p_slider = gr.Slider(
322
  label="Variation Parameter (p)",
323
  minimum=0,
324
  maximum=1,
325
- value=p_default,
326
  step=0.1,
327
  )
328
 
@@ -333,20 +321,24 @@ def create_section_ui(section_name, bpm_default, bars_default, p_default):
333
  with gr.Column(scale=2):
334
  status = gr.Textbox(label="Status", interactive=False)
335
  descriptions = gr.JSON(label="Variant Descriptions")
 
 
336
 
337
- # Create empty lists to store the audio and checkbox components
338
- variant_audio_list = []
339
- select_btn_list = []
340
-
341
  with gr.Row():
 
 
342
  for i in range(1, 5):
343
  with gr.Column():
344
  gr.Markdown(f"### Variant {i}")
345
- # Create and immediately append each component to its respective list
346
  variant_audio = gr.Audio(label=f"Variant {i}", interactive=True)
347
  variant_audio_list.append(variant_audio)
348
 
349
- select_btn = gr.Checkbox(label=f"Select Variant {i}")
 
 
 
 
 
350
  select_btn_list.append(select_btn)
351
 
352
  return {
@@ -356,11 +348,13 @@ def create_section_ui(section_name, bpm_default, bars_default, p_default):
356
  "generate_btn": generate_btn,
357
  "status": status,
358
  "descriptions": descriptions,
359
- "variant_audio": variant_audio_list, # Return the complete list of audio components
360
- "select_btn": select_btn_list, # Return the complete list of checkbox components
 
 
361
  }
362
 
363
- def setup_section_event_handlers(section_name, section_ui):
364
  """Setup event handlers for a given section."""
365
  section_type = gr.State(section_name)
366
 
@@ -377,6 +371,7 @@ def setup_section_event_handlers(section_name, section_ui):
377
  section_ui["status"],
378
  *section_ui["variant_audio"],
379
  section_ui["descriptions"],
 
380
  ],
381
  )
382
 
@@ -386,7 +381,26 @@ def setup_section_event_handlers(section_name, section_ui):
386
  select_btn.change(
387
  fn=select_variant,
388
  inputs=[section_type, variant_num, gr.State(False)],
389
- outputs=[section_ui["status"]],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  )
391
 
392
 
@@ -430,16 +444,25 @@ with gr.Blocks(title="Interactive Music Track Generator") as demo:
430
  # Editable diagram with progress indicator
431
  with gr.Row():
432
  gr.Markdown("⏳ In Progress: Adjusting sections...")
 
433
  edm_arrangement_tab()
434
 
435
  with gr.Tab("2. Generate Section Variants"):
436
- # Example of creating UI for sections dynamically
 
 
 
437
  section_uis = {}
 
 
 
 
 
 
 
438
  for section_name, params in sections.items():
439
- section_uis[section_name] = create_section_ui(
440
- section_name, params["bpm"], params["bars"], params["p"]
441
- )
442
- setup_section_event_handlers(section_name, section_uis[section_name])
443
 
444
  with gr.Tab("3. Create Full Track"):
445
  with gr.Row():
@@ -459,11 +482,18 @@ with gr.Blocks(title="Interactive Music Track Generator") as demo:
459
  )
460
 
461
  gr.Markdown("### Sections to Include")
462
- include_intro = gr.Checkbox(label="Include Intro", value=True)
463
- include_buildup = gr.Checkbox(label="Include buildup", value=True)
464
- include_breakdown = gr.Checkbox(label="Include breakdown", value=True)
465
- include_drop = gr.Checkbox(label="Include drop", value=True)
466
- include_outro = gr.Checkbox(label="Include Outro", value=True)
 
 
 
 
 
 
 
467
 
468
  generate_track_btn = gr.Button(
469
  "Generate Full Track", variant="primary", scale=2
@@ -487,11 +517,7 @@ with gr.Blocks(title="Interactive Music Track Generator") as demo:
487
  inputs=[
488
  crossfade_ms,
489
  output_track_name,
490
- include_intro,
491
- include_breakdown,
492
- include_buildup,
493
- include_drop,
494
- include_outro,
495
  ],
496
  outputs=[track_status, full_track_audio, track_summary],
497
  )
 
133
  descriptions = {key: data["description"] for key, data in variants.items()}
134
  descriptions_json = json.dumps(descriptions, indent=2)
135
 
136
+ stem_list = {key: data["stems"] for key, data in variants.items()}
137
+
138
  logger.info(f"S3: DESCRIPTIONS of section {section_type} : {descriptions_json}")
139
 
140
  progress(1.0, desc="Complete!")
 
146
  variant3_audio,
147
  variant4_audio,
148
  descriptions_json,
149
+ stem_list
150
  )
151
 
152
  except Exception as e:
153
+ return f"Error generating variants: {str(e)}", None, None, None, None, None, None
154
 
155
 
156
  def select_variant(section_type, variant_num, append):
157
+ """Select a variant for a specific section, with an option to append."""
158
  global ALL_VARIANTS, SELECTED_VARIANTS
159
 
160
+ try:
161
+ if section_type not in ALL_VARIANTS:
162
+ return f"No variants generated for {section_type} yet", "None"
 
 
 
 
 
163
 
164
+ variant_key = f"variant{variant_num}"
165
+ if variant_key not in ALL_VARIANTS[section_type]:
166
+ return f"Variant {variant_num} not found for {section_type}", "None"
 
 
 
167
 
168
+ # Store the selection
169
+ SELECTED_VARIANTS[section_type] = ALL_VARIANTS[section_type][variant_key]["config"]
170
+
171
+ # Create a display string for the selected variant
172
+ variant_info = ALL_VARIANTS[section_type][variant_key]
173
+ display_text = f"Selected: Variant {variant_num}"
174
+ if "description" in variant_info:
175
+ display_text += f" - {variant_info['description']}"
176
 
177
+ return f"Selected variant {variant_num} for {section_type}", display_text
178
+
179
+ except Exception as e:
180
+ return f"Error selecting variant: {str(e)}", "None"
 
 
181
 
182
 
183
  def generate_full_track(
184
  crossfade_ms,
185
  output_track_name,
186
+ *section_flags,
 
 
 
 
187
  progress=gr.Progress(),
188
  ):
189
  """Generate the full track from selected variants"""
190
+ global TEMP_DIR, SELECTED_VARIANTS, UPLOADED_STEMS, sections
191
 
192
  if not TEMP_DIR or not os.path.exists(TEMP_DIR):
193
+ return "Error: No stems loaded", None, None, None
194
 
195
  try:
196
  progress(0.1, desc="Preparing to generate full track...")
197
 
198
+ # Get section names from the configuration
199
+ section_names = list(sections.keys())
200
+
201
+ # Map section flags to section names
202
  sections_to_include = {}
203
+ for section_name, include_flag in zip(section_names, section_flags):
204
+ if include_flag and section_name in SELECTED_VARIANTS:
205
+ sections_to_include[section_name] = SELECTED_VARIANTS[section_name]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
  if not sections_to_include:
208
+ return "Error: No sections selected or available", None, None, None
209
 
210
  progress(0.3, desc="Creating track structure...")
211
 
212
  # Create the final track
213
  final_track = None
214
 
215
+ # Process each section in order from the configuration
216
+ for section_name in section_names:
 
 
 
217
  if section_name not in sections_to_include:
218
  continue
219
 
220
  progress(
221
+ 0.4 + 0.1 * section_names.index(section_name) / len(section_names),
222
  desc=f"Processing {section_name}...",
223
  )
224
 
 
230
 
231
  # Create audio for this section
232
  from utils import create_section_from_json
 
233
  section_audio = create_section_from_json(variant_config, stems_copy)
234
 
235
  # Add to final track
 
253
  "Total sections": len(sections_list),
254
  "Duration": f"{int(track_duration // 60)}:{int(track_duration % 60):02d}",
255
  "Crossfade": f"{crossfade_ms} ms",
256
+ "Section Details": {
257
+ section: {
258
+ "BPM": sections[section]["bpm"],
259
+ "Bars": sections[section]["bars"],
260
+ "Volume Automation": sections[section]["volume_automation"],
261
+ "Curve": sections[section]["curve"]
262
+ }
263
+ for section in sections_list
264
+ }
265
  }
266
 
267
  progress(1.0, desc="Complete!")
 
283
  )
284
 
285
 
286
+ def create_section_ui(section_name, params):
287
  """Helper function to create UI elements for a section."""
288
  with gr.Accordion(f"Generate {section_name.capitalize()} Variants", open=False):
289
  with gr.Row():
290
  with gr.Column(scale=1):
291
  gr.Markdown(f"### {section_name.capitalize()} Parameters")
292
+ gr.Markdown(f"**Volume Automation**: {params['volume_automation']}")
293
+ gr.Markdown(f"**Curve Type**: {params['curve']}")
294
+
295
  bpm_slider = gr.Slider(
296
  label="BPM (Beats Per Minute)",
297
  minimum=60,
298
  maximum=180,
299
+ value=params['bpm'],
300
  step=1,
301
  )
302
  bars_slider = gr.Slider(
303
+ label="Number of Bars",
304
+ minimum=4,
305
+ maximum=64,
306
+ value=params['bars'],
307
+ step=4
308
  )
309
  p_slider = gr.Slider(
310
  label="Variation Parameter (p)",
311
  minimum=0,
312
  maximum=1,
313
+ value=params['p'],
314
  step=0.1,
315
  )
316
 
 
321
  with gr.Column(scale=2):
322
  status = gr.Textbox(label="Status", interactive=False)
323
  descriptions = gr.JSON(label="Variant Descriptions")
324
+ stem_list = gr.JSON(label="Stem List")
325
+ selected_variant = gr.Text(label="Selected Variant", value="None", interactive=False)
326
 
 
 
 
 
327
  with gr.Row():
328
+ variant_audio_list = []
329
+ select_btn_list = []
330
  for i in range(1, 5):
331
  with gr.Column():
332
  gr.Markdown(f"### Variant {i}")
 
333
  variant_audio = gr.Audio(label=f"Variant {i}", interactive=True)
334
  variant_audio_list.append(variant_audio)
335
 
336
+ select_btn = gr.Radio(
337
+ choices=[f"Select Variant {i}"],
338
+ label="",
339
+ value=None,
340
+ interactive=True
341
+ )
342
  select_btn_list.append(select_btn)
343
 
344
  return {
 
348
  "generate_btn": generate_btn,
349
  "status": status,
350
  "descriptions": descriptions,
351
+ "variant_audio": variant_audio_list,
352
+ "select_btn": select_btn_list,
353
+ "selected_variant": selected_variant,
354
+ "stem_list": stem_list
355
  }
356
 
357
+ def setup_section_event_handlers(section_name, section_ui, selected_variants_display):
358
  """Setup event handlers for a given section."""
359
  section_type = gr.State(section_name)
360
 
 
371
  section_ui["status"],
372
  *section_ui["variant_audio"],
373
  section_ui["descriptions"],
374
+ section_ui["stem_list"]
375
  ],
376
  )
377
 
 
381
  select_btn.change(
382
  fn=select_variant,
383
  inputs=[section_type, variant_num, gr.State(False)],
384
+ outputs=[section_ui["status"], section_ui["selected_variant"]],
385
+ )
386
+
387
+ # Update selected variants display whenever a variant is selected
388
+ def update_selected_variants_display():
389
+ selected = {}
390
+ for s in SELECTED_VARIANTS:
391
+ if s in ALL_VARIANTS:
392
+ for v in range(1, 5):
393
+ variant_key = f"variant{v}"
394
+ if variant_key in ALL_VARIANTS[s]:
395
+ if s not in selected:
396
+ selected[s] = {}
397
+ selected[s]["Selected Variant"] = ALL_VARIANTS[s][variant_key].get("description", f"Variant {v}")
398
+ return json.dumps(selected, indent=2)
399
+
400
+ select_btn.change(
401
+ fn=update_selected_variants_display,
402
+ inputs=[],
403
+ outputs=[selected_variants_display],
404
  )
405
 
406
 
 
444
  # Editable diagram with progress indicator
445
  with gr.Row():
446
  gr.Markdown("⏳ In Progress: Adjusting sections...")
447
+
448
  edm_arrangement_tab()
449
 
450
  with gr.Tab("2. Generate Section Variants"):
451
+ gr.Markdown("### Generate and Select Variants for Each Section")
452
+ gr.Markdown("Generate variants for each section and select which one to use in the final track")
453
+
454
+ # Create UI for sections dynamically based on final_arrangement.json
455
  section_uis = {}
456
+
457
+ # Create selected variants display first
458
+ selected_variants_display = gr.JSON(
459
+ label="Selected Variants",
460
+ value={"No variants selected yet": "Generate and select variants in sections below"}
461
+ )
462
+
463
  for section_name, params in sections.items():
464
+ section_uis[section_name] = create_section_ui(section_name, params)
465
+ setup_section_event_handlers(section_name, section_uis[section_name], selected_variants_display)
 
 
466
 
467
  with gr.Tab("3. Create Full Track"):
468
  with gr.Row():
 
482
  )
483
 
484
  gr.Markdown("### Sections to Include")
485
+ section_checkboxes = {}
486
+ for section_name in sections.keys():
487
+ section_checkboxes[section_name] = gr.Checkbox(
488
+ label=f"Include {section_name.capitalize()}",
489
+ value=True
490
+ )
491
+
492
+ gr.Markdown("### Selected Variants Summary")
493
+ selected_variants_display = gr.JSON(
494
+ label="Selected Variants",
495
+ value={"No variants selected yet": "Generate and select variants in Section 2"}
496
+ )
497
 
498
  generate_track_btn = gr.Button(
499
  "Generate Full Track", variant="primary", scale=2
 
517
  inputs=[
518
  crossfade_ms,
519
  output_track_name,
520
+ *[section_checkboxes[section] for section in sections.keys()]
 
 
 
 
521
  ],
522
  outputs=[track_status, full_track_audio, track_summary],
523
  )
final_arrangement.json CHANGED
@@ -2,46 +2,81 @@
2
  "intro": {
3
  "bpm": 120,
4
  "bars": 8,
5
- "p": 0.3
 
 
 
 
 
6
  },
7
  "verse1": {
8
- "bpm": 40,
9
  "bars": 32,
10
- "p": 0.5
 
 
 
 
 
11
  },
12
- "pre_chorus": {
13
- "bpm": 60,
14
  "bars": 16,
15
- "p": 0.5
 
 
 
 
 
16
  },
17
  "drop": {
18
  "bpm": 120,
19
  "bars": 16,
20
- "p": 0.7
 
 
 
 
 
21
  },
22
  "breakdown": {
23
  "bpm": 120,
24
  "bars": 16,
25
- "p": 0.6
 
 
 
 
 
26
  },
27
  "bridge": {
28
  "bpm": 60,
29
  "bars": 32,
30
- "p": 0.5
31
- },
32
- "buildup": {
33
- "bpm": 120,
34
- "bars": 16,
35
- "p": 0.4
36
  },
37
  "drop2": {
38
  "bpm": 100,
39
  "bars": 64,
40
- "p": 0.5
 
 
 
 
 
41
  },
42
  "outro": {
43
  "bpm": 120,
44
  "bars": 8,
45
- "p": 0.3
 
 
 
 
 
46
  }
47
  }
 
2
  "intro": {
3
  "bpm": 120,
4
  "bars": 8,
5
+ "p": 0.3,
6
+ "volume_automation": [
7
+ 9.6,
8
+ 16
9
+ ],
10
+ "curve": "Linear"
11
  },
12
  "verse1": {
13
+ "bpm": 48,
14
  "bars": 32,
15
+ "p": 0.5,
16
+ "volume_automation": [
17
+ 48,
18
+ 48
19
+ ],
20
+ "curve": "Flat"
21
  },
22
+ "buildup": {
23
+ "bpm": 120,
24
  "bars": 16,
25
+ "p": 0.4,
26
+ "volume_automation": [
27
+ 38.4,
28
+ 64
29
+ ],
30
+ "curve": "Linear"
31
  },
32
  "drop": {
33
  "bpm": 120,
34
  "bars": 16,
35
+ "p": 0.7,
36
+ "volume_automation": [
37
+ 100,
38
+ 100
39
+ ],
40
+ "curve": "Flat"
41
  },
42
  "breakdown": {
43
  "bpm": 120,
44
  "bars": 16,
45
+ "p": 0.6,
46
+ "volume_automation": [
47
+ 40,
48
+ 24.0
49
+ ],
50
+ "curve": "-ve Linear"
51
  },
52
  "bridge": {
53
  "bpm": 60,
54
  "bars": 32,
55
+ "p": 0.5,
56
+ "volume_automation": [
57
+ 60,
58
+ 60
59
+ ],
60
+ "curve": "Flat"
61
  },
62
  "drop2": {
63
  "bpm": 100,
64
  "bars": 64,
65
+ "p": 0.5,
66
+ "volume_automation": [
67
+ 100,
68
+ 100
69
+ ],
70
+ "curve": "Flat"
71
  },
72
  "outro": {
73
  "bpm": 120,
74
  "bars": 8,
75
+ "p": 0.3,
76
+ "volume_automation": [
77
+ 40,
78
+ 24.0
79
+ ],
80
+ "curve": "-ve Linear"
81
  }
82
  }
temp_choose.py CHANGED
@@ -1,8 +1,16 @@
1
  import gradio as gr
2
  import plotly.graph_objects as go
3
  import numpy as np
 
4
  import json
5
 
 
 
 
 
 
 
 
6
  # Three base arrangements
7
  arrangements = {
8
  "High Energy Flow": [
@@ -62,7 +70,8 @@ def editable_diagram(section_data):
62
  y = np.full(len(x), tempo)
63
  fig.add_trace(
64
  go.Scatter(
65
- x=x, y=y, fill="tozeroy", name=name, mode="lines", line_shape="hv"
 
66
  )
67
  )
68
  total_bars = max(total_bars, bar + length)
@@ -71,7 +80,12 @@ def editable_diagram(section_data):
71
  title="EDM Arrangement Energy Curve",
72
  xaxis_title="Bar",
73
  yaxis_title="Volume (Energy)",
74
- xaxis=dict(range=[0, total_bars + 4]),
 
 
 
 
 
75
  yaxis=dict(range=[0, 100]),
76
  height=400,
77
  )
@@ -112,6 +126,7 @@ def finalise():
112
  "Verse 1": "verse1",
113
  "Pre-Chorus": "pre_chorus",
114
  "Bridge": "bridge",
 
115
  # Add more mappings as needed
116
  }
117
  # Example default values for bpm, bars, p (customize as needed)
@@ -124,16 +139,35 @@ def finalise():
124
  # Add more as needed
125
  }
126
  result = {}
127
- for bar, tempo, name, length, curve in arrangement:
 
 
 
128
  key = section_key_map.get(name, name.lower().replace(' ', '_'))
129
- # You can customize how you set bpm, bars, p here
130
  params = default_section_params.get(key, {"bpm": tempo, "bars": length, "p": 0.5})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  result[key] = params
132
  with open("final_arrangement.json", "w") as f:
133
  json.dump(result, f, indent=2)
134
  return json.dumps(result, indent=2)
135
 
136
 
 
 
 
137
  # with gr.Blocks() as iface:
138
  # gr.Markdown("# 🌚 Interactive EDM Arrangement Tool")
139
 
@@ -144,9 +178,9 @@ def finalise():
144
  # label="Choose Arrangement Variation",
145
  # )
146
 
147
- # out_plot = gr.Plot(label="Arrangement Diagram")
148
  # variation.change(fn=load_variation, inputs=variation, outputs=out_plot)
149
- # out_plot.value = editable_diagram(arrangement)
150
 
151
  # with gr.Accordion("🎻 Edit Section Parameters", open=False):
152
  # for i, (bar, tempo, name, length, curve) in enumerate(arrangement):
 
1
  import gradio as gr
2
  import plotly.graph_objects as go
3
  import numpy as np
4
+ import logging
5
  import json
6
 
7
+ logger = logging.getLogger(__name__)
8
+ logger.setLevel(logging.INFO)
9
+ file_handler = logging.FileHandler('temp_choose.log')
10
+ file_handler.setLevel(logging.INFO)
11
+ file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
12
+ logger.addHandler(file_handler)
13
+
14
  # Three base arrangements
15
  arrangements = {
16
  "High Energy Flow": [
 
70
  y = np.full(len(x), tempo)
71
  fig.add_trace(
72
  go.Scatter(
73
+ x=x, y=y, fill="tozeroy", name=name, mode="lines", line_shape="hv",
74
+ text=[name] * len(x), textposition="top center"
75
  )
76
  )
77
  total_bars = max(total_bars, bar + length)
 
80
  title="EDM Arrangement Energy Curve",
81
  xaxis_title="Bar",
82
  yaxis_title="Volume (Energy)",
83
+ xaxis=dict(
84
+ range=[0, total_bars + 4],
85
+ tickmode='linear',
86
+ tick0=0,
87
+ dtick=4
88
+ ),
89
  yaxis=dict(range=[0, 100]),
90
  height=400,
91
  )
 
126
  "Verse 1": "verse1",
127
  "Pre-Chorus": "pre_chorus",
128
  "Bridge": "bridge",
129
+ "Pre-Verse": "pre_verse",
130
  # Add more mappings as needed
131
  }
132
  # Example default values for bpm, bars, p (customize as needed)
 
139
  # Add more as needed
140
  }
141
  result = {}
142
+
143
+ logger.info(f"Arrangement: {arrangement}")
144
+ print(f"Arrangement: {arrangement}")
145
+ for starting_bar, tempo, name, length, curve in arrangement:
146
  key = section_key_map.get(name, name.lower().replace(' ', '_'))
 
147
  params = default_section_params.get(key, {"bpm": tempo, "bars": length, "p": 0.5})
148
+
149
+ # Volume automation logic
150
+ if curve.lower() == "flat":
151
+ volume_automation = [tempo, tempo]
152
+ elif curve.lower() == "linear":
153
+ volume_automation = [round(tempo * 0.6, 2), tempo]
154
+ elif curve.lower() in ["-ve linear", "negative linear"]:
155
+ volume_automation = [tempo, round(tempo * 0.6, 2)]
156
+ else:
157
+ volume_automation = [tempo, tempo] # default to flat
158
+
159
+ params["volume_automation"] = volume_automation
160
+ params["curve"] = curve # Optionally save the curve type too
161
+
162
  result[key] = params
163
  with open("final_arrangement.json", "w") as f:
164
  json.dump(result, f, indent=2)
165
  return json.dumps(result, indent=2)
166
 
167
 
168
+ # To be commented, as UI is in different file
169
+ # Commented out for now
170
+
171
  # with gr.Blocks() as iface:
172
  # gr.Markdown("# 🌚 Interactive EDM Arrangement Tool")
173
 
 
178
  # label="Choose Arrangement Variation",
179
  # )
180
 
181
+ # out_plot = gr.Plot(label="Arrangement Diagram", value=load_variation("High Energy Flow"))
182
  # variation.change(fn=load_variation, inputs=variation, outputs=out_plot)
183
+ # iface.load(fn=load_variation, inputs=[variation], outputs=[out_plot])
184
 
185
  # with gr.Accordion("🎻 Edit Section Parameters", open=False):
186
  # for i, (bar, tempo, name, length, curve) in enumerate(arrangement):
utils.py CHANGED
@@ -11,21 +11,14 @@ import logging
11
 
12
  from dotenv import load_dotenv
13
  import random
14
- from temp_choose import (
15
- arrangements,
16
- arrangement,
17
- shift_arrangement,
18
- editable_diagram,
19
- update_section,
20
- insert_section,
21
- finalise,
22
- load_variation,
23
- )
24
 
25
  load_dotenv()
26
 
27
  logger = logging.getLogger(__name__)
28
  logger.setLevel(logging.INFO)
 
 
29
 
30
  def make_groq_call(stems, song_name, p, section_type=None, bpm=120, bars=16):
31
  """
@@ -156,15 +149,15 @@ def get_stems(folder):
156
 
157
  def apply_audio_operation(audio, operation, value):
158
  """Apply various audio operations to an AudioSegment"""
159
- if operation == "low_pass_filter":
160
  return low_pass_filter(audio, value)
161
- elif operation == "high_pass_filter":
162
  return high_pass_filter(audio, value)
163
- elif operation == "fade_in":
164
  return audio.fade_in(value)
165
- elif operation == "fade_out":
166
  return audio.fade_out(value)
167
- elif operation == "reverb":
168
  # Simple reverb simulation by adding delayed and attenuated copies
169
  result = audio
170
  for delay in [50, 100, 150, 200]:
@@ -172,20 +165,20 @@ def apply_audio_operation(audio, operation, value):
172
  delayed = AudioSegment.silent(duration=delay) + attenuated
173
  result = result.overlay(delayed)
174
  return result
175
- elif operation == "delay":
176
  # Simulate delay by adding a delayed copy
177
  result = audio
178
  delayed = AudioSegment.silent(duration=value) + (audio - 6) # -6dB for the echo
179
  return result.overlay(delayed)
180
- elif operation == "distortion":
181
  # Simulate distortion by adding some limiting/clipping
182
  gain = 1.0 + (value * 5) # Boost the gain based on distortion value
183
  return audio + (gain) # Add gain in dB
184
- elif operation == "pitch_shift":
185
  # Note: pydub doesn't natively support pitch shifting
186
  print(f"Warning: Pitch shift not implemented, value: {value}")
187
  return audio
188
- elif operation == "volume":
189
  # Adjust volume by dB
190
  return audio + value
191
  return audio
@@ -306,18 +299,35 @@ def generate_section_variants(
306
 
307
  progress(0.2, desc=f"Generating structure and effects for variants of {section_type}...")
308
  # Create each variant
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  variants = {}
310
  for variant_key in progress.tqdm(llm_response, desc="Getting variants as per AI arranegments..."):
311
  if variant_key.startswith("variant"):
312
  variant_config = llm_response[variant_key]
 
313
  audio = create_section_from_json(variant_config, audio_stems)
314
  description = variant_config.get(
315
  "description", f"Variant {variant_key[-1]}"
316
  )
 
317
  variants[variant_key] = {
318
  "audio": audio,
319
  "description": description,
320
  "config": variant_config,
 
321
  }
322
 
323
 
@@ -434,19 +444,20 @@ def export_section_variants(variants, output_folder, section_name):
434
 
435
 
436
  def edm_arrangement_tab():
437
- with gr.Tab("🎢 EDM Arranger"):
 
438
  gr.Markdown("# 🌚 Interactive EDM Arrangement Tool")
439
 
440
- out_plot = gr.Plot(label="Arrangement Diagram")
441
-
442
  with gr.Row():
443
  variation = gr.Radio(
444
  choices=list(arrangements.keys()),
445
  value="High Energy Flow",
446
  label="Choose Arrangement Variation",
447
  )
448
- variation.change(fn=load_variation, inputs=variation, outputs=out_plot)
449
- out_plot.value = editable_diagram(arrangement)
 
 
450
 
451
  with gr.Accordion("🎻 Edit Section Parameters", open=False):
452
  for i, (bar, tempo, name, length, curve) in enumerate(arrangement):
@@ -486,9 +497,7 @@ def edm_arrangement_tab():
486
  new_tempo = gr.Slider(minimum=20, maximum=100, value=50, label="Volume")
487
  new_length = gr.Slider(minimum=1, maximum=64, value=8, label="Length")
488
  new_curve = gr.Radio(
489
- choices=["Flat", "Linear", "-ve Linear"],
490
- value="Flat",
491
- label="Curve Type",
492
  )
493
  insert_btn = gr.Button("Insert Section")
494
  insert_btn.click(
@@ -501,3 +510,6 @@ def edm_arrangement_tab():
501
  final_btn = gr.Button("Finalise and Export JSON")
502
  final_output = gr.Textbox(label="Final Arrangement JSON", lines=15)
503
  final_btn.click(fn=finalise, outputs=final_output)
 
 
 
 
11
 
12
  from dotenv import load_dotenv
13
  import random
14
+ from temp_choose import *
 
 
 
 
 
 
 
 
 
15
 
16
  load_dotenv()
17
 
18
  logger = logging.getLogger(__name__)
19
  logger.setLevel(logging.INFO)
20
+ logger.addHandler(logging.StreamHandler())
21
+ logger.addHandler(logging.FileHandler("log.txt"))
22
 
23
  def make_groq_call(stems, song_name, p, section_type=None, bpm=120, bars=16):
24
  """
 
149
 
150
  def apply_audio_operation(audio, operation, value):
151
  """Apply various audio operations to an AudioSegment"""
152
+ if operation == "low_pass_filter" and isinstance(value, float):
153
  return low_pass_filter(audio, value)
154
+ elif operation == "high_pass_filter" and isinstance(value, float):
155
  return high_pass_filter(audio, value)
156
+ elif operation == "fade_in" and isinstance(value, int):
157
  return audio.fade_in(value)
158
+ elif operation == "fade_out" and isinstance(value, int):
159
  return audio.fade_out(value)
160
+ elif operation == "reverb" and isinstance(value, float):
161
  # Simple reverb simulation by adding delayed and attenuated copies
162
  result = audio
163
  for delay in [50, 100, 150, 200]:
 
165
  delayed = AudioSegment.silent(duration=delay) + attenuated
166
  result = result.overlay(delayed)
167
  return result
168
+ elif operation == "delay" and isinstance(value, int):
169
  # Simulate delay by adding a delayed copy
170
  result = audio
171
  delayed = AudioSegment.silent(duration=value) + (audio - 6) # -6dB for the echo
172
  return result.overlay(delayed)
173
+ elif operation == "distortion" and isinstance(value, float):
174
  # Simulate distortion by adding some limiting/clipping
175
  gain = 1.0 + (value * 5) # Boost the gain based on distortion value
176
  return audio + (gain) # Add gain in dB
177
+ elif operation == "pitch_shift" and isinstance(value, float):
178
  # Note: pydub doesn't natively support pitch shifting
179
  print(f"Warning: Pitch shift not implemented, value: {value}")
180
  return audio
181
+ elif operation == "volume" and isinstance(value, float):
182
  # Adjust volume by dB
183
  return audio + value
184
  return audio
 
299
 
300
  progress(0.2, desc=f"Generating structure and effects for variants of {section_type}...")
301
  # Create each variant
302
+ # hERE IS tHE validation for the LLM RESPONSE
303
+ if not isinstance(llm_response, dict):
304
+ logger.error(f"Invalid LLM response: {llm_response}")
305
+
306
+
307
+ # Check if the response is a valid JSON object
308
+ try:
309
+ if isinstance(llm_response, str):
310
+ llm_response = json.loads(llm_response)
311
+ elif isinstance(llm_response, dict):
312
+ llm_response = llm_response
313
+ except json.JSONDecodeError:
314
+ logger.error(f"Tried Converting the LLM response to JSON, but failed: {llm_response}")
315
+
316
  variants = {}
317
  for variant_key in progress.tqdm(llm_response, desc="Getting variants as per AI arranegments..."):
318
  if variant_key.startswith("variant"):
319
  variant_config = llm_response[variant_key]
320
+ logger.info(f" gsv: Variant config: {variant_config}")
321
  audio = create_section_from_json(variant_config, audio_stems)
322
  description = variant_config.get(
323
  "description", f"Variant {variant_key[-1]}"
324
  )
325
+ list_stems = variant_config.get("stems", [])
326
  variants[variant_key] = {
327
  "audio": audio,
328
  "description": description,
329
  "config": variant_config,
330
+ "stems": list_stems
331
  }
332
 
333
 
 
444
 
445
 
446
  def edm_arrangement_tab():
447
+
448
+ with gr.Blocks() as iface:
449
  gr.Markdown("# 🌚 Interactive EDM Arrangement Tool")
450
 
 
 
451
  with gr.Row():
452
  variation = gr.Radio(
453
  choices=list(arrangements.keys()),
454
  value="High Energy Flow",
455
  label="Choose Arrangement Variation",
456
  )
457
+
458
+ out_plot = gr.Plot(label="Arrangement Diagram", value=load_variation("High Energy Flow"))
459
+ variation.change(fn=load_variation, inputs=variation, outputs=out_plot)
460
+ iface.load(fn=load_variation, inputs=[variation], outputs=[out_plot])
461
 
462
  with gr.Accordion("🎻 Edit Section Parameters", open=False):
463
  for i, (bar, tempo, name, length, curve) in enumerate(arrangement):
 
497
  new_tempo = gr.Slider(minimum=20, maximum=100, value=50, label="Volume")
498
  new_length = gr.Slider(minimum=1, maximum=64, value=8, label="Length")
499
  new_curve = gr.Radio(
500
+ choices=["Flat", "Linear", "-ve Linear"], value="Flat", label="Curve Type"
 
 
501
  )
502
  insert_btn = gr.Button("Insert Section")
503
  insert_btn.click(
 
510
  final_btn = gr.Button("Finalise and Export JSON")
511
  final_output = gr.Textbox(label="Final Arrangement JSON", lines=15)
512
  final_btn.click(fn=finalise, outputs=final_output)
513
+
514
+
515
+