Skip to content

Commit

Permalink
Merge pull request #1279 from theGreatWhiteShark/phil-jack-timebase-r…
Browse files Browse the repository at this point in the history
…eposition

Fix JACK synchronization while repositioning
  • Loading branch information
terminator356 authored May 17, 2024
2 parents 8a2cd6a + 5949444 commit 7074cff
Showing 1 changed file with 65 additions and 49 deletions.
114 changes: 65 additions & 49 deletions src/muse/driver/jack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,39 @@ static int processSync(jack_transport_state_t state, jack_position_t* pos, void*
return rv;
}

//---------------------------------------------------------
// pos_to_jack_position
//---------------------------------------------------------

static void pos_to_jack_position(const Pos& p, jack_position_t* pos) {

pos->valid = JackPositionBBT;
int bar, beat, tick;
p.mbt(&bar, &beat, &tick);
pos->bar = bar;
pos->beat = beat;
pos->tick = tick;

pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
pos->bar++;
pos->beat++;

int z, n;
MusEGlobal::sigmap.timesig(p.tick(), z, n);
pos->beats_per_bar = z;
pos->beat_type = n;
pos->ticks_per_beat = MusEGlobal::config.division;
//pos->ticks_per_beat = 24;

double tempo = MusEGlobal::tempomap.tempo(p.tick());
pos->beats_per_minute = ((double)MusEGlobal::tempomap.globalTempo() * 600000.0) / tempo;
#if JACK_DEBUG
fprintf(stderr, "pos_to_jack_position new: bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
#endif

}

//---------------------------------------------------------
// timebase_callback
//---------------------------------------------------------
Expand Down Expand Up @@ -423,34 +456,13 @@ static void timebase_callback(jack_transport_state_t,
Pos p(MusEGlobal::extSyncFlag ? MusEGlobal::audio->tickPos() : pos->frame, MusEGlobal::extSyncFlag ? true : false);
// Can't use song pos - it is only updated every (slow) GUI heartbeat !
//Pos p(MusEGlobal::extSyncFlag ? MusEGlobal::song->cpos() : pos->frame, MusEGlobal::extSyncFlag ? true : false);

pos->valid = JackPositionBBT;
int bar, beat, tick;
p.mbt(&bar, &beat, &tick);
pos->bar = bar;
pos->beat = beat;
pos->tick = tick;

pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
pos->bar++;
pos->beat++;

int z, n;
MusEGlobal::sigmap.timesig(p.tick(), z, n);
pos->beats_per_bar = z;
pos->beat_type = n;
pos->ticks_per_beat = MusEGlobal::config.division;
//pos->ticks_per_beat = 24;

double tempo = MusEGlobal::tempomap.tempo(p.tick());
pos->beats_per_minute = ((double)MusEGlobal::tempomap.globalTempo() * 600000.0) / tempo;
pos_to_jack_position(p, pos);

#if JACK_DEBUG
fprintf(stderr, "timebase_callback is new_pos:%d nframes:%u frame:%u tickPos:%d cpos:%d\n", new_pos, nframes, pos->frame, MusEGlobal::audio->tickPos(), MusEGlobal::song->cpos());
fprintf(stderr, " new: bar:%d beat:%d tick:%d\n bar_start_tick:%f beats_per_bar:%f beat_type:%f ticks_per_beat:%f beats_per_minute:%f\n",
pos->bar, pos->beat, pos->tick, pos->bar_start_tick, pos->beats_per_bar, pos->beat_type, pos->ticks_per_beat, pos->beats_per_minute);
// fprintf(stderr, "timebase_callback is new_pos:%d nframes:%u frame:%u tickPos:%d cpos:%d\n", new_pos, nframes, pos->frame, MusEGlobal::audio->tickPos(), MusEGlobal::song->cpos());
#endif

}
}

//---------------------------------------------------------
// processShutdown
Expand Down Expand Up @@ -2261,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 @@ -2281,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 7074cff

Please sign in to comment.