diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-07 22:22:11 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-07 22:22:11 -0400 |
commit | 1ab61b8564f9934c533d1c1a229888bc7e2fd557 (patch) | |
tree | baa1b05b50c018ca0edbda936b35de58adb29d94 /libs/ardour/ardour | |
parent | 83a0c30c24ce6bb6e3e718c267a82fbaffc33b4b (diff) |
major redesign of MIDI port heirarchy and management (part 2)
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/audio_port.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/debug.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/jack_audiobackend.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_ui.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/midiport_manager.h | 10 | ||||
-rw-r--r-- | libs/ardour/ardour/port_manager.h | 35 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/slave.h | 30 | ||||
-rw-r--r-- | libs/ardour/ardour/ticker.h | 53 |
10 files changed, 94 insertions, 60 deletions
diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h index f5affb0580..f87b134e9e 100644 --- a/libs/ardour/ardour/audio_port.h +++ b/libs/ardour/ardour/audio_port.h @@ -49,9 +49,7 @@ class AudioPort : public Port friend class PortManager; AudioPort (std::string const &, PortFlags); - protected: - friend class AudioEngine; - /* special access for engine only (hah, C++) */ + /* special access for PortManager only (hah, C++) */ Sample* engine_get_whole_audio_buffer (); private: diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 6fb13b7ae0..509d330f12 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -36,13 +36,9 @@ #include "pbd/signals.h" #include "pbd/stacktrace.h" -#include <jack/weakjack.h> -#include <jack/jack.h> -#include <jack/transport.h> -#include <jack/thread.h> +#include "midi++/mmc.h" #include "ardour/ardour.h" - #include "ardour/data_type.h" #include "ardour/session_handle.h" #include "ardour/types.h" @@ -192,6 +188,8 @@ public: /* sets up the process callback thread */ static void thread_init_callback (void *); + MIDI::MachineControl& mmc() { return _mmc; } + private: AudioEngine (); @@ -206,16 +204,17 @@ public: gain_t session_removal_gain; gain_t session_removal_gain_step; bool _running; + bool _freewheeling; /// number of frames between each check for changes in monitor input framecnt_t monitor_check_interval; /// time of the last monitor check in frames framecnt_t last_monitor_check; /// the number of frames processed since start() was called framecnt_t _processed_frames; - bool _freewheeling; bool _pre_freewheel_mmc_enabled; Glib::Threads::Thread* m_meter_thread; ProcessThread* _main_thread; + MIDI::MachineControl _mmc; void meter_thread (); void start_metering_thread (); diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index 202d0cc424..5811f7a484 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -63,6 +63,7 @@ namespace PBD { extern uint64_t OrderKeys; extern uint64_t Automation; extern uint64_t WiimoteControl; + extern uint64_t Ports; } } diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h index 9fa3d0c1cc..ada7ce8e33 100644 --- a/libs/ardour/ardour/jack_audiobackend.h +++ b/libs/ardour/ardour/jack_audiobackend.h @@ -178,6 +178,8 @@ class JACKAudioBackend : public AudioBackend { typedef std::map<std::string,DeviceList> DriverDeviceMap; mutable DriverDeviceMap all_devices; + + PBD::ScopedConnection disconnect_connection; }; } // namespace diff --git a/libs/ardour/ardour/midi_ui.h b/libs/ardour/ardour/midi_ui.h index 34e97494be..c15a530057 100644 --- a/libs/ardour/ardour/midi_ui.h +++ b/libs/ardour/ardour/midi_ui.h @@ -26,13 +26,11 @@ #include "pbd/signals.h" #include "pbd/stacktrace.h" -namespace MIDI { - class Port; -} namespace ARDOUR { class Session; +class AsyncMIDIPort; /* this is mostly a placeholder because I suspect that at some point we will want to add more members to accomodate @@ -67,7 +65,7 @@ class MidiControlUI : public AbstractUI<MidiUIRequest> ARDOUR::Session& _session; PBD::ScopedConnection rebind_connection; - bool midi_input_handler (Glib::IOCondition, MIDI::Port*); + bool midi_input_handler (Glib::IOCondition, AsyncMIDIPort*); void reset_ports (); void clear_ports (); diff --git a/libs/ardour/ardour/midiport_manager.h b/libs/ardour/ardour/midiport_manager.h index 9c45e60341..df33038f2b 100644 --- a/libs/ardour/ardour/midiport_manager.h +++ b/libs/ardour/ardour/midiport_manager.h @@ -56,8 +56,10 @@ class MidiPortManager { * callback. */ - MIDI::Port* midi_input_port () { return _midi_input_port; } - MIDI::Port* midi_output_port () { return _midi_output_port; } + MIDI::Port* midi_input_port () const { return _midi_input_port; } + MIDI::Port* midi_output_port () const { return _midi_output_port; } + MIDI::Port* mmc_input_port () const { return _mmc_input_port; } + MIDI::Port* mmc_output_port () const { return _mmc_output_port; } /* Ports used for synchronization. These have their I/O handled inside the * process callback. @@ -76,8 +78,12 @@ class MidiPortManager { /* asynchronously handled ports: MIDI::Port */ MIDI::Port* _midi_input_port; MIDI::Port* _midi_output_port; + MIDI::Port* _mmc_input_port; + MIDI::Port* _mmc_output_port; boost::shared_ptr<Port> _midi_in; boost::shared_ptr<Port> _midi_out; + boost::shared_ptr<Port> _mmc_in; + boost::shared_ptr<Port> _mmc_out; /* synchronously handled ports: ARDOUR::MidiPort */ boost::shared_ptr<MidiPort> _mtc_input_port; diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h index 06e4939101..895294810e 100644 --- a/libs/ardour/ardour/port_manager.h +++ b/libs/ardour/ardour/port_manager.h @@ -32,15 +32,17 @@ #include "pbd/rcu.h" #include "ardour/chan_count.h" +#include "ardour/midiport_manager.h" #include "ardour/port.h" #include "ardour/port_engine.h" namespace ARDOUR { -class PortManager +class PortManager : public MidiPortManager { public: typedef std::map<std::string,boost::shared_ptr<Port> > Ports; + typedef std::list<boost::shared_ptr<Port> > PortList; PortManager (); virtual ~PortManager() {} @@ -53,8 +55,8 @@ class PortManager /* Port registration */ - boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname); - boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname); + boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname, bool async = false); + boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname, bool async = false); int unregister_port (boost::shared_ptr<Port>); /* Port connectivity */ @@ -87,7 +89,8 @@ class PortManager ChanCount n_physical_inputs () const; int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&); - + int get_ports (DataType, PortList&); + void remove_all_ports (); /* per-Port monitoring */ @@ -135,9 +138,31 @@ class PortManager SerializedRCUManager<Ports> ports; bool _port_remove_in_progress; - boost::shared_ptr<Port> register_port (DataType type, const std::string& portname, bool input); + boost::shared_ptr<Port> register_port (DataType type, const std::string& portname, bool input, bool async = false); void port_registration_failure (const std::string& portname); + + /** List of ports to be used between ::cycle_start() and ::cycle_end() + */ + boost::shared_ptr<Ports> _cycle_ports; + + void fade_out (gain_t, gain_t, pframes_t); + void silence (pframes_t nframes); + void check_monitoring (); + /** Signal the start of an audio cycle. + * This MUST be called before any reading/writing for this cycle. + * Realtime safe. + */ + void cycle_start (pframes_t nframes); + + /** Signal the end of an audio cycle. + * This signifies that the cycle began with @ref cycle_start has ended. + * This MUST be called at the end of each cycle. + * Realtime safe. + */ + void cycle_end (pframes_t nframes); }; + + } // namespace diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a12f816c1e..a47c13046d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -813,7 +813,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr<SessionPlaylists> playlists; void send_mmc_locate (framepos_t); - int send_full_time_code (framepos_t); + int send_full_time_code (framepos_t, pframes_t nframes); void send_song_position_pointer (framepos_t); bool step_editing() const { return (_step_editors > 0); } diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 4408da2d25..adf425ea43 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -40,15 +40,12 @@ #define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") ) #define LEADINGZERO(A) ( (A)<10 ? " " : (A)<100 ? " " : (A)<1000 ? " " : "" ) -namespace MIDI { - class Port; -} - namespace ARDOUR { class TempoMap; class Session; class AudioEngine; +class MidiPort; /** * @class Slave @@ -67,6 +64,15 @@ class Slave { Slave() { } virtual ~Slave() {} + /** The slave should read any incoming information in this method + * and use it adjust its current idea of reality. If no such + * processing is required, it does need to be implemented. + * + * @param nframes specifies the number of frames-worth of data that + * can be read from any ports used by the slave. + */ + virtual int process (pframes_t) { return 0; } + /** * This is the most important function to implement: * Each process cycle, Session::follow_slave will call this method. @@ -253,10 +259,11 @@ class TimecodeSlave : public Slave { class MTC_Slave : public TimecodeSlave { public: - MTC_Slave (Session&, MIDI::Port&); + MTC_Slave (Session&, MidiPort&); ~MTC_Slave (); - void rebind (MIDI::Port&); + void rebind (MidiPort&); + int process (pframes_t); bool speed_and_position (double&, framepos_t&); bool locked() const; @@ -274,7 +281,8 @@ class MTC_Slave : public TimecodeSlave { private: Session& session; - MIDI::Port* port; + MidiPort* port; + MIDI::Parser parser; PBD::ScopedConnectionList port_connections; PBD::ScopedConnection config_connection; bool can_notify_on_unknown_rate; @@ -405,13 +413,14 @@ public: class MIDIClock_Slave : public Slave { public: - MIDIClock_Slave (Session&, MIDI::Port&, int ppqn = 24); + MIDIClock_Slave (Session&, MidiPort&, int ppqn = 24); /// Constructor for unit tests MIDIClock_Slave (ISlaveSessionProxy* session_proxy = 0, int ppqn = 24); ~MIDIClock_Slave (); - void rebind (MIDI::Port&); + void rebind (MidiPort&); + int process (pframes_t); bool speed_and_position (double&, framepos_t&); bool locked() const; @@ -427,7 +436,8 @@ class MIDIClock_Slave : public Slave { protected: ISlaveSessionProxy* session; - MIDI::Port* port; + MidiPort* port; + MIDI::Parser parser; PBD::ScopedConnectionList port_connections; /// pulses per quarter note for one MIDI clock frame (default 24) diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index b6e5376c12..7f0d1987fc 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -27,17 +27,13 @@ #include "ardour/session_handle.h" -#ifndef TICKER_H_ -#define TICKER_H_ +#ifndef __libardour_ticker_h__ +#define __libardour_ticker_h__ -namespace MIDI { - class Port; -} - -namespace ARDOUR -{ +namespace ARDOUR { class Session; +class MidiPort; class MidiClockTicker : public SessionHandlePtr, boost::noncopyable { @@ -45,7 +41,7 @@ public: MidiClockTicker (); virtual ~MidiClockTicker(); - void tick (const framepos_t& transport_frames); + void tick (const framepos_t& transport_frames, pframes_t nframes); bool has_midi_port() const { return _midi_port != 0; } @@ -58,9 +54,6 @@ public: /// slot for the signal session::TransportStateChange void transport_state_changed(); - /// slot for the signal session::PositionChanged - void position_changed (framepos_t position); - /// slot for the signal session::TransportLooped void transport_looped(); @@ -70,23 +63,25 @@ public: /// pulses per quarter note (default 24) void set_ppqn(int ppqn) { _ppqn = ppqn; } -private: - MIDI::Port* _midi_port; - int _ppqn; - double _last_tick; - - class Position; - boost::scoped_ptr<Position> _pos; - - double one_ppqn_in_frames (framepos_t transport_position); - - void send_midi_clock_event (pframes_t offset); - void send_start_event (pframes_t offset); - void send_continue_event (pframes_t offset); - void send_stop_event (pframes_t offset); - void send_position_event (uint32_t midi_clocks, pframes_t offset); + private: + boost::shared_ptr<MidiPort> _midi_port; + int _ppqn; + double _last_tick; + bool _send_pos; + bool _send_state; + + class Position; + boost::scoped_ptr<Position> _pos; + + double one_ppqn_in_frames (framepos_t transport_position); + + void send_midi_clock_event (pframes_t offset, pframes_t nframes); + void send_start_event (pframes_t offset, pframes_t nframes); + void send_continue_event (pframes_t offset, pframes_t nframes); + void send_stop_event (pframes_t offset, pframes_t nframes); + void send_position_event (uint32_t midi_clocks, pframes_t offset, pframes_t nframes); }; - } + // namespace -#endif /* TICKER_H_ */ +#endif /* __libardour_ticker_h__ */ |