Loading...
Searching...
No Matches
Transport.hpp
1#pragma once
2
3// Builds the clap_event_transport_t for a tick.
4//
5// CLAP song positions are *fixed-point*: clap_beattime / clap_sectime are
6// int64 scaled by CLAP_BEATTIME_FACTOR / CLAP_SECTIME_FACTOR (1 << 31, see
7// clap/fixedpoint.h). Passing raw beat counts makes every host-side position
8// read as ~0 (beats / 2^31): plug-ins that follow the transport - step
9// sequencers like Stochas, arpeggiators, tempo-synced delays - saw
10// isPlaying==true but a song position frozen at zero and never advanced.
11
12#include <ossia/dataflow/token_request.hpp>
13
14#include <clap/all.h>
15
16#include <cmath>
17
18namespace Clap
19{
20inline clap_event_transport_t make_transport(const ossia::token_request& tk) noexcept
21{
22 // Quarter notes, like VST2 ppqPos / VST3 projectTimeMusic
23 const double song_pos_beats = tk.musical_start_position;
24 const double song_pos_seconds
25 = tk.tempo > 0. ? song_pos_beats * (60. / tk.tempo) : 0.;
26
27 uint32_t transport_flags
28 = CLAP_TRANSPORT_HAS_TEMPO | CLAP_TRANSPORT_HAS_BEATS_TIMELINE
29 | CLAP_TRANSPORT_HAS_SECONDS_TIMELINE | CLAP_TRANSPORT_HAS_TIME_SIGNATURE;
30 if(tk.prev_date != tk.date)
31 transport_flags |= CLAP_TRANSPORT_IS_PLAYING;
32
33 // Bar information
34 const double bar_start = tk.musical_start_last_bar;
35 const double quarters_per_bar = 4.0 * tk.signature.upper / tk.signature.lower;
36 const int32_t bar_number = quarters_per_bar > 0.
37 ? static_cast<int32_t>(bar_start / quarters_per_bar)
38 : 0;
39
40 return clap_event_transport_t{
41 .header = {
42 .size = sizeof(clap_event_transport_t),
43 .time = 0,
44 .space_id = CLAP_CORE_EVENT_SPACE_ID,
45 .type = CLAP_EVENT_TRANSPORT,
46 .flags = 0,
47 },
48 .flags = transport_flags,
49 .song_pos_beats
50 = (clap_beattime)std::round(song_pos_beats * CLAP_BEATTIME_FACTOR),
51 .song_pos_seconds
52 = (clap_sectime)std::round(song_pos_seconds * CLAP_SECTIME_FACTOR),
53 .tempo = tk.tempo,
54 .tempo_inc = 0.0,
55 .loop_start_beats = 0,
56 .loop_end_beats = 0,
57 .loop_start_seconds = 0,
58 .loop_end_seconds = 0,
59 .bar_start = (clap_beattime)std::round(bar_start * CLAP_BEATTIME_FACTOR),
60 .bar_number = bar_number,
61 .tsig_num = static_cast<uint16_t>(tk.signature.upper),
62 .tsig_denom = static_cast<uint16_t>(tk.signature.lower)};
63}
64}