ChuxiJ commited on
Commit
22b5dfd
·
1 Parent(s): 1ff710f

fix: duration parse

Browse files
Files changed (1) hide show
  1. acestep/api_server.py +76 -27
acestep/api_server.py CHANGED
@@ -414,15 +414,42 @@ def create_app() -> FastAPI:
414
  return None if fv >= 1.0 else fv
415
 
416
  def _maybe_fill_from_metadata(current: GenerateMusicRequest, meta: Dict[str, Any]) -> tuple[Optional[int], str, str, Optional[float]]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  # Fill only when user did not provide values
418
  bpm_val = current.bpm
419
  if bpm_val is None:
420
- try:
421
- m = meta.get("bpm")
422
- if m not in (None, "", "N/A"):
423
- bpm_val = int(float(m))
424
- except Exception:
425
- bpm_val = current.bpm
426
 
427
  key_scale_val = current.key_scale
428
  if not key_scale_val:
@@ -439,19 +466,18 @@ def create_app() -> FastAPI:
439
  dur_val = current.audio_duration
440
  if dur_val is None:
441
  m = meta.get("duration", meta.get("audio_duration"))
442
- try:
443
- if m not in (None, "", "N/A"):
444
- dur_val = float(m)
445
- if dur_val <= 0:
446
- dur_val = None
447
- # Avoid truncating lyrical songs when LM predicts a very short duration.
448
- # (Users can still force a short duration by explicitly setting `audio_duration`.)
449
- if dur_val is not None and (current.lyrics or "").strip():
450
- min_dur = float(os.getenv("ACESTEP_LM_MIN_DURATION_SECONDS", "30"))
451
- if dur_val < min_dur:
452
- dur_val = None
453
- except Exception:
454
- dur_val = current.audio_duration
455
 
456
  return bpm_val, key_scale_val, time_sig_val, dur_val
457
 
@@ -476,6 +502,35 @@ def create_app() -> FastAPI:
476
  return float(min(max(est, min_dur), max_dur))
477
 
478
  def _extract_lm_fields(meta: Dict[str, Any]) -> Dict[str, Any]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
  def _none_if_na(v: Any) -> Any:
480
  if v is None:
481
  return None
@@ -486,16 +541,10 @@ def create_app() -> FastAPI:
486
  out: Dict[str, Any] = {}
487
 
488
  bpm_raw = _none_if_na(meta.get("bpm"))
489
- try:
490
- out["bpm"] = int(float(bpm_raw)) if bpm_raw is not None else None
491
- except Exception:
492
- out["bpm"] = None
493
 
494
  dur_raw = _none_if_na(meta.get("duration"))
495
- try:
496
- out["duration"] = float(dur_raw) if dur_raw is not None else None
497
- except Exception:
498
- out["duration"] = None
499
 
500
  genres_raw = _none_if_na(meta.get("genres"))
501
  out["genres"] = str(genres_raw) if genres_raw is not None else None
 
414
  return None if fv >= 1.0 else fv
415
 
416
  def _maybe_fill_from_metadata(current: GenerateMusicRequest, meta: Dict[str, Any]) -> tuple[Optional[int], str, str, Optional[float]]:
417
+ def _parse_first_float(v: Any) -> Optional[float]:
418
+ if v is None:
419
+ return None
420
+ if isinstance(v, (int, float)):
421
+ return float(v)
422
+ s = str(v).strip()
423
+ if not s or s.upper() == "N/A":
424
+ return None
425
+ try:
426
+ return float(s)
427
+ except Exception:
428
+ pass
429
+ m = re.search(r"[-+]?\d*\.?\d+", s)
430
+ if not m:
431
+ return None
432
+ try:
433
+ return float(m.group(0))
434
+ except Exception:
435
+ return None
436
+
437
+ def _parse_first_int(v: Any) -> Optional[int]:
438
+ fv = _parse_first_float(v)
439
+ if fv is None:
440
+ return None
441
+ try:
442
+ return int(round(fv))
443
+ except Exception:
444
+ return None
445
+
446
  # Fill only when user did not provide values
447
  bpm_val = current.bpm
448
  if bpm_val is None:
449
+ m = meta.get("bpm")
450
+ parsed = _parse_first_int(m)
451
+ if parsed is not None and parsed > 0:
452
+ bpm_val = parsed
 
 
453
 
454
  key_scale_val = current.key_scale
455
  if not key_scale_val:
 
466
  dur_val = current.audio_duration
467
  if dur_val is None:
468
  m = meta.get("duration", meta.get("audio_duration"))
469
+ parsed = _parse_first_float(m)
470
+ if parsed is not None:
471
+ dur_val = float(parsed)
472
+ if dur_val <= 0:
473
+ dur_val = None
474
+
475
+ # Avoid truncating lyrical songs when LM predicts a very short duration.
476
+ # (Users can still force a short duration by explicitly setting `audio_duration`.)
477
+ if dur_val is not None and (current.lyrics or "").strip():
478
+ min_dur = float(os.getenv("ACESTEP_LM_MIN_DURATION_SECONDS", "30"))
479
+ if dur_val < min_dur:
480
+ dur_val = None
 
481
 
482
  return bpm_val, key_scale_val, time_sig_val, dur_val
483
 
 
502
  return float(min(max(est, min_dur), max_dur))
503
 
504
  def _extract_lm_fields(meta: Dict[str, Any]) -> Dict[str, Any]:
505
+ def _parse_first_float(v: Any) -> Optional[float]:
506
+ if v is None:
507
+ return None
508
+ if isinstance(v, (int, float)):
509
+ return float(v)
510
+ s = str(v).strip()
511
+ if not s or s.upper() == "N/A":
512
+ return None
513
+ try:
514
+ return float(s)
515
+ except Exception:
516
+ pass
517
+ m = re.search(r"[-+]?\d*\.?\d+", s)
518
+ if not m:
519
+ return None
520
+ try:
521
+ return float(m.group(0))
522
+ except Exception:
523
+ return None
524
+
525
+ def _parse_first_int(v: Any) -> Optional[int]:
526
+ fv = _parse_first_float(v)
527
+ if fv is None:
528
+ return None
529
+ try:
530
+ return int(round(fv))
531
+ except Exception:
532
+ return None
533
+
534
  def _none_if_na(v: Any) -> Any:
535
  if v is None:
536
  return None
 
541
  out: Dict[str, Any] = {}
542
 
543
  bpm_raw = _none_if_na(meta.get("bpm"))
544
+ out["bpm"] = _parse_first_int(bpm_raw)
 
 
 
545
 
546
  dur_raw = _none_if_na(meta.get("duration"))
547
+ out["duration"] = _parse_first_float(dur_raw)
 
 
 
548
 
549
  genres_raw = _none_if_na(meta.get("genres"))
550
  out["genres"] = str(genres_raw) if genres_raw is not None else None