From 47add43cd028855cda2292bef9dcde607f948490 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 19 Jul 2007 18:21:58 +0000 Subject: 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 --- libs/midi++2/alsa_sequencer_midiport.cc | 76 ++++++++++++++++++++++++++++++++- libs/midi++2/coremidi_midiport.cc | 7 +++ libs/midi++2/midi++/alsa_sequencer.h | 3 ++ libs/midi++2/midi++/coremidi_midiport.h | 3 ++ libs/midi++2/midi++/factory.h | 3 ++ libs/midi++2/midi++/manager.h | 5 +++ libs/midi++2/midi++/port_request.h | 10 ++++- libs/midi++2/midifactory.cc | 31 ++++++++++++++ libs/midi++2/midimanager.cc | 6 +++ 9 files changed, 142 insertions(+), 2 deletions(-) (limited to 'libs') diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc index a47678bf1b..9ffd9f7832 100644 --- a/libs/midi++2/alsa_sequencer_midiport.cc +++ b/libs/midi++2/alsa_sequencer_midiport.cc @@ -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& 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; +} diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc index 8d1d927b7b..38f84fe750 100644 --- a/libs/midi++2/coremidi_midiport.cc +++ b/libs/midi++2/coremidi_midiport.cc @@ -142,3 +142,10 @@ void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, } } +int +CoreMidi_MidiPort::discover (vector& ports) +{ + /* XXX do dynamic port discovery here */ + + return 0; +} diff --git a/libs/midi++2/midi++/alsa_sequencer.h b/libs/midi++2/midi++/alsa_sequencer.h index 5ca70529c5..78e4a01683 100644 --- a/libs/midi++2/midi++/alsa_sequencer.h +++ b/libs/midi++2/midi++/alsa_sequencer.h @@ -27,6 +27,7 @@ #include #include +#include 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&); protected: /* Direct I/O */ diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h index d7df23aa04..20fe739b94 100644 --- a/libs/midi++2/midi++/coremidi_midiport.h +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -40,6 +40,9 @@ namespace MIDI { virtual int selectable() const { return -1; } + + static int discover (std::vector&); + protected: /* Direct I/O */ int write(byte * msg, size_t msglen); diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h index f2963624fe..186c3973e3 100644 --- a/libs/midi++2/midi++/factory.h +++ b/libs/midi++2/midi++/factory.h @@ -23,6 +23,7 @@ #include #include +#include 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&); + static std::string default_port_type (); }; } // namespace MIDI diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index 40140cfde2..c230933689 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -21,10 +21,13 @@ #define __midi_manager_h__ #include +#include + #include #include #include +#include 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&); + private: /* This is a SINGLETON pattern */ diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h index 0cb4ffded6..cd4e758ebb 100644 --- a/libs/midi++2/midi++/port_request.h +++ b/libs/midi++2/midi++/port_request.h @@ -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 #include 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 ports; +}; + } // namespace MIDI #endif // __midi_port_request_h__ diff --git a/libs/midi++2/midifactory.cc b/libs/midi++2/midifactory.cc index 0a86c94cb9..0912c8ae7b 100644 --- a/libs/midi++2/midifactory.cc +++ b/libs/midi++2/midifactory.cc @@ -17,6 +17,8 @@ $Id$ */ +#include + #include #include #include @@ -101,3 +103,32 @@ PortFactory::ignore_duplicate_devices (Port::Type type) return ret; } +int +PortFactory::get_known_ports (vector& 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; +} diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc index 44fd89108c..3b7323541d 100644 --- a/libs/midi++2/midimanager.cc +++ b/libs/midi++2/midimanager.cc @@ -380,3 +380,9 @@ Manager::parse_port_request (string str, Port::Type type) return 0; } + +int +Manager::get_known_ports (vector& ports) +{ + return PortFactory::get_known_ports (ports); +} -- cgit v1.2.3