MIDI Clock - Shuffling locate code (not actually used yet)
- Subscribe to Session::Locate to detect seeks - Shuffle Mclk locating computations into a separate private class
This commit is contained in:
parent
9afb71eb5a
commit
0ed083730a
@ -42,7 +42,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
|
||||
{
|
||||
public:
|
||||
MidiClockTicker ();
|
||||
virtual ~MidiClockTicker() {}
|
||||
virtual ~MidiClockTicker();
|
||||
|
||||
void tick (const framepos_t& transport_frames);
|
||||
|
||||
@ -63,6 +63,9 @@ public:
|
||||
/// slot for the signal session::TransportLooped
|
||||
void transport_looped();
|
||||
|
||||
/// slot for the signal session::Located
|
||||
void session_located();
|
||||
|
||||
/// pulses per quarter note (default 24)
|
||||
void set_ppqn(int ppqn) { _ppqn = ppqn; }
|
||||
|
||||
@ -71,6 +74,9 @@ private:
|
||||
int _ppqn;
|
||||
double _last_tick;
|
||||
|
||||
class Position;
|
||||
Position* _pos;
|
||||
|
||||
double one_ppqn_in_frames (framepos_t transport_position);
|
||||
|
||||
void send_midi_clock_event (pframes_t offset);
|
||||
|
@ -33,11 +33,84 @@
|
||||
|
||||
using namespace ARDOUR;
|
||||
|
||||
|
||||
/** MIDI Clock Position tracking */
|
||||
class MidiClockTicker::Position : public Timecode::BBT_Time
|
||||
{
|
||||
public:
|
||||
|
||||
Position() : speed(0.0f), frame(0), clocks_till_locate(-1) { }
|
||||
~Position() { }
|
||||
|
||||
/** Sync timing information taken from the given Session
|
||||
@return True if timings differed */
|
||||
bool sync (Session* s) {
|
||||
|
||||
bool didit = false;
|
||||
|
||||
double sp = s->transport_speed();
|
||||
framecnt_t fr = s->transport_frame();
|
||||
|
||||
if (speed != sp) {
|
||||
speed = sp;
|
||||
didit = true;
|
||||
}
|
||||
|
||||
if (frame != fr) {
|
||||
|
||||
s->bbt_time (fr, *this);
|
||||
|
||||
const TempoMap& tempo = s->tempo_map();
|
||||
|
||||
const double divisions = tempo.meter_at(frame).divisions_per_bar();
|
||||
const double divisor = tempo.meter_at(frame).note_divisor();
|
||||
const double qnote_scale = divisor * 0.25f;
|
||||
|
||||
frame = fr;
|
||||
|
||||
/* Midi Beats in terms of Song Position Pointer is equivalent to total
|
||||
sixteenth notes at 'time' */
|
||||
|
||||
midi_beats = (((bars - 1) * divisions) + beats - 1);
|
||||
midi_beats += (double)ticks / (double)Position::ticks_per_beat * qnote_scale;
|
||||
midi_beats *= 16.0f / divisor;
|
||||
|
||||
midi_clocks = midi_beats * 6.0f;
|
||||
|
||||
didit = true;
|
||||
}
|
||||
|
||||
print (std::clog);
|
||||
|
||||
return didit;
|
||||
}
|
||||
|
||||
double speed;
|
||||
framecnt_t frame;
|
||||
double midi_beats;
|
||||
double midi_clocks;
|
||||
|
||||
void print (std::ostream& s) {
|
||||
s << "MCLK Position: frames: " << frame << " midi beats: " << midi_beats << " speed: " << speed << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MidiClockTicker::MidiClockTicker ()
|
||||
: _midi_port (0)
|
||||
, _ppqn (24)
|
||||
, _last_tick (0.0)
|
||||
{
|
||||
_pos = new Position();
|
||||
}
|
||||
|
||||
MidiClockTicker::~MidiClockTicker()
|
||||
{
|
||||
_midi_port = 0;
|
||||
if (_pos) {
|
||||
delete _pos;
|
||||
_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -49,10 +122,32 @@ MidiClockTicker::set_session (Session* s)
|
||||
_session->TransportStateChange.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_state_changed, this));
|
||||
_session->PositionChanged.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::position_changed, this, _1));
|
||||
_session->TransportLooped.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_looped, this));
|
||||
_session->Located.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::session_located, this));
|
||||
|
||||
update_midi_clock_port();
|
||||
_pos->sync (_session);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiClockTicker::session_located()
|
||||
{
|
||||
if (0 == _session || ! _pos->sync (_session)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_last_tick = _pos->frame;
|
||||
|
||||
// WIP - Testing code
|
||||
if (0 == _pos->frame) {
|
||||
std::clog << "zero frame\n";
|
||||
if (1.0f == _pos->speed) {
|
||||
std::clog << "normal speed:\n";
|
||||
_pos->clocks_till_locate = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiClockTicker::session_going_away ()
|
||||
{
|
||||
@ -157,6 +252,12 @@ MidiClockTicker::transport_looped()
|
||||
void
|
||||
MidiClockTicker::tick (const framepos_t& transport_frame)
|
||||
{
|
||||
if (_pos->clocks_till_locate == 0) {
|
||||
std::clog << "Locate: " << transport_frame << std::endl;
|
||||
}
|
||||
|
||||
--_pos->clocks_till_locate;
|
||||
|
||||
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0) {
|
||||
return;
|
||||
}
|
||||
@ -165,13 +266,14 @@ MidiClockTicker::tick (const framepos_t& transport_frame)
|
||||
double next_tick = _last_tick + one_ppqn_in_frames (transport_frame);
|
||||
frameoffset_t next_tick_offset = llrint (next_tick) - transport_frame;
|
||||
|
||||
|
||||
MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
|
||||
|
||||
/*
|
||||
|
||||
DEBUG_TRACE (PBD::DEBUG::MidiClock,
|
||||
string_compose ("Transport: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
|
||||
transport_frame, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
|
||||
*/
|
||||
|
||||
|
||||
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
|
||||
break;
|
||||
@ -181,7 +283,7 @@ MidiClockTicker::tick (const framepos_t& transport_frame)
|
||||
send_midi_clock_event (next_tick_offset);
|
||||
}
|
||||
|
||||
_last_tick = next_tick;
|
||||
_pos->frame = _last_tick = next_tick;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user