mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-18 12:46:32 +01:00
Setup fixed ports for MIDI control data; hence remove configuration of those ports. Move MIDI tracer to the Windows menu. Trim some unused code from the midi++ Manager.
git-svn-id: svn://localhost/ardour2/branches/3.0@7384 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
6cccf3ce7d
commit
ea23298f10
31 changed files with 249 additions and 1015 deletions
|
|
@ -9,10 +9,8 @@ export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs
|
||||||
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/default/gtk2_ardour:.
|
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/default/gtk2_ardour:.
|
||||||
|
|
||||||
if test -d $HOME/gtk/inst ; then
|
if test -d $HOME/gtk/inst ; then
|
||||||
echo USING NEW CLEARLOOKS
|
|
||||||
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer
|
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer
|
||||||
else
|
else
|
||||||
echo USING OLD CLEARLOOKS
|
|
||||||
export GTK_PATH=~/.ardour3:$libs/clearlooks-older
|
export GTK_PATH=~/.ardour3:$libs/clearlooks-older
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,7 @@
|
||||||
<menuitem action='ToggleBundleManager'/>
|
<menuitem action='ToggleBundleManager'/>
|
||||||
<menuitem action='ToggleThemeManager'/>
|
<menuitem action='ToggleThemeManager'/>
|
||||||
<menuitem action='ToggleBigClock'/>
|
<menuitem action='ToggleBigClock'/>
|
||||||
|
<menuitem action='ToggleMIDITracer'/>
|
||||||
<menuitem action='toggle-audio-connection-manager'/>
|
<menuitem action='toggle-audio-connection-manager'/>
|
||||||
<menuitem action='toggle-midi-connection-manager'/>
|
<menuitem action='toggle-midi-connection-manager'/>
|
||||||
<menuitem action='toggle-log-window'/>
|
<menuitem action='toggle-log-window'/>
|
||||||
|
|
|
||||||
|
|
@ -365,9 +365,6 @@ ARDOUR_UI::post_engine ()
|
||||||
/* Things to be done once we create the AudioEngine
|
/* Things to be done once we create the AudioEngine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MIDI::Manager::instance()->set_api_data (engine->jack());
|
|
||||||
setup_midi ();
|
|
||||||
|
|
||||||
ARDOUR::init_post_engine ();
|
ARDOUR::init_post_engine ();
|
||||||
|
|
||||||
ActionManager::init ();
|
ActionManager::init ();
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ class RouteParams_UI;
|
||||||
class SessionOptionEditor;
|
class SessionOptionEditor;
|
||||||
class Splash;
|
class Splash;
|
||||||
class ThemeManager;
|
class ThemeManager;
|
||||||
|
class MidiTracer;
|
||||||
|
|
||||||
namespace Gtkmm2ext {
|
namespace Gtkmm2ext {
|
||||||
class TearOff;
|
class TearOff;
|
||||||
|
|
@ -164,6 +165,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
||||||
void toggle_theme_manager ();
|
void toggle_theme_manager ();
|
||||||
void toggle_bundle_manager ();
|
void toggle_bundle_manager ();
|
||||||
void toggle_big_clock_window ();
|
void toggle_big_clock_window ();
|
||||||
|
void toggle_midi_tracer_window ();
|
||||||
void toggle_route_params_window ();
|
void toggle_route_params_window ();
|
||||||
void toggle_editing_space();
|
void toggle_editing_space();
|
||||||
|
|
||||||
|
|
@ -325,6 +327,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
||||||
void update_transport_clocks (nframes_t pos);
|
void update_transport_clocks (nframes_t pos);
|
||||||
void record_state_changed ();
|
void record_state_changed ();
|
||||||
|
|
||||||
|
MidiTracer* _midi_tracer_window;
|
||||||
|
|
||||||
/* Transport Control */
|
/* Transport Control */
|
||||||
|
|
||||||
void detach_tearoff (Gtk::Box* parent, Gtk::Widget* contents);
|
void detach_tearoff (Gtk::Box* parent, Gtk::Widget* contents);
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include "actions.h"
|
#include "actions.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "theme_manager.h"
|
#include "theme_manager.h"
|
||||||
|
#include "midi_tracer.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -106,6 +107,9 @@ ARDOUR_UI::setup_windows ()
|
||||||
setup_transport();
|
setup_transport();
|
||||||
build_menu_bar ();
|
build_menu_bar ();
|
||||||
|
|
||||||
|
_midi_tracer_window = new MidiTracer ();
|
||||||
|
manage_window (*_midi_tracer_window);
|
||||||
|
|
||||||
setup_tooltips ();
|
setup_tooltips ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "bundle_manager.h"
|
#include "bundle_manager.h"
|
||||||
#include "keyeditor.h"
|
#include "keyeditor.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
|
#include "midi_tracer.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -214,6 +215,22 @@ ARDOUR_UI::toggle_big_clock_window ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ARDOUR_UI::toggle_midi_tracer_window ()
|
||||||
|
{
|
||||||
|
RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleMIDITracer"));
|
||||||
|
if (!act) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
|
||||||
|
if (tact->get_active ()) {
|
||||||
|
_midi_tracer_window->show_all ();
|
||||||
|
} else {
|
||||||
|
_midi_tracer_window->hide ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ARDOUR_UI::toggle_rc_options_window ()
|
ARDOUR_UI::toggle_rc_options_window ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,8 @@ ARDOUR_UI::install_actions ()
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
|
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
act = ActionManager::register_toggle_action (common_actions, X_("ToggleMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_midi_tracer_window));
|
||||||
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
ActionManager::register_action (common_actions, X_("About"), _("About"), sigc::mem_fun(*this, &ARDOUR_UI::show_about));
|
ActionManager::register_action (common_actions, X_("About"), _("About"), sigc::mem_fun(*this, &ARDOUR_UI::show_about));
|
||||||
ActionManager::register_action (common_actions, X_("Chat"), _("Chat"), sigc::mem_fun(*this, &ARDOUR_UI::launch_chat));
|
ActionManager::register_action (common_actions, X_("Chat"), _("Chat"), sigc::mem_fun(*this, &ARDOUR_UI::launch_chat));
|
||||||
ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
|
ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,22 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2010 Paul Davis
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#define __STDC_FORMAT_MACROS 1
|
#define __STDC_FORMAT_MACROS 1
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
@ -6,6 +25,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "midi++/parser.h"
|
#include "midi++/parser.h"
|
||||||
|
#include "midi++/manager.h"
|
||||||
|
|
||||||
#include "midi_tracer.h"
|
#include "midi_tracer.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
|
|
@ -16,9 +36,9 @@ using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
using namespace Glib;
|
using namespace Glib;
|
||||||
|
|
||||||
MidiTracer::MidiTracer (const std::string& name, Parser& p)
|
MidiTracer::MidiTracer ()
|
||||||
: ArdourDialog (string_compose (_("MIDI Trace %1"), name))
|
: ArdourDialog (_("MIDI Tracer"))
|
||||||
, parser (p)
|
, parser (0)
|
||||||
, line_count_adjustment (200, 1, 2000, 1, 10)
|
, line_count_adjustment (200, 1, 2000, 1, 10)
|
||||||
, line_count_spinner (line_count_adjustment)
|
, line_count_spinner (line_count_adjustment)
|
||||||
, line_count_label (_("Store this many lines: "))
|
, line_count_label (_("Store this many lines: "))
|
||||||
|
|
@ -32,6 +52,18 @@ MidiTracer::MidiTracer (const std::string& name, Parser& p)
|
||||||
, base_button (_("Decimal"))
|
, base_button (_("Decimal"))
|
||||||
, collect_button (_("Enabled"))
|
, collect_button (_("Enabled"))
|
||||||
{
|
{
|
||||||
|
get_vbox()->set_spacing (4);
|
||||||
|
|
||||||
|
Manager::instance()->PortsChanged.connect (_manager_connection, invalidator (*this), boost::bind (&MidiTracer::ports_changed, this), gui_context());
|
||||||
|
|
||||||
|
HBox* pbox = manage (new HBox);
|
||||||
|
pbox->pack_start (*manage (new Label (_("Port:"))), false, false);
|
||||||
|
|
||||||
|
_port_combo.signal_changed().connect (sigc::mem_fun (*this, &MidiTracer::port_changed));
|
||||||
|
pbox->pack_start (_port_combo);
|
||||||
|
pbox->show_all ();
|
||||||
|
get_vbox()->pack_start (*pbox, false, false);
|
||||||
|
|
||||||
scroller.add (text);
|
scroller.add (text);
|
||||||
get_vbox()->set_border_width (12);
|
get_vbox()->set_border_width (12);
|
||||||
get_vbox()->pack_start (scroller, true, true);
|
get_vbox()->pack_start (scroller, true, true);
|
||||||
|
|
@ -71,7 +103,8 @@ MidiTracer::MidiTracer (const std::string& name, Parser& p)
|
||||||
collect_button.show ();
|
collect_button.show ();
|
||||||
autoscroll_button.show ();
|
autoscroll_button.show ();
|
||||||
|
|
||||||
connect ();
|
ports_changed ();
|
||||||
|
port_changed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,16 +113,36 @@ MidiTracer::~MidiTracer()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTracer::connect ()
|
MidiTracer::ports_changed ()
|
||||||
|
{
|
||||||
|
string const c = _port_combo.get_active_text ();
|
||||||
|
_port_combo.clear ();
|
||||||
|
|
||||||
|
Manager::PortList const & p = Manager::instance()->get_midi_ports ();
|
||||||
|
for (Manager::PortList::const_iterator i = p.begin(); i != p.end(); ++i) {
|
||||||
|
_port_combo.append_text ((*i)->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
_port_combo.set_active_text (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiTracer::port_changed ()
|
||||||
{
|
{
|
||||||
disconnect ();
|
disconnect ();
|
||||||
parser.any.connect_same_thread (connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
|
|
||||||
|
Port* p = Manager::instance()->port (_port_combo.get_active_text());
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
Parser* parser = p->input() ? p->input() : p->output();
|
||||||
|
parser->any.connect_same_thread (_parser_connection, boost::bind (&MidiTracer::tracer, this, _1, _2, _3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTracer::disconnect ()
|
MidiTracer::disconnect ()
|
||||||
{
|
{
|
||||||
connection.disconnect ();
|
_parser_connection.disconnect ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -330,7 +383,7 @@ void
|
||||||
MidiTracer::collect_toggle ()
|
MidiTracer::collect_toggle ()
|
||||||
{
|
{
|
||||||
if (collect_button.get_active ()) {
|
if (collect_button.get_active ()) {
|
||||||
connect ();
|
port_changed ();
|
||||||
} else {
|
} else {
|
||||||
disconnect ();
|
disconnect ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <gtkmm/adjustment.h>
|
#include <gtkmm/adjustment.h>
|
||||||
#include <gtkmm/spinbutton.h>
|
#include <gtkmm/spinbutton.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
#include <gtkmm/comboboxtext.h>
|
||||||
|
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
#include "pbd/ringbuffer.h"
|
#include "pbd/ringbuffer.h"
|
||||||
|
|
@ -21,11 +22,11 @@ namespace MIDI {
|
||||||
class MidiTracer : public ArdourDialog
|
class MidiTracer : public ArdourDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MidiTracer (const std::string&, MIDI::Parser&);
|
MidiTracer ();
|
||||||
~MidiTracer();
|
~MidiTracer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MIDI::Parser& parser;
|
MIDI::Parser* parser;
|
||||||
Gtk::TextView text;
|
Gtk::TextView text;
|
||||||
Gtk::ScrolledWindow scroller;
|
Gtk::ScrolledWindow scroller;
|
||||||
Gtk::Adjustment line_count_adjustment;
|
Gtk::Adjustment line_count_adjustment;
|
||||||
|
|
@ -53,14 +54,17 @@ class MidiTracer : public ArdourDialog
|
||||||
Gtk::CheckButton autoscroll_button;
|
Gtk::CheckButton autoscroll_button;
|
||||||
Gtk::CheckButton base_button;
|
Gtk::CheckButton base_button;
|
||||||
Gtk::CheckButton collect_button;
|
Gtk::CheckButton collect_button;
|
||||||
|
Gtk::ComboBoxText _port_combo;
|
||||||
|
|
||||||
void base_toggle ();
|
void base_toggle ();
|
||||||
void autoscroll_toggle ();
|
void autoscroll_toggle ();
|
||||||
void collect_toggle ();
|
void collect_toggle ();
|
||||||
|
|
||||||
void connect ();
|
void port_changed ();
|
||||||
|
void ports_changed ();
|
||||||
void disconnect ();
|
void disconnect ();
|
||||||
PBD::ScopedConnection connection;
|
PBD::ScopedConnection _parser_connection;
|
||||||
|
PBD::ScopedConnection _manager_connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_gtk_midi_tracer_h__ */
|
#endif /* __ardour_gtk_midi_tracer_h__ */
|
||||||
|
|
|
||||||
|
|
@ -30,225 +30,6 @@ using namespace Gtkmm2ext;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
|
||||||
class MIDIPorts : public OptionEditorBox
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MIDIPorts (RCConfiguration* c, list<ComboOption<string>* > const & o)
|
|
||||||
: _rc_config (c),
|
|
||||||
_add_port_button (Stock::ADD),
|
|
||||||
_port_combos (o)
|
|
||||||
{
|
|
||||||
_store = ListStore::create (_model);
|
|
||||||
_view.set_model (_store);
|
|
||||||
_view.append_column (_("Name"), _model.name);
|
|
||||||
_view.get_column(0)->set_resizable (true);
|
|
||||||
_view.get_column(0)->set_expand (true);
|
|
||||||
_view.append_column_editable (_("Online"), _model.online);
|
|
||||||
_view.append_column_editable (_("Trace input"), _model.trace_input);
|
|
||||||
_view.append_column_editable (_("Trace output"), _model.trace_output);
|
|
||||||
|
|
||||||
HBox* h = manage (new HBox);
|
|
||||||
h->set_spacing (4);
|
|
||||||
h->pack_start (_view, true, true);
|
|
||||||
|
|
||||||
VBox* v = manage (new VBox);
|
|
||||||
v->set_spacing (4);
|
|
||||||
v->pack_start (_add_port_button, false, false);
|
|
||||||
h->pack_start (*v, false, false);
|
|
||||||
|
|
||||||
_box->pack_start (*h);
|
|
||||||
|
|
||||||
ports_changed ();
|
|
||||||
|
|
||||||
_store->signal_row_changed().connect (sigc::mem_fun (*this, &MIDIPorts::model_changed));
|
|
||||||
|
|
||||||
_add_port_button.signal_clicked().connect (sigc::mem_fun (*this, &MIDIPorts::add_port_clicked));
|
|
||||||
}
|
|
||||||
|
|
||||||
void parameter_changed (string const &) {}
|
|
||||||
void set_state_from_config () {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef std::map<MIDI::Port*,MidiTracer*> PortTraceMap;
|
|
||||||
PortTraceMap port_input_trace_map;
|
|
||||||
PortTraceMap port_output_trace_map;
|
|
||||||
|
|
||||||
void model_changed (TreeModel::Path const &, TreeModel::iterator const & i)
|
|
||||||
{
|
|
||||||
TreeModel::Row r = *i;
|
|
||||||
|
|
||||||
MIDI::Port* port = r[_model.port];
|
|
||||||
if (!port) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port->input()) {
|
|
||||||
|
|
||||||
if (r[_model.online] == port->input()->offline()) {
|
|
||||||
port->input()->set_offline (!r[_model.online]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r[_model.trace_input] != port->input()->tracing()) {
|
|
||||||
PortTraceMap::iterator x = port_input_trace_map.find (port);
|
|
||||||
MidiTracer* mt;
|
|
||||||
|
|
||||||
if (x == port_input_trace_map.end()) {
|
|
||||||
mt = new MidiTracer (port->name() + string (" [input]"), *port->input());
|
|
||||||
port_input_trace_map.insert (pair<MIDI::Port*,MidiTracer*> (port, mt));
|
|
||||||
} else {
|
|
||||||
mt = x->second;
|
|
||||||
}
|
|
||||||
mt->present ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port->output()) {
|
|
||||||
|
|
||||||
if (r[_model.trace_output] != port->output()->tracing()) {
|
|
||||||
PortTraceMap::iterator x = port_output_trace_map.find (port);
|
|
||||||
MidiTracer* mt;
|
|
||||||
|
|
||||||
if (x == port_output_trace_map.end()) {
|
|
||||||
mt = new MidiTracer (port->name() + string (" [output]"), *port->output());
|
|
||||||
port_output_trace_map.insert (pair<MIDI::Port*,MidiTracer*> (port, mt));
|
|
||||||
} else {
|
|
||||||
mt = x->second;
|
|
||||||
}
|
|
||||||
mt->present ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_ports_combo (ComboOption<string>* c)
|
|
||||||
{
|
|
||||||
c->clear ();
|
|
||||||
MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
|
|
||||||
for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
|
|
||||||
c->add ((*i)->name(), (*i)->name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ports_changed ()
|
|
||||||
{
|
|
||||||
/* XXX: why is this coming from here? */
|
|
||||||
MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
|
|
||||||
|
|
||||||
_store->clear ();
|
|
||||||
port_connections.drop_connections ();
|
|
||||||
|
|
||||||
for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
|
|
||||||
|
|
||||||
TreeModel::Row r = *_store->append ();
|
|
||||||
|
|
||||||
r[_model.name] = (*i)->name();
|
|
||||||
|
|
||||||
if ((*i)->input()) {
|
|
||||||
r[_model.online] = !(*i)->input()->offline();
|
|
||||||
(*i)->input()->OfflineStatusChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&MIDIPorts::port_offline_changed, this, (*i)), gui_context());
|
|
||||||
r[_model.trace_input] = (*i)->input()->tracing();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*i)->output()) {
|
|
||||||
r[_model.trace_output] = (*i)->output()->tracing();
|
|
||||||
}
|
|
||||||
|
|
||||||
r[_model.port] = (*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (list<ComboOption<string>* >::iterator i = _port_combos.begin(); i != _port_combos.end(); ++i) {
|
|
||||||
setup_ports_combo (*i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void port_offline_changed (MIDI::Port* p)
|
|
||||||
{
|
|
||||||
if (!p->input()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TreeModel::Children::iterator i = _store->children().begin(); i != _store->children().end(); ++i) {
|
|
||||||
if ((*i)[_model.port] == p) {
|
|
||||||
(*i)[_model.online] = !p->input()->offline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_port_clicked ()
|
|
||||||
{
|
|
||||||
MidiPortDialog dialog;
|
|
||||||
|
|
||||||
dialog.set_position (WIN_POS_MOUSE);
|
|
||||||
|
|
||||||
dialog.show ();
|
|
||||||
|
|
||||||
int const r = dialog.run ();
|
|
||||||
|
|
||||||
switch (r) {
|
|
||||||
case RESPONSE_ACCEPT:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Glib::ustring const mode = dialog.port_mode_combo.get_active_text ();
|
|
||||||
string smod;
|
|
||||||
|
|
||||||
if (mode == _("input")) {
|
|
||||||
smod = X_("input");
|
|
||||||
} else if (mode == (_("output"))) {
|
|
||||||
smod = X_("output");
|
|
||||||
} else {
|
|
||||||
smod = "duplex";
|
|
||||||
}
|
|
||||||
|
|
||||||
XMLNode node (X_("MIDI-port"));
|
|
||||||
|
|
||||||
node.add_property ("tag", dialog.port_name.get_text());
|
|
||||||
node.add_property ("device", X_("ardour")); // XXX this can't be right for all types
|
|
||||||
node.add_property ("mode", smod);
|
|
||||||
|
|
||||||
if (MIDI::Manager::instance()->add_port (node) != 0) {
|
|
||||||
cerr << " there are now " << MIDI::Manager::instance()->nports() << endl;
|
|
||||||
ports_changed ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MIDIModelColumns : public TreeModelColumnRecord
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MIDIModelColumns ()
|
|
||||||
{
|
|
||||||
add (name);
|
|
||||||
add (online);
|
|
||||||
add (trace_input);
|
|
||||||
add (trace_output);
|
|
||||||
add (port);
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeModelColumn<string> name;
|
|
||||||
TreeModelColumn<bool> online;
|
|
||||||
TreeModelColumn<bool> trace_input;
|
|
||||||
TreeModelColumn<bool> trace_output;
|
|
||||||
TreeModelColumn<MIDI::Port*> port;
|
|
||||||
};
|
|
||||||
|
|
||||||
RCConfiguration* _rc_config;
|
|
||||||
Glib::RefPtr<ListStore> _store;
|
|
||||||
MIDIModelColumns _model;
|
|
||||||
TreeView _view;
|
|
||||||
Button _add_port_button;
|
|
||||||
ComboBoxText _mtc_combo;
|
|
||||||
ComboBoxText _midi_clock_combo;
|
|
||||||
ComboBoxText _mmc_combo;
|
|
||||||
ComboBoxText _mpc_combo;
|
|
||||||
list<ComboOption<string>* > _port_combos;
|
|
||||||
PBD::ScopedConnectionList port_connections;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ClickOptions : public OptionEditorBox
|
class ClickOptions : public OptionEditorBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -1429,44 +1210,6 @@ RCOptionEditor::RCOptionEditor ()
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
|
sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
|
||||||
));
|
));
|
||||||
|
|
||||||
/* MIDI CONTROL */
|
|
||||||
|
|
||||||
list<ComboOption<string>* > midi_combos;
|
|
||||||
|
|
||||||
midi_combos.push_back (new ComboOption<string> (
|
|
||||||
"mtc-port-name",
|
|
||||||
_("Send/Receive MTC via"),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_port_name),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_port_name)
|
|
||||||
));
|
|
||||||
|
|
||||||
midi_combos.push_back (new ComboOption<string> (
|
|
||||||
"midi-clock-port-name",
|
|
||||||
_("Send/Receive MIDI clock via"),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_clock_port_name),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_clock_port_name)
|
|
||||||
));
|
|
||||||
|
|
||||||
midi_combos.push_back (new ComboOption<string> (
|
|
||||||
"mmc-port-name",
|
|
||||||
_("Send/Receive MMC via"),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_port_name),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_port_name)
|
|
||||||
));
|
|
||||||
|
|
||||||
midi_combos.push_back (new ComboOption<string> (
|
|
||||||
"midi-port-name",
|
|
||||||
_("Send/Receive MIDI parameter control via"),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_port_name),
|
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_port_name)
|
|
||||||
));
|
|
||||||
|
|
||||||
add_option (_("MIDI control"), new MIDIPorts (_rc_config, midi_combos));
|
|
||||||
|
|
||||||
for (list<ComboOption<string>* >::iterator i = midi_combos.begin(); i != midi_combos.end(); ++i) {
|
|
||||||
add_option (_("MIDI control"), *i);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_option (_("MIDI control"),
|
add_option (_("MIDI control"),
|
||||||
new BoolOption (
|
new BoolOption (
|
||||||
"send-mtc",
|
"send-mtc",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* This is subclassed from OptionEditor. Simple options (e.g. boolean and simple choices)
|
* This is subclassed from OptionEditor. Simple options (e.g. boolean and simple choices)
|
||||||
* are expressed using subclasses of Option. More complex UI elements are represented
|
* are expressed using subclasses of Option. More complex UI elements are represented
|
||||||
* using individual classes subclassed rom OptionEditorBox.
|
* using individual classes subclassed from OptionEditorBox.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Editor for options which are obtained from and written back to one of the .rc files. */
|
/** Editor for options which are obtained from and written back to one of the .rc files. */
|
||||||
|
|
|
||||||
|
|
@ -71,13 +71,6 @@ namespace ARDOUR {
|
||||||
static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */
|
static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */
|
||||||
|
|
||||||
void setup_fpu ();
|
void setup_fpu ();
|
||||||
|
|
||||||
extern MIDI::Port* default_mmc_port;
|
|
||||||
extern MIDI::Port* default_mtc_port;
|
|
||||||
extern MIDI::Port* default_midi_port;
|
|
||||||
extern MIDI::Port *default_midi_clock_port;
|
|
||||||
|
|
||||||
int setup_midi ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __ardour_ardour_h__ */
|
#endif /* __ardour_ardour_h__ */
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,6 @@ class RCConfiguration : public Configuration
|
||||||
XMLNode& get_variables ();
|
XMLNode& get_variables ();
|
||||||
void set_variables (XMLNode const &);
|
void set_variables (XMLNode const &);
|
||||||
|
|
||||||
std::map<std::string, XMLNode> midi_ports;
|
|
||||||
|
|
||||||
int load_state ();
|
int load_state ();
|
||||||
int save_state ();
|
int save_state ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,6 @@ CONFIG_VARIABLE (AutoConnectOption, input_auto_connect, "input-auto-connect", Au
|
||||||
|
|
||||||
/* MIDI and MIDI related */
|
/* MIDI and MIDI related */
|
||||||
|
|
||||||
CONFIG_VARIABLE (std::string, mtc_port_name, "mtc-port-name", "control")
|
|
||||||
CONFIG_VARIABLE (std::string, mmc_port_name, "mmc-port-name", "control")
|
|
||||||
CONFIG_VARIABLE (std::string, midi_port_name, "midi-port-name", "control")
|
|
||||||
CONFIG_VARIABLE (std::string, midi_clock_port_name, "midi-clock-port-name", "control")
|
|
||||||
CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
|
CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
|
||||||
CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
|
CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
|
||||||
CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
|
CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
|
||||||
|
|
|
||||||
|
|
@ -641,23 +641,17 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
/* MIDI control */
|
/* MIDI control */
|
||||||
|
|
||||||
void midi_panic(void);
|
void midi_panic(void);
|
||||||
int set_mtc_port (std::string port_tag);
|
MIDI::Port *mtc_input_port() const { return _mtc_input_port; }
|
||||||
int set_midi_port (std::string port_tag);
|
MIDI::Port *mtc_output_port() const { return _mtc_output_port; }
|
||||||
int set_midi_clock_port (std::string port_tag);
|
MIDI::Port *midi_input_port() const { return _midi_input_port; }
|
||||||
MIDI::Port *mtc_port() const { return _mtc_port; }
|
MIDI::Port *midi_output_port() const { return _midi_output_port; }
|
||||||
MIDI::Port *midi_port() const { return _midi_port; }
|
MIDI::Port *midi_clock_input_port() const { return _midi_clock_input_port; }
|
||||||
MIDI::Port *midi_clock_port() const { return _midi_clock_port; }
|
MIDI::Port *midi_clock_output_port() const { return _midi_clock_output_port; }
|
||||||
|
|
||||||
PBD::Signal0<void> MTC_PortChanged;
|
PBD::Signal0<void> MTC_PortChanged;
|
||||||
PBD::Signal0<void> MIDI_PortChanged;
|
PBD::Signal0<void> MIDI_PortChanged;
|
||||||
PBD::Signal0<void> MIDIClock_PortChanged;
|
PBD::Signal0<void> MIDIClock_PortChanged;
|
||||||
|
|
||||||
void set_trace_midi_input (bool, MIDI::Port* port = 0);
|
|
||||||
void set_trace_midi_output (bool, MIDI::Port* port = 0);
|
|
||||||
|
|
||||||
bool get_trace_midi_input(MIDI::Port *port = 0);
|
|
||||||
bool get_trace_midi_output(MIDI::Port *port = 0);
|
|
||||||
|
|
||||||
/* Scrubbing */
|
/* Scrubbing */
|
||||||
|
|
||||||
void start_scrub (nframes_t where);
|
void start_scrub (nframes_t where);
|
||||||
|
|
@ -950,9 +944,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
void check_declick_out ();
|
void check_declick_out ();
|
||||||
|
|
||||||
MIDI::MachineControl* _mmc;
|
MIDI::MachineControl* _mmc;
|
||||||
MIDI::Port* _mtc_port;
|
MIDI::Port* _mtc_input_port;
|
||||||
MIDI::Port* _midi_port;
|
MIDI::Port* _mtc_output_port;
|
||||||
MIDI::Port* _midi_clock_port;
|
MIDI::Port* _midi_input_port;
|
||||||
|
MIDI::Port* _midi_output_port;
|
||||||
|
MIDI::Port* _midi_clock_input_port;
|
||||||
|
MIDI::Port* _midi_clock_output_port;
|
||||||
std::string _path;
|
std::string _path;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
bool _is_new;
|
bool _is_new;
|
||||||
|
|
@ -1154,8 +1151,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
int start_midi_thread ();
|
int start_midi_thread ();
|
||||||
void terminate_midi_thread ();
|
void terminate_midi_thread ();
|
||||||
|
|
||||||
int use_config_midi_ports ();
|
|
||||||
|
|
||||||
void set_play_loop (bool yn);
|
void set_play_loop (bool yn);
|
||||||
void unset_play_loop ();
|
void unset_play_loop ();
|
||||||
void overwrite_some_buffers (Track *);
|
void overwrite_some_buffers (Track *);
|
||||||
|
|
|
||||||
|
|
@ -98,11 +98,6 @@ using namespace ARDOUR;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
MIDI::Port *ARDOUR::default_mmc_port = 0;
|
|
||||||
MIDI::Port *ARDOUR::default_mtc_port = 0;
|
|
||||||
MIDI::Port *ARDOUR::default_midi_port = 0;
|
|
||||||
MIDI::Port *ARDOUR::default_midi_clock_port = 0;
|
|
||||||
|
|
||||||
compute_peak_t ARDOUR::compute_peak = 0;
|
compute_peak_t ARDOUR::compute_peak = 0;
|
||||||
find_peaks_t ARDOUR::find_peaks = 0;
|
find_peaks_t ARDOUR::find_peaks = 0;
|
||||||
apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
|
apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
|
||||||
|
|
@ -146,87 +141,6 @@ ARDOUR::make_property_quarks ()
|
||||||
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope_FAKE = %1\n", Properties::envelope.property_id));
|
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope_FAKE = %1\n", Properties::envelope.property_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ARDOUR::setup_midi ()
|
|
||||||
{
|
|
||||||
if (Config->midi_ports.size() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BootMessage (_("Configuring MIDI ports"));
|
|
||||||
|
|
||||||
for (std::map<string,XMLNode>::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
|
|
||||||
MIDI::Manager::instance()->add_port (i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
MIDI::Port* first;
|
|
||||||
const MIDI::Manager::PortList& ports = MIDI::Manager::instance()->get_midi_ports();
|
|
||||||
|
|
||||||
if (ports.size() > 1) {
|
|
||||||
|
|
||||||
first = ports.front();
|
|
||||||
|
|
||||||
/* More than one port, so try using specific names for each port */
|
|
||||||
|
|
||||||
default_mmc_port = MIDI::Manager::instance()->port (Config->get_mmc_port_name());
|
|
||||||
default_mtc_port = MIDI::Manager::instance()->port (Config->get_mtc_port_name());
|
|
||||||
default_midi_port = MIDI::Manager::instance()->port (Config->get_midi_port_name());
|
|
||||||
default_midi_clock_port = MIDI::Manager::instance()->port (Config->get_midi_clock_port_name());
|
|
||||||
|
|
||||||
/* If that didn't work, just use the first listed port */
|
|
||||||
|
|
||||||
if (default_mmc_port == 0) {
|
|
||||||
default_mmc_port = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_mtc_port == 0) {
|
|
||||||
default_mtc_port = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_port == 0) {
|
|
||||||
default_midi_port = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_clock_port == 0) {
|
|
||||||
default_midi_clock_port = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (ports.size() == 1) {
|
|
||||||
|
|
||||||
first = ports.front();
|
|
||||||
|
|
||||||
/* Only one port described, so use it for both MTC and MMC */
|
|
||||||
|
|
||||||
default_mmc_port = first;
|
|
||||||
default_mtc_port = default_mmc_port;
|
|
||||||
default_midi_port = default_mmc_port;
|
|
||||||
default_midi_clock_port = default_mmc_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_mmc_port == 0) {
|
|
||||||
warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name())
|
|
||||||
<< endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (default_mtc_port == 0) {
|
|
||||||
warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name())
|
|
||||||
<< endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_port == 0) {
|
|
||||||
warning << string_compose (_("No MIDI parameter support (MIDI port \"%1\" not available)"), Config->get_midi_port_name())
|
|
||||||
<< endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_clock_port == 0) {
|
|
||||||
warning << string_compose (_("No MIDI Clock support (MIDI port \"%1\" not available)"), Config->get_midi_clock_port_name())
|
|
||||||
<< endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
setup_hardware_optimization (bool try_optimization)
|
setup_hardware_optimization (bool try_optimization)
|
||||||
{
|
{
|
||||||
|
|
@ -373,8 +287,6 @@ ARDOUR::init (bool use_vst, bool try_optimization)
|
||||||
|
|
||||||
Config->set_use_vst (use_vst);
|
Config->set_use_vst (use_vst);
|
||||||
|
|
||||||
cerr << "After config loaded, MTC port name = " << Config->get_mtc_port_name() << endl;
|
|
||||||
|
|
||||||
Profile = new RuntimeProfile;
|
Profile = new RuntimeProfile;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,26 +258,7 @@ RCConfiguration::set_state (const XMLNode& root, int /*version*/)
|
||||||
|
|
||||||
node = *niter;
|
node = *niter;
|
||||||
|
|
||||||
if (node->name() == "MIDI-port") {
|
if (node->name() == "Config") {
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
MIDI::Port::Descriptor desc (*node);
|
|
||||||
map<string,XMLNode>::iterator x;
|
|
||||||
|
|
||||||
if ((x = midi_ports.find (desc.tag)) != midi_ports.end()) {
|
|
||||||
warning << string_compose (_("Duplicate MIDI port definition found (tag=\"%1\") - ignored"),
|
|
||||||
desc.tag) << endmsg;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
midi_ports.insert (pair<string,XMLNode>(desc.tag,*node));
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
|
||||||
warning << _("ill-formed MIDI port specification in ardour rcfile (ignored)") << endmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (node->name() == "Config") {
|
|
||||||
|
|
||||||
set_variables (*node);
|
set_variables (*node);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,6 @@ Session::Session (AudioEngine &eng,
|
||||||
_target_transport_speed (0.0),
|
_target_transport_speed (0.0),
|
||||||
_requested_return_frame (-1),
|
_requested_return_frame (-1),
|
||||||
_mmc (0),
|
_mmc (0),
|
||||||
_mtc_port (default_mtc_port),
|
|
||||||
_midi_port (default_midi_port),
|
|
||||||
_midi_clock_port (default_midi_clock_port),
|
|
||||||
_session_dir (new SessionDirectory(fullpath)),
|
_session_dir (new SessionDirectory(fullpath)),
|
||||||
state_tree (0),
|
state_tree (0),
|
||||||
_butler (new Butler (*this)),
|
_butler (new Butler (*this)),
|
||||||
|
|
@ -307,6 +304,13 @@ Session::destroy ()
|
||||||
|
|
||||||
delete _mmc;
|
delete _mmc;
|
||||||
|
|
||||||
|
delete _mtc_input_port;
|
||||||
|
delete _mtc_output_port;
|
||||||
|
delete _midi_input_port;
|
||||||
|
delete _midi_output_port;
|
||||||
|
delete _midi_clock_input_port;
|
||||||
|
delete _midi_clock_output_port;
|
||||||
|
|
||||||
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
|
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
|
||||||
playlists.reset ();
|
playlists.reset ();
|
||||||
|
|
||||||
|
|
@ -3855,11 +3859,11 @@ Session::get_available_sync_options () const
|
||||||
|
|
||||||
ret.push_back (JACK);
|
ret.push_back (JACK);
|
||||||
|
|
||||||
if (mtc_port()) {
|
if (mtc_input_port()) {
|
||||||
ret.push_back (MTC);
|
ret.push_back (MTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (midi_clock_port()) {
|
if (midi_clock_input_port()) {
|
||||||
ret.push_back (MIDIClock);
|
ret.push_back (MIDIClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,298 +71,6 @@ Session::midi_panic()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Session::use_config_midi_ports ()
|
|
||||||
{
|
|
||||||
string port_name;
|
|
||||||
|
|
||||||
if (default_mmc_port) {
|
|
||||||
_mmc->set_port (default_mmc_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_mtc_port) {
|
|
||||||
set_mtc_port (default_mtc_port->name());
|
|
||||||
} else {
|
|
||||||
set_mtc_port ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_port) {
|
|
||||||
set_midi_port (default_midi_port->name());
|
|
||||||
} else {
|
|
||||||
set_midi_port ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_midi_clock_port) {
|
|
||||||
set_midi_clock_port (default_midi_clock_port->name());
|
|
||||||
} else {
|
|
||||||
set_midi_clock_port ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
MTC, MMC, etc.
|
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
int
|
|
||||||
Session::set_mtc_port (string port_tag)
|
|
||||||
{
|
|
||||||
MTC_Slave *ms;
|
|
||||||
|
|
||||||
if (port_tag.length() == 0) {
|
|
||||||
|
|
||||||
if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
|
|
||||||
error << string_compose (_("%1 is slaved to MTC - port cannot be reset"), PROGRAM_NAME) << endmsg;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mtc_port == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mtc_port = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIDI::Port* port;
|
|
||||||
|
|
||||||
if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
|
|
||||||
error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mtc_port = port;
|
|
||||||
|
|
||||||
if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
|
|
||||||
ms->rebind (*port);
|
|
||||||
}
|
|
||||||
|
|
||||||
Config->set_mtc_port_name (port_tag);
|
|
||||||
|
|
||||||
out:
|
|
||||||
MTC_PortChanged(); /* EMIT SIGNAL */
|
|
||||||
set_dirty();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Session::set_midi_port (string /*port_tag*/)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (port_tag.length() == 0) {
|
|
||||||
if (_midi_port == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_midi_port = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIDI::Port* port;
|
|
||||||
|
|
||||||
if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_midi_port = port;
|
|
||||||
|
|
||||||
/* XXX need something to forward this to control protocols ? or just
|
|
||||||
use the signal below
|
|
||||||
*/
|
|
||||||
|
|
||||||
Config->set_midi_port_name (port_tag);
|
|
||||||
|
|
||||||
out:
|
|
||||||
#endif
|
|
||||||
MIDI_PortChanged(); /* EMIT SIGNAL */
|
|
||||||
set_dirty();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Session::set_midi_clock_port (string port_tag)
|
|
||||||
{
|
|
||||||
MIDIClock_Slave *ms;
|
|
||||||
|
|
||||||
if (port_tag.length() == 0) {
|
|
||||||
|
|
||||||
if (_slave && ((ms = dynamic_cast<MIDIClock_Slave*> (_slave)) != 0)) {
|
|
||||||
error << string_compose (_("%1 is slaved to MIDI Clock - port cannot be reset"), PROGRAM_NAME) << endmsg;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_clock_port == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_midi_clock_port = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIDI::Port* port;
|
|
||||||
|
|
||||||
if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
|
|
||||||
error << string_compose (_("unknown port %1 requested for MIDI Clock"), port_tag) << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_midi_clock_port = port;
|
|
||||||
|
|
||||||
if (_slave && ((ms = dynamic_cast<MIDIClock_Slave*> (_slave)) != 0)) {
|
|
||||||
ms->rebind (*port);
|
|
||||||
}
|
|
||||||
|
|
||||||
Config->set_midi_clock_port_name (port_tag);
|
|
||||||
|
|
||||||
out:
|
|
||||||
MIDIClock_PortChanged(); /* EMIT SIGNAL */
|
|
||||||
set_dirty();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Session::set_trace_midi_input (bool yn, MIDI::Port* port)
|
|
||||||
{
|
|
||||||
MIDI::Parser* input_parser;
|
|
||||||
|
|
||||||
cerr << "enabling tracing: " << yn << " for input port " << port->name() << endl;
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
if ((input_parser = port->input()) != 0) {
|
|
||||||
input_parser->trace (yn, &cout, "input: ");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (_mmc->port()) {
|
|
||||||
if ((input_parser = _mmc->port()->input()) != 0) {
|
|
||||||
input_parser->trace (yn, &cout, "input: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mtc_port && _mtc_port != _mmc->port()) {
|
|
||||||
if ((input_parser = _mtc_port->input()) != 0) {
|
|
||||||
input_parser->trace (yn, &cout, "input: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_port && _midi_port != _mmc->port() && _midi_port != _mtc_port) {
|
|
||||||
if ((input_parser = _midi_port->input()) != 0) {
|
|
||||||
input_parser->trace (yn, &cout, "input: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_clock_port
|
|
||||||
&& _midi_clock_port != _mmc->port()
|
|
||||||
&& _midi_clock_port != _mtc_port
|
|
||||||
&& _midi_clock_port != _midi_port) {
|
|
||||||
if ((input_parser = _midi_clock_port->input()) != 0) {
|
|
||||||
input_parser->trace (yn, &cout, "input: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Config->set_trace_midi_input (yn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Session::set_trace_midi_output (bool yn, MIDI::Port* port)
|
|
||||||
{
|
|
||||||
MIDI::Parser* output_parser;
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
if ((output_parser = port->output()) != 0) {
|
|
||||||
output_parser->trace (yn, &cout, "output: ");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_mmc->port()) {
|
|
||||||
if ((output_parser = _mmc->port()->output()) != 0) {
|
|
||||||
output_parser->trace (yn, &cout, "output: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mtc_port && _mtc_port != _mmc->port()) {
|
|
||||||
if ((output_parser = _mtc_port->output()) != 0) {
|
|
||||||
output_parser->trace (yn, &cout, "output: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_port && _midi_port != _mmc->port() && _midi_port != _mtc_port) {
|
|
||||||
if ((output_parser = _midi_port->output()) != 0) {
|
|
||||||
output_parser->trace (yn, &cout, "output: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Config->set_trace_midi_output (yn);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Session::get_trace_midi_input(MIDI::Port *port)
|
|
||||||
{
|
|
||||||
MIDI::Parser* input_parser;
|
|
||||||
if (port) {
|
|
||||||
if ((input_parser = port->input()) != 0) {
|
|
||||||
return input_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (_mmc->port()) {
|
|
||||||
if ((input_parser = _mmc->port()->input()) != 0) {
|
|
||||||
return input_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mtc_port) {
|
|
||||||
if ((input_parser = _mtc_port->input()) != 0) {
|
|
||||||
return input_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_port) {
|
|
||||||
if ((input_parser = _midi_port->input()) != 0) {
|
|
||||||
return input_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Session::get_trace_midi_output(MIDI::Port *port)
|
|
||||||
{
|
|
||||||
MIDI::Parser* output_parser;
|
|
||||||
if (port) {
|
|
||||||
if ((output_parser = port->output()) != 0) {
|
|
||||||
return output_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (_mmc->port()) {
|
|
||||||
if ((output_parser = _mmc->port()->output()) != 0) {
|
|
||||||
return output_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mtc_port) {
|
|
||||||
if ((output_parser = _mtc_port->output()) != 0) {
|
|
||||||
return output_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_midi_port) {
|
|
||||||
if ((output_parser = _midi_port->output()) != 0) {
|
|
||||||
return output_parser->tracing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::setup_midi_control ()
|
Session::setup_midi_control ()
|
||||||
{
|
{
|
||||||
|
|
@ -649,7 +357,7 @@ Session::send_full_time_code(nframes_t /*nframes*/)
|
||||||
|
|
||||||
_send_timecode_update = false;
|
_send_timecode_update = false;
|
||||||
|
|
||||||
if (_mtc_port == 0 || !session_send_mtc || _slave) {
|
if (_mtc_output_port == 0 || !session_send_mtc || _slave) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -684,7 +392,7 @@ Session::send_full_time_code(nframes_t /*nframes*/)
|
||||||
msg[8] = timecode.frames;
|
msg[8] = timecode.frames;
|
||||||
|
|
||||||
// Send message at offset 0, sent time is for the start of this cycle
|
// Send message at offset 0, sent time is for the start of this cycle
|
||||||
if (_mtc_port->midimsg (msg, sizeof (msg), 0)) {
|
if (_mtc_output_port->midimsg (msg, sizeof (msg), 0)) {
|
||||||
error << _("Session: could not send full MIDI time code") << endmsg;
|
error << _("Session: could not send full MIDI time code") << endmsg;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -702,7 +410,7 @@ Session::send_full_time_code(nframes_t /*nframes*/)
|
||||||
int
|
int
|
||||||
Session::send_midi_time_code_for_cycle(nframes_t nframes)
|
Session::send_midi_time_code_for_cycle(nframes_t nframes)
|
||||||
{
|
{
|
||||||
if (_mtc_port == 0 || _slave || !session_send_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
|
if (_mtc_output_port == 0 || _slave || !session_send_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
|
||||||
// cerr << "(MTC) Not sending MTC\n";
|
// cerr << "(MTC) Not sending MTC\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -763,7 +471,7 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
|
||||||
nframes_t out_stamp = msg_time - _transport_frame;
|
nframes_t out_stamp = msg_time - _transport_frame;
|
||||||
assert(out_stamp < nframes);
|
assert(out_stamp < nframes);
|
||||||
|
|
||||||
if (_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
|
if (_mtc_output_port->midimsg (mtc_msg, 2, out_stamp)) {
|
||||||
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
||||||
<< endmsg;
|
<< endmsg;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
|
|
||||||
#include "midi++/mmc.h"
|
#include "midi++/mmc.h"
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
|
#include "midi++/manager.h"
|
||||||
|
|
||||||
#include "pbd/boost_debug.h"
|
#include "pbd/boost_debug.h"
|
||||||
#include "pbd/controllable_descriptor.h"
|
#include "pbd/controllable_descriptor.h"
|
||||||
|
|
@ -276,6 +277,17 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||||
|
|
||||||
Delivery::disable_panners ();
|
Delivery::disable_panners ();
|
||||||
IO::disable_connecting ();
|
IO::disable_connecting ();
|
||||||
|
|
||||||
|
/* Create MIDI control ports */
|
||||||
|
|
||||||
|
MIDI::Manager* m = MIDI::Manager::instance ();
|
||||||
|
|
||||||
|
_mtc_input_port = m->add_port (new MIDI::Port ("MTC", O_RDONLY, _engine.jack()));
|
||||||
|
_mtc_output_port = m->add_port (new MIDI::Port ("MTC", O_WRONLY, _engine.jack()));
|
||||||
|
_midi_input_port = m->add_port (new MIDI::Port ("MIDI control", O_RDONLY, _engine.jack()));
|
||||||
|
_midi_output_port = m->add_port (new MIDI::Port ("MIDI control", O_WRONLY, _engine.jack()));
|
||||||
|
_midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock", O_RDONLY, _engine.jack()));
|
||||||
|
_midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock", O_WRONLY, _engine.jack()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -1243,8 +1255,6 @@ Session::set_state (const XMLNode& node, int version)
|
||||||
error << _("Session: XML state has no options section") << endmsg;
|
error << _("Session: XML state has no options section") << endmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
use_config_midi_ports ();
|
|
||||||
|
|
||||||
if (version >= 3000) {
|
if (version >= 3000) {
|
||||||
if ((child = find_named_node (node, "Metadata")) == 0) {
|
if ((child = find_named_node (node, "Metadata")) == 0) {
|
||||||
warning << _("Session: XML state has no metadata section") << endmsg;
|
warning << _("Session: XML state has no metadata section") << endmsg;
|
||||||
|
|
@ -3247,18 +3257,10 @@ Session::config_changed (std::string p, bool ours)
|
||||||
|
|
||||||
} else if (p == "send-mtc") {
|
} else if (p == "send-mtc") {
|
||||||
|
|
||||||
/* only set the internal flag if we have
|
session_send_mtc = Config->get_send_mtc();
|
||||||
a port.
|
if (session_send_mtc) {
|
||||||
*/
|
/* mark us ready to send */
|
||||||
|
next_quarter_frame_to_send = 0;
|
||||||
if (_mtc_port != 0) {
|
|
||||||
session_send_mtc = Config->get_send_mtc();
|
|
||||||
if (session_send_mtc) {
|
|
||||||
/* mark us ready to send */
|
|
||||||
next_quarter_frame_to_send = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
session_send_mtc = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (p == "send-mmc") {
|
} else if (p == "send-mmc") {
|
||||||
|
|
@ -3267,13 +3269,7 @@ Session::config_changed (std::string p, bool ours)
|
||||||
|
|
||||||
} else if (p == "midi-feedback") {
|
} else if (p == "midi-feedback") {
|
||||||
|
|
||||||
/* only set the internal flag if we have
|
session_midi_feedback = Config->get_midi_feedback();
|
||||||
a port.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_mtc_port != 0) {
|
|
||||||
session_midi_feedback = Config->get_midi_feedback();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (p == "jack-time-master") {
|
} else if (p == "jack-time-master") {
|
||||||
|
|
||||||
|
|
@ -3311,22 +3307,13 @@ Session::config_changed (std::string p, bool ours)
|
||||||
sync_order_keys ("session");
|
sync_order_keys ("session");
|
||||||
} else if (p == "initial-program-change") {
|
} else if (p == "initial-program-change") {
|
||||||
|
|
||||||
if (_mmc->port() && Config->get_initial_program_change() >= 0) {
|
if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
|
||||||
MIDI::byte buf[2];
|
MIDI::byte buf[2];
|
||||||
|
|
||||||
buf[0] = MIDI::program; // channel zero by default
|
buf[0] = MIDI::program; // channel zero by default
|
||||||
buf[1] = (Config->get_initial_program_change() & 0x7f);
|
buf[1] = (Config->get_initial_program_change() & 0x7f);
|
||||||
|
|
||||||
_mmc->port()->midimsg (buf, sizeof (buf), 0);
|
_mmc->output_port()->midimsg (buf, sizeof (buf), 0);
|
||||||
}
|
|
||||||
} else if (p == "initial-program-change") {
|
|
||||||
|
|
||||||
if (_mmc->port() && Config->get_initial_program_change() >= 0) {
|
|
||||||
MIDI::byte* buf = new MIDI::byte[2];
|
|
||||||
|
|
||||||
buf[0] = MIDI::program; // channel zero by default
|
|
||||||
buf[1] = (Config->get_initial_program_change() & 0x7f);
|
|
||||||
// deliver_midi (_mmc_port, buf, 2);
|
|
||||||
}
|
}
|
||||||
} else if (p == "solo-mute-override") {
|
} else if (p == "solo-mute-override") {
|
||||||
// catch_up_on_solo_mute_override ();
|
// catch_up_on_solo_mute_override ();
|
||||||
|
|
@ -3379,7 +3366,7 @@ Session::load_diskstreams_2X (XMLNode const & node, int)
|
||||||
void
|
void
|
||||||
Session::setup_midi_machine_control ()
|
Session::setup_midi_machine_control ()
|
||||||
{
|
{
|
||||||
_mmc = new MIDI::MachineControl;
|
_mmc = new MIDI::MachineControl (_engine.jack());
|
||||||
|
|
||||||
_mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
_mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
||||||
_mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
_mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
||||||
|
|
|
||||||
|
|
@ -1246,9 +1246,9 @@ Session::switch_to_sync_source (SyncSource src)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mtc_port) {
|
if (_mtc_input_port) {
|
||||||
try {
|
try {
|
||||||
new_slave = new MTC_Slave (*this, *_mtc_port);
|
new_slave = new MTC_Slave (*this, *_mtc_input_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
|
|
@ -1266,9 +1266,9 @@ Session::switch_to_sync_source (SyncSource src)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_midi_clock_port) {
|
if (_midi_clock_input_port) {
|
||||||
try {
|
try {
|
||||||
new_slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
|
new_slave = new MIDIClock_Slave (*this, *_midi_clock_input_port, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ MidiClockTicker::session_going_away ()
|
||||||
|
|
||||||
void MidiClockTicker::update_midi_clock_port()
|
void MidiClockTicker::update_midi_clock_port()
|
||||||
{
|
{
|
||||||
_midi_port = _session->midi_clock_port();
|
_midi_port = _session->midi_clock_output_port();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiClockTicker::transport_state_changed()
|
void MidiClockTicker::transport_state_changed()
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,10 @@ using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
/* XXX check for strdup leaks */
|
|
||||||
|
|
||||||
Manager *Manager::theManager = 0;
|
Manager *Manager::theManager = 0;
|
||||||
|
|
||||||
Manager::Manager ()
|
Manager::Manager ()
|
||||||
{
|
{
|
||||||
inputPort = 0;
|
|
||||||
outputPort = 0;
|
|
||||||
inputChannelNumber = 0;
|
|
||||||
outputChannelNumber = 0;
|
|
||||||
api_data = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager ()
|
Manager::~Manager ()
|
||||||
|
|
@ -57,144 +50,13 @@ Manager::~Manager ()
|
||||||
}
|
}
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
Manager::add_port (const XMLNode& node)
|
Manager::add_port (Port* p)
|
||||||
{
|
{
|
||||||
Port::Descriptor desc (node);
|
_ports.push_back (p);
|
||||||
Port *port;
|
|
||||||
PortList::iterator p;
|
|
||||||
|
|
||||||
for (p = _ports.begin(); p != _ports.end(); ++p) {
|
|
||||||
|
|
||||||
if (desc.tag == (*p)->name()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p != _ports.end()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = new Port (node, (jack_client_t *) api_data);
|
|
||||||
|
|
||||||
if (port == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!port->ok()) {
|
|
||||||
delete port;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ports.push_back (port);
|
|
||||||
|
|
||||||
/* first port added becomes the default input
|
|
||||||
port.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (inputPort == 0) {
|
|
||||||
inputPort = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputPort == 0) {
|
|
||||||
outputPort = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortsChanged (); /* EMIT SIGNAL */
|
PortsChanged (); /* EMIT SIGNAL */
|
||||||
|
|
||||||
return port;
|
return p;
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::remove_port (Port* port)
|
|
||||||
{
|
|
||||||
if (inputPort == port) {
|
|
||||||
inputPort = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputPort == port) {
|
|
||||||
outputPort = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ports.remove (port);
|
|
||||||
delete port;
|
|
||||||
|
|
||||||
PortsChanged (); /* EMIT SIGNAL */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_input_port (string tag)
|
|
||||||
{
|
|
||||||
for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
|
|
||||||
if ((*p)->name() == tag) {
|
|
||||||
inputPort = (*p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_output_port (string tag)
|
|
||||||
{
|
|
||||||
PortList::iterator p;
|
|
||||||
|
|
||||||
for (p = _ports.begin(); p != _ports.end(); ++p) {
|
|
||||||
if ((*p)->name() == tag) {
|
|
||||||
inputPort = (*p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p == _ports.end()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX send a signal to say we're about to change output ports
|
|
||||||
|
|
||||||
if (outputPort) {
|
|
||||||
for (channel_t chan = 0; chan < 16; chan++) {
|
|
||||||
outputPort->channel (chan)->all_notes_off (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outputPort = (*p);
|
|
||||||
|
|
||||||
// XXX send a signal to say we've changed output ports
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Port *
|
|
||||||
Manager::port (string name)
|
|
||||||
{
|
|
||||||
for (PortList::iterator p = _ports.begin(); p != _ports.end(); ++p) {
|
|
||||||
if (name == (*p)->name()) {
|
|
||||||
return (*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::foreach_port (int (*func)(const Port &, size_t, void *),
|
|
||||||
void *arg)
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
for (PortList::const_iterator p = _ports.begin(); p != _ports.end(); ++p, ++n) {
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
if ((retval = func (**p, n, arg)) != 0) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -230,3 +92,18 @@ Manager::reconnect ()
|
||||||
(*p)->reconnect ();
|
(*p)->reconnect ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Port*
|
||||||
|
Manager::port (string const & n)
|
||||||
|
{
|
||||||
|
PortList::const_iterator p = _ports.begin();
|
||||||
|
while (p != _ports.end() && (*p)->name() != n) {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == _ports.end()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#define __midi_manager_h__
|
#define __midi_manager_h__
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -34,8 +33,6 @@ class Manager {
|
||||||
public:
|
public:
|
||||||
~Manager ();
|
~Manager ();
|
||||||
|
|
||||||
void set_api_data(void* data) { api_data = data; }
|
|
||||||
|
|
||||||
/** Signal the start of an audio cycle.
|
/** Signal the start of an audio cycle.
|
||||||
* This MUST be called before any reading/writing for this cycle.
|
* This MUST be called before any reading/writing for this cycle.
|
||||||
* Realtime safe.
|
* Realtime safe.
|
||||||
|
|
@ -49,26 +46,9 @@ class Manager {
|
||||||
*/
|
*/
|
||||||
void cycle_end();
|
void cycle_end();
|
||||||
|
|
||||||
Port *add_port (const XMLNode& node);
|
Port* add_port (Port *);
|
||||||
int remove_port (Port*);
|
|
||||||
|
|
||||||
Port *port (std::string name);
|
Port* port (std::string const &);
|
||||||
|
|
||||||
size_t nports () const { return _ports.size(); }
|
|
||||||
|
|
||||||
/* defaults for clients who are not picky */
|
|
||||||
|
|
||||||
Port *inputPort;
|
|
||||||
Port *outputPort;
|
|
||||||
channel_t inputChannelNumber;
|
|
||||||
channel_t outputChannelNumber;
|
|
||||||
|
|
||||||
int set_input_port (std::string);
|
|
||||||
int set_output_port (std::string);
|
|
||||||
int set_input_channel (channel_t);
|
|
||||||
int set_output_channel (channel_t);
|
|
||||||
|
|
||||||
int foreach_port (int (*func)(const Port &, size_t n, void *), void *arg);
|
|
||||||
|
|
||||||
typedef std::list<Port *> PortList;
|
typedef std::list<Port *> PortList;
|
||||||
|
|
||||||
|
|
@ -90,13 +70,9 @@ class Manager {
|
||||||
/* This is a SINGLETON pattern */
|
/* This is a SINGLETON pattern */
|
||||||
|
|
||||||
Manager ();
|
Manager ();
|
||||||
|
|
||||||
static Manager *theManager;
|
static Manager *theManager;
|
||||||
|
|
||||||
std::list<Port*> _ports;
|
std::list<Port*> _ports;
|
||||||
|
|
||||||
void* api_data;
|
|
||||||
|
|
||||||
void close_ports ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#ifndef __midipp_mmc_h_h__
|
#ifndef __midipp_mmc_h_h__
|
||||||
#define __midipp_mmc_h_h__
|
#define __midipp_mmc_h_h__
|
||||||
|
|
||||||
|
#include <jack/types.h>
|
||||||
#include "control_protocol/timecode.h"
|
#include "control_protocol/timecode.h"
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
#include "pbd/ringbuffer.h"
|
#include "pbd/ringbuffer.h"
|
||||||
|
|
@ -87,10 +88,9 @@ class MachineControl
|
||||||
cmdResume = 0x7F
|
cmdResume = 0x7F
|
||||||
};
|
};
|
||||||
|
|
||||||
MachineControl ();
|
MachineControl (jack_client_t *);
|
||||||
void set_port (Port* p);
|
|
||||||
|
|
||||||
Port* port() { return _port; }
|
Port* output_port() { return _output_port; }
|
||||||
|
|
||||||
void set_receive_device_id (byte id);
|
void set_receive_device_id (byte id);
|
||||||
void set_send_device_id (byte id);
|
void set_send_device_id (byte id);
|
||||||
|
|
@ -255,7 +255,8 @@ class MachineControl
|
||||||
private:
|
private:
|
||||||
byte _receive_device_id;
|
byte _receive_device_id;
|
||||||
byte _send_device_id;
|
byte _send_device_id;
|
||||||
Port* _port;
|
Port* _input_port;
|
||||||
|
Port* _output_port;
|
||||||
bool _enable_send; ///< true if MMC sending is enabled
|
bool _enable_send; ///< true if MMC sending is enabled
|
||||||
|
|
||||||
void process_mmc_message (Parser &p, byte *, size_t len);
|
void process_mmc_message (Parser &p, byte *, size_t len);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ class PortRequest;
|
||||||
|
|
||||||
class Port {
|
class Port {
|
||||||
public:
|
public:
|
||||||
|
Port (std::string const &, int, jack_client_t *);
|
||||||
Port (const XMLNode&, jack_client_t *);
|
Port (const XMLNode&, jack_client_t *);
|
||||||
~Port ();
|
~Port ();
|
||||||
|
|
||||||
|
|
@ -135,7 +136,7 @@ private:
|
||||||
|
|
||||||
static size_t nports;
|
static size_t nports;
|
||||||
|
|
||||||
int create_ports(const XMLNode&);
|
void create_port_names ();
|
||||||
int create_ports ();
|
int create_ports ();
|
||||||
|
|
||||||
jack_client_t* _jack_client;
|
jack_client_t* _jack_client;
|
||||||
|
|
@ -156,6 +157,7 @@ private:
|
||||||
void flush (void* jack_port_buffer);
|
void flush (void* jack_port_buffer);
|
||||||
void jack_halted ();
|
void jack_halted ();
|
||||||
void make_connections();
|
void make_connections();
|
||||||
|
void init (std::string const &, int);
|
||||||
|
|
||||||
static pthread_t _process_thread;
|
static pthread_t _process_thread;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "control_protocol/timecode.h"
|
#include "control_protocol/timecode.h"
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
#include "midi++/mmc.h"
|
#include "midi++/mmc.h"
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
#include "midi++/parser.h"
|
#include "midi++/parser.h"
|
||||||
|
#include "midi++/manager.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
|
@ -193,30 +195,20 @@ static void build_mmc_cmd_map ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MachineControl::MachineControl ()
|
MachineControl::MachineControl (jack_client_t* jack)
|
||||||
: _port (0)
|
|
||||||
{
|
{
|
||||||
build_mmc_cmd_map ();
|
build_mmc_cmd_map ();
|
||||||
|
|
||||||
_receive_device_id = 0;
|
_receive_device_id = 0;
|
||||||
_send_device_id = 0x7f;
|
_send_device_id = 0x7f;
|
||||||
}
|
|
||||||
|
|
||||||
void
|
_input_port = Manager::instance()->add_port (new Port ("MMC", O_RDONLY, jack));
|
||||||
MachineControl::set_port (Port* p)
|
_output_port = Manager::instance()->add_port (new Port ("MMC", O_WRONLY, jack));
|
||||||
{
|
|
||||||
_port = p;
|
|
||||||
|
|
||||||
port_connections.drop_connections ();
|
_input_port->input()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
|
||||||
|
_input_port->input()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
|
||||||
if (_port->input()) {
|
_input_port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
|
||||||
_port->input()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3));
|
_input_port->input()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
|
||||||
_port->input()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this, _1, _2));
|
|
||||||
_port->input()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this, _1, _2));
|
|
||||||
_port->input()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this, _1, _2));
|
|
||||||
} else {
|
|
||||||
warning << "MMC connected to a non-input port: useless!" << endmsg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -643,7 +635,7 @@ MachineControl::enable_send (bool yn)
|
||||||
void
|
void
|
||||||
MachineControl::send (MachineControlCommand const & c)
|
MachineControl::send (MachineControlCommand const & c)
|
||||||
{
|
{
|
||||||
if (_port == 0 || !_enable_send) {
|
if (_output_port == 0 || !_enable_send) {
|
||||||
// cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl;
|
// cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -651,7 +643,7 @@ MachineControl::send (MachineControlCommand const & c)
|
||||||
MIDI::byte buffer[32];
|
MIDI::byte buffer[32];
|
||||||
MIDI::byte* b = c.fill_buffer (this, buffer);
|
MIDI::byte* b = c.fill_buffer (this, buffer);
|
||||||
|
|
||||||
if (_port->midimsg (buffer, b - buffer, 0)) {
|
if (_output_port->midimsg (buffer, b - buffer, 0)) {
|
||||||
error << "MMC: cannot send command" << endmsg;
|
error << "MMC: cannot send command" << endmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,19 @@ pthread_t Port::_process_thread;
|
||||||
Signal0<void> Port::JackHalted;
|
Signal0<void> Port::JackHalted;
|
||||||
Signal0<void> Port::MakeConnections;
|
Signal0<void> Port::MakeConnections;
|
||||||
|
|
||||||
|
Port::Port (string const & name, int mode, jack_client_t* jack_client)
|
||||||
|
: _currently_in_cycle (false)
|
||||||
|
, _nframes_this_cycle (0)
|
||||||
|
, _jack_client (jack_client)
|
||||||
|
, _jack_input_port (0)
|
||||||
|
, _jack_output_port (0)
|
||||||
|
, _last_read_index (0)
|
||||||
|
, output_fifo (512)
|
||||||
|
, input_fifo (1024)
|
||||||
|
{
|
||||||
|
init (name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
||||||
: _currently_in_cycle (false)
|
: _currently_in_cycle (false)
|
||||||
, _nframes_this_cycle (0)
|
, _nframes_this_cycle (0)
|
||||||
|
|
@ -56,6 +69,14 @@ Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
||||||
{
|
{
|
||||||
Descriptor desc (node);
|
Descriptor desc (node);
|
||||||
|
|
||||||
|
init (desc.tag, desc.mode);
|
||||||
|
|
||||||
|
set_state (node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Port::init (string const & name, int mode)
|
||||||
|
{
|
||||||
_ok = false; /* derived class must set to true if constructor
|
_ok = false; /* derived class must set to true if constructor
|
||||||
succeeds.
|
succeeds.
|
||||||
*/
|
*/
|
||||||
|
|
@ -63,8 +84,8 @@ Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
||||||
input_parser = 0;
|
input_parser = 0;
|
||||||
output_parser = 0;
|
output_parser = 0;
|
||||||
|
|
||||||
_tagname = desc.tag;
|
_tagname = name;
|
||||||
_mode = desc.mode;
|
_mode = mode;
|
||||||
|
|
||||||
if (_mode == O_RDONLY || _mode == O_RDWR) {
|
if (_mode == O_RDONLY || _mode == O_RDWR) {
|
||||||
input_parser = new Parser (*this);
|
input_parser = new Parser (*this);
|
||||||
|
|
@ -90,14 +111,14 @@ Port::Port (const XMLNode& node, jack_client_t* jack_client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create_ports (node)) {
|
create_port_names ();
|
||||||
|
|
||||||
|
if (!create_ports ()) {
|
||||||
_ok = true;
|
_ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeConnections.connect_same_thread (connect_connection, boost::bind (&Port::make_connections, this));
|
MakeConnections.connect_same_thread (connect_connection, boost::bind (&Port::make_connections, this));
|
||||||
JackHalted.connect_same_thread (halt_connection, boost::bind (&Port::jack_halted, this));
|
JackHalted.connect_same_thread (halt_connection, boost::bind (&Port::jack_halted, this));
|
||||||
|
|
||||||
set_state (node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -108,17 +129,17 @@ Port::~Port ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_jack_input_port) {
|
if (_jack_input_port) {
|
||||||
if (_jack_client) {
|
if (_jack_client && _jack_input_port) {
|
||||||
jack_port_unregister (_jack_client, _jack_input_port);
|
jack_port_unregister (_jack_client, _jack_input_port);
|
||||||
}
|
}
|
||||||
_jack_input_port = 0;
|
_jack_input_port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_jack_output_port) {
|
if (_jack_output_port) {
|
||||||
if (_jack_client) {
|
if (_jack_client && _jack_output_port) {
|
||||||
jack_port_unregister (_jack_client, _jack_input_port);
|
jack_port_unregister (_jack_client, _jack_output_port);
|
||||||
}
|
}
|
||||||
_jack_input_port = 0;
|
_jack_output_port = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,23 +428,19 @@ Port::read (byte *, size_t)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
Port::create_ports(const XMLNode& node)
|
Port::create_port_names ()
|
||||||
{
|
{
|
||||||
Descriptor desc (node);
|
|
||||||
|
|
||||||
assert(!_jack_input_port);
|
assert(!_jack_input_port);
|
||||||
assert(!_jack_output_port);
|
assert(!_jack_output_port);
|
||||||
|
|
||||||
if (desc.mode == O_RDWR || desc.mode == O_WRONLY) {
|
if (_mode == O_RDWR || _mode == O_WRONLY) {
|
||||||
_jack_output_port_name = string(desc.tag).append ("_out");
|
_jack_output_port_name = _tagname.append ("_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.mode == O_RDWR || desc.mode == O_RDONLY) {
|
if (_mode == O_RDWR || _mode == O_RDONLY) {
|
||||||
_jack_input_port_name = string(desc.tag).append ("_in");
|
_jack_input_port_name = _tagname.append ("_in");
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ports ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#include "pbd/xml++.h"
|
#include "pbd/xml++.h"
|
||||||
|
|
||||||
#include "midi++/port.h"
|
#include "midi++/port.h"
|
||||||
#include "midi++/manager.h"
|
|
||||||
|
|
||||||
#include "ardour/filesystem_paths.h"
|
#include "ardour/filesystem_paths.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
|
@ -57,20 +56,8 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||||
, gui (0)
|
, gui (0)
|
||||||
{
|
{
|
||||||
|
|
||||||
MIDI::Manager* mm = MIDI::Manager::instance();
|
_input_port = s.midi_input_port ();
|
||||||
|
_output_port = s.midi_output_port ();
|
||||||
/* XXX it might be nice to run "control" through i18n, but thats a bit tricky because
|
|
||||||
the name is defined in ardour.rc which is likely not internationalized.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_port = mm->port (Config->get_midi_port_name());
|
|
||||||
|
|
||||||
if (_port == 0) {
|
|
||||||
error << string_compose (_("no MIDI port named \"%1\" exists - generic MIDI control disabled"),
|
|
||||||
Config->get_midi_port_name())
|
|
||||||
<< endmsg;
|
|
||||||
throw failed_constructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
do_feedback = false;
|
do_feedback = false;
|
||||||
_feedback_interval = 10000; // microseconds
|
_feedback_interval = 10000; // microseconds
|
||||||
|
|
@ -274,7 +261,7 @@ GenericMidiControlProtocol::_send_feedback ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_port->write (buf, (int32_t) (end - buf), 0);
|
_output_port->write (buf, (int32_t) (end - buf), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -324,7 +311,7 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mc) {
|
if (!mc) {
|
||||||
mc = new MIDIControllable (*_port, *c, false);
|
mc = new MIDIControllable (*_input_port, *c, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -421,7 +408,7 @@ GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos,
|
||||||
MIDI::byte value = control_number;
|
MIDI::byte value = control_number;
|
||||||
|
|
||||||
// Create a MIDIControllable
|
// Create a MIDIControllable
|
||||||
MIDIControllable* mc = new MIDIControllable (*_port, *control, false);
|
MIDIControllable* mc = new MIDIControllable (*_input_port, *control, false);
|
||||||
|
|
||||||
// Remove any old binding for this midi channel/type/value pair
|
// Remove any old binding for this midi channel/type/value pair
|
||||||
// Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
|
// Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
|
||||||
|
|
@ -533,7 +520,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
|
||||||
c = session->controllable_by_id (id);
|
c = session->controllable_by_id (id);
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
MIDIControllable* mc = new MIDIControllable (*_port, *c, false);
|
MIDIControllable* mc = new MIDIControllable (*_input_port, *c, false);
|
||||||
|
|
||||||
if (mc->set_state (**niter, version) == 0) {
|
if (mc->set_state (**niter, version) == 0) {
|
||||||
controllables.push_back (mc);
|
controllables.push_back (mc);
|
||||||
|
|
@ -715,7 +702,7 @@ GenericMidiControlProtocol::create_binding (const XMLNode& node)
|
||||||
prop = node.property (X_("uri"));
|
prop = node.property (X_("uri"));
|
||||||
uri = prop->value();
|
uri = prop->value();
|
||||||
|
|
||||||
MIDIControllable* mc = new MIDIControllable (*_port, momentary);
|
MIDIControllable* mc = new MIDIControllable (*_input_port, momentary);
|
||||||
|
|
||||||
if (mc->init (uri)) {
|
if (mc->init (uri)) {
|
||||||
delete mc;
|
delete mc;
|
||||||
|
|
@ -832,7 +819,7 @@ GenericMidiControlProtocol::create_function (const XMLNode& node)
|
||||||
|
|
||||||
prop = node.property (X_("function"));
|
prop = node.property (X_("function"));
|
||||||
|
|
||||||
MIDIFunction* mf = new MIDIFunction (*_port);
|
MIDIFunction* mf = new MIDIFunction (*_input_port);
|
||||||
|
|
||||||
if (mf->init (*this, prop->value(), data, data_size)) {
|
if (mf->init (*this, prop->value(), data, data_size)) {
|
||||||
delete mf;
|
delete mf;
|
||||||
|
|
@ -928,7 +915,7 @@ GenericMidiControlProtocol::create_action (const XMLNode& node)
|
||||||
|
|
||||||
prop = node.property (X_("action"));
|
prop = node.property (X_("action"));
|
||||||
|
|
||||||
MIDIAction* ma = new MIDIAction (*_port);
|
MIDIAction* ma = new MIDIAction (*_input_port);
|
||||||
|
|
||||||
if (ma->init (*this, prop->value(), data, data_size)) {
|
if (ma->init (*this, prop->value(), data, data_size)) {
|
||||||
delete ma;
|
delete ma;
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
int set_active (bool yn);
|
int set_active (bool yn);
|
||||||
static bool probe() { return true; }
|
static bool probe() { return true; }
|
||||||
|
|
||||||
MIDI::Port* port () const { return _port; }
|
MIDI::Port* input_port () const { return _input_port; }
|
||||||
|
MIDI::Port* output_port () const { return _output_port; }
|
||||||
void set_feedback_interval (ARDOUR::microseconds_t);
|
void set_feedback_interval (ARDOUR::microseconds_t);
|
||||||
|
|
||||||
int set_feedback (bool yn);
|
int set_feedback (bool yn);
|
||||||
|
|
@ -81,7 +82,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||||
void prev_bank ();
|
void prev_bank ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MIDI::Port* _port;
|
MIDI::Port* _input_port;
|
||||||
|
MIDI::Port* _output_port;
|
||||||
ARDOUR::microseconds_t _feedback_interval;
|
ARDOUR::microseconds_t _feedback_interval;
|
||||||
ARDOUR::microseconds_t last_feedback_time;
|
ARDOUR::microseconds_t last_feedback_time;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,36 +31,19 @@ using namespace std;
|
||||||
ControlProtocol*
|
ControlProtocol*
|
||||||
new_mackie_protocol (ControlProtocolDescriptor*, Session* s)
|
new_mackie_protocol (ControlProtocolDescriptor*, Session* s)
|
||||||
{
|
{
|
||||||
if ( Config->get_mmc_port_name().substr(0,3) == "mcu" )
|
MackieControlProtocol* mcp = 0;
|
||||||
{
|
|
||||||
error << "mcu already used as mmc port" << endmsg;
|
try {
|
||||||
|
mcp = new MackieControlProtocol (*s);
|
||||||
|
mcp->set_active (true);
|
||||||
}
|
}
|
||||||
else if ( Config->get_mtc_port_name().substr(0,3) == "mcu" )
|
catch (exception & e) {
|
||||||
{
|
error << "Error instantiating MackieControlProtocol: " << e.what() << endmsg;
|
||||||
error << "mcu already used as mtc port" << endmsg;
|
delete mcp;
|
||||||
|
mcp = 0;
|
||||||
}
|
}
|
||||||
else if ( Config->get_midi_port_name().substr(0,3) == "mcu" )
|
|
||||||
{
|
return mcp;
|
||||||
error << "mcu already used as midi port" << endmsg;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no one else is using the port, so try instantiate the object
|
|
||||||
MackieControlProtocol * mcp = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mcp = new MackieControlProtocol (*s);
|
|
||||||
mcp->set_active( true );
|
|
||||||
}
|
|
||||||
catch( exception & e )
|
|
||||||
{
|
|
||||||
error << "Error instantiating MackieControlProtocol: " << e.what() << endmsg;
|
|
||||||
delete mcp;
|
|
||||||
mcp = 0;
|
|
||||||
}
|
|
||||||
return mcp;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue