mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 08:14:58 +01:00
Merge branch 'master' into windows
This commit is contained in:
commit
aaabaf5d3c
38 changed files with 247 additions and 97 deletions
|
|
@ -303,7 +303,12 @@ MidiTracer::tracer (Parser&, byte* msg, size_t len)
|
||||||
s += snprintf (
|
s += snprintf (
|
||||||
&buf[s], bufsize, " MTC full frame to %02d:%02d:%02d:%02d\n", msg[5] & 0x1f, msg[6], msg[7], msg[8]
|
&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 {
|
} else {
|
||||||
|
|
||||||
/* other sys-ex */
|
/* other sys-ex */
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ PortMatrix::init ()
|
||||||
|
|
||||||
/* and also bundles */
|
/* and also bundles */
|
||||||
_session->BundleAdded.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
|
_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 */
|
/* and also ports */
|
||||||
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
|
_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 ();
|
boost::shared_ptr<RouteList> routes = _session->get_routes ();
|
||||||
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
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)->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
|
void
|
||||||
PortMatrix::routes_changed ()
|
PortMatrix::routes_changed ()
|
||||||
{
|
{
|
||||||
|
if (!_session) return;
|
||||||
reconnect_to_routes ();
|
reconnect_to_routes ();
|
||||||
setup_global_ports ();
|
setup_global_ports ();
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +209,10 @@ PortMatrix::routes_changed ()
|
||||||
void
|
void
|
||||||
PortMatrix::setup ()
|
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
|
/* this needs to be done first, as the visible_ports() method uses the
|
||||||
notebook state to decide which ports are being shown */
|
notebook state to decide which ports are being shown */
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Amp::display_name() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
bool visible () const;
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ class AUPlugin : public ARDOUR::Plugin
|
||||||
|
|
||||||
bool has_editor () const;
|
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 output_streams() const;
|
||||||
ChanCount input_streams() const;
|
ChanCount input_streams() const;
|
||||||
bool configure_io (ChanCount in, ChanCount out);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class CapturingProcessor : public Processor
|
||||||
int set_block_size (pframes_t nframes);
|
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);
|
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 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);
|
virtual XMLNode& state (bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ public:
|
||||||
std::string display_name() const;
|
std::string display_name() const;
|
||||||
|
|
||||||
Role role() const { return _role; }
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class InternalReturn : public Return
|
||||||
|
|
||||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
||||||
bool configure_io (ChanCount, ChanCount);
|
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 add_send (InternalSend *);
|
||||||
void remove_send (InternalSend *);
|
void remove_send (InternalSend *);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class InternalSend : public Send
|
||||||
void cycle_start (pframes_t);
|
void cycle_start (pframes_t);
|
||||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
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 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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
int set_block_size (pframes_t);
|
int set_block_size (pframes_t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public:
|
||||||
void reset ();
|
void reset ();
|
||||||
void reset_max ();
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
/* special method for meter, to ensure that it can always handle the maximum
|
/* special method for meter, to ensure that it can always handle the maximum
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ public:
|
||||||
int set_state (const XMLNode&, int /* version */);
|
int set_state (const XMLNode&, int /* version */);
|
||||||
|
|
||||||
bool configure_io (ChanCount in, ChanCount out);
|
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_cut_all (bool);
|
||||||
void set_dim_all (bool);
|
void set_dim_all (bool);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public:
|
||||||
|
|
||||||
std::string describe_parameter (Evoral::Parameter param);
|
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);
|
void configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
/// The fundamental Panner function
|
/// The fundamental Panner function
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
||||||
/* specific types of plugins can overload this. As of September 2008, only
|
/* specific types of plugins can overload this. As of September 2008, only
|
||||||
AUPlugin does this.
|
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 output_streams() const;
|
||||||
virtual ChanCount input_streams() const;
|
virtual ChanCount input_streams() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class PluginInsert : public Processor
|
||||||
bool set_count (uint32_t num);
|
bool set_count (uint32_t num);
|
||||||
uint32_t get_count () const { return _plugins.size(); }
|
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 configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
bool has_no_inputs() const;
|
bool has_no_inputs() const;
|
||||||
|
|
@ -160,6 +160,8 @@ class PluginInsert : public Processor
|
||||||
BufferSet _signal_analysis_inputs;
|
BufferSet _signal_analysis_inputs;
|
||||||
BufferSet _signal_analysis_outputs;
|
BufferSet _signal_analysis_outputs;
|
||||||
|
|
||||||
|
ChanCount midi_bypass;
|
||||||
|
|
||||||
/** Description of how we can match our plugin's IO to our own insert IO */
|
/** Description of how we can match our plugin's IO to our own insert IO */
|
||||||
struct Match {
|
struct Match {
|
||||||
Match () : method (Impossible), plugins (0) {}
|
Match () : method (Impossible), plugins (0) {}
|
||||||
|
|
@ -170,7 +172,7 @@ class PluginInsert : public Processor
|
||||||
ChanCount hide; ///< number of channels to hide
|
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 */
|
/** details of the match currently being used */
|
||||||
Match _match;
|
Match _match;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class PortInsert : public IOProcessor
|
||||||
|
|
||||||
bool set_name (const std::string& name);
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
void activate ();
|
void activate ();
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
/* 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 input_streams () const { return _configured_input; }
|
||||||
virtual ChanCount output_streams() const { return _configured_output; }
|
virtual ChanCount output_streams() const { return _configured_output; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public:
|
||||||
|
|
||||||
uint32_t pans_required() const { return _configured_input.n_audio(); }
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
static uint32_t how_many_returns();
|
static uint32_t how_many_returns();
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class Send : public Delivery
|
||||||
|
|
||||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
|
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);
|
bool configure_io (ChanCount in, ChanCount out);
|
||||||
|
|
||||||
void activate ();
|
void activate ();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
|
|
||||||
|
|
@ -42,7 +43,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MidiClockTicker ();
|
MidiClockTicker ();
|
||||||
virtual ~MidiClockTicker() {}
|
virtual ~MidiClockTicker();
|
||||||
|
|
||||||
void tick (const framepos_t& transport_frames);
|
void tick (const framepos_t& transport_frames);
|
||||||
|
|
||||||
|
|
@ -63,6 +64,9 @@ public:
|
||||||
/// slot for the signal session::TransportLooped
|
/// slot for the signal session::TransportLooped
|
||||||
void transport_looped();
|
void transport_looped();
|
||||||
|
|
||||||
|
/// slot for the signal session::Located
|
||||||
|
void session_located();
|
||||||
|
|
||||||
/// pulses per quarter note (default 24)
|
/// pulses per quarter note (default 24)
|
||||||
void set_ppqn(int ppqn) { _ppqn = ppqn; }
|
void set_ppqn(int ppqn) { _ppqn = ppqn; }
|
||||||
|
|
||||||
|
|
@ -71,13 +75,16 @@ private:
|
||||||
int _ppqn;
|
int _ppqn;
|
||||||
double _last_tick;
|
double _last_tick;
|
||||||
|
|
||||||
|
class Position;
|
||||||
|
boost::scoped_ptr<Position> _pos;
|
||||||
|
|
||||||
double one_ppqn_in_frames (framepos_t transport_position);
|
double one_ppqn_in_frames (framepos_t transport_position);
|
||||||
|
|
||||||
void send_midi_clock_event (pframes_t offset);
|
void send_midi_clock_event (pframes_t offset);
|
||||||
void send_start_event (pframes_t offset);
|
void send_start_event (pframes_t offset);
|
||||||
void send_continue_event (pframes_t offset);
|
void send_continue_event (pframes_t offset);
|
||||||
void send_stop_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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_support_io_configuration (const ChanCount &, ChanCount &) const {
|
bool can_support_io_configuration (const ChanCount &, ChanCount &) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -998,7 +998,7 @@ AUPlugin::output_streams() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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.
|
// Note: We never attempt to multiply-instantiate plugins to meet io configurations.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ CapturingProcessor::configure_io (ChanCount in, ChanCount out)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ Delivery::display_name () const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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) {
|
if (_role == Main) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ InternalReturn::get_state()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ InternalSend::connect_when_legal ()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -971,7 +971,7 @@ LV2Plugin::find_presets()
|
||||||
lilv_node_as_string(name))));
|
lilv_node_as_string(name))));
|
||||||
} else {
|
} else {
|
||||||
warning << string_compose(
|
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(lilv_plugin_get_uri(_impl->plugin)),
|
||||||
lilv_node_as_string(preset)) << endmsg;
|
lilv_node_as_string(preset)) << endmsg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ PeakMeter::reset_max ()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ PluginInsert::output_streams() const
|
||||||
ChanCount out = info->n_outputs;
|
ChanCount out = info->n_outputs;
|
||||||
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
|
// 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_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;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +465,6 @@ PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (has_no_audio_inputs()) {
|
if (has_no_audio_inputs()) {
|
||||||
|
|
||||||
/* silence all (audio) outputs. Should really declick
|
/* 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.
|
* @return true if the given IO configuration can be supported.
|
||||||
*/
|
*/
|
||||||
bool
|
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;
|
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.
|
* it can be.
|
||||||
*/
|
*/
|
||||||
PluginInsert::Match
|
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();
|
PluginInfoPtr info = _plugins.front()->get_info();
|
||||||
|
ChanCount in; in += inx;
|
||||||
|
midi_bypass.reset();
|
||||||
|
|
||||||
if (info->reconfigurable_io()) {
|
if (info->reconfigurable_io()) {
|
||||||
/* Plugin has flexible I/O, so delegate to it */
|
/* 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 inputs = info->n_inputs;
|
||||||
ChanCount outputs = info->n_outputs;
|
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;
|
bool no_inputs = true;
|
||||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
if (inputs.get (*t) != 0) {
|
if (inputs.get (*t) != 0) {
|
||||||
|
|
@ -741,13 +751,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
|
||||||
|
|
||||||
if (no_inputs) {
|
if (no_inputs) {
|
||||||
/* no inputs so we can take any input configuration since we throw it away */
|
/* no inputs so we can take any input configuration since we throw it away */
|
||||||
out = outputs;
|
out = outputs + midi_bypass;
|
||||||
return Match (NoInputs, 1);
|
return Match (NoInputs, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plugin inputs match requested inputs exactly */
|
/* Plugin inputs match requested inputs exactly */
|
||||||
if (inputs == in) {
|
if (inputs == in) {
|
||||||
out = outputs;
|
out = outputs + midi_bypass;
|
||||||
return Match (ExactMatch, 1);
|
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) {
|
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||||
out.set (*t, outputs.get(*t) * f);
|
out.set (*t, outputs.get(*t) * f);
|
||||||
}
|
}
|
||||||
|
out += midi_bypass;
|
||||||
return Match (Replicate, f);
|
return Match (Replicate, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -812,7 +823,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_split) {
|
if (can_split) {
|
||||||
out = outputs;
|
out = outputs + midi_bypass;
|
||||||
return Match (Split, 1);
|
return Match (Split, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -836,10 +847,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (could_hide && !cannot_hide) {
|
if (could_hide && !cannot_hide) {
|
||||||
out = outputs;
|
out = outputs + midi_bypass;
|
||||||
return Match (Hide, 1, hide_channels);
|
return Match (Hide, 1, hide_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
midi_bypass.reset();
|
||||||
return Match (Impossible, 0);
|
return Match (Impossible, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pfra
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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();
|
out = in + _input->n_ports();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -543,11 +543,10 @@ Route::process_output_buffers (BufferSet& bufs,
|
||||||
if (bufs.count() != (*i)->input_streams()) {
|
if (bufs.count() != (*i)->input_streams()) {
|
||||||
DEBUG_TRACE (
|
DEBUG_TRACE (
|
||||||
DEBUG::Processors, string_compose (
|
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()
|
_name, bufs.count(), (*i)->name(), (*i)->input_streams()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1656,7 +1655,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
|
||||||
|
|
||||||
if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
|
if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
|
||||||
DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
|
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)) {
|
if ((*p)->can_support_io_configuration(in, out)) {
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ Send::set_state_2X (const XMLNode& node, int /* version */)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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
|
/* sends have no impact at all on the channel configuration of the
|
||||||
streams passing through the route. so, out == in.
|
streams passing through the route. so, out == in.
|
||||||
|
|
|
||||||
|
|
@ -590,7 +590,7 @@ void
|
||||||
Session::send_song_position_pointer (framepos_t t)
|
Session::send_song_position_pointer (framepos_t t)
|
||||||
{
|
{
|
||||||
if (midi_clock) {
|
if (midi_clock) {
|
||||||
midi_clock->position_changed (t);
|
/* Do nothing for the moment */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,7 @@ Session::butler_transport_work ()
|
||||||
g_atomic_int_dec_and_test (&_butler->should_do_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_("Butler transport work all done\n"));
|
||||||
|
DEBUG_TRACE (DEBUG::Transport, X_(string_compose ("Frame %1\n", _transport_frame)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1007,6 +1008,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
|
||||||
send_mmc_locate (_transport_frame);
|
send_mmc_locate (_transport_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_roll_location = _last_roll_or_reversal_location = _transport_frame;
|
||||||
Located (); /* EMIT SIGNAL */
|
Located (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,80 @@
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
|
|
||||||
using namespace ARDOUR;
|
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 ()
|
MidiClockTicker::MidiClockTicker ()
|
||||||
: _midi_port (0)
|
: _midi_port (0)
|
||||||
, _ppqn (24)
|
, _ppqn (24)
|
||||||
, _last_tick (0.0)
|
, _last_tick (0.0)
|
||||||
{
|
{
|
||||||
|
_pos.reset (new Position());
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiClockTicker::~MidiClockTicker()
|
||||||
|
{
|
||||||
|
_midi_port = 0;
|
||||||
|
_pos.reset (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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->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->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->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();
|
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
|
void
|
||||||
MidiClockTicker::session_going_away ()
|
MidiClockTicker::session_going_away ()
|
||||||
{
|
{
|
||||||
|
|
@ -79,56 +189,61 @@ MidiClockTicker::transport_state_changed()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float speed = _session->transport_speed();
|
if (! _pos->sync (_session)) {
|
||||||
framepos_t position = _session->transport_frame();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_TRACE (PBD::DEBUG::MidiClock,
|
DEBUG_TRACE (DEBUG::MidiClock,
|
||||||
string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position)
|
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 = _pos->frame;
|
||||||
_last_tick = position;
|
|
||||||
|
|
||||||
if (!Config->get_send_midi_clock())
|
if (! Config->get_send_midi_clock()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pos->speed == 1.0f) {
|
||||||
|
|
||||||
if (_session->get_play_loop()) {
|
if (_session->get_play_loop()) {
|
||||||
assert(_session->locations()->auto_loop_location());
|
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);
|
send_start_event(0);
|
||||||
} else {
|
} else {
|
||||||
send_continue_event(0);
|
send_continue_event(0);
|
||||||
}
|
}
|
||||||
} else if (position == 0) {
|
|
||||||
|
} else if (_pos->frame == 0) {
|
||||||
send_start_event(0);
|
send_start_event(0);
|
||||||
} else {
|
} else {
|
||||||
send_continue_event(0);
|
send_continue_event(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_midi_clock_event(0);
|
// send_midi_clock_event (0);
|
||||||
|
|
||||||
} else if (speed == 0.0f) {
|
} else if (_pos->speed == 0.0f) {
|
||||||
if (!Config->get_send_midi_clock())
|
send_stop_event (0);
|
||||||
return;
|
send_position_event (llrint (_pos->midi_beats), 0);
|
||||||
|
|
||||||
send_stop_event(0);
|
|
||||||
send_position_event (position, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tick (position);
|
// tick (_pos->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiClockTicker::position_changed (framepos_t position)
|
MidiClockTicker::position_changed (framepos_t)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
const double speed = _session->transport_speed();
|
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()) {
|
if (speed == 0.0f && Config->get_send_midi_clock()) {
|
||||||
send_position_event (position, 0);
|
send_position_event (position, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_tick = position;
|
_last_tick = position;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -137,7 +252,7 @@ MidiClockTicker::transport_looped()
|
||||||
Location* loop_location = _session->locations()->auto_loop_location();
|
Location* loop_location = _session->locations()->auto_loop_location();
|
||||||
assert(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",
|
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())
|
_session->transport_frame(), loop_location->start(), loop_location->end(), _session->get_play_loop())
|
||||||
);
|
);
|
||||||
|
|
@ -155,23 +270,28 @@ MidiClockTicker::transport_looped()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
|
||||||
double next_tick = _last_tick + one_ppqn_in_frames (transport_frame);
|
if (! mp) {
|
||||||
frameoffset_t next_tick_offset = llrint (next_tick) - transport_frame;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
|
const framepos_t end = _pos->frame + mp->nframes_this_cycle();
|
||||||
|
double iter = _last_tick;
|
||||||
/*
|
|
||||||
DEBUG_TRACE (PBD::DEBUG::MidiClock,
|
while (true) {
|
||||||
string_compose ("Transport: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
|
double clock_delta = one_ppqn_in_frames (llrint (iter));
|
||||||
transport_frame, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
|
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())) {
|
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -181,10 +301,14 @@ MidiClockTicker::tick (const framepos_t& transport_frame)
|
||||||
send_midi_clock_event (next_tick_offset);
|
send_midi_clock_event (next_tick_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_tick = next_tick;
|
iter = next_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_tick = iter;
|
||||||
|
_pos->frame = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
|
MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
|
||||||
{
|
{
|
||||||
|
|
@ -204,7 +328,7 @@ MidiClockTicker::send_midi_clock_event (pframes_t offset)
|
||||||
return;
|
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 };
|
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK };
|
||||||
_midi_port->write (_midi_clock_tick, 1, offset);
|
_midi_port->write (_midi_clock_tick, 1, offset);
|
||||||
|
|
@ -217,7 +341,7 @@ MidiClockTicker::send_start_event (pframes_t offset)
|
||||||
return;
|
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 };
|
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
|
||||||
_midi_port->write (_midi_clock_tick, 1, offset);
|
_midi_port->write (_midi_clock_tick, 1, offset);
|
||||||
|
|
@ -230,7 +354,7 @@ MidiClockTicker::send_continue_event (pframes_t offset)
|
||||||
return;
|
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 };
|
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
|
||||||
_midi_port->write (_midi_clock_tick, 1, offset);
|
_midi_port->write (_midi_clock_tick, 1, offset);
|
||||||
|
|
@ -243,29 +367,19 @@ MidiClockTicker::send_stop_event (pframes_t offset)
|
||||||
return;
|
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 };
|
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
|
||||||
_midi_port->write (_midi_clock_tick, 1, offset);
|
_midi_port->write (_midi_clock_tick, 1, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
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 */
|
/* can only use 14bits worth */
|
||||||
if (midi_beats > 0x3fff) {
|
if (midi_beats > 0x3fff) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -278,7 +392,7 @@ MidiClockTicker::send_position_event (framepos_t transport_position, pframes_t o
|
||||||
midi_beats & 0x3f80
|
midi_beats & 0x3f80
|
||||||
};
|
};
|
||||||
|
|
||||||
DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Song Position: %1\n", midi_beats));
|
|
||||||
|
|
||||||
_midi_port->midimsg (msg, sizeof (msg), offset);
|
_midi_port->midimsg (msg, sizeof (msg), offset);
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Song Position Sent: %1\n", midi_beats));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <CoreFoundation/CFLocale.h>
|
#include <CoreFoundation/CFLocale.h>
|
||||||
#import <CoreFoundation/CFString.h>
|
#import <CoreFoundation/CFString.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSURL.h>
|
||||||
#import <Foundation/NSAutoreleasePool.h>
|
#import <Foundation/NSAutoreleasePool.h>
|
||||||
#import <AppKit/NSWorkspace.h>
|
#import <AppKit/NSWorkspace.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,12 +132,13 @@ def build(bld):
|
||||||
obj.uselib = 'GLIBMM SIGCPP XML UUID SNDFILE GIOMM'
|
obj.uselib = 'GLIBMM SIGCPP XML UUID SNDFILE GIOMM'
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
|
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.uselib += ' OSX'
|
||||||
obj.vnum = LIBPBD_LIB_VERSION
|
obj.vnum = LIBPBD_LIB_VERSION
|
||||||
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
|
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
|
||||||
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"']
|
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"']
|
||||||
|
|
||||||
if bld.env['build_target'] == 'x86_64':
|
if bld.env['build_target'] == 'x86_64':
|
||||||
obj.defines += [ 'USE_X86_64_ASM' ]
|
obj.defines += [ 'USE_X86_64_ASM' ]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue