fluidstudio

Programmable music notation — write music as text, compile to MIDI + WAV stems + mix
Log | Files | Refs | README

fps.py (1690B)


      1 """BPM to FPS calculator for clean frame sync.
      2 
      3 Frame sync formula:
      4 - fps × 60 = fpm (frames per minute)
      5 - BPM = beats per minute
      6 - frames_per_beat = fpm / BPM = (fps × 60) / BPM
      7 
      8 For clean sync: frames_per_beat must be integer.
      9 Base fps = BPM / 5 (gives 12 frames/beat).
     10 If fps < 24, double resolution to maintain fluidity.
     11 """
     12 
     13 
     14 def bpm_to_fps(bpm: float, min_fps: int = 24) -> dict:
     15     """Calculate clean fps from BPM.
     16 
     17     Returns dict with fps, frames_per_beat, and multiplier used.
     18     """
     19     # Base fps for clean sync (12 frames/beat)
     20     fps_base = bpm / 5
     21 
     22     # Double resolution if below min_fps
     23     multiplier = 1
     24     fps = fps_base
     25     while fps < min_fps:
     26         multiplier *= 2
     27         fps = fps_base * multiplier
     28 
     29     frames_per_beat = (fps * 60) / bpm
     30 
     31     return {
     32         "bpm": bpm,
     33         "fps": fps,
     34         "frames_per_beat": int(frames_per_beat),
     35         "multiplier": multiplier,
     36         "fpm": int(fps * 60),
     37     }
     38 
     39 
     40 def print_fps_table(bpm_range: range = range(60, 181, 10)):
     41     """Print fps table for common BPMs."""
     42     print(f"{'BPM':>5} {'FPS':>5} {'FPB':>5} {'Mult':>5} {'FPM':>8}")
     43     print("-" * 35)
     44     for bpm in bpm_range:
     45         r = bpm_to_fps(bpm)
     46         print(f"{r['bpm']:>5} {r['fps']:>5.0f} {r['frames_per_beat']:>5} {r['multiplier']:>5} {r['fpm']:>8}")
     47 
     48 
     49 if __name__ == "__main__":
     50     import sys
     51 
     52     if len(sys.argv) > 1:
     53         bpm = float(sys.argv[1])
     54         r = bpm_to_fps(bpm)
     55         print(f"BPM: {r['bpm']}")
     56         print(f"FPS: {r['fps']}")
     57         print(f"Frames/beat: {r['frames_per_beat']}")
     58         print(f"Resolution multiplier: {r['multiplier']}x")
     59         print(f"FPM: {r['fpm']}")
     60     else:
     61         print_fps_table()