SHIKARICHACHA commited on
Commit
712a483
·
verified ·
1 Parent(s): 4a0045e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -14
app.py CHANGED
@@ -302,16 +302,33 @@ def midi_to_mp3(midi_obj: MidiFile, instrument: str = "Trumpet") -> Tuple[str, f
302
  def get_fallback_exercise(instrument: str, level: str, key: str,
303
  time_sig: str, measures: int) -> str:
304
  key_notes = {
305
- "C Major": ["C4", "D4", "E4", "G4"],
306
- "G Major": ["G4", "A4", "B4", "D5"],
307
- "D Major": ["D4", "E4", "F#4", "A4"],
308
- "F Major": ["F4", "G4", "A4", "C5"],
309
- "Bb Major": ["Bb3", "C4", "D4", "F4"],
310
- "A Minor": ["A3", "B3", "C4", "D4", "E4", "G4"],
311
- "E Minor": ["E3", "F#3", "G3", "A3", "B3", "D4"],
312
  }
313
 
 
 
 
 
 
314
  notes = key_notes.get(key, key_notes["C Major"])
 
 
 
 
 
 
 
 
 
 
 
 
315
  numerator, denominator = map(int, time_sig.split('/'))
316
 
317
  # Calculate units based on 8th notes
@@ -329,14 +346,30 @@ def get_fallback_exercise(instrument: str, level: str, key: str,
329
  cumulative = 0
330
  current_units = 0
331
 
332
- while current_units < target_units:
333
- note = random.choice(notes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  dur = random.choice(rhythm)
335
 
336
- # Don't exceed target
337
- if current_units + dur > target_units:
338
- dur = target_units - current_units
339
- if dur == 0:
340
  break
341
 
342
  cumulative += dur
@@ -347,6 +380,16 @@ def get_fallback_exercise(instrument: str, level: str, key: str,
347
  "cumulative_duration": cumulative
348
  })
349
 
 
 
 
 
 
 
 
 
 
 
350
  return json.dumps(result)
351
 
352
  def get_style_based_on_level(level: str) -> str:
@@ -399,9 +442,19 @@ def query_mistral(prompt: str, instrument: str, level: str, key: str,
399
  else:
400
  style = get_style_based_on_level(level)
401
  technique = get_technique_based_on_level(level)
 
 
 
 
 
 
 
 
 
 
402
  user_prompt = (
403
  f"Create a {style} {instrument.lower()} exercise in {key} with {time_sig} time signature "
404
- f"{technique} for a {level.lower()} player. {duration_constraint} "
405
  "Output ONLY a JSON array of objects with the following structure: "
406
  "[{{'note': string, 'duration': integer, 'cumulative_duration': integer}}] "
407
  "Use standard note names (e.g., \"Bb4\", \"F#5\"). Monophonic only. "
 
302
  def get_fallback_exercise(instrument: str, level: str, key: str,
303
  time_sig: str, measures: int) -> str:
304
  key_notes = {
305
+ "C Major": ["C4", "D4", "E4", "F4", "G4", "A4", "B4"],
306
+ "G Major": ["G3", "A3", "B3", "C4", "D4", "E4", "F#4"],
307
+ "D Major": ["D4", "E4", "F#4", "G4", "A4", "B4", "C#5"],
308
+ "F Major": ["F3", "G3", "A3", "Bb3", "C4", "D4", "E4"],
309
+ "Bb Major": ["Bb3", "C4", "D4", "Eb4", "F4", "G4", "A4"],
310
+ "A Minor": ["A3", "B3", "C4", "D4", "E4", "F4", "G4"],
311
+ "E Minor": ["E3", "F#3", "G3", "A3", "B3", "C4", "D4"],
312
  }
313
 
314
+ # Get fundamental note from key signature
315
+ fundamental_note = key.split()[0] # Gets 'C' from 'C Major' or 'A' from 'A Minor'
316
+ is_major = "Major" in key
317
+
318
+ # Get notes for the key
319
  notes = key_notes.get(key, key_notes["C Major"])
320
+
321
+ # Find fundamental note with octave for ending
322
+ fundamental_with_octave = None
323
+ for note in notes:
324
+ if note.startswith(fundamental_note):
325
+ fundamental_with_octave = note
326
+ break
327
+
328
+ # If not found, use the first note (should not happen with our key definitions)
329
+ if not fundamental_with_octave:
330
+ fundamental_with_octave = notes[0]
331
+
332
  numerator, denominator = map(int, time_sig.split('/'))
333
 
334
  # Calculate units based on 8th notes
 
346
  cumulative = 0
347
  current_units = 0
348
 
349
+ # Reserve at least 2 units for the final note
350
+ final_note_duration = min(4, max(2, rhythm[0])) # Between 2 and 4 units
351
+ available_units = target_units - final_note_duration
352
+
353
+ # Generate notes until we reach the available units
354
+ while current_units < available_units:
355
+ # Avoid minor 7th in major keys
356
+ if is_major:
357
+ # Filter out minor 7th notes (e.g., Bb in C major)
358
+ available_notes = [n for n in notes if not (n.startswith("Bb") and key == "C Major") and
359
+ not (n.startswith("F") and key == "G Major") and
360
+ not (n.startswith("C") and key == "D Major") and
361
+ not (n.startswith("Eb") and key == "F Major") and
362
+ not (n.startswith("Ab") and key == "Bb Major")]
363
+ else:
364
+ available_notes = notes
365
+
366
+ note = random.choice(available_notes)
367
  dur = random.choice(rhythm)
368
 
369
+ # Don't exceed available units
370
+ if current_units + dur > available_units:
371
+ dur = available_units - current_units
372
+ if dur <= 0:
373
  break
374
 
375
  cumulative += dur
 
380
  "cumulative_duration": cumulative
381
  })
382
 
383
+ # Add the final note (fundamental of the key)
384
+ final_duration = target_units - current_units
385
+ if final_duration > 0:
386
+ cumulative += final_duration
387
+ result.append({
388
+ "note": fundamental_with_octave,
389
+ "duration": final_duration,
390
+ "cumulative_duration": cumulative
391
+ })
392
+
393
  return json.dumps(result)
394
 
395
  def get_style_based_on_level(level: str) -> str:
 
442
  else:
443
  style = get_style_based_on_level(level)
444
  technique = get_technique_based_on_level(level)
445
+ # Extract fundamental note from key signature
446
+ fundamental_note = key.split()[0] # Gets 'C' from 'C Major' or 'A' from 'A Minor'
447
+ is_major = "Major" in key
448
+
449
+ # Create additional musical constraints
450
+ key_constraints = (
451
+ f"The exercise MUST end on the fundamental note of the key ({fundamental_note}). "
452
+ f"{'' if not is_major else 'For this major key, avoid using the minor 7th degree.'}"
453
+ )
454
+
455
  user_prompt = (
456
  f"Create a {style} {instrument.lower()} exercise in {key} with {time_sig} time signature "
457
+ f"{technique} for a {level.lower()} player. {duration_constraint} {key_constraints} "
458
  "Output ONLY a JSON array of objects with the following structure: "
459
  "[{{'note': string, 'duration': integer, 'cumulative_duration': integer}}] "
460
  "Use standard note names (e.g., \"Bb4\", \"F#5\"). Monophonic only. "