Merge branch 'master' into windows
This commit is contained in:
commit
aaabaf5d3c
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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' ]
|
||||
|
||||
|
|
Loading…
Reference in New Issue