15 halp_meta(name,
"Free metronome")
16 halp_meta(c_name,
"Metro")
17 halp_meta(category,
"Timing/Control")
18 halp_meta(author,
"ossia score")
19 halp_meta(manual_url,
"https://ossia.io/score-docs/processes/control-utilities.html#free-metronome")
20 halp_meta(description,
"Metronome which is not synced to the parent quantization settings")
22 halp_meta(uuid, "6e001674-d4a5-478f-9f7e-d7ad1bdcee2b")
28 halp::time_chooser<
"Period", halp::range{0.001, 60., 0.25}> period;
32 halp::timed_callback<
"out"> out;
36 void prepare(halp::setup s) { setup = s; }
38 using tick = halp::tick_musical;
39 void operator()(
const halp::tick_musical& tk)
41 if(tk.start_position_in_quarters >= tk.end_position_in_quarters || tk.frames <= 0)
43 const double period = inputs.period.value;
47 if(inputs.period.sync)
51 const double q0 = tk.start_position_in_quarters;
52 const double q1 = tk.end_position_in_quarters;
53 const double step = period * tk.tempo / 60.;
58 auto k = int64_t(std::ceil(q0 / step));
59 while(
double(k - 1) * step >= q0)
61 while(
double(k) * step < q0)
63 for(
double q =
double(k) * step; q < q1; q = double(++k) * step)
64 outputs.out(std::clamp<int64_t>(
65 halp::musical_to_frame(q, q0, q1, tk.frames), 0, tk.frames - 1));
70 const int64_t p = std::max<int64_t>(1, std::llround(period * setup.rate));
71 const int64_t pos = tk.position_in_frames;
72 for(int64_t t = ((pos + p - 1) / p) * p; t < pos + tk.frames; t += p)