new functionality to add MIDI ports from the options editor, not totally finished but functional
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2152 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
fdfa8a0d93
commit
47add43cd0
|
@ -162,6 +162,7 @@ marker.cc
|
|||
marker_time_axis.cc
|
||||
marker_time_axis_view.cc
|
||||
marker_view.cc
|
||||
midi_port_dialog.cc
|
||||
mixer_strip.cc
|
||||
mixer_ui.cc
|
||||
new_session_dialog.cc
|
||||
|
|
|
@ -704,8 +704,11 @@ ARDOUR_UI::build_menu_bar ()
|
|||
* until the Menu GObject class is registered, which happens
|
||||
* when the first menu instance is created.
|
||||
*/
|
||||
Gtk::Settings::get_default()->property_gtk_can_change_accels() = true;
|
||||
|
||||
// XXX bug in gtkmm causes this to popup an error message
|
||||
// Gtk::Settings::get_default()->property_gtk_can_change_accels() = true;
|
||||
// so use this instead ...
|
||||
gtk_settings_set_long_property (gtk_settings_get_default(), "gtk-can-change-accels", 1, "Ardour:designers");
|
||||
|
||||
wall_clock_box.add (wall_clock_label);
|
||||
wall_clock_box.set_name ("WallClock");
|
||||
wall_clock_label.set_name ("WallClock");
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
||||
}
|
|
@ -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,7 @@
|
|||
#include <ardour/sndfilesource.h>
|
||||
#include <ardour/crossfade.h>
|
||||
#include <midi++/manager.h>
|
||||
#include <midi++/factory.h>
|
||||
#include <gtkmm2ext/stop_signal.h>
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <gtkmm2ext/window_title.h>
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include "utils.h"
|
||||
#include "editing.h"
|
||||
#include "option_editor.h"
|
||||
#include "midi_port_dialog.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -75,8 +77,10 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
|
|||
|
||||
/* MIDI */
|
||||
|
||||
midi_port_table (4, 10),
|
||||
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
||||
mmc_device_id_spinner (mmc_device_id_adjustment),
|
||||
add_midi_port_button (_("Add new MIDI port")),
|
||||
|
||||
/* Click */
|
||||
|
||||
|
@ -134,10 +138,8 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
|
|||
notebook.pages().push_back (TabElem (audition_packer, _("Audition")));
|
||||
notebook.pages().push_back (TabElem (fade_packer, _("Layers & Fades")));
|
||||
|
||||
if (!MIDI::Manager::instance()->get_midi_ports().empty()) {
|
||||
setup_midi_options ();
|
||||
notebook.pages().push_back (TabElem (midi_packer, _("MIDI")));
|
||||
}
|
||||
setup_midi_options ();
|
||||
notebook.pages().push_back (TabElem (midi_packer, _("MIDI")));
|
||||
|
||||
set_session (0);
|
||||
show_all_children();
|
||||
|
@ -368,41 +370,108 @@ void
|
|||
OptionEditor::setup_midi_options ()
|
||||
{
|
||||
HBox* hbox;
|
||||
|
||||
midi_port_table.set_row_spacings (6);
|
||||
midi_port_table.set_col_spacings (10);
|
||||
|
||||
redisplay_midi_ports ();
|
||||
|
||||
mmc_device_id_adjustment.signal_value_changed().connect (mem_fun (*this, &OptionEditor::mmc_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);
|
||||
|
||||
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;
|
||||
const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
|
||||
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);
|
||||
table->set_col_spacings (10);
|
||||
// XXX broken in gtkmm 2.10
|
||||
// midi_port_table.clear ();
|
||||
|
||||
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);
|
||||
for (vector<Widget*>::iterator w = midi_port_table_widgets.begin(); w != midi_port_table_widgets.end(); ++w) {
|
||||
midi_port_table.remove (**w);
|
||||
}
|
||||
|
||||
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);
|
||||
midi_port_table_widgets.clear ();
|
||||
|
||||
midi_port_table.resize (ports.size() + 4, 10);
|
||||
|
||||
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);
|
||||
|
||||
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));
|
||||
label = (manage (new Label (_("MMC Device ID"))));
|
||||
label->show ();
|
||||
midi_port_table_widgets.push_back (label);
|
||||
midi_port_table.attach (*label, 9, 10, 0, 1);
|
||||
midi_port_table_widgets.push_back (&mmc_device_id_spinner);
|
||||
midi_port_table.attach (mmc_device_id_spinner, 9, 10, 1, 2);
|
||||
|
||||
for (n = 0, i = ports.begin(); i != ports.end(); ++n, ++i) {
|
||||
|
||||
pair<MIDI::Port*,vector<RadioButton*> > newpair;
|
||||
ToggleButton* tb;
|
||||
RadioButton* rb;
|
||||
|
||||
newpair.first = i->second;
|
||||
|
||||
table->attach (*(manage (new Label (i->first))), 0, 1, n+2, n+3,FILL|EXPAND, FILL );
|
||||
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 );
|
||||
|
||||
tb = manage (new ToggleButton (_("online")));
|
||||
tb->set_name ("OptionEditorToggleButton");
|
||||
|
||||
|
@ -416,22 +485,29 @@ OptionEditor::setup_midi_options ()
|
|||
set_size_request_to_display_given_text (*tb, _("online"), 15, 12);
|
||||
}
|
||||
|
||||
tb->set_active (!(*i).second->input()->offline());
|
||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), (*i).second, tb));
|
||||
(*i).second->input()->OfflineStatusChanged.connect (bind (mem_fun(*this, &OptionEditor::map_port_online), (*i).second, tb));
|
||||
table->attach (*tb, 1, 2, n+2, n+3, FILL|EXPAND, FILL);
|
||||
if (i->second->input()) {
|
||||
tb->set_active (!i->second->input()->offline());
|
||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_online_toggled), i->second, tb));
|
||||
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->set_name ("OptionEditorToggleButton");
|
||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_in_toggled), (*i).second, tb));
|
||||
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->set_name ("OptionEditorToggleButton");
|
||||
tb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::port_trace_out_toggled), (*i).second, tb));
|
||||
tb->set_size_request (10, 10);
|
||||
table->attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
|
||||
tb->show ();
|
||||
midi_port_table.attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
|
||||
|
||||
rb = manage (new RadioButton ());
|
||||
newpair.second.push_back (rb);
|
||||
|
@ -442,10 +518,12 @@ OptionEditor::setup_midi_options ()
|
|||
rb->set_group (mtc_button_group);
|
||||
|
||||
}
|
||||
table->attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL);
|
||||
rb->show ();
|
||||
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));
|
||||
|
||||
if (Config->get_mtc_port_name() == i->first) {
|
||||
if (session && i->second == session->mtc_port()) {
|
||||
rb->set_active (true);
|
||||
}
|
||||
|
||||
|
@ -457,10 +535,12 @@ OptionEditor::setup_midi_options ()
|
|||
} else {
|
||||
rb->set_group (mmc_button_group);
|
||||
}
|
||||
table->attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL);
|
||||
rb->show ();
|
||||
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));
|
||||
|
||||
if (Config->get_mmc_port_name() == i->first) {
|
||||
if (session && i->second == session->mmc_port()) {
|
||||
rb->set_active (true);
|
||||
}
|
||||
|
||||
|
@ -472,22 +552,60 @@ OptionEditor::setup_midi_options ()
|
|||
} else {
|
||||
rb->set_group (midi_button_group);
|
||||
}
|
||||
table->attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL);
|
||||
rb->show ();
|
||||
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));
|
||||
|
||||
if (Config->get_midi_port_name() == i->first) {
|
||||
if (session && i->second == session->midi_port()) {
|
||||
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
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -543,23 +661,27 @@ OptionEditor::port_online_toggled (MIDI::Port* port, ToggleButton* tb)
|
|||
{
|
||||
bool wanted = tb->get_active();
|
||||
|
||||
if (wanted != port->input()->offline()) {
|
||||
port->input()->set_offline (wanted);
|
||||
}
|
||||
if (port->input()) {
|
||||
if (wanted != port->input()->offline()) {
|
||||
port->input()->set_offline (wanted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditor::map_port_online (MIDI::Port* port, ToggleButton* tb)
|
||||
{
|
||||
bool bstate = tb->get_active ();
|
||||
|
||||
if (bstate != port->input()->offline()) {
|
||||
if (port->input()->offline()) {
|
||||
tb->set_label (_("offline"));
|
||||
tb->set_active (false);
|
||||
} else {
|
||||
tb->set_label (_("online"));
|
||||
tb->set_active (true);
|
||||
|
||||
if (port->input()) {
|
||||
if (bstate != port->input()->offline()) {
|
||||
if (port->input()->offline()) {
|
||||
tb->set_label (_("offline"));
|
||||
tb->set_active (false);
|
||||
} else {
|
||||
tb->set_label (_("online"));
|
||||
tb->set_active (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -579,8 +701,10 @@ OptionEditor::port_trace_in_toggled (MIDI::Port* port, ToggleButton* tb)
|
|||
{
|
||||
bool trace = tb->get_active();
|
||||
|
||||
if (port->input()->tracing() != trace) {
|
||||
port->input()->trace (trace, &cerr, string (port->name()) + string (" input: "));
|
||||
if (port->input()) {
|
||||
if (port->input()->tracing() != trace) {
|
||||
port->input()->trace (trace, &cerr, string (port->name()) + string (" input: "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,8 +713,10 @@ OptionEditor::port_trace_out_toggled (MIDI::Port* port, ToggleButton* tb)
|
|||
{
|
||||
bool trace = tb->get_active();
|
||||
|
||||
if (port->output()->tracing() != trace) {
|
||||
port->output()->trace (trace, &cerr, string (port->name()) + string (" output: "));
|
||||
if (port->output()) {
|
||||
if (port->output()->tracing() != trace) {
|
||||
port->output()->trace (trace, &cerr, string (port->name()) + string (" output: "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,8 +110,14 @@ class OptionEditor : public Gtk::Dialog
|
|||
Gtk::RadioButton::Group mmc_button_group;
|
||||
Gtk::RadioButton::Group midi_button_group;
|
||||
|
||||
Gtk::Table midi_port_table;
|
||||
std::vector<Gtk::Widget*> midi_port_table_widgets;
|
||||
Gtk::Adjustment mmc_device_id_adjustment;
|
||||
Gtk::SpinButton mmc_device_id_spinner;
|
||||
Gtk::Button add_midi_port_button;
|
||||
|
||||
void add_midi_port ();
|
||||
void redisplay_midi_ports ();
|
||||
|
||||
void port_online_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
||||
void port_trace_in_toggled (MIDI::Port*,Gtk::ToggleButton*);
|
||||
|
|
|
@ -170,7 +170,10 @@ ALSA_SequencerMidiPort::CreatePorts (PortRequest &req)
|
|||
if (req.mode == O_RDONLY || req.mode == O_RDWR)
|
||||
caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
|
||||
|
||||
if (0 <= (err = snd_seq_create_simple_port (seq, req.tagname, caps, SND_SEQ_PORT_TYPE_MIDI_GENERIC))) {
|
||||
if (0 <= (err = snd_seq_create_simple_port (seq, req.tagname, caps,
|
||||
(SND_SEQ_PORT_TYPE_MIDI_GENERIC|
|
||||
SND_SEQ_PORT_TYPE_SOFTWARE|
|
||||
SND_SEQ_PORT_TYPE_APPLICATION)))) {
|
||||
|
||||
port_id = err;
|
||||
|
||||
|
@ -205,3 +208,74 @@ ALSA_SequencerMidiPort::init_client (std::string name)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ALSA_SequencerMidiPort::discover (vector<PortSet>& ports)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
snd_seq_client_info_t *client_info;
|
||||
snd_seq_port_info_t *port_info;
|
||||
|
||||
snd_seq_client_info_alloca (&client_info);
|
||||
snd_seq_port_info_alloca (&port_info);
|
||||
snd_seq_client_info_set_client (client_info, -1);
|
||||
|
||||
while (snd_seq_query_next_client(seq, client_info) >= 0) {
|
||||
|
||||
int alsa_client;
|
||||
|
||||
if ((alsa_client = snd_seq_client_info_get_client(client_info)) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
snd_seq_port_info_set_client(port_info, alsa_client);
|
||||
snd_seq_port_info_set_port(port_info, -1);
|
||||
|
||||
char client[256];
|
||||
snprintf (client, sizeof (client), "%d:%s", alsa_client, snd_seq_client_info_get_name(client_info));
|
||||
|
||||
ports.push_back (PortSet (client));
|
||||
|
||||
while (snd_seq_query_next_port(seq, port_info) >= 0) {
|
||||
|
||||
#if 0
|
||||
int type = snd_seq_port_info_get_type(pinfo);
|
||||
if (!(type & SND_SEQ_PORT_TYPE_PORT)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int port_capability = snd_seq_port_info_get_capability(port_info);
|
||||
|
||||
if ((port_capability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0) {
|
||||
|
||||
int alsa_port = snd_seq_port_info_get_port(port_info);
|
||||
|
||||
char port[256];
|
||||
snprintf (port, sizeof (port), "%d:%s", alsa_port, snd_seq_port_info_get_name(port_info));
|
||||
|
||||
std::string mode;
|
||||
|
||||
if (port_capability & SND_SEQ_PORT_CAP_READ) {
|
||||
if (port_capability & SND_SEQ_PORT_CAP_WRITE) {
|
||||
mode = "duplex";
|
||||
} else {
|
||||
mode = "output";
|
||||
}
|
||||
} else if (port_capability & SND_SEQ_PORT_CAP_WRITE) {
|
||||
if (port_capability & SND_SEQ_PORT_CAP_READ) {
|
||||
mode = "duplex";
|
||||
} else {
|
||||
mode = "input";
|
||||
}
|
||||
}
|
||||
|
||||
ports.back().ports.push_back (PortRequest (client, port, mode, "alsa/sequencer"));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -142,3 +142,10 @@ void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon,
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
CoreMidi_MidiPort::discover (vector<PortSet>& ports)
|
||||
{
|
||||
/* XXX do dynamic port discovery here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <midi++/port.h>
|
||||
#include <midi++/port_request.h>
|
||||
|
||||
namespace MIDI {
|
||||
|
||||
|
@ -40,6 +41,8 @@ class ALSA_SequencerMidiPort : public Port
|
|||
/* select(2)/poll(2)-based I/O */
|
||||
|
||||
virtual int selectable() const;
|
||||
|
||||
static int discover (std::vector<PortSet>&);
|
||||
|
||||
protected:
|
||||
/* Direct I/O */
|
||||
|
|
|
@ -40,6 +40,9 @@ namespace MIDI {
|
|||
virtual int selectable() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int discover (std::vector<PortSet>&);
|
||||
|
||||
protected:
|
||||
/* Direct I/O */
|
||||
int write(byte * msg, size_t msglen);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <string>
|
||||
|
||||
#include <midi++/port.h>
|
||||
#include <midi++/port_request.h>
|
||||
|
||||
namespace MIDI {
|
||||
|
||||
|
@ -31,6 +32,8 @@ class PortFactory {
|
|||
Port *create_port (PortRequest &req);
|
||||
|
||||
static bool ignore_duplicate_devices (Port::Type);
|
||||
static int get_known_ports (std::vector<PortSet>&);
|
||||
static std::string default_port_type ();
|
||||
};
|
||||
|
||||
} // namespace MIDI
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
#define __midi_manager_h__
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <midi++/types.h>
|
||||
#include <midi++/port.h>
|
||||
#include <midi++/port_request.h>
|
||||
|
||||
namespace MIDI {
|
||||
|
||||
|
@ -70,6 +73,8 @@ class Manager {
|
|||
|
||||
static int parse_port_request (std::string str, Port::Type type);
|
||||
|
||||
int get_known_ports (std::vector<PortSet>&);
|
||||
|
||||
private:
|
||||
/* This is a SINGLETON pattern */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 1999 Paul Barton-Davis
|
||||
Copyright (C) 1999-2007 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
|
||||
|
@ -20,6 +20,7 @@
|
|||
#ifndef __midi_port_request_h__
|
||||
#define __midi_port_request_h__
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace MIDI {
|
||||
|
@ -53,6 +54,13 @@ struct PortRequest {
|
|||
const std::string &xtype);
|
||||
};
|
||||
|
||||
struct PortSet {
|
||||
PortSet (std::string str) : owner (str) { }
|
||||
|
||||
std::string owner;
|
||||
std::list<PortRequest> ports;
|
||||
};
|
||||
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __midi_port_request_h__
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include <midi++/types.h>
|
||||
#include <midi++/factory.h>
|
||||
#include <midi++/nullmidi.h>
|
||||
|
@ -101,3 +103,32 @@ PortFactory::ignore_duplicate_devices (Port::Type type)
|
|||
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_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;
|
||||
}
|
||||
|
|
|
@ -380,3 +380,9 @@ Manager::parse_port_request (string str, Port::Type type)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Manager::get_known_ports (vector<PortSet>& ports)
|
||||
{
|
||||
return PortFactory::get_known_ports (ports);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue