mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
merge changes to libmidi++ API from 2.0-ongoing
git-svn-id: svn://localhost/ardour2/trunk@2256 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
684ef0eb7a
commit
b9b6ba8be4
25 changed files with 614 additions and 195 deletions
|
|
@ -100,6 +100,7 @@ control_point.cc
|
||||||
automation_line.cc
|
automation_line.cc
|
||||||
automation_time_axis.cc
|
automation_time_axis.cc
|
||||||
automation_controller.cc
|
automation_controller.cc
|
||||||
|
midi_port_dialog.cc
|
||||||
midi_time_axis.cc
|
midi_time_axis.cc
|
||||||
midi_streamview.cc
|
midi_streamview.cc
|
||||||
axis_view.cc
|
axis_view.cc
|
||||||
|
|
|
||||||
55
gtk2_ardour/midi_port_dialog.cc
Normal file
55
gtk2_ardour/midi_port_dialog.cc
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include <string>
|
||||||
|
#include <sigc++/bind.h>
|
||||||
|
#include <gtkmm/stock.h>
|
||||||
|
|
||||||
|
#include <pbd/convert.h>
|
||||||
|
#include <gtkmm2ext/utils.h>
|
||||||
|
|
||||||
|
#include "midi_port_dialog.h"
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace PBD;
|
||||||
|
using namespace Gtk;
|
||||||
|
using namespace Gtkmm2ext;
|
||||||
|
using namespace sigc;
|
||||||
|
|
||||||
|
static const char* mode_strings[] = { "duplex", "output", "input", (char*) 0 };
|
||||||
|
|
||||||
|
MidiPortDialog::MidiPortDialog ()
|
||||||
|
: ArdourDialog ("midi_port_dialog"),
|
||||||
|
port_label (_("Port name"))
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<string> str = internationalize (PACKAGE, mode_strings);
|
||||||
|
set_popdown_strings (port_mode_combo, str);
|
||||||
|
port_mode_combo.set_active_text (str.front());
|
||||||
|
|
||||||
|
hpacker.pack_start (port_label);
|
||||||
|
hpacker.pack_start (port_name);
|
||||||
|
hpacker.pack_start (port_mode_combo);
|
||||||
|
|
||||||
|
port_label.show ();
|
||||||
|
port_name.show ();
|
||||||
|
port_mode_combo.show ();
|
||||||
|
hpacker.show ();
|
||||||
|
|
||||||
|
get_vbox()->pack_start (hpacker);
|
||||||
|
|
||||||
|
port_name.signal_activate().connect (mem_fun (*this, &MidiPortDialog::entry_activated));
|
||||||
|
|
||||||
|
add_button (Stock::ADD, RESPONSE_ACCEPT);
|
||||||
|
add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiPortDialog::entry_activated ()
|
||||||
|
{
|
||||||
|
response (RESPONSE_ACCEPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
MidiPortDialog::~MidiPortDialog ()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
21
gtk2_ardour/midi_port_dialog.h
Normal file
21
gtk2_ardour/midi_port_dialog.h
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <gtkmm/box.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
#include <gtkmm/entry.h>
|
||||||
|
#include <gtkmm/comboboxtext.h>
|
||||||
|
|
||||||
|
#include "ardour_dialog.h"
|
||||||
|
|
||||||
|
class MidiPortDialog : public ArdourDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiPortDialog ();
|
||||||
|
~MidiPortDialog ();
|
||||||
|
|
||||||
|
Gtk::HBox hpacker;
|
||||||
|
Gtk::Label port_label;
|
||||||
|
Gtk::Entry port_name;
|
||||||
|
Gtk::ComboBoxText port_mode_combo;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void entry_activated ();
|
||||||
|
};
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <ardour/sndfilesource.h>
|
#include <ardour/sndfilesource.h>
|
||||||
#include <ardour/crossfade.h>
|
#include <ardour/crossfade.h>
|
||||||
#include <midi++/manager.h>
|
#include <midi++/manager.h>
|
||||||
|
#include <midi++/factory.h>
|
||||||
|
#include <midi++/port_request.h>
|
||||||
#include <gtkmm2ext/stop_signal.h>
|
#include <gtkmm2ext/stop_signal.h>
|
||||||
#include <gtkmm2ext/utils.h>
|
#include <gtkmm2ext/utils.h>
|
||||||
#include <gtkmm2ext/window_title.h>
|
#include <gtkmm2ext/window_title.h>
|
||||||
|
|
@ -40,6 +42,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "editing.h"
|
#include "editing.h"
|
||||||
#include "option_editor.h"
|
#include "option_editor.h"
|
||||||
|
#include "midi_port_dialog.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -75,8 +78,10 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
|
||||||
|
|
||||||
/* MIDI */
|
/* MIDI */
|
||||||
|
|
||||||
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
mmc_receive_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
||||||
mmc_device_id_spinner (mmc_device_id_adjustment),
|
mmc_receive_device_id_spinner (mmc_receive_device_id_adjustment),
|
||||||
|
mmc_send_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
||||||
|
mmc_send_device_id_spinner (mmc_send_device_id_adjustment),
|
||||||
|
|
||||||
/* Click */
|
/* Click */
|
||||||
|
|
||||||
|
|
@ -363,46 +368,131 @@ OptionEditor::smpte_offset_chosen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::setup_midi_options ()
|
OptionEditor::setup_midi_options ()
|
||||||
{
|
{
|
||||||
HBox* hbox;
|
HBox* hbox;
|
||||||
|
Label* label;
|
||||||
|
|
||||||
|
midi_port_table.set_row_spacings (6);
|
||||||
|
midi_port_table.set_col_spacings (10);
|
||||||
|
|
||||||
|
redisplay_midi_ports ();
|
||||||
|
|
||||||
|
mmc_receive_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_receive_device_id_adjusted));
|
||||||
|
mmc_send_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_send_device_id_adjusted));
|
||||||
|
|
||||||
|
hbox = manage (new HBox);
|
||||||
|
hbox->set_border_width (6);
|
||||||
|
hbox->pack_start (midi_port_table, true, false);
|
||||||
|
|
||||||
|
midi_packer.pack_start (*hbox, false, false);
|
||||||
|
midi_packer.pack_start (add_midi_port_button, false, false);
|
||||||
|
|
||||||
|
hbox = manage (new HBox);
|
||||||
|
hbox->set_border_width (6);
|
||||||
|
hbox->set_spacing (6);
|
||||||
|
label = (manage (new Label (_("Inbound MMC Device ID"))));
|
||||||
|
hbox->pack_start (mmc_receive_device_id_spinner, false, false);
|
||||||
|
hbox->pack_start (*label, false, false);
|
||||||
|
midi_packer.pack_start (*hbox, false, false);
|
||||||
|
|
||||||
|
hbox = manage (new HBox);
|
||||||
|
hbox->set_border_width (6);
|
||||||
|
hbox->set_spacing (6);
|
||||||
|
label = (manage (new Label (_("Outbound MMC Device ID"))));
|
||||||
|
hbox->pack_start (mmc_send_device_id_spinner, false, false);
|
||||||
|
hbox->pack_start (*label, false, false);
|
||||||
|
midi_packer.pack_start (*hbox, false, false);
|
||||||
|
|
||||||
|
add_midi_port_button.signal_clicked().connect (mem_fun (*this, &OptionEditor::add_midi_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionEditor::redisplay_midi_ports ()
|
||||||
|
{
|
||||||
MIDI::Manager::PortMap::const_iterator i;
|
MIDI::Manager::PortMap::const_iterator i;
|
||||||
const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
|
const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
|
||||||
int n;
|
int n;
|
||||||
ToggleButton* tb;
|
|
||||||
RadioButton* rb;
|
|
||||||
|
|
||||||
Gtk::Table* table = manage (new Table (ports.size() + 4, 10));
|
/* remove all existing widgets */
|
||||||
|
|
||||||
table->set_row_spacings (6);
|
// XXX broken in gtkmm 2.10
|
||||||
table->set_col_spacings (10);
|
// midi_port_table.clear ();
|
||||||
|
|
||||||
table->attach (*(manage (new Label (_("Port")))), 0, 1, 0, 1);
|
for (vector<Widget*>::iterator w = midi_port_table_widgets.begin(); w != midi_port_table_widgets.end(); ++w) {
|
||||||
table->attach (*(manage (new Label (_("Offline")))), 1, 2, 0, 1);
|
midi_port_table.remove (**w);
|
||||||
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);
|
midi_port_table_widgets.clear ();
|
||||||
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);
|
midi_port_table.resize (ports.size() + 4, 11);
|
||||||
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));
|
Gtk::Label* label;
|
||||||
|
|
||||||
|
label = (manage (new Label (_("Port"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 0, 1, 0, 1);
|
||||||
|
label = (manage (new Label (_("Offline"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 1, 2, 0, 1);
|
||||||
|
label = (manage (new Label (_("Trace\nInput"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 2, 3, 0, 1);
|
||||||
|
label = (manage (new Label (_("Trace\nOutput"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 3, 4, 0, 1);
|
||||||
|
label = (manage (new Label (_("MTC"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 4, 5, 0, 1);
|
||||||
|
label = (manage (new Label (_("MMC"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 6, 7, 0, 1);
|
||||||
|
label = (manage (new Label (_("MIDI Parameter\nControl"))));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 8, 9, 0, 1);
|
||||||
|
|
||||||
|
Gtk::HSeparator* hsep = (manage (new HSeparator()));
|
||||||
|
hsep->show ();
|
||||||
|
midi_port_table_widgets.push_back (hsep);
|
||||||
|
midi_port_table.attach (*hsep, 0, 9, 1, 2);
|
||||||
|
Gtk::VSeparator* vsep = (manage (new VSeparator()));
|
||||||
|
vsep->show ();
|
||||||
|
midi_port_table_widgets.push_back (vsep);
|
||||||
|
midi_port_table.attach (*vsep, 5, 6, 0, 8);
|
||||||
|
vsep = (manage (new VSeparator()));
|
||||||
|
vsep->show ();
|
||||||
|
midi_port_table_widgets.push_back (vsep);
|
||||||
|
midi_port_table.attach (*vsep, 7, 8, 0, 8);
|
||||||
|
|
||||||
for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) {
|
for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) {
|
||||||
|
|
||||||
pair<MIDI::Port*,vector<RadioButton*> > newpair;
|
ToggleButton* tb;
|
||||||
|
RadioButton* rb;
|
||||||
|
Button* bb;
|
||||||
|
|
||||||
newpair.first = i->second;
|
/* the remove button. create early so we can pass it to various callbacks */
|
||||||
|
|
||||||
|
bb = manage (new Button (Stock::REMOVE));
|
||||||
|
bb->set_name ("OptionEditorToggleButton");
|
||||||
|
bb->show ();
|
||||||
|
midi_port_table_widgets.push_back (bb);
|
||||||
|
midi_port_table.attach (*bb, 9, 10, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
bb->signal_clicked().connect (bind (mem_fun(*this, &OptionEditor::remove_midi_port), i->second));
|
||||||
|
bb->set_sensitive (port_removable (i->second));
|
||||||
|
|
||||||
|
label = (manage (new Label (i->first)));
|
||||||
|
label->show ();
|
||||||
|
midi_port_table_widgets.push_back (label);
|
||||||
|
midi_port_table.attach (*label, 0, 1, n+2, n+3,FILL|EXPAND, FILL );
|
||||||
|
|
||||||
table->attach (*(manage (new Label (i->first))), 0, 1, n+2, n+3,FILL|EXPAND, FILL );
|
|
||||||
tb = manage (new ToggleButton (_("online")));
|
tb = manage (new ToggleButton (_("online")));
|
||||||
tb->set_name ("OptionEditorToggleButton");
|
tb->set_name ("OptionEditorToggleButton");
|
||||||
|
|
||||||
|
|
@ -416,25 +506,32 @@ OptionEditor::setup_midi_options ()
|
||||||
set_size_request_to_display_given_text (*tb, _("online"), 15, 12);
|
set_size_request_to_display_given_text (*tb, _("online"), 15, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
tb->set_active (!(*i).second->input()->offline());
|
if (i->second->input()) {
|
||||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), (*i).second, tb));
|
tb->set_active (!i->second->input()->offline());
|
||||||
(*i).second->input()->OfflineStatusChanged.connect (bind (mem_fun(*this, &OptionEditor::map_port_online), (*i).second, tb));
|
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), i->second, tb));
|
||||||
table->attach (*tb, 1, 2, n+2, n+3, FILL|EXPAND, FILL);
|
i->second->input()->OfflineStatusChanged.connect (bind (mem_fun(*this, &OptionEditor::map_port_online), (*i).second, tb));
|
||||||
|
}
|
||||||
|
tb->show ();
|
||||||
|
midi_port_table_widgets.push_back (tb);
|
||||||
|
midi_port_table.attach (*tb, 1, 2, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
|
||||||
tb = manage (new ToggleButton ());
|
tb = manage (new ToggleButton ());
|
||||||
tb->set_name ("OptionEditorToggleButton");
|
tb->set_name ("OptionEditorToggleButton");
|
||||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_in_toggled), (*i).second, tb));
|
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_in_toggled), (*i).second, tb));
|
||||||
tb->set_size_request (10, 10);
|
tb->set_size_request (10, 10);
|
||||||
table->attach (*tb, 2, 3, n+2, n+3, FILL|EXPAND, FILL);
|
tb->show ();
|
||||||
|
midi_port_table_widgets.push_back (tb);
|
||||||
|
midi_port_table.attach (*tb, 2, 3, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
|
||||||
tb = manage (new ToggleButton ());
|
tb = manage (new ToggleButton ());
|
||||||
tb->set_name ("OptionEditorToggleButton");
|
tb->set_name ("OptionEditorToggleButton");
|
||||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_out_toggled), (*i).second, tb));
|
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_out_toggled), (*i).second, tb));
|
||||||
tb->set_size_request (10, 10);
|
tb->set_size_request (10, 10);
|
||||||
table->attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
|
tb->show ();
|
||||||
|
midi_port_table_widgets.push_back (tb);
|
||||||
|
midi_port_table.attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
|
||||||
rb = manage (new RadioButton ());
|
rb = manage (new RadioButton ());
|
||||||
newpair.second.push_back (rb);
|
|
||||||
rb->set_name ("OptionEditorToggleButton");
|
rb->set_name ("OptionEditorToggleButton");
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
mtc_button_group = rb->get_group();
|
mtc_button_group = rb->get_group();
|
||||||
|
|
@ -442,99 +539,154 @@ OptionEditor::setup_midi_options ()
|
||||||
rb->set_group (mtc_button_group);
|
rb->set_group (mtc_button_group);
|
||||||
|
|
||||||
}
|
}
|
||||||
table->attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL);
|
rb->show ();
|
||||||
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mtc_port_chosen), (*i).second, rb));
|
midi_port_table_widgets.push_back (rb);
|
||||||
|
midi_port_table.attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mtc_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (Config->get_mtc_port_name() == i->first) {
|
if (session && i->second == session->mtc_port()) {
|
||||||
rb->set_active (true);
|
rb->set_active (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb = manage (new RadioButton ());
|
rb = manage (new RadioButton ());
|
||||||
newpair.second.push_back (rb);
|
|
||||||
rb->set_name ("OptionEditorToggleButton");
|
rb->set_name ("OptionEditorToggleButton");
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
mmc_button_group = rb->get_group();
|
mmc_button_group = rb->get_group();
|
||||||
} else {
|
} else {
|
||||||
rb->set_group (mmc_button_group);
|
rb->set_group (mmc_button_group);
|
||||||
}
|
}
|
||||||
table->attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL);
|
rb->show ();
|
||||||
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mmc_port_chosen), (*i).second, rb));
|
midi_port_table_widgets.push_back (rb);
|
||||||
|
midi_port_table.attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mmc_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (Config->get_mmc_port_name() == i->first) {
|
if (session && i->second == session->mmc_port()) {
|
||||||
rb->set_active (true);
|
rb->set_active (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb = manage (new RadioButton ());
|
rb = manage (new RadioButton ());
|
||||||
newpair.second.push_back (rb);
|
|
||||||
rb->set_name ("OptionEditorToggleButton");
|
rb->set_name ("OptionEditorToggleButton");
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
midi_button_group = rb->get_group();
|
midi_button_group = rb->get_group();
|
||||||
} else {
|
} else {
|
||||||
rb->set_group (midi_button_group);
|
rb->set_group (midi_button_group);
|
||||||
}
|
}
|
||||||
table->attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL);
|
rb->show ();
|
||||||
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::midi_port_chosen), (*i).second, rb));
|
midi_port_table_widgets.push_back (rb);
|
||||||
|
midi_port_table.attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL);
|
||||||
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::midi_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (Config->get_midi_port_name() == i->first) {
|
if (session && i->second == session->midi_port()) {
|
||||||
rb->set_active (true);
|
rb->set_active (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
port_toggle_buttons.insert (newpair);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table->show_all ();
|
midi_port_table.show();
|
||||||
|
|
||||||
hbox = manage (new HBox);
|
|
||||||
hbox->set_border_width (6);
|
|
||||||
hbox->pack_start (*table, true, false);
|
|
||||||
midi_packer.pack_start (*hbox, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::mtc_port_chosen (MIDI::Port *port, Gtk::RadioButton* rb)
|
OptionEditor::remove_midi_port (MIDI::Port* port)
|
||||||
|
{
|
||||||
|
MIDI::Manager::instance()->remove_port (port);
|
||||||
|
redisplay_midi_ports ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionEditor::add_midi_port ()
|
||||||
|
{
|
||||||
|
MidiPortDialog dialog;
|
||||||
|
|
||||||
|
dialog.set_position (WIN_POS_MOUSE);
|
||||||
|
dialog.set_transient_for (*this);
|
||||||
|
|
||||||
|
dialog.show ();
|
||||||
|
|
||||||
|
int ret = dialog.run ();
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case RESPONSE_ACCEPT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Glib::ustring mode = dialog.port_mode_combo.get_active_text();
|
||||||
|
std::string smod;
|
||||||
|
|
||||||
|
if (mode == _("input")) {
|
||||||
|
smod = X_("input");
|
||||||
|
} else if (mode == (_("output"))) {
|
||||||
|
smod = X_("output");
|
||||||
|
} else {
|
||||||
|
smod = "duplex";
|
||||||
|
}
|
||||||
|
|
||||||
|
MIDI::PortRequest req (X_("ardour"),
|
||||||
|
dialog.port_name.get_text(),
|
||||||
|
smod,
|
||||||
|
MIDI::PortFactory::default_port_type());
|
||||||
|
|
||||||
|
if (MIDI::Manager::instance()->add_port (req) != 0) {
|
||||||
|
redisplay_midi_ports ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
OptionEditor::port_removable (MIDI::Port *port)
|
||||||
|
{
|
||||||
|
if (!session) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port == session->mtc_port() ||
|
||||||
|
port == session->mmc_port() ||
|
||||||
|
port == session->midi_port()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionEditor::mtc_port_chosen (MIDI::Port *port, Gtk::RadioButton* rb, Gtk::Button* bb)
|
||||||
{
|
{
|
||||||
if (session) {
|
if (session) {
|
||||||
if (rb->get_active()) {
|
if (rb->get_active()) {
|
||||||
if (port) {
|
|
||||||
session->set_mtc_port (port->name());
|
session->set_mtc_port (port->name());
|
||||||
Config->set_mtc_port_name (port->name());
|
Config->set_mtc_port_name (port->name());
|
||||||
} else {
|
} else {
|
||||||
session->set_mtc_port ("");
|
session->set_mtc_port ("");
|
||||||
}
|
}
|
||||||
rb->set_active (true);
|
bb->set_sensitive (port_removable (port));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::mmc_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb)
|
OptionEditor::mmc_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb, Gtk::Button* bb)
|
||||||
{
|
{
|
||||||
if (session) {
|
if (session) {
|
||||||
if (rb->get_active()) {
|
if (rb->get_active()) {
|
||||||
if (port) {
|
|
||||||
session->set_mmc_port (port->name());
|
session->set_mmc_port (port->name());
|
||||||
Config->set_mtc_port_name (port->name());
|
Config->set_mtc_port_name (port->name());
|
||||||
} else {
|
} else {
|
||||||
session->set_mmc_port ("");
|
session->set_mmc_port ("");
|
||||||
}
|
}
|
||||||
rb->set_active (true);
|
bb->set_sensitive (port_removable (port));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::midi_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb)
|
OptionEditor::midi_port_chosen (MIDI::Port* port, Gtk::RadioButton* rb, Gtk::Button* bb)
|
||||||
{
|
{
|
||||||
if (session) {
|
if (session) {
|
||||||
if (rb->get_active()) {
|
if (rb->get_active()) {
|
||||||
if (port) {
|
|
||||||
session->set_midi_port (port->name());
|
session->set_midi_port (port->name());
|
||||||
Config->set_midi_port_name (port->name());
|
Config->set_midi_port_name (port->name());
|
||||||
} else {
|
} else {
|
||||||
session->set_midi_port ("");
|
session->set_midi_port ("");
|
||||||
}
|
}
|
||||||
rb->set_active (true);
|
bb->set_sensitive (port_removable (port));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,12 +717,22 @@ OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::mmc_device_id_adjusted ()
|
OptionEditor::mmc_receive_device_id_adjusted ()
|
||||||
{
|
{
|
||||||
uint8_t id = (uint8_t) mmc_device_id_spinner.get_value();
|
uint8_t id = (uint8_t) mmc_receive_device_id_spinner.get_value();
|
||||||
|
|
||||||
if (id != Config->get_mmc_device_id()) {
|
if (id != Config->get_mmc_receive_device_id()) {
|
||||||
Config->set_mmc_device_id (id);
|
Config->set_mmc_receive_device_id (id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionEditor::mmc_send_device_id_adjusted ()
|
||||||
|
{
|
||||||
|
uint8_t id = (uint8_t) mmc_send_device_id_spinner.get_value();
|
||||||
|
|
||||||
|
if (id != Config->get_mmc_send_device_id()) {
|
||||||
|
Config->set_mmc_send_device_id (id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,18 +110,29 @@ class OptionEditor : public Gtk::Dialog
|
||||||
Gtk::RadioButton::Group mmc_button_group;
|
Gtk::RadioButton::Group mmc_button_group;
|
||||||
Gtk::RadioButton::Group midi_button_group;
|
Gtk::RadioButton::Group midi_button_group;
|
||||||
|
|
||||||
Gtk::Adjustment mmc_device_id_adjustment;
|
Gtk::Table midi_port_table;
|
||||||
Gtk::SpinButton mmc_device_id_spinner;
|
std::vector<Gtk::Widget*> midi_port_table_widgets;
|
||||||
|
Gtk::Adjustment mmc_receive_device_id_adjustment;
|
||||||
|
Gtk::SpinButton mmc_receive_device_id_spinner;
|
||||||
|
Gtk::Adjustment mmc_send_device_id_adjustment;
|
||||||
|
Gtk::SpinButton mmc_send_device_id_spinner;
|
||||||
|
Gtk::Button add_midi_port_button;
|
||||||
|
|
||||||
|
void add_midi_port ();
|
||||||
|
void remove_midi_port (MIDI::Port*);
|
||||||
|
void redisplay_midi_ports ();
|
||||||
|
|
||||||
void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
||||||
void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
||||||
void port_trace_out_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
void port_trace_out_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
||||||
|
|
||||||
void mmc_port_chosen (MIDI::Port*,Gtk::RadioButton*);
|
void mmc_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
|
||||||
void mtc_port_chosen (MIDI::Port*,Gtk::RadioButton*);
|
void mtc_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
|
||||||
void midi_port_chosen (MIDI::Port*,Gtk::RadioButton*);
|
void midi_port_chosen (MIDI::Port*,Gtk::RadioButton*, Gtk::Button*);
|
||||||
|
bool port_removable (MIDI::Port*);
|
||||||
|
|
||||||
void mmc_device_id_adjusted ();
|
void mmc_receive_device_id_adjusted ();
|
||||||
|
void mmc_send_device_id_adjusted ();
|
||||||
|
|
||||||
void map_port_online (MIDI::Port*, Gtk::ToggleButton*);
|
void map_port_online (MIDI::Port*, Gtk::ToggleButton*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
|
||||||
CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false)
|
CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false)
|
||||||
CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false)
|
CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false)
|
||||||
CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
|
CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
|
||||||
CONFIG_VARIABLE (uint8_t, mmc_device_id, "mmc-device-id", 0)
|
CONFIG_VARIABLE (uint8_t, mmc_receive_device_id, "mmc-receive-device-id", 0)
|
||||||
|
CONFIG_VARIABLE (uint8_t, mmc_send_device_id, "mmc-send-device-id", 0)
|
||||||
|
|
||||||
/* control surfaces */
|
/* control surfaces */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -744,7 +744,8 @@ class Session : public PBD::StatefulDestructible
|
||||||
|
|
||||||
void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
|
void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
|
||||||
|
|
||||||
void set_mmc_device_id (uint32_t id);
|
void set_mmc_receive_device_id (uint32_t id);
|
||||||
|
void set_mmc_send_device_id (uint32_t id);
|
||||||
|
|
||||||
/* Scrubbing */
|
/* Scrubbing */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,97 +88,66 @@ Session::use_config_midi_ports ()
|
||||||
int
|
int
|
||||||
Session::set_mtc_port (string port_tag)
|
Session::set_mtc_port (string port_tag)
|
||||||
{
|
{
|
||||||
#if 0
|
MTC_Slave *ms;
|
||||||
MIDI::byte old_device_id = 0;
|
|
||||||
bool reset_id = false;
|
|
||||||
|
|
||||||
if (port_tag.length() == 0) {
|
if (port_tag.length() == 0) {
|
||||||
if (_mmc_port == 0) {
|
|
||||||
|
if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
|
||||||
|
error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mtc_port == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_mmc_port = 0;
|
|
||||||
|
_mtc_port = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIDI::Port* port;
|
MIDI::Port* port;
|
||||||
|
|
||||||
if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
|
if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
|
||||||
|
error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mmc_port = port;
|
_mtc_port = port;
|
||||||
|
|
||||||
if (mmc) {
|
if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
|
||||||
old_device_id = mmc->device_id();
|
ms->rebind (*port);
|
||||||
reset_id = true;
|
|
||||||
delete mmc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
|
Config->set_mtc_port_name (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));
|
|
||||||
mmc->DeferredPlay.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_deferred_play));
|
|
||||||
mmc->Stop.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_stop));
|
|
||||||
mmc->FastForward.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_fast_forward));
|
|
||||||
mmc->Rewind.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_rewind));
|
|
||||||
mmc->Pause.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_pause));
|
|
||||||
mmc->RecordPause.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_record_pause));
|
|
||||||
mmc->RecordStrobe.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_record_strobe));
|
|
||||||
mmc->RecordExit.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_record_exit));
|
|
||||||
mmc->Locate.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_locate));
|
|
||||||
mmc->Step.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_step));
|
|
||||||
mmc->Shuttle.connect
|
|
||||||
(mem_fun (*this, &Session::mmc_shuttle));
|
|
||||||
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));
|
|
||||||
_mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
|
|
||||||
_mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
|
|
||||||
|
|
||||||
Config->set_mmc_port_name (port_tag);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
MMC_PortChanged(); /* EMIT SIGNAL */
|
MTC_PortChanged(); /* EMIT SIGNAL */
|
||||||
change_midi_ports ();
|
change_midi_ports ();
|
||||||
set_dirty();
|
set_dirty();
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::set_mmc_device_id (uint32_t device_id)
|
Session::set_mmc_receive_device_id (uint32_t device_id)
|
||||||
{
|
{
|
||||||
if (mmc) {
|
if (mmc) {
|
||||||
mmc->set_device_id (device_id);
|
mmc->set_receive_device_id (device_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::set_mmc_send_device_id (uint32_t device_id)
|
||||||
|
{
|
||||||
|
if (mmc) {
|
||||||
|
mmc->set_send_device_id (device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Session::set_mmc_port (string port_tag)
|
Session::set_mmc_port (string port_tag)
|
||||||
{
|
{
|
||||||
#if 0
|
MIDI::byte old_recv_device_id = 0;
|
||||||
MIDI::byte old_device_id = 0;
|
MIDI::byte old_send_device_id = 0;
|
||||||
bool reset_id = false;
|
bool reset_id = false;
|
||||||
|
|
||||||
if (port_tag.length() == 0) {
|
if (port_tag.length() == 0) {
|
||||||
|
|
@ -198,7 +167,8 @@ Session::set_mmc_port (string port_tag)
|
||||||
_mmc_port = port;
|
_mmc_port = port;
|
||||||
|
|
||||||
if (mmc) {
|
if (mmc) {
|
||||||
old_device_id = mmc->device_id();
|
old_recv_device_id = mmc->receive_device_id();
|
||||||
|
old_recv_device_id = mmc->send_device_id();
|
||||||
reset_id = true;
|
reset_id = true;
|
||||||
delete mmc;
|
delete mmc;
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +178,8 @@ Session::set_mmc_port (string port_tag)
|
||||||
MMC_ResponseSignature);
|
MMC_ResponseSignature);
|
||||||
|
|
||||||
if (reset_id) {
|
if (reset_id) {
|
||||||
mmc->set_device_id (old_device_id);
|
mmc->set_receive_device_id (old_recv_device_id);
|
||||||
|
mmc->set_send_device_id (old_send_device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmc->Play.connect
|
mmc->Play.connect
|
||||||
|
|
@ -248,7 +219,6 @@ Session::set_mmc_port (string port_tag)
|
||||||
Config->set_mmc_port_name (port_tag);
|
Config->set_mmc_port_name (port_tag);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
#endif
|
|
||||||
MMC_PortChanged(); /* EMIT SIGNAL */
|
MMC_PortChanged(); /* EMIT SIGNAL */
|
||||||
change_midi_ports ();
|
change_midi_ports ();
|
||||||
set_dirty();
|
set_dirty();
|
||||||
|
|
@ -438,7 +408,7 @@ Session::setup_midi_control ()
|
||||||
|
|
||||||
mmc_buffer[0] = 0xf0; // SysEx
|
mmc_buffer[0] = 0xf0; // SysEx
|
||||||
mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
|
mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
|
||||||
mmc_buffer[2] = 0x7f; // "broadcast" device ID
|
mmc_buffer[2] = mmc->send_device_id();
|
||||||
mmc_buffer[3] = 0x6; // MCC
|
mmc_buffer[3] = 0x6; // MCC
|
||||||
|
|
||||||
/* Set up the qtr frame message */
|
/* Set up the qtr frame message */
|
||||||
|
|
|
||||||
|
|
@ -2872,10 +2872,16 @@ Session::config_changed (const char* parameter_name)
|
||||||
|
|
||||||
//poke_midi_thread ();
|
//poke_midi_thread ();
|
||||||
|
|
||||||
} else if (PARAM_IS ("mmc-device-id")) {
|
} else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
|
||||||
|
|
||||||
if (mmc) {
|
if (mmc) {
|
||||||
mmc->set_device_id (Config->get_mmc_device_id());
|
mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PARAM_IS ("mmc-send-id")) {
|
||||||
|
|
||||||
|
if (mmc) {
|
||||||
|
mmc->set_send_device_id (Config->get_mmc_send_device_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (PARAM_IS ("midi-control")) {
|
} else if (PARAM_IS ("midi-control")) {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,13 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
||||||
ALSA_RawMidiPort (MIDI::PortRequest &req)
|
ALSA_RawMidiPort (MIDI::PortRequest &req)
|
||||||
: FD_MidiPort (req, "/dev/snd", "midi") {}
|
: FD_MidiPort (req, "/dev/snd", "midi") {}
|
||||||
virtual ~ALSA_RawMidiPort () {}
|
virtual ~ALSA_RawMidiPort () {}
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,9 @@
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
class ALSA_SequencerMidiPort : public Port
|
class PortRequest;
|
||||||
|
|
||||||
|
class ALSA_SequencerMidiPort : public Port
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ALSA_SequencerMidiPort (PortRequest &req);
|
ALSA_SequencerMidiPort (PortRequest &req);
|
||||||
|
|
@ -41,6 +42,13 @@ class ALSA_SequencerMidiPort : public Port
|
||||||
|
|
||||||
virtual int selectable() const;
|
virtual int selectable() const;
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,10 @@
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
class CoreMidi_MidiPort:public Port {
|
namespace PortRequest;
|
||||||
|
|
||||||
|
class CoreMidi_MidiPort:public Port
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
CoreMidi_MidiPort(PortRequest & req);
|
CoreMidi_MidiPort(PortRequest & req);
|
||||||
virtual ~ CoreMidi_MidiPort();
|
virtual ~ CoreMidi_MidiPort();
|
||||||
|
|
@ -40,6 +43,13 @@ class CoreMidi_MidiPort:public Port {
|
||||||
virtual int selectable() const {
|
virtual int selectable() const {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <midi++/port.h>
|
#include <midi++/port.h>
|
||||||
|
#include <midi++/port_request.h>
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
|
|
@ -31,6 +32,11 @@ class PortFactory {
|
||||||
Port *create_port (PortRequest &req, void* data);
|
Port *create_port (PortRequest &req, void* data);
|
||||||
|
|
||||||
static bool ignore_duplicate_devices (Port::Type);
|
static bool ignore_duplicate_devices (Port::Type);
|
||||||
|
static int get_known_ports (std::vector<PortSet>&);
|
||||||
|
static std::string default_port_type ();
|
||||||
|
static Port::Type string_to_type (const std::string&);
|
||||||
|
static std::string mode_to_string (int);
|
||||||
|
static int string_to_mode (const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,13 @@ class FD_MidiPort : public Port
|
||||||
virtual int selectable() const;
|
virtual int selectable() const;
|
||||||
static std::vector<std::string *> *list_devices ();
|
static std::vector<std::string *> *list_devices ();
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _fd;
|
int _fd;
|
||||||
virtual void open (PortRequest &req);
|
virtual void open (PortRequest &req);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,13 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort
|
||||||
FIFO_MidiPort (PortRequest &req);
|
FIFO_MidiPort (PortRequest &req);
|
||||||
~FIFO_MidiPort () {};
|
~FIFO_MidiPort () {};
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void open (PortRequest &req);
|
void open (PortRequest &req);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,13 @@ public:
|
||||||
|
|
||||||
virtual void cycle_start(nframes_t nframes);
|
virtual void cycle_start(nframes_t nframes);
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
int write(byte *msg, size_t msglen, timestamp_t timestamp);
|
int write(byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,9 @@ class Manager {
|
||||||
void cycle_end();
|
void cycle_end();
|
||||||
|
|
||||||
Port *add_port (PortRequest &);
|
Port *add_port (PortRequest &);
|
||||||
int remove_port (std::string port);
|
int remove_port (Port*);
|
||||||
|
|
||||||
Port *port (std::string name);
|
Port *port (std::string name);
|
||||||
Port *port (size_t number);
|
|
||||||
|
|
||||||
size_t nports () { return ports_by_device.size(); }
|
size_t nports () { return ports_by_device.size(); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,10 @@ class MachineControl : public sigc::trackable
|
||||||
|
|
||||||
Port &port() { return _port; }
|
Port &port() { return _port; }
|
||||||
|
|
||||||
void set_device_id (byte id);
|
void set_receive_device_id (byte id);
|
||||||
byte device_id () const { return _device_id; }
|
void set_send_device_id (byte id);
|
||||||
|
byte receive_device_id () const { return _receive_device_id; }
|
||||||
|
byte send_device_id () const { return _send_device_id; }
|
||||||
|
|
||||||
static bool is_mmc (byte *sysex_buf, size_t len);
|
static bool is_mmc (byte *sysex_buf, size_t len);
|
||||||
|
|
||||||
|
|
@ -244,7 +246,8 @@ class MachineControl : public sigc::trackable
|
||||||
byte resume;
|
byte resume;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
byte _device_id;
|
byte _receive_device_id;
|
||||||
|
byte _send_device_id;
|
||||||
MIDI::Port &_port;
|
MIDI::Port &_port;
|
||||||
|
|
||||||
void process_mmc_message (Parser &p, byte *, size_t len);
|
void process_mmc_message (Parser &p, byte *, size_t len);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,13 @@ class Null_MidiPort : public Port
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int selectable() const { return -1; }
|
virtual int selectable() const { return -1; }
|
||||||
|
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,13 @@ struct PortRequest {
|
||||||
const std::string &xtype);
|
const std::string &xtype);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PortSet {
|
||||||
|
PortSet (std::string str) : owner (str) { }
|
||||||
|
|
||||||
|
std::string owner;
|
||||||
|
std::list<PortRequest> ports;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
||||||
#endif // __midi_port_request_h__
|
#endif // __midi_port_request_h__
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <pbd/error.h>
|
||||||
|
#include <pbd/convert.h>
|
||||||
|
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
#include <midi++/factory.h>
|
#include <midi++/factory.h>
|
||||||
#include <midi++/nullmidi.h>
|
#include <midi++/nullmidi.h>
|
||||||
|
|
@ -25,20 +29,32 @@
|
||||||
|
|
||||||
#ifdef WITH_JACK_MIDI
|
#ifdef WITH_JACK_MIDI
|
||||||
#include <midi++/jack.h>
|
#include <midi++/jack.h>
|
||||||
|
|
||||||
|
std::string MIDI::JACK_MidiPort::typestring = "jack";
|
||||||
#endif // WITH_JACK_MIDI
|
#endif // WITH_JACK_MIDI
|
||||||
|
|
||||||
|
std::string MIDI::Null_MidiPort::typestring = "null";
|
||||||
|
std::string MIDI::FIFO_MidiPort::typestring = "fifo";
|
||||||
|
|
||||||
#ifdef WITH_ALSA
|
#ifdef WITH_ALSA
|
||||||
#include <midi++/alsa_sequencer.h>
|
#include <midi++/alsa_sequencer.h>
|
||||||
#include <midi++/alsa_rawmidi.h>
|
#include <midi++/alsa_rawmidi.h>
|
||||||
|
|
||||||
|
std::string MIDI::ALSA_SequencerMidiPort::typestring = "alsa/sequencer";
|
||||||
|
std::string MIDI::ALSA_RawMidiPort::typestring = "alsa/raw";
|
||||||
|
|
||||||
#endif // WITH_ALSA
|
#endif // WITH_ALSA
|
||||||
|
|
||||||
#ifdef WITH_COREMIDI
|
#ifdef WITH_COREMIDI
|
||||||
#include <midi++/coremidi_midiport.h>
|
#include <midi++/coremidi_midiport.h>
|
||||||
#endif // WITH_COREMIDI
|
|
||||||
|
|
||||||
|
std::string MIDI::CoreMidi_MidiPort::typestring = "coremidi";
|
||||||
|
|
||||||
|
#endif // WITH_COREMIDI
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
using namespace PBD;
|
||||||
|
|
||||||
// FIXME: void* data pointer, filthy
|
// FIXME: void* data pointer, filthy
|
||||||
Port *
|
Port *
|
||||||
|
|
@ -114,3 +130,88 @@ PortFactory::ignore_duplicate_devices (Port::Type type)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PortFactory::get_known_ports (vector<PortSet>& ports)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
n += ALSA_SequencerMidiPort::discover (ports);
|
||||||
|
#endif // WITH_ALSA
|
||||||
|
|
||||||
|
#if WITH_COREMIDI
|
||||||
|
n += CoreMidi_MidiPort::discover (ports);
|
||||||
|
#endif // WITH_COREMIDI
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
PortFactory::default_port_type ()
|
||||||
|
{
|
||||||
|
#ifdef WITH_JACK_MIDI
|
||||||
|
return "jack";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
return "alsa/sequencer";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_COREMIDI
|
||||||
|
return "coremidi";
|
||||||
|
#endif // WITH_COREMIDI
|
||||||
|
|
||||||
|
PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg;
|
||||||
|
/*NOTREACHED*/
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Port::Type
|
||||||
|
PortFactory::string_to_type (const string& xtype)
|
||||||
|
{
|
||||||
|
if (0){
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
} else if (strings_equal_ignore_case (xtype, ALSA_RawMidiPort::typestring)) {
|
||||||
|
return Port::ALSA_RawMidi;
|
||||||
|
} else if (strings_equal_ignore_case (xtype, ALSA_SequencerMidiPort::typestring)) {
|
||||||
|
return Port::ALSA_Sequencer;
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_COREMIDI
|
||||||
|
} else if (strings_equal_ignore_case (xtype, CoreMidi_MidiPort::typestring)) {
|
||||||
|
return Port::CoreMidi_MidiPort;
|
||||||
|
#endif
|
||||||
|
} else if (strings_equal_ignore_case (xtype, Null_MidiPort::typestring)) {
|
||||||
|
return Port::Null;
|
||||||
|
} else if (strings_equal_ignore_case (xtype, FIFO_MidiPort::typestring)) {
|
||||||
|
return Port::FIFO;
|
||||||
|
#ifdef WITH_JACK_MIDI
|
||||||
|
} else if (strings_equal_ignore_case (xtype, JACK_MidiPort::typestring)) {
|
||||||
|
return Port::JACK_Midi;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return Port::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
PortFactory::mode_to_string (int mode)
|
||||||
|
{
|
||||||
|
if (mode == O_RDONLY) {
|
||||||
|
return "input";
|
||||||
|
} else if (mode == O_WRONLY) {
|
||||||
|
return "output";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "duplex";
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PortFactory::string_to_mode (const string& str)
|
||||||
|
{
|
||||||
|
if (strings_equal_ignore_case (str, "output") || strings_equal_ignore_case (str, "out")) {
|
||||||
|
return O_WRONLY;
|
||||||
|
} else if (strings_equal_ignore_case (str, "input") || strings_equal_ignore_case (str, "in")) {
|
||||||
|
return O_RDONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return O_RDWR;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,18 +126,32 @@ Manager::add_port (PortRequest &req)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Manager::remove_port (string name)
|
Manager::remove_port (Port* port)
|
||||||
{
|
{
|
||||||
PortMap::iterator res;
|
PortMap::iterator res;
|
||||||
|
|
||||||
if ((res = ports_by_device.find (name)) == ports_by_device.end()) {
|
for (res = ports_by_device.begin(); res != ports_by_device.end(); ) {
|
||||||
return -1;
|
PortMap::iterator tmp;
|
||||||
|
tmp = res;
|
||||||
|
++tmp;
|
||||||
|
if (res->second == port) {
|
||||||
|
ports_by_device.erase (res);
|
||||||
|
}
|
||||||
|
res = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ports_by_device.erase (res);
|
|
||||||
ports_by_device.erase ((*res).second->name());
|
|
||||||
|
|
||||||
delete (*res).second;
|
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); ) {
|
||||||
|
PortMap::iterator tmp;
|
||||||
|
tmp = res;
|
||||||
|
++tmp;
|
||||||
|
if (res->second == port) {
|
||||||
|
ports_by_tag.erase (res);
|
||||||
|
}
|
||||||
|
res = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete port;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -156,21 +170,6 @@ Manager::port (string name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Port *
|
|
||||||
Manager::port (size_t portnum)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if ((*res).second->number() == portnum) {
|
|
||||||
return (*res).second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Manager::foreach_port (int (*func)(const Port &, size_t, void *),
|
Manager::foreach_port (int (*func)(const Port &, size_t, void *),
|
||||||
void *arg)
|
void *arg)
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,8 @@ MachineControl::MachineControl (Port &p, float version,
|
||||||
|
|
||||||
build_mmc_cmd_map ();
|
build_mmc_cmd_map ();
|
||||||
|
|
||||||
_device_id = 0;
|
_receive_device_id = 0;
|
||||||
|
_send_device_id = 0x7f;
|
||||||
|
|
||||||
if ((parser = _port.input()) != 0) {
|
if ((parser = _port.input()) != 0) {
|
||||||
parser->mmc.connect
|
parser->mmc.connect
|
||||||
|
|
@ -214,10 +215,15 @@ MachineControl::MachineControl (Port &p, float version,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MachineControl::set_device_id (byte id)
|
MachineControl::set_receive_device_id (byte id)
|
||||||
|
|
||||||
{
|
{
|
||||||
_device_id = id & 0x7f;
|
_receive_device_id = id & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MachineControl::set_send_device_id (byte id)
|
||||||
|
{
|
||||||
|
_send_device_id = id & 0x7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -258,14 +264,14 @@ MachineControl::process_mmc_message (Parser &p, byte *msg, size_t len)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
cerr << "*** me = " << (int) _device_id << " MMC message: len = " << len << "\n\t";
|
cerr << "*** me = " << (int) _receive_device_id << " MMC message: len = " << len << "\n\t";
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
cerr << hex << (int) msg[i] << dec << ' ';
|
cerr << hex << (int) msg[i] << dec << ' ';
|
||||||
}
|
}
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (msg[1] != 0x7f && msg[1] != _device_id) {
|
if (msg[1] != 0x7f && msg[1] != _receive_device_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,5 +233,21 @@ length2string (const int64_t frames, const double sample_rate)
|
||||||
|
|
||||||
return duration_str;
|
return duration_str;
|
||||||
}
|
}
|
||||||
|
static bool
|
||||||
|
chars_equal_ignore_case(char x, char y)
|
||||||
|
{
|
||||||
|
static std::locale loc;
|
||||||
|
return toupper(x, loc) == toupper(y, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
strings_equal_ignore_case (const string& a, const string& b)
|
||||||
|
{
|
||||||
|
if (a.length() == b.length()) {
|
||||||
|
return std::equal (a.begin(), a.end(), b.begin(), chars_equal_ignore_case);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace PBD
|
} // namespace PBD
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ void url_decode (std::string&);
|
||||||
std::string length2string (const int64_t frames, const double sample_rate);
|
std::string length2string (const int64_t frames, const double sample_rate);
|
||||||
|
|
||||||
std::vector<std::string> internationalize (const char *, const char **);
|
std::vector<std::string> internationalize (const char *, const char **);
|
||||||
|
bool strings_equal_ignore_case (const std::string& a, const std::string& b);
|
||||||
|
|
||||||
} //namespace PBD
|
} //namespace PBD
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue