Merge branch 'master' into windows

This commit is contained in:
Paul Davis 2013-08-02 12:51:24 -04:00
commit aaabaf5d3c
38 changed files with 247 additions and 97 deletions

View File

@ -303,7 +303,12 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len)
s += snprintf (
&buf[s], bufsize, " MTC full frame to %02d:%02d:%02d:%02d\n", msg[5] & 0x1f, msg[6], msg[7], msg[8]
);
} else if (len == 3 && msg[0] == MIDI::position) {
/* MIDI Song Position */
uint16_t midi_beats = (uint16_t) msg[1];
midi_beats |= msg[2];
s += snprintf (&buf[s], bufsize, "%16s %d\n", "Position", (int) midi_beats);
} else {
/* other sys-ex */

View File

@ -152,6 +152,7 @@ PortMatrix::init ()
/* and also bundles */
_session->BundleAdded.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
_session->BundleRemoved.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
/* and also ports */
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
@ -180,6 +181,7 @@ PortMatrix::reconnect_to_routes ()
boost::shared_ptr<RouteList> routes = _session->get_routes ();
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
(*i)->processors_changed.connect (_route_connections, invalidator (*this), boost::bind (&PortMatrix::route_processors_changed, this, _1), gui_context());
(*i)->DropReferences.connect (_route_connections, invalidator (*this), boost::bind (&PortMatrix::routes_changed, this), gui_context());
}
}
@ -198,6 +200,7 @@ PortMatrix::route_processors_changed (RouteProcessorChange c)
void
PortMatrix::routes_changed ()
{
if (!_session) return;
reconnect_to_routes ();
setup_global_ports ();
}
@ -206,7 +209,10 @@ PortMatrix::routes_changed ()
void
PortMatrix::setup ()
{
if (!_session) return; // session went away
if (!_session) {
_route_connections.drop_connections ();
return; // session went away
}
/* this needs to be done first, as the visible_ports() method uses the
notebook state to decide which ports are being shown */

View File

@ -61,7 +61,7 @@ Amp::display_name() const
}
bool
Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -40,7 +40,7 @@ public:
bool visible () const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);

View File

@ -104,7 +104,7 @@ class AUPlugin : public ARDOUR::Plugin
bool has_editor () const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
ChanCount output_streams() const;
ChanCount input_streams() const;
bool configure_io (ChanCount in, ChanCount out);

View File

@ -38,7 +38,7 @@ class CapturingProcessor : public Processor
int set_block_size (pframes_t nframes);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required);
bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
virtual XMLNode& state (bool);
private:

View File

@ -67,7 +67,7 @@ public:
std::string display_name() const;
Role role() const { return _role; }
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);

View File

@ -39,7 +39,7 @@ class InternalReturn : public Return
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool configure_io (ChanCount, ChanCount);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
void add_send (InternalSend *);
void remove_send (InternalSend *);

View File

@ -42,7 +42,7 @@ class InternalSend : public Send
void cycle_start (pframes_t);
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool feeds (boost::shared_ptr<Route> other) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
int set_block_size (pframes_t);

View File

@ -56,7 +56,7 @@ public:
void reset ();
void reset_max ();
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
/* special method for meter, to ensure that it can always handle the maximum

View File

@ -118,7 +118,7 @@ public:
int set_state (const XMLNode&, int /* version */);
bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
void set_cut_all (bool);
void set_dim_all (bool);

View File

@ -53,7 +53,7 @@ public:
std::string describe_parameter (Evoral::Parameter param);
bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; };
bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return true; };
void configure_io (ChanCount in, ChanCount out);
/// The fundamental Panner function

View File

@ -242,7 +242,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent
/* specific types of plugins can overload this. As of September 2008, only
AUPlugin does this.
*/
virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return false; }
virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return false; }
virtual ChanCount output_streams() const;
virtual ChanCount input_streams() const;

View File

