jack: Improve transport BBT handling

The bar can start from 0 in JACK.

Add bar_start_tick and ticks_per_beat to the io_segment_bar so that we
can losslesly store the complete jack BBT values.

See #4314
This commit is contained in:
Wim Taymans 2024-09-24 18:43:33 +02:00
parent 99c23d5b0e
commit ed0556e34c
2 changed files with 32 additions and 27 deletions

View file

@ -1771,39 +1771,41 @@ static void complete_process(struct client *c, uint32_t frames)
static inline void debug_position(struct client *c, jack_position_t *p) static inline void debug_position(struct client *c, jack_position_t *p)
{ {
pw_log_trace_fp("usecs: %"PRIu64, p->usecs); #define pw_log_custom pw_log_trace_fp
pw_log_trace_fp("frame_rate: %u", p->frame_rate); pw_log_custom("usecs: %"PRIu64, p->usecs);
pw_log_trace_fp("frame: %u", p->frame); pw_log_custom("frame_rate: %u", p->frame_rate);
pw_log_trace_fp("valid: %08x", p->valid); pw_log_custom("frame: %u", p->frame);
pw_log_custom("valid: %08x", p->valid);
if (p->valid & JackPositionBBT) { if (p->valid & JackPositionBBT) {
pw_log_trace_fp("BBT"); pw_log_custom("BBT");
pw_log_trace_fp(" bar: %u", p->bar); pw_log_custom(" bar: %u", p->bar);
pw_log_trace_fp(" beat: %u", p->beat); pw_log_custom(" beat: %u", p->beat);
pw_log_trace_fp(" tick: %u", p->tick); pw_log_custom(" tick: %u", p->tick);
pw_log_trace_fp(" bar_start_tick: %f", p->bar_start_tick); pw_log_custom(" bar_start_tick: %f", p->bar_start_tick);
pw_log_trace_fp(" beats_per_bar: %f", p->beats_per_bar); pw_log_custom(" beats_per_bar: %f", p->beats_per_bar);
pw_log_trace_fp(" beat_type: %f", p->beat_type); pw_log_custom(" beat_type: %f", p->beat_type);
pw_log_trace_fp(" ticks_per_beat: %f", p->ticks_per_beat); pw_log_custom(" ticks_per_beat: %f", p->ticks_per_beat);
pw_log_trace_fp(" beats_per_minute: %f", p->beats_per_minute); pw_log_custom(" beats_per_minute: %f", p->beats_per_minute);
} }
if (p->valid & JackPositionTimecode) { if (p->valid & JackPositionTimecode) {
pw_log_trace_fp("Timecode:"); pw_log_custom("Timecode:");
pw_log_trace_fp(" frame_time: %f", p->frame_time); pw_log_custom(" frame_time: %f", p->frame_time);
pw_log_trace_fp(" next_time: %f", p->next_time); pw_log_custom(" next_time: %f", p->next_time);
} }
if (p->valid & JackBBTFrameOffset) { if (p->valid & JackBBTFrameOffset) {
pw_log_trace_fp("BBTFrameOffset:"); pw_log_custom("BBTFrameOffset:");
pw_log_trace_fp(" bbt_offset: %u", p->bbt_offset); pw_log_custom(" bbt_offset: %u", p->bbt_offset);
} }
if (p->valid & JackAudioVideoRatio) { if (p->valid & JackAudioVideoRatio) {
pw_log_trace_fp("AudioVideoRatio:"); pw_log_custom("AudioVideoRatio:");
pw_log_trace_fp(" audio_frames_per_video_frame: %f", p->audio_frames_per_video_frame); pw_log_custom(" audio_frames_per_video_frame: %f", p->audio_frames_per_video_frame);
} }
if (p->valid & JackVideoFrameOffset) { if (p->valid & JackVideoFrameOffset) {
pw_log_trace_fp("JackVideoFrameOffset:"); pw_log_custom("JackVideoFrameOffset:");
pw_log_trace_fp(" video_offset: %u", p->video_offset); pw_log_custom(" video_offset: %u", p->video_offset);
} }
#undef pw_log_custom
} }
static inline void jack_to_position(jack_position_t *s, struct pw_node_activation *a) static inline void jack_to_position(jack_position_t *s, struct pw_node_activation *a)
@ -1818,8 +1820,10 @@ static inline void jack_to_position(jack_position_t *s, struct pw_node_activatio
d->bar.offset = 0; d->bar.offset = 0;
d->bar.signature_num = s->beats_per_bar; d->bar.signature_num = s->beats_per_bar;
d->bar.signature_denom = s->beat_type; d->bar.signature_denom = s->beat_type;
d->bar.ticks_per_beat = s->ticks_per_beat;
d->bar.bar_start_tick = s->bar_start_tick;
d->bar.bpm = s->beats_per_minute; d->bar.bpm = s->beats_per_minute;
d->bar.beat = (s->bar - 1) * s->beats_per_bar + (s->beat - 1) + d->bar.beat = s->bar * s->beats_per_bar + (s->beat-1) +
(s->tick / s->ticks_per_beat); (s->tick / s->ticks_per_beat);
} }
} }
@ -1882,18 +1886,17 @@ static inline jack_transport_state_t position_to_jack(struct pw_node_activation
d->beats_per_bar = seg->bar.signature_num; d->beats_per_bar = seg->bar.signature_num;
d->beat_type = seg->bar.signature_denom; d->beat_type = seg->bar.signature_denom;
d->ticks_per_beat = 1920.0f; d->ticks_per_beat = seg->bar.ticks_per_beat;
d->bar_start_tick = seg->bar.bar_start_tick;
d->beats_per_minute = seg->bar.bpm; d->beats_per_minute = seg->bar.bpm;
abs_beat = seg->bar.beat; abs_beat = seg->bar.beat;
d->bar = (int32_t) (abs_beat / d->beats_per_bar); d->bar = (int32_t) (abs_beat / d->beats_per_bar);
beats = (long int) (d->bar * d->beats_per_bar); beats = (long int) (d->bar * d->beats_per_bar);
d->bar_start_tick = beats * d->ticks_per_beat;
d->beat = (int32_t) (abs_beat - beats); d->beat = (int32_t) (abs_beat - beats);
beats += d->beat; beats += d->beat;
d->tick = (int32_t) ((abs_beat - beats) * d->ticks_per_beat); d->tick = (int32_t) ((abs_beat - beats) * d->ticks_per_beat);
d->bar++;
d->beat++; d->beat++;
} }
d->unique_2 = d->unique_1; d->unique_2 = d->unique_1;

View file

@ -191,7 +191,9 @@ struct spa_io_segment_bar {
float signature_denom; /**< time signature denominator */ float signature_denom; /**< time signature denominator */
double bpm; /**< beats per minute */ double bpm; /**< beats per minute */
double beat; /**< current beat in segment */ double beat; /**< current beat in segment */
uint32_t padding[8]; double bar_start_tick;
double ticks_per_beat;
uint32_t padding[4];
}; };
/** video frame segment */ /** video frame segment */