Skip to content

Commit

Permalink
jack: fix synchronization while repositioning
Browse files Browse the repository at this point in the history
While using JACK Timebase support and being registered as Timebase master MusE
appends the JACKs current transport position with bar, beat, tick, tempo,
measure, etc (BBT) information via `timebase_callback`. Other clients can then
trigger tempo changes, relocations etc. using these BBT infos.

But when repositioning to another location MusE did use the
`jack_transport_locate` method of the JACK API, which only sends frame
information. Thus, the JACK server will drop BBT support for a single process
cycle and other clients need to figure out the new transport position by frame
alone (which most probably will not work correctly when they did already handled
tempo or measure changes). Instead, MusE does now use
`jack_transport_reposition` in case it is registered as Timebase master. Using
this method not just the new frame but all BBT information similar to the
`timebase_callback` are provided.
  • Loading branch information
theGreatWhiteShark committed May 15, 2024
1 parent b86d0de commit 5949444
Showing 1 changed file with 28 additions and 24 deletions.
52 changes: 28 additions & 24 deletions src/muse/driver/jack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2273,7 +2273,21 @@ void JackAudioDevice::seekTransport(unsigned frame)

if(!checkJackClient(_client)) return;
// fprintf(stderr, "JACK: seekTransport %d\n", frame);
jack_transport_locate(_client, frame);

if(MusEGlobal::timebaseMasterState)
{
// We are timebase master. Provide a BBT representation of the new
// position as well.
jack_position_t jp;
Pos p(frame, false);
jp.frame = frame;
pos_to_jack_position(p, &jp);
jack_transport_reposition(_client, &jp);
}
else
{
jack_transport_locate(_client, frame);
}
}

//---------------------------------------------------------
Expand All @@ -2293,29 +2307,19 @@ void JackAudioDevice::seekTransport(const Pos &p)

if(!checkJackClient(_client)) return;

// TODO: Be friendly to other apps... Sadly not many of us use jack_transport_reposition.
// This is actually required IF we want the extra position info to show up
// in the sync callback, otherwise we get just the frame only.
// This information is shared on the server, it is directly passed around.
// jack_transport_locate blanks the info from sync until the timebase callback reads
// it again right after, from some timebase master. See process in audio.cpp

// jack_position_t jp;
// jp.frame = p.frame();
//
// jp.valid = JackPositionBBT;
// p.mbt(&jp.bar, &jp.beat, &jp.tick);
// jp.bar_start_tick = Pos(jp.bar, 0, 0).tick();
// jp.bar++;
// jp.beat++;
// jp.beats_per_bar = 5; // TODO Make this correct !
// jp.beat_type = 8; //
// jp.ticks_per_beat = MusEGlobal::config.division;
// int tempo = MusEGlobal::tempomap.tempo(p.tick());
// jp.beats_per_minute = (60000000.0 / tempo) * MusEGlobal::tempomap.globalTempo()/100.0;
// jack_transport_reposition(_client, &jp);

jack_transport_locate(_client, p.frame());
if(MusEGlobal::timebaseMasterState)
{
// We are timebase master. Provide a BBT representation of the new
// position as well.
jack_position_t jp;
jp.frame = p.frame();
pos_to_jack_position(p, &jp);
jack_transport_reposition(_client, &jp);
}
else
{
jack_transport_locate(_client, p.frame());
}
}

//---------------------------------------------------------
Expand Down

0 comments on commit 5949444

Please sign in to comment.