make MMC work again, make tracing MIDI input work again, add GUI control for MMC device ID ++

git-svn-id: svn://localhost/ardour2/trunk@1480 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-02-20 21:26:20 +00:00
parent 780e9d7ecb
commit 326cd24c12
17 changed files with 154 additions and 129 deletions

View File

@ -707,40 +707,6 @@ ARDOUR_UI::update_wall_clock ()
return TRUE;
}
void
ARDOUR_UI::control_methods_adjusted ()
{
int which_method;
which_method = (int) online_control_button->adjustment.get_value();
switch (which_method) {
case 0:
allow_mmc_and_local ();
break;
case 1:
allow_mmc_only ();
break;
case 2:
allow_local_only ();
break;
default:
fatal << _("programming error: impossible control method") << endmsg;
}
}
void
ARDOUR_UI::mmc_device_id_adjusted ()
{
#if 0
if (mmc) {
int dev_id = (int) mmc_id_button->adjustment.get_value();
mmc->set_device_id (dev_id);
}
#endif
}
gint
ARDOUR_UI::session_menu (GdkEventButton *ev)
@ -1309,24 +1275,6 @@ ARDOUR_UI::map_transport_state ()
}
}
void
ARDOUR_UI::allow_local_only ()
{
}
void
ARDOUR_UI::allow_mmc_only ()
{
}
void
ARDOUR_UI::allow_mmc_and_local ()
{
}
void
ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
{

View File

@ -273,9 +273,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
GlobalClickBox *crossfade_time_button;
vector<string> crossfade_time_strings;
GlobalClickBox *mmc_id_button;
vector<string> mmc_id_strings;
Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
@ -285,7 +282,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
int setup_windows ();
void setup_transport ();
void setup_clock ();
void setup_adjustables ();
static ARDOUR_UI *theArdourUI;
@ -313,9 +309,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void start_blinking ();
void stop_blinking ();
void control_methods_adjusted ();
void mmc_device_id_adjusted ();
void about_signal_response(int response);
private:
@ -467,14 +460,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void transport_rec_enable_blink (bool onoff);
/* These change where we accept control from:
MMC, X (local) or both.
*/
void allow_mmc_only ();
void allow_mmc_and_local ();
void allow_local_only ();
Gtk::Menu* session_popup_menu;
struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord {

View File

@ -73,7 +73,6 @@ ARDOUR_UI::setup_windows ()
setup_clock ();
setup_transport();
setup_adjustables ();
build_menu_bar ();
top_packer.pack_start (menu_bar_base, false, false);
@ -84,38 +83,6 @@ ARDOUR_UI::setup_windows ()
return 0;
}
void
ARDOUR_UI::setup_adjustables ()
{
adjuster_table.set_homogeneous (true);
online_control_strings.push_back (_("MMC + Local"));
online_control_strings.push_back (_("MMC"));
online_control_strings.push_back (_("Local"));
online_control_button = new GlobalClickBox ("CONTROL",
online_control_strings);
online_control_button->adjustment.signal_value_changed().connect(mem_fun(*this,&ARDOUR_UI::control_methods_adjusted));
mmc_id_strings.push_back ("1");
mmc_id_strings.push_back ("2");
mmc_id_strings.push_back ("3");
mmc_id_strings.push_back ("4");
mmc_id_strings.push_back ("5");
mmc_id_strings.push_back ("6");
mmc_id_strings.push_back ("7");
mmc_id_strings.push_back ("8");
mmc_id_strings.push_back ("9");
mmc_id_button = new GlobalClickBox (_("MMC ID"), mmc_id_strings);
mmc_id_button->adjustment.signal_value_changed().connect (mem_fun(*this,&ARDOUR_UI::mmc_device_id_adjusted));
adjuster_table.attach (*online_control_button, 0, 2, 1, 2, FILL|EXPAND, FILL, 5, 5);
adjuster_table.attach (*mmc_id_button, 2, 3, 1, 2, FILL, FILL, 5, 5);
}
void
ARDOUR_UI::transport_stopped ()
{

View File

@ -76,12 +76,6 @@ Keyboard::Keyboard ()
}
Meta = possible_meta[i];
if (Meta) {
cerr << "Using " << possible_meta[i] << " for Meta\n";
} else {
cerr << "NO Meta\n";
}
snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this);
XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();

