Push Beats/Seconds through the remaining controller methods that took a bare
f64 and let the audio thread wrap it in a newtype, so the caller's domain is
now compiler-checked (the seam that hid the recording bug):
- seek -> Seconds
- set_trim_start/set_trim_end -> Seconds / Option<Seconds> (metatrack, always seconds)
- add_midi_note, add_loaded_midi_clip, update_midi_clip_notes -> Beats
- add_automation_point, remove_automation_point, automation_add_keyframe,
automation_remove_keyframe -> Beats
Command enums stay raw f64 transport; only the public signatures + call sites
change. No behavior change — every caller already passed the right domain, this
just makes it enforced.
Two deliberate exceptions, documented in place:
- trim_clip stays f64: the TrimClip handler interprets it as Seconds for a
sampled-audio clip but Beats for a MIDI clip, so no single newtype fits;
callers pass the clip's own trim value, which matches its content domain.
- The piano-roll MIDI note model stays f64 internally (a beats-only subsystem
with no seconds anywhere); it's converted to Beats at the update_midi_clip_notes
boundary in UpdateMidiNotesAction, same as trim_start f64 -> Seconds at add_audio_clip.