mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-20 21:56:30 +01:00
permit MIDI port removal now, and save MIDI ports back to the ardour.rc file
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2163 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
e644ddc4c8
commit
ab3020cee1
20 changed files with 261 additions and 174 deletions
|
|
@ -77,7 +77,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
|
||||||
|
|
||||||
/* MIDI */
|
/* MIDI */
|
||||||
|
|
||||||
midi_port_table (4, 10),
|
midi_port_table (4, 11),
|
||||||
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
mmc_device_id_adjustment (0.0, 0.0, (double) 0x7f, 1.0, 16.0),
|
||||||
mmc_device_id_spinner (mmc_device_id_adjustment),
|
mmc_device_id_spinner (mmc_device_id_adjustment),
|
||||||
add_midi_port_button (_("Add new MIDI port")),
|
add_midi_port_button (_("Add new MIDI port")),
|
||||||
|
|
@ -179,27 +179,7 @@ OptionEditor::set_session (Session *s)
|
||||||
|
|
||||||
smpte_offset_negative_button.set_active (session->smpte_offset_negative());
|
smpte_offset_negative_button.set_active (session->smpte_offset_negative());
|
||||||
|
|
||||||
/* set up port assignments */
|
redisplay_midi_ports ();
|
||||||
|
|
||||||
std::map<MIDI::Port*,vector<RadioButton*> >::iterator res;
|
|
||||||
|
|
||||||
if (session->mtc_port()) {
|
|
||||||
if ((res = port_toggle_buttons.find (session->mtc_port())) != port_toggle_buttons.end()) {
|
|
||||||
(*res).second[MtcIndex]->set_active (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->mmc_port ()) {
|
|
||||||
if ((res = port_toggle_buttons.find (session->mmc_port())) != port_toggle_buttons.end()) {
|
|
||||||
(*res).second[MmcIndex]->set_active (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->midi_port()) {
|
|
||||||
if ((res = port_toggle_buttons.find (session->midi_port())) != port_toggle_buttons.end()) {
|
|
||||||
(*res).second[MidiIndex]->set_active (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_click_editor ();
|
setup_click_editor ();
|
||||||
connect_audition_editor ();
|
connect_audition_editor ();
|
||||||
|
|
@ -406,7 +386,7 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
|
|
||||||
midi_port_table_widgets.clear ();
|
midi_port_table_widgets.clear ();
|
||||||
|
|
||||||
midi_port_table.resize (ports.size() + 4, 10);
|
midi_port_table.resize (ports.size() + 4, 11);
|
||||||
|
|
||||||
Gtk::Label* label;
|
Gtk::Label* label;
|
||||||
|
|
||||||
|
|
@ -461,11 +441,19 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
|
|
||||||
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;
|
ToggleButton* tb;
|
||||||
RadioButton* rb;
|
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 = (manage (new Label (i->first)));
|
||||||
label->show ();
|
label->show ();
|
||||||
|
|
@ -507,10 +495,10 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
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);
|
||||||
tb->show ();
|
tb->show ();
|
||||||
|
midi_port_table_widgets.push_back (tb);
|
||||||
midi_port_table.attach (*tb, 3, 4, n+2, n+3, FILL|EXPAND, FILL);
|
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();
|
||||||
|
|
@ -521,14 +509,13 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
rb->show ();
|
rb->show ();
|
||||||
midi_port_table_widgets.push_back (rb);
|
midi_port_table_widgets.push_back (rb);
|
||||||
midi_port_table.attach (*rb, 4, 5, n+2, n+3, FILL|EXPAND, FILL);
|
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));
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mtc_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (session && i->second == session->mtc_port()) {
|
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();
|
||||||
|
|
@ -538,14 +525,13 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
rb->show ();
|
rb->show ();
|
||||||
midi_port_table_widgets.push_back (rb);
|
midi_port_table_widgets.push_back (rb);
|
||||||
midi_port_table.attach (*rb, 6, 7, n+2, n+3, FILL|EXPAND, FILL);
|
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));
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::mmc_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (session && i->second == session->mmc_port()) {
|
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();
|
||||||
|
|
@ -555,18 +541,24 @@ OptionEditor::redisplay_midi_ports ()
|
||||||
rb->show ();
|
rb->show ();
|
||||||
midi_port_table_widgets.push_back (rb);
|
midi_port_table_widgets.push_back (rb);
|
||||||
midi_port_table.attach (*rb, 8, 9, n+2, n+3, FILL|EXPAND, FILL);
|
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));
|
rb->signal_toggled().connect (bind (mem_fun(*this, &OptionEditor::midi_port_chosen), (*i).second, rb, bb));
|
||||||
|
|
||||||
if (session && i->second == session->midi_port()) {
|
if (session && i->second == session->midi_port()) {
|
||||||
rb->set_active (true);
|
rb->set_active (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
port_toggle_buttons.insert (newpair);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
midi_port_table.show();
|
midi_port_table.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionEditor::remove_midi_port (MIDI::Port* port)
|
||||||
|
{
|
||||||
|
MIDI::Manager::instance()->remove_port (port);
|
||||||
|
redisplay_midi_ports ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OptionEditor::add_midi_port ()
|
OptionEditor::add_midi_port ()
|
||||||
{
|
{
|
||||||
|
|
@ -608,51 +600,60 @@ OptionEditor::add_midi_port ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
OptionEditor::mtc_port_chosen (MIDI::Port *port, Gtk::RadioButton* rb)
|
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));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,15 +117,17 @@ class OptionEditor : public Gtk::Dialog
|
||||||
Gtk::Button add_midi_port_button;
|
Gtk::Button add_midi_port_button;
|
||||||
|
|
||||||
void add_midi_port ();
|
void add_midi_port ();
|
||||||
|
void remove_midi_port (MIDI::Port*);
|
||||||
void redisplay_midi_ports ();
|
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_device_id_adjusted ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
#include <pbd/failed_constructor.h>
|
#include <pbd/failed_constructor.h>
|
||||||
#include <pbd/xml++.h>
|
#include <pbd/xml++.h>
|
||||||
|
|
||||||
|
#include <midi++/manager.h>
|
||||||
|
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
#include <ardour/configuration.h>
|
#include <ardour/configuration.h>
|
||||||
#include <ardour/audio_diskstream.h>
|
#include <ardour/audio_diskstream.h>
|
||||||
|
|
@ -157,9 +159,12 @@ Configuration::get_state ()
|
||||||
LocaleGuard lg (X_("POSIX"));
|
LocaleGuard lg (X_("POSIX"));
|
||||||
|
|
||||||
root = new XMLNode("Ardour");
|
root = new XMLNode("Ardour");
|
||||||
typedef map<string, MidiPortDescriptor*>::const_iterator CI;
|
|
||||||
for(CI m = midi_ports.begin(); m != midi_ports.end(); ++m){
|
MIDI::Manager::PortMap::const_iterator i;
|
||||||
root->add_child_nocopy(m->second->get_state());
|
const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
|
||||||
|
|
||||||
|
for(i = ports.begin(); i != ports.end(); ++i) {
|
||||||
|
root->add_child_nocopy(i->second->get_state());
|
||||||
}
|
}
|
||||||
|
|
||||||
root->add_child_nocopy (get_variables (sigc::mem_fun (*this, &Configuration::save_config_options_predicate)));
|
root->add_child_nocopy (get_variables (sigc::mem_fun (*this, &Configuration::save_config_options_predicate)));
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,10 @@ setup_midi ()
|
||||||
nports++;
|
nports++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIDI::Port* first;
|
||||||
|
const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports();
|
||||||
|
first = ports.begin()->second;
|
||||||
|
|
||||||
if (nports > 1) {
|
if (nports > 1) {
|
||||||
|
|
||||||
/* More than one port, so try using specific names for each port */
|
/* More than one port, so try using specific names for each port */
|
||||||
|
|
@ -158,22 +162,22 @@ setup_midi ()
|
||||||
/* If that didn't work, just use the first listed port */
|
/* If that didn't work, just use the first listed port */
|
||||||
|
|
||||||
if (default_mmc_port == 0) {
|
if (default_mmc_port == 0) {
|
||||||
default_mmc_port = MIDI::Manager::instance()->port (0);
|
default_mmc_port = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_mtc_port == 0) {
|
if (default_mtc_port == 0) {
|
||||||
default_mtc_port = MIDI::Manager::instance()->port (0);
|
default_mtc_port = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_midi_port == 0) {
|
if (default_midi_port == 0) {
|
||||||
default_midi_port = MIDI::Manager::instance()->port (0);
|
default_midi_port = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Only one port described, so use it for both MTC and MMC */
|
/* Only one port described, so use it for both MTC and MMC */
|
||||||
|
|
||||||
default_mmc_port = MIDI::Manager::instance()->port (0);
|
default_mmc_port = first;
|
||||||
default_mtc_port = default_mmc_port;
|
default_mtc_port = default_mmc_port;
|
||||||
default_midi_port = default_mmc_port;
|
default_midi_port = default_mmc_port;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,15 @@ CoreMidi_MidiPort::CoreMidi_MidiPort (PortRequest &req) : Port (req)
|
||||||
|
|
||||||
CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
|
CoreMidi_MidiPort::~CoreMidi_MidiPort () {Close();}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
CoreMidi::MidiPort::get_state() const
|
||||||
|
{
|
||||||
|
XMLNode& node (Port::get_state());
|
||||||
|
node.add_property ("type", "coremidi");
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CoreMidi_MidiPort::Close ()
|
void CoreMidi_MidiPort::Close ()
|
||||||
{
|
{
|
||||||
if (midi_destination) MIDIEndpointDispose(midi_destination);
|
if (midi_destination) MIDIEndpointDispose(midi_destination);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#include <midi++/port.h>
|
#include <midi++/port.h>
|
||||||
#include <midi++/fd_midiport.h>
|
#include <midi++/fd_midiport.h>
|
||||||
|
|
||||||
|
namespace MIDI {
|
||||||
|
|
||||||
class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -35,8 +37,16 @@ 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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __alsa_rawmidi_h__
|
#endif // __alsa_rawmidi_h__
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ class ALSA_SequencerMidiPort : public Port
|
||||||
virtual int selectable() const;
|
virtual int selectable() const;
|
||||||
|
|
||||||
static int discover (std::vector<PortSet>&);
|
static int discover (std::vector<PortSet>&);
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
|
|
@ -50,6 +51,10 @@ class ALSA_SequencerMidiPort : public Port
|
||||||
int write (byte *msg, size_t msglen);
|
int write (byte *msg, size_t msglen);
|
||||||
int read (byte *buf, size_t max);
|
int read (byte *buf, size_t max);
|
||||||
|
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
snd_midi_event_t *decoder, *encoder;
|
snd_midi_event_t *decoder, *encoder;
|
||||||
int port_id;
|
int port_id;
|
||||||
|
|
|
||||||
|
|
@ -42,16 +42,24 @@ namespace MIDI {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int discover (std::vector<PortSet>&);
|
static int discover (std::vector<PortSet>&);
|
||||||
|
static std::string typestring;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
int write(byte * msg, size_t msglen);
|
int write(byte * msg, size_t msglen);
|
||||||
|
|
||||||
int read(byte * buf, size_t max) {
|
int read(byte * buf, size_t max) {
|
||||||
return 0;
|
return 0;
|
||||||
} /* CoreMidi callback */
|
}
|
||||||
|
|
||||||
|
/* CoreMidi callback */
|
||||||
static void read_proc(const MIDIPacketList * pktlist,
|
static void read_proc(const MIDIPacketList * pktlist,
|
||||||
void *refCon, void *connRefCon);
|
void *refCon, void *connRefCon);
|
||||||
|
|
||||||
|
std::string get_typestring () const {
|
||||||
|
return typestring;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
byte midi_buffer[1024];
|
byte midi_buffer[1024];
|
||||||
MIDIClientRef midi_client;
|
MIDIClientRef midi_client;
|
||||||
|
|
@ -63,6 +71,7 @@ namespace MIDI {
|
||||||
static MIDITimeStamp MIDIGetCurrentHostTime();
|
static MIDITimeStamp MIDIGetCurrentHostTime();
|
||||||
|
|
||||||
bool firstrecv;
|
bool firstrecv;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MIDI
|
} // namespace MIDI
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ class PortFactory {
|
||||||
static bool ignore_duplicate_devices (Port::Type);
|
static bool ignore_duplicate_devices (Port::Type);
|
||||||
static int get_known_ports (std::vector<PortSet>&);
|
static int get_known_ports (std::vector<PortSet>&);
|
||||||
static std::string default_port_type ();
|
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
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ 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 ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,9 @@ class Manager {
|
||||||
~Manager ();
|
~Manager ();
|
||||||
|
|
||||||
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(); }
|
||||||
|
|
||||||
|
|
@ -50,9 +49,7 @@ class Manager {
|
||||||
channel_t inputChannelNumber;
|
channel_t inputChannelNumber;
|
||||||
channel_t outputChannelNumber;
|
channel_t outputChannelNumber;
|
||||||
|
|
||||||
int set_input_port (size_t port);
|
|
||||||
int set_input_port (std::string);
|
int set_input_port (std::string);
|
||||||
int set_output_port (size_t port);
|
|
||||||
int set_output_port (std::string);
|
int set_output_port (std::string);
|
||||||
int set_input_channel (channel_t);
|
int set_input_channel (channel_t);
|
||||||
int set_output_channel (channel_t);
|
int set_output_channel (channel_t);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,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
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
#include <midi++/parser.h>
|
#include <midi++/parser.h>
|
||||||
|
|
||||||
|
class XMLNode;
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
class Channel;
|
class Channel;
|
||||||
|
|
@ -46,6 +48,8 @@ class Port : public sigc::trackable {
|
||||||
Port (PortRequest &);
|
Port (PortRequest &);
|
||||||
virtual ~Port ();
|
virtual ~Port ();
|
||||||
|
|
||||||
|
virtual XMLNode& get_state () const;
|
||||||
|
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
|
|
||||||
virtual int write (byte *msg, size_t msglen) = 0;
|
virtual int write (byte *msg, size_t msglen) = 0;
|
||||||
|
|
@ -118,7 +122,6 @@ class Port : public sigc::trackable {
|
||||||
Type type () const { return _type; }
|
Type type () const { return _type; }
|
||||||
int mode () const { return _mode; }
|
int mode () const { return _mode; }
|
||||||
bool ok () const { return _ok; }
|
bool ok () const { return _ok; }
|
||||||
size_t number () const { return _number; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _ok;
|
bool _ok;
|
||||||
|
|
@ -126,7 +129,6 @@ class Port : public sigc::trackable {
|
||||||
std::string _devname;
|
std::string _devname;
|
||||||
std::string _tagname;
|
std::string _tagname;
|
||||||
int _mode;
|
int _mode;
|
||||||
size_t _number;
|
|
||||||
Channel *_channel[16];
|
Channel *_channel[16];
|
||||||
sigc::connection thru_connection;
|
sigc::connection thru_connection;
|
||||||
unsigned int bytes_written;
|
unsigned int bytes_written;
|
||||||
|
|
@ -135,6 +137,8 @@ class Port : public sigc::trackable {
|
||||||
Parser *output_parser;
|
Parser *output_parser;
|
||||||
size_t slowdown;
|
size_t slowdown;
|
||||||
|
|
||||||
|
virtual std::string get_typestring () const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static size_t nports;
|
static size_t nports;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,25 +17,39 @@
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <pbd/error.h>
|
#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>
|
||||||
#include <midi++/fifomidi.h>
|
#include <midi++/fifomidi.h>
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
std::string MIDI::CoreMidi_MidiPort::typestring = "coremidi";
|
||||||
|
|
||||||
#endif // WITH_COREMIDI
|
#endif // WITH_COREMIDI
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
using namespace PBD;
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
PortFactory::create_port (PortRequest &req)
|
PortFactory::create_port (PortRequest &req)
|
||||||
|
|
@ -132,3 +146,50 @@ PortFactory::default_port_type ()
|
||||||
|
|
||||||
PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg;
|
PBD::fatal << "programming error: no default port type defined in midifactory.cc" << endmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,18 +145,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;
|
||||||
}
|
}
|
||||||
|
|
@ -183,22 +197,6 @@ Manager::set_input_port (string tag)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_input_port (size_t portnum)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if ((*res).second->number() == portnum) {
|
|
||||||
inputPort = (*res).second;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Manager::set_output_port (string tag)
|
Manager::set_output_port (string tag)
|
||||||
|
|
||||||
|
|
@ -231,22 +229,6 @@ Manager::set_output_port (string tag)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_output_port (size_t portnum)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if ((*res).second->number() == portnum) {
|
|
||||||
outputPort = (*res).second;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
Manager::port (string name)
|
Manager::port (string name)
|
||||||
{
|
{
|
||||||
|
|
@ -261,25 +243,9 @@ 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)
|
||||||
|
|
||||||
{
|
{
|
||||||
PortMap::const_iterator i;
|
PortMap::const_iterator i;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,13 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <pbd/xml++.h>
|
||||||
|
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
#include <midi++/port.h>
|
#include <midi++/port.h>
|
||||||
#include <midi++/channel.h>
|
#include <midi++/channel.h>
|
||||||
#include <midi++/port_request.h>
|
#include <midi++/port_request.h>
|
||||||
|
#include <midi++/factory.h>
|
||||||
|
|
||||||
//using namespace Select;
|
//using namespace Select;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
|
@ -47,7 +50,6 @@ Port::Port (PortRequest &req)
|
||||||
_devname = req.devname;
|
_devname = req.devname;
|
||||||
_tagname = req.tagname;
|
_tagname = req.tagname;
|
||||||
_mode = req.mode;
|
_mode = req.mode;
|
||||||
_number = nports++;
|
|
||||||
|
|
||||||
if (_mode == O_RDONLY || _mode == O_RDWR) {
|
if (_mode == O_RDONLY || _mode == O_RDWR) {
|
||||||
input_parser = new Parser (*this);
|
input_parser = new Parser (*this);
|
||||||
|
|
@ -83,6 +85,18 @@ Port::~Port ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLNode&
|
||||||
|
Port::get_state () const
|
||||||
|
{
|
||||||
|
XMLNode* node = new XMLNode ("MIDI-port");
|
||||||
|
node->add_property ("tag", _tagname);
|
||||||
|
node->add_property ("device", _devname);
|
||||||
|
node->add_property ("mode", PortFactory::mode_to_string (_mode));
|
||||||
|
node->add_property ("type", get_typestring());
|
||||||
|
|
||||||
|
return *node;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Port::clock ()
|
Port::clock ()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,9 @@
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <midi++/port.h>
|
#include <midi++/port.h>
|
||||||
#include <midi++/port_request.h>
|
#include <midi++/port_request.h>
|
||||||
|
#include <midi++/factory.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
|
@ -36,45 +35,7 @@ PortRequest::PortRequest (const string &xdev,
|
||||||
|
|
||||||
devname = strdup (xdev.c_str());
|
devname = strdup (xdev.c_str());
|
||||||
tagname = strdup (xtag.c_str());
|
tagname = strdup (xtag.c_str());
|
||||||
|
mode = PortFactory::string_to_mode (xmode);
|
||||||
if (xmode == "output" ||
|
type = PortFactory::string_to_type (xtype);
|
||||||
xmode == "out" ||
|
|
||||||
xmode == "OUTPUT" ||
|
|
||||||
xmode == "OUT") {
|
|
||||||
mode = O_WRONLY;
|
|
||||||
|
|
||||||
} else if (xmode == "input" ||
|
|
||||||
xmode == "in" ||
|
|
||||||
xmode == "INPUT" ||
|
|
||||||
xmode == "IN") {
|
|
||||||
mode = O_RDONLY;
|
|
||||||
|
|
||||||
} else if (xmode == "duplex" ||
|
|
||||||
xmode == "DUPLEX" ||
|
|
||||||
xmode == "inout" ||
|
|
||||||
xmode == "INOUT") {
|
|
||||||
mode = O_RDWR;
|
|
||||||
} else {
|
|
||||||
status = Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xtype == "ALSA/RAW" ||
|
|
||||||
xtype == "alsa/raw") {
|
|
||||||
type = Port::ALSA_RawMidi;
|
|
||||||
} else if (xtype == "ALSA/SEQUENCER" ||
|
|
||||||
xtype == "alsa/sequencer") {
|
|
||||||
type = Port::ALSA_Sequencer;
|
|
||||||
} else if (xtype == "COREMIDI" ||
|
|
||||||
xtype == "coremidi") {
|
|
||||||
type = Port::CoreMidi_MidiPort;
|
|
||||||
} else if (xtype == "NULL" ||
|
|
||||||
xtype == "null") {
|
|
||||||
type = Port::Null;
|
|
||||||
} else if (xtype == "FIFO" ||
|
|
||||||
xtype == "fifo") {
|
|
||||||
type = Port::FIFO;
|
|
||||||
} else {
|
|
||||||
status = Unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <locale>
|
||||||
|
#include <algorithm>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#ifndef __STDC_FORMAT_MACROS
|
#ifndef __STDC_FORMAT_MACROS
|
||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
|
|
@ -234,4 +236,22 @@ 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