View File

@ -75,6 +75,9 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
/* MIDI */
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
mmc_device_id_spinner (mmc_device_id_adjustment),
/* Click */
click_table (2, 3),
@ -368,23 +371,28 @@ OptionEditor::setup_midi_options ()
ToggleButton* tb;
RadioButton* rb;
Gtk::Table* table = manage (new Table (ports.size() + 4, 9));
Gtk::Table* table = manage (new Table (ports.size() + 4, 10));
table->set_row_spacings (6);
table->set_col_spacings (10);
table->attach (*(manage (new Label (X_("Port")))), 0, 1, 0, 1);
table->attach (*(manage (new Label (X_("Offline")))), 1, 2, 0, 1);
table->attach (*(manage (new Label (X_("Trace\nInput")))), 2, 3, 0, 1);
table->attach (*(manage (new Label (X_("Trace\nOutput")))), 3, 4, 0, 1);
table->attach (*(manage (new Label (X_("MTC")))), 4, 5, 0, 1);
table->attach (*(manage (new Label (X_("MMC")))), 6, 7, 0, 1);
table->attach (*(manage (new Label (X_("MIDI Parameter\nControl")))), 8, 9, 0, 1);
table->attach (*(manage (new Label (_("Port")))), 0, 1, 0, 1);
table->attach (*(manage (new Label (_("Offline")))), 1, 2, 0, 1);
table->attach (*(manage (new Label (_("Trace\nInput")))), 2, 3, 0, 1);
table->attach (*(manage (new Label (_("Trace\nOutput")))), 3, 4, 0, 1);
table->attach (*(manage (new Label (_("MTC")))), 4, 5, 0, 1);
table->attach (*(manage (new Label (_("MMC")))), 6, 7, 0, 1);
table->attach (*(manage (new Label (_("MIDI Parameter\nControl")))), 8, 9, 0, 1);
table->attach (*(manage (new HSeparator())), 0, 9, 1, 2);
table->attach (*(manage (new VSeparator())), 5, 6, 0, 8);
table->attach (*(manage (new VSeparator())), 7, 8, 0, 8);
table->attach (*(manage (new Label (_("MMC Device ID")))), 9, 10, 0, 1);
table->attach (mmc_device_id_spinner, 9, 10, 1, 2);
mmc_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_device_id_adjusted));
for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) {
pair<MIDI::Port*,vector<RadioButton*> > newpair;
@ -553,13 +561,23 @@ OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb)
}
}
void
OptionEditor::mmc_device_id_adjusted ()
{
uint8_t id = (uint8_t) mmc_device_id_spinner.get_value();
if (id != Config->get_mmc_device_id()) {
Config->set_mmc_device_id (id);
}
}
void
OptionEditor::port_trace_in_toggled (MIDI::Port* port, ToggleButton* tb)
{
bool trace = tb->get_active();
if (port->input()->tracing() != trace) {
port->output()->trace (trace, &cerr, string (port->name()) + string (" input: "));
port->input()->trace (trace, &cerr, string (port->name()) + string (" input: "));
}
}

View File

@ -111,6 +111,9 @@ class OptionEditor : public Gtk::Dialog
Gtk::RadioButton::Group mmc_button_group;
Gtk::RadioButton::Group midi_button_group;
Gtk::Adjustment mmc_device_id_adjustment;
Gtk::SpinButton mmc_device_id_spinner;
void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*);
void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*);
void port_trace_out_toggled (MIDI::Port*,Gtk::ToggleButton*);
@ -119,6 +122,8 @@ class OptionEditor : public Gtk::Dialog
void mtc_port_chosen (MIDI::Port*,Gtk::RadioButton*);
void midi_port_chosen (MIDI::Port*,Gtk::RadioButton*);
void mmc_device_id_adjusted ();
void map_port_online (MIDI::Port*, Gtk::ToggleButton*);
void setup_midi_options();

View File

@ -18,6 +18,7 @@ CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false)
CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false)
CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
CONFIG_VARIABLE (bool, midi_control, "midi-control", false)
CONFIG_VARIABLE (uint8_t, mmc_device_id, "mmc-device-id", 0)
/* control surfaces */