@ -69,7 +69,7 @@ class PluginInsert : public Processor
bool set_count (uint32_t num);
uint32_t get_count () const { return _plugins.size(); }
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
bool has_no_inputs() const;
@ -160,6 +160,8 @@ class PluginInsert : public Processor
BufferSet _signal_analysis_inputs;
BufferSet _signal_analysis_outputs;
ChanCount midi_bypass;
/** Description of how we can match our plugin's IO to our own insert IO */
struct Match {
Match () : method (Impossible), plugins (0) {}
@ -170,7 +172,7 @@ class PluginInsert : public Processor
ChanCount hide; ///< number of channels to hide
};
Match private_can_support_io_configuration (ChanCount const &, ChanCount &) const;
Match private_can_support_io_configuration (ChanCount const &, ChanCount &);
/** details of the match currently being used */
Match _match;

View File

@ -57,7 +57,7 @@ class PortInsert : public IOProcessor
bool set_name (const std::string& name);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void activate ();

View File

@ -82,7 +82,7 @@ class Processor : public SessionObject, public Automatable, public Latent
/* Derived classes should override these, or processor appears as an in-place pass-through */
virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0;
virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) = 0;
virtual ChanCount input_streams () const { return _configured_input; }
virtual ChanCount output_streams() const { return _configured_output; }

View File

@ -56,7 +56,7 @@ public:
uint32_t pans_required() const { return _configured_input.n_audio(); }
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
static uint32_t how_many_returns();

View File

@ -56,7 +56,7 @@ class Send : public Delivery
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
void activate ();

View File

@ -19,6 +19,7 @@
*/
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include "pbd/signals.h"
@ -42,7 +43,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
{
public:
MidiClockTicker ();
virtual ~MidiClockTicker() {}
virtual ~MidiClockTicker();
void tick (const framepos_t& transport_frames);
@ -63,6 +64,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,13 +75,16 @@ private:
int _ppqn;
double _last_tick;
class Position;
boost::scoped_ptr<Position> _pos;
double one_ppqn_in_frames (framepos_t transport_position);
void send_midi_clock_event (pframes_t offset);
void send_start_event (pframes_t offset);
void send_continue_event (pframes_t offset);
void send_stop_event (pframes_t offset);
void send_position_event (framepos_t transport_position, pframes_t offset);
void send_position_event (uint32_t midi_clocks, pframes_t offset);
};
}

View File

@ -49,7 +49,7 @@ public:
return false;
}
bool can_support_io_configuration (const ChanCount &, ChanCount &) const {
bool can_support_io_configuration (const ChanCount &, ChanCount &) {
return false;
}

View File

@ -998,7 +998,7 @@ AUPlugin::output_streams() const
}
bool
AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
// Note: We never attempt to multiply-instantiate plugins to meet io configurations.

View File

@ -62,7 +62,7 @@ CapturingProcessor::configure_io (ChanCount in, ChanCount out)
}
bool
CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -124,7 +124,7 @@ Delivery::display_name () const
}
bool
Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
if (_role == Main) {

View File

@ -80,7 +80,7 @@ InternalReturn::get_state()
}
bool
InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -284,7 +284,7 @@ InternalSend::connect_when_legal ()
}
bool
InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -971,7 +971,7 @@ LV2Plugin::find_presets()
lilv_node_as_string(name))));
} else {
warning << string_compose(
_("Plugin \"%1\% preset \"%2%\" is missing a label\n"),
_("Plugin \"%1\" preset \"%2\" is missing a label\n"),
lilv_node_as_string(lilv_plugin_get_uri(_impl->plugin)),
lilv_node_as_string(preset)) << endmsg;
}

View File

