#include <cmath>
#include <errno.h>
-#include <poll.h>
#include <sys/types.h>
#include <unistd.h>
#include "pbd/error.h"
#include "ardour/slave.h"
#include "ardour/tempo.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
MIDIClock_Slave::MIDIClock_Slave (Session& s, MidiPort& p, int ppqn)
: ppqn (ppqn)
- , bandwidth (10.0 / 60.0) // 1 BpM = 1 / 60 Hz
+ , bandwidth (2.0 / 60.0) // 1 BpM = 1 / 60 Hz
{
session = (ISlaveSessionProxy *) new SlaveSessionProxy(s);
rebind (p);
MIDIClock_Slave::MIDIClock_Slave (ISlaveSessionProxy* session_proxy, int ppqn)
: session(session_proxy)
, ppqn (ppqn)
- , bandwidth (10.0 / 60.0) // 1 BpM = 1 / 60 Hz
+ , bandwidth (2.0 / 60.0) // 1 BpM = 1 / 60 Hz
{
reset ();
}
void
MIDIClock_Slave::calculate_one_ppqn_in_frames_at(framepos_t time)
{
- const Tempo& current_tempo = session->tempo_map().tempo_at(time);
- double frames_per_beat = current_tempo.frames_per_beat(session->frame_rate());
-
- double quarter_notes_per_beat = 4.0 / current_tempo.note_type();
- double frames_per_quarter_note = frames_per_beat / quarter_notes_per_beat;
+ const double frames_per_quarter_note = session->tempo_map().frames_per_quarter_note_at (time, session->frame_rate());
one_ppqn_in_frames = frames_per_quarter_note / double (ppqn);
// DEBUG_TRACE (DEBUG::MidiClock, string_compose ("at %1, one ppqn = %2\n", time, one_ppqn_in_frames));
return;
}
+ pframes_t cycle_offset = timestamp - session->sample_time_at_cycle_start();
+
calculate_one_ppqn_in_frames_at(should_be_position);
framepos_t elapsed_since_start = timestamp - first_timestamp;
first_timestamp = timestamp;
elapsed_since_start = should_be_position;
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("first clock message after start received @ %1\n", timestamp));
+
// calculate filter coefficients
calculate_filter_coefficients();
// we use session->transport_frame() instead of t1 here
// because t1 is used to calculate the transport speed,
// so the loop will compensate for accumulating rounding errors
- error = (double(should_be_position) - double(session->transport_frame()));
+ error = (double(should_be_position) - (double(session->transport_frame()) + double(cycle_offset)));
e = error / double(session->frame_rate());
current_delta = error;
e2 += c * e;
}
- DEBUG_TRACE (DEBUG::MidiClock, string_compose ("clock #%1 @ %2 arrived %3 (theoretical) audible %4 transport %5 error %6 "
- "read delta %7 should-be delta %8 t1-t0 %9 t0 %10 t1 %11 framerate %12 appspeed %13\n",
- midi_clock_count,
- elapsed_since_start,
- should_be_position,
- session->audible_frame(),
- session->transport_frame(),
- error,
- timestamp - last_timestamp,
- one_ppqn_in_frames,
- (t1 -t0) * session->frame_rate(),
- t0 * session->frame_rate(),
- t1 * session->frame_rate(),
- session->frame_rate(),
- ((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames));
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("clock #%1 @ %2 should-be %3 transport %4 error %5 appspeed %6 "
+ "read-delta %7 should-be delta %8 t1-t0 %9 t0 %10 t1 %11 framerate %12 engine %13\n",
+ midi_clock_count, // #
+ elapsed_since_start, // @
+ should_be_position, // should-be
+ session->transport_frame(), // transport
+ error, // error
+ ((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames, // appspeed
+ timestamp - last_timestamp, // read delta
+ one_ppqn_in_frames, // should-be delta
+ (t1 - t0) * session->frame_rate(), // t1-t0
+ t0 * session->frame_rate(), // t0
+ t1 * session->frame_rate(), // t1
+ session->frame_rate(), // framerate
+ session->frame_time()
+
+ ));
last_timestamp = timestamp;
}
void
MIDIClock_Slave::start (Parser& /*parser*/, framepos_t timestamp)
{
- DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave got start message at time %1 engine time %2\n", timestamp, session->frame_time()));
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave got start message at time %1 engine time %2 transport_frame %3\n", timestamp, session->frame_time(), session->transport_frame()));
if (!_started) {
reset();
void
MIDIClock_Slave::reset ()
{
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MidiClock_Slave reset(): calculated filter bandwidth is %1 for period size %2\n", bandwidth, session->frames_per_cycle()));
+
should_be_position = session->transport_frame();
last_timestamp = 0;
}
void
-MIDIClock_Slave::position (Parser& /*parser*/, byte* message, size_t size)
+MIDIClock_Slave::position (Parser& /*parser*/, MIDI::byte* message, size_t size)
{
// we are note supposed to get position messages while we are running
// so lets be robust and ignore those
}
assert(size == 3);
- byte lsb = message[1];
- byte msb = message[2];
+ MIDI::byte lsb = message[1];
+ MIDI::byte msb = message[2];
assert((lsb <= 0x7f) && (msb <= 0x7f));
uint16_t position_in_sixteenth_notes = (uint16_t(msb) << 7) | uint16_t(lsb);
pos = should_be_position;
}
- DEBUG_TRACE (DEBUG::MidiClock, string_compose ("speed_and_position: %1 & %2 <-> %3 (transport)\n", speed, pos, session->transport_frame()));
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("speed_and_position: speed %1 should-be %2 transport %3 \n", speed, pos, session->transport_frame()));
return true;
}