View File

@ -724,6 +724,8 @@ class Session : public PBD::StatefulDestructible
void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
void set_mmc_device_id (uint32_t id);
/* Scrubbing */
void start_scrub (nframes_t where);
@ -1267,8 +1269,7 @@ class Session : public PBD::StatefulDestructible
void mmc_record_pause (MIDI::MachineControl &);
void mmc_record_strobe (MIDI::MachineControl &);
void mmc_record_exit (MIDI::MachineControl &);
void mmc_track_record_status (MIDI::MachineControl &,
uint32_t track, bool enabled);
void mmc_track_record_status (MIDI::MachineControl &, uint32_t track, bool enabled);
void mmc_fast_forward (MIDI::MachineControl &);
void mmc_rewind (MIDI::MachineControl &);
void mmc_locate (MIDI::MachineControl &, const MIDI::byte *);

View File

@ -126,9 +126,20 @@ Session::set_mtc_port (string port_tag)
return 0;
}
void
Session::set_mmc_device_id (uint32_t device_id)
{
if (mmc) {
mmc->set_device_id (device_id);
}
}
int
Session::set_mmc_port (string port_tag)
{
MIDI::byte old_device_id;
bool reset_id = false;
if (port_tag.length() == 0) {
if (_mmc_port == 0) {
return 0;
@ -146,6 +157,8 @@ Session::set_mmc_port (string port_tag)
_mmc_port = port;
if (mmc) {
old_device_id = mmc->device_id();
reset_id = true;
delete mmc;
}
@ -153,6 +166,9 @@ Session::set_mmc_port (string port_tag)
MMC_CommandSignature,
MMC_ResponseSignature);
if (reset_id) {
mmc->set_device_id (old_device_id);
}
mmc->Play.connect
(mem_fun (*this, &Session::mmc_deferred_play));
@ -181,6 +197,7 @@ Session::set_mmc_port (string port_tag)
mmc->TrackRecordStatusChange.connect
(mem_fun (*this, &Session::mmc_record_enable));
/* also handle MIDI SPP because its so common */
_mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
@ -543,7 +560,6 @@ Session::mmc_pause (MIDI::MachineControl &mmc)
static bool step_queued = false;
void
Session::mmc_step (MIDI::MachineControl &mmc, int steps)
{
if (!Config->get_mmc_control()) {

View File

@ -2832,6 +2832,12 @@ Session::set_deletion_in_progress ()
void
Session::add_controllable (Controllable* c)
{
/* this adds a controllable to the list managed by the Session.
this is a subset of those managed by the Controllable class
itself, and represents the only ones whose state will be saved
as part of the session.
*/
Glib::Mutex::Lock lm (controllables_lock);
controllables.insert (c);
}
@ -3065,6 +3071,12 @@ Session::config_changed (const char* parameter_name)
poke_midi_thread ();
} else if (PARAM_IS ("mmc-device-id")) {
if (mmc) {
mmc->set_device_id (Config->get_mmc_device_id());
}
} else if (PARAM_IS ("midi-control")) {
poke_midi_thread ();

View File

@ -93,6 +93,8 @@ class MachineControl : public sigc::trackable
Port &port() { return _port; }
void set_device_id (byte id);
byte device_id () const { return _device_id; }
static bool is_mmc (byte *sysex_buf, size_t len);
/* Signals to connect to if you want to run "callbacks"

View File

@ -25,6 +25,7 @@
#include <unistd.h>
#include <string>
#include <iostream>
#include <iterator>
#include <midi++/types.h>
#include <midi++/parser.h>
@ -138,7 +139,6 @@ Parser::~Parser ()
void
Parser::trace_event (Parser &p, byte *msg, size_t len)
{
eventType type;
ostream *o;
@ -309,15 +309,13 @@ Parser::trace_event (Parser &p, byte *msg, size_t len)
void
Parser::trace (bool onoff, ostream *o, const string &prefix)
{
trace_connection.disconnect ();
if (onoff) {
trace_stream = o;
trace_prefix = prefix;
trace_connection = any.connect
(mem_fun (*this, &Parser::trace_event));
trace_connection = any.connect (mem_fun (*this, &Parser::trace_event));
} else {
trace_prefix = "";
trace_stream = 0;

View File

@ -202,7 +202,7 @@ MachineControl::MachineControl (Port &p, float version,
build_mmc_cmd_map ();
_device_id = 1;
_device_id = 0;
if ((parser = _port.input()) != 0) {
parser->mmc.connect
@ -258,7 +258,7 @@ MachineControl::process_mmc_message (Parser &p, byte *msg, size_t len)
*/
#if 0
cerr << "*** MMC message: len = " << len << "\n\t";
cerr << "*** me = " << (int) _device_id << " MMC message: len = " << len << "\n\t";
for (size_t i = 0; i < len; i++) {
cerr << hex << (int) msg[i] << dec << ' ';
}

View File

@ -10,9 +10,64 @@ sigc::signal<void,Controllable*> Controllable::Destroyed;
sigc::signal<bool,Controllable*> Controllable::StartLearning;
sigc::signal<void,Controllable*> Controllable::StopLearning;
Glib::Mutex* Controllable::registry_lock = 0;
Controllable::Controllables Controllable::registry;
Controllable::Controllable (std::string name)
: _name (name)
{
if (registry_lock == 0) {
registry_lock = new Glib::Mutex;
}
add ();
}
void
Controllable::add ()
{
Glib::Mutex::Lock lm (*registry_lock);
registry.insert (this);
this->GoingAway.connect (mem_fun (this, &Controllable::remove));
}
void
Controllable::remove ()
{
Glib::Mutex::Lock lm (*registry_lock);
for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
if ((*i) == this) {
registry.erase (i);
break;
}
}
}
Controllable*
Controllable::by_id (const ID& id)
{
Glib::Mutex::Lock lm (*registry_lock);
for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
if ((*i)->id() == id) {
return (*i);
}
}
return 0;
}
Controllable*
Controllable::by_name (const std::string& str)
{
Glib::Mutex::Lock lm (*registry_lock);
for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
if ((*i)->_name == str) {
return (*i);
}
}
return 0;
}
XMLNode&

View File

@ -2,6 +2,7 @@
#define __pbd_controllable_h__
#include <string>
#include <set>
#include <sigc++/trackable.h>
#include <sigc++/signal.h>
@ -36,8 +37,18 @@ class Controllable : public PBD::StatefulDestructible {
std::string name() const { return _name; }
static Controllable* by_id (const PBD::ID&);
static Controllable* by_name (const std::string&);
private:
std::string _name;
void add ();
void remove ();
typedef std::set<PBD::Controllable*> Controllables;
static Glib::Mutex* registry_lock;
static Controllables registry;
};
}

View File

@ -171,6 +171,8 @@ void
GenericMidiControlProtocol::stop_learning (Controllable* c)
{
Glib::Mutex::Lock lm (pending_lock);
Glib::Mutex::Lock lm2 (controllables_lock);
MIDIControllable* dptr = 0;
/* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
relevant MIDIControllable and remove it from the pending list.
@ -179,11 +181,22 @@ GenericMidiControlProtocol::stop_learning (Controllable* c)
for (MIDIControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
if (&(*i)->get_controllable() == c) {
(*i)->stop_learning ();
delete (*i);
dptr = *i;
pending_controllables.erase (i);
break;
}
}
for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
if (&(*i)->get_controllable() == c) {
controllables.erase (i);
break;
}
}
if (dptr) {
delete dptr;
}
}
XMLNode&
@ -255,7 +268,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
ID id = prop->value ();
c = session->controllable_by_id (id);
c = Controllable::by_id (id);
if (c) {
MIDIControllable* mc = new MIDIControllable (*_port, *c);
@ -264,8 +277,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
}
} else {
warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"),
id)
warning << string_compose (_("Generic MIDI control: controllable %1 not found (ignored)"), id)
<< endmsg;
}
}

View File

@ -1160,7 +1160,7 @@ void MackieControlProtocol::notify_remote_id_changed()
if ( sorted.size() - _current_initial_bank < route_signals.size() )
{
// but don't shift backwards past the zeroth channel
switch_banks( max( (unsigned int)0, sorted.size() - route_signals.size() ) );
switch_banks( max(0UL, sorted.size() - route_signals.size() ) );
}
// Otherwise just refresh the current bank
else