@ -165,7 +165,7 @@ PeakMeter::reset_max ()
}
bool
PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -355,7 +355,7 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out)
}
bool
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -145,7 +145,7 @@ PluginInsert::output_streams() const
ChanCount out = info->n_outputs;
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
out.set_audio (out.n_audio() * _plugins.size());
out.set_midi (out.n_midi() * _plugins.size());
out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
return out;
}
}
@ -465,7 +465,6 @@ PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end
}
} else {
if (has_no_audio_inputs()) {
/* silence all (audio) outputs. Should really declick
@ -704,7 +703,7 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
* @return true if the given IO configuration can be supported.
*/
bool
PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
return private_can_support_io_configuration (in, out).method != Impossible;
}
@ -714,9 +713,11 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
* it can be.
*/
PluginInsert::Match
PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCount& out) const
PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
{
PluginInfoPtr info = _plugins.front()->get_info();
ChanCount in; in += inx;
midi_bypass.reset();
if (info->reconfigurable_io()) {
/* Plugin has flexible I/O, so delegate to it */
@ -731,6 +732,15 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
ChanCount inputs = info->n_inputs;
ChanCount outputs = info->n_outputs;
if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
midi_bypass.set(DataType::MIDI, 1);
}
if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
in.set(DataType::MIDI, 0);
}
bool no_inputs = true;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (inputs.get (*t) != 0) {
@ -741,13 +751,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
if (no_inputs) {
/* no inputs so we can take any input configuration since we throw it away */
out = outputs;
out = outputs + midi_bypass;
return Match (NoInputs, 1);
}
/* Plugin inputs match requested inputs exactly */
if (inputs == in) {
out = outputs;
out = outputs + midi_bypass;
return Match (ExactMatch, 1);
}
@ -789,6 +799,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
out.set (*t, outputs.get(*t) * f);
}
out += midi_bypass;
return Match (Replicate, f);
}
@ -812,7 +823,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
}
if (can_split) {
out = outputs;
out = outputs + midi_bypass;
return Match (Split, 1);
}
@ -836,10 +847,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
}
if (could_hide && !cannot_hide) {
out = outputs;
out = outputs + midi_bypass;
return Match (Hide, 1, hide_channels);
}
midi_bypass.reset();
return Match (Impossible, 0);
}

View File

@ -268,7 +268,7 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
}
bool
PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;

View File

@ -136,7 +136,7 @@ Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pfra
}
bool
Return::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
Return::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in + _input->n_ports();
return true;

View File

@ -543,11 +543,10 @@ Route::process_output_buffers (BufferSet& bufs,
if (bufs.count() != (*i)->input_streams()) {
DEBUG_TRACE (
DEBUG::Processors, string_compose (
"%1 bufs = %2 input for %3 = %4\n",
"input port mismatch %1 bufs = %2 input for %3 = %4\n",
_name, bufs.count(), (*i)->name(), (*i)->input_streams()
)
);
continue;
}
}
#endif
@ -1656,7 +1655,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
break;
DEBUG_TRACE (DEBUG::Processors, "}\n");
return list<pair<ChanCount, ChanCount> > ();
}
if ((*p)->can_support_io_configuration(in, out)) {

View File

@ -270,7 +270,7 @@ Send::set_state_2X (const XMLNode& node, int /* version */)
}
bool
Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
Send::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
/* sends have no impact at all on the channel configuration of the
streams passing through the route. so, out == in.

View File

@ -590,7 +590,7 @@ void
Session::send_song_position_pointer (framepos_t t)
{
if (midi_clock) {
midi_clock->position_changed (t);
/* Do nothing for the moment */
}
}

View File

@ -384,6 +384,7 @@ Session::butler_transport_work ()
g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
}
void
@ -1007,6 +1008,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
send_mmc_locate (_transport_frame);
}
_last_roll_location = _last_roll_or_reversal_location = _transport_frame;
Located (); /* EMIT SIGNAL */
}

View File

@ -32,12 +32,80 @@
#include "ardour/debug.h"
using namespace ARDOUR;
using namespace PBD;
/** MIDI Clock Position tracking */
class MidiClockTicker::Position : public Timecode::BBT_Time
{
public:
Position() : speed(0.0f), frame(0) { }
~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) {
frame = fr;
didit = true;
}
/* Midi beats and clocks always gets updated for now */
s->bbt_time (this->frame, *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;
/** 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;
return didit;
}
double speed;
framecnt_t frame;
double midi_beats;
double midi_clocks;
void print (std::ostream& s) {
s << "frames: " << frame << " midi beats: " << midi_beats << " speed: " << speed;
}
};
MidiClockTicker::MidiClockTicker ()
: _midi_port (0)
, _ppqn (24)
, _last_tick (0.0)
{
_pos.reset (new Position());
}
MidiClockTicker::~MidiClockTicker()
{
_midi_port = 0;
_pos.reset (0);
}
void
@ -49,10 +117,52 @@ 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()
{
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Session Located: %1, speed: %2\n", _session->transport_frame(), _session->transport_speed()));
if (0 == _session || ! _pos->sync (_session)) {
return;
}
_last_tick = _pos->frame;
if (!Config->get_send_midi_clock()) {
return;
}
if (_pos->speed == 0.0f) {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0);
} else if (_pos->speed == 1.0f) {
#if 1
/* Experimental. To really do this and have accuracy, the
stop/locate/continue sequence would need queued to send immediately
before the next midi clock. */
send_stop_event (0);
if (_pos->frame == 0) {
send_start_event (0);
} else {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0);
send_continue_event (0);
}
#endif
} else {
/* Varispeed not supported */
}
}
void
MidiClockTicker::session_going_away ()
{
@ -79,56 +189,61 @@ MidiClockTicker::transport_state_changed()
return;
}
float speed = _session->transport_speed();
framepos_t position = _session->transport_frame();
if (! _pos->sync (_session)) {
return;
}
DEBUG_TRACE (PBD::DEBUG::MidiClock,
string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position)
DEBUG_TRACE (DEBUG::MidiClock,
string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n",
_pos->speed, _pos->frame, _session->get_play_loop(), _pos->frame)
);
if (speed == 1.0f) {
_last_tick = position;
_last_tick = _pos->frame;
if (!Config->get_send_midi_clock())
return;
if (! Config->get_send_midi_clock()) {
return;
}
if (_pos->speed == 1.0f) {
if (_session->get_play_loop()) {
assert(_session->locations()->auto_loop_location());
if (position == _session->locations()->auto_loop_location()->start()) {
if (_pos->frame == _session->locations()->auto_loop_location()->start()) {
send_start_event(0);
} else {
send_continue_event(0);
}
} else if (position == 0) {
} else if (_pos->frame == 0) {
send_start_event(0);
} else {
send_continue_event(0);
}
send_midi_clock_event(0);
// send_midi_clock_event (0);
} else if (speed == 0.0f) {
if (!Config->get_send_midi_clock())
return;
send_stop_event(0);
send_position_event (position, 0);
} else if (_pos->speed == 0.0f) {
send_stop_event (0);
send_position_event (llrint (_pos->midi_beats), 0);
}
tick (position);
// tick (_pos->frame);
}
void
MidiClockTicker::position_changed (framepos_t position)
MidiClockTicker::position_changed (framepos_t)
{
#if 0
const double speed = _session->transport_speed();
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Transport Position Change: %1, speed: %2\n", position, speed));
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Transport Position Change: %1, speed: %2\n", position, speed));
if (speed == 0.0f && Config->get_send_midi_clock()) {
send_position_event (position, 0);
}
_last_tick = position;
#endif
}
void
@ -137,7 +252,7 @@ MidiClockTicker::transport_looped()
Location* loop_location = _session->locations()->auto_loop_location();
assert(loop_location);
DEBUG_TRACE (PBD::DEBUG::MidiClock,
DEBUG_TRACE (DEBUG::MidiClock,
string_compose ("Transport looped, position: %1, loop start: %2, loop end: %3, play loop: %4\n",
_session->transport_frame(), loop_location->start(), loop_location->end(), _session->get_play_loop())
);
@ -155,23 +270,28 @@ MidiClockTicker::transport_looped()
}
void
MidiClockTicker::tick (const framepos_t& transport_frame)
MidiClockTicker::tick (const framepos_t& /* transport_frame */)
{
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0) {
return;
}
while (true) {
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);
if (! mp) {
return;
}
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));
*/
const framepos_t end = _pos->frame + mp->nframes_this_cycle();
double iter = _last_tick;
while (true) {
double clock_delta = one_ppqn_in_frames (llrint (iter));
double next_tick = iter + clock_delta;
frameoffset_t next_tick_offset = llrint (next_tick) - end;
DEBUG_TRACE (DEBUG::MidiClock,
string_compose ("Tick: iter: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
iter, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
break;
@ -181,10 +301,14 @@ MidiClockTicker::tick (const framepos_t& transport_frame)
send_midi_clock_event (next_tick_offset);
}
_last_tick = next_tick;
iter = next_tick;
}
_last_tick = iter;
_pos->frame = end;
}
double
MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
{
@ -204,7 +328,7 @@ MidiClockTicker::send_midi_clock_event (pframes_t offset)
return;
}
// DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset));
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK };
_midi_port->write (_midi_clock_tick, 1, offset);
@ -217,7 +341,7 @@ MidiClockTicker::send_start_event (pframes_t offset)
return;
}
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Start %1\n", _last_tick));
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Start %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
_midi_port->write (_midi_clock_tick, 1, offset);
@ -230,7 +354,7 @@ MidiClockTicker::send_continue_event (pframes_t offset)
return;
}
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Continue %1\n", _last_tick));
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Continue %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
_midi_port->write (_midi_clock_tick, 1, offset);
@ -243,29 +367,19 @@ MidiClockTicker::send_stop_event (pframes_t offset)
return;
}
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Stop %1\n", _last_tick));
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Stop %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
_midi_port->write (_midi_clock_tick, 1, offset);
}
void
MidiClockTicker::send_position_event (framepos_t transport_position, pframes_t offset)
MidiClockTicker::send_position_event (uint32_t midi_beats, pframes_t offset)
{
if (_midi_port == 0 || _session == 0 || _session->engine().freewheeling()) {
if (!_midi_port) {
return;
}
const TempoMap& tempo = _session->tempo_map();
Timecode::BBT_Time time;
_session->bbt_time (transport_position, time);
const double beats_per_bar = tempo.meter_at(transport_position).divisions_per_bar();
/* Midi Beats in terms of Song Position Pointer is equivalent to total
sixteenth notes at 'time' */
const uint32_t midi_beats = 4 * (((time.bars - 1) * beats_per_bar) + time.beats - 1);
/* can only use 14bits worth */
if (midi_beats > 0x3fff) {
return;
@ -278,7 +392,7 @@ MidiClockTicker::send_position_event (framepos_t transport_position, pframes_t o
midi_beats & 0x3f80
};
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Song Position: %1\n", midi_beats));
_midi_port->midimsg (msg, sizeof (msg), offset);
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Song Position Sent: %1\n", midi_beats));
}

View File

@ -1,6 +1,7 @@
#include <CoreFoundation/CFLocale.h>
#import <CoreFoundation/CFString.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSAutoreleasePool.h>
#import <AppKit/NSWorkspace.h>

View File

@ -132,12 +132,13 @@ def build(bld):
obj.uselib = 'GLIBMM SIGCPP XML UUID SNDFILE GIOMM'
if sys.platform == 'darwin':
TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
obj.source += [ 'cocoa_open_uri.mm' ]
if 'cocoa_open_uri.mm' not in obj.source:
obj.source += [ 'cocoa_open_uri.mm' ]
obj.uselib += ' OSX'
obj.vnum = LIBPBD_LIB_VERSION
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"']
if bld.env['build_target'] == 'x86_64':
obj.defines += [ 'USE_X86_64_ASM' ]