From f3cf31009a3b52fa126356b6f826958393c6a956 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 16 Oct 2007 21:01:12 +0000 Subject: virtualize Port object; clean up automation tracks from track deletion git-svn-id: svn://localhost/ardour2/trunk@2556 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/SConscript | 81 +++++++++-------- libs/ardour/ardour/audio_port.h | 35 +++---- libs/ardour/ardour/audioengine.h | 4 +- libs/ardour/ardour/jack_audio_port.h | 49 ++++++++++ libs/ardour/ardour/jack_midi_port.h | 53 +++++++++++ libs/ardour/ardour/midi_port.h | 12 +-- libs/ardour/ardour/port.h | 110 ++++++++-------------- libs/ardour/audio_port.cc | 11 +-- libs/ardour/audioengine.cc | 171 +++++++++-------------------------- libs/ardour/io.cc | 2 + libs/ardour/jack_audio_port.cc | 41 +++++++++ libs/ardour/jack_midi_port.cc | 94 +++++++++++++++++++ libs/ardour/jack_port.cc | 111 +++++++++++++++++++++++ libs/ardour/midi_port.cc | 77 +--------------- libs/ardour/port.cc | 30 +----- libs/ardour/session.cc | 10 +- 16 files changed, 509 insertions(+), 382 deletions(-) create mode 100644 libs/ardour/ardour/jack_audio_port.h create mode 100644 libs/ardour/ardour/jack_midi_port.h create mode 100644 libs/ardour/jack_audio_port.cc create mode 100644 libs/ardour/jack_midi_port.cc create mode 100644 libs/ardour/jack_port.cc (limited to 'libs/ardour') diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 465138d90d..556c6c3c9b 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -27,47 +27,26 @@ ardour.Append(POTFILE = domain + '.pot') ardour.Append(CPPPATH = '#libs/surfaces/control_protocol') ardour_files=Split(""" -bundle.cc -chan_count.cc -diskstream.cc -directory_names.cc -filename_extensions.cc -filesystem_paths.cc -find_session.cc -tape_file_matcher.cc -template_utils.cc -track.cc +amp.cc +audio_buffer.cc audio_diskstream.cc audio_library.cc audio_playlist.cc +audio_port.cc audio_track.cc audioengine.cc -port.cc -audio_port.cc -midi_port.cc -port_set.cc -buffer.cc -audio_buffer.cc -midi_buffer.cc -buffer_set.cc -meter.cc -amp.cc -panner.cc -filter.cc audiofilesource.cc audioregion.cc audiosource.cc -midi_source.cc -midi_diskstream.cc -midi_playlist.cc -midi_track.cc -midi_region.cc -midi_model.cc -note.cc -smf_source.cc auditioner.cc +automatable.cc automation.cc +automation_control.cc automation_event.cc +buffer.cc +buffer_set.cc +bundle.cc +chan_count.cc configuration.cc control_protocol_manager.cc control_protocol_search_path.cc @@ -75,34 +54,55 @@ crossfade.cc curve.cc cycle_timer.cc default_click.cc +directory_names.cc +diskstream.cc enums.cc +filename_extensions.cc +filesystem_paths.cc +filter.cc +find_session.cc gain.cc gdither.cc globals.cc import.cc -automatable.cc -automation_control.cc -processor.cc -io_processor.cc -plugin_insert.cc -port_insert.cc io.cc +io_processor.cc +jack_port.cc +jack_audio_port.cc +jack_midi_port.cc jack_slave.cc ladspa_plugin.cc location.cc +meter.cc +midi_buffer.cc +midi_diskstream.cc +midi_model.cc +midi_playlist.cc +midi_port.cc +midi_region.cc +midi_source.cc +midi_track.cc +mix.cc mtc_slave.cc named_selection.cc +note.cc +panner.cc pcm_utils.cc playlist.cc playlist_factory.cc plugin.cc +plugin_insert.cc plugin_manager.cc +port.cc +port_insert.cc +port_set.cc +processor.cc +quantize.cc recent_sessions.cc region.cc region_factory.cc -reverse.cc resampled_source.cc -quantize.cc +reverse.cc route.cc route_group.cc send.cc @@ -122,14 +122,17 @@ session_timefx.cc session_transport.cc session_utils.cc silentfilesource.cc +smf_source.cc sndfile_helpers.cc sndfilesource.cc source.cc source_factory.cc +tape_file_matcher.cc +template_utils.cc tempo.cc +track.cc utils.cc version.cc -mix.cc """) arch_specific_objects = [ ] diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h index d480eaf193..c6df9e0a2f 100644 --- a/libs/ardour/ardour/audio_port.h +++ b/libs/ardour/ardour/audio_port.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -32,19 +31,9 @@ namespace ARDOUR { class AudioEngine; -class AudioPort : public Port { +class AudioPort : public virtual Port { public: - virtual ~AudioPort() { - free (_port); - } - - void cycle_start(nframes_t nframes) { - _buffer.set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes); - } - - void cycle_end() {} - - DataType type() const { return DataType(DataType::AUDIO); } + DataType type() const { return DataType::AUDIO; } Buffer& get_buffer () { return _buffer; @@ -69,8 +58,8 @@ class AudioPort : public Port { reset_overs (); } - float peak_db() const { return _peak_db; } - jack_default_audio_sample_t peak() const { return _peak; } + float peak_db() const { return _peak_db; } + Sample peak() const { return _peak; } uint32_t short_overs () const { return _short_overs; } uint32_t long_overs () const { return _long_overs; } @@ -81,21 +70,21 @@ class AudioPort : public Port { protected: friend class AudioEngine; - AudioPort (jack_port_t *port); + AudioPort (); void reset (); /* engine isn't supposed to access below here */ AudioBuffer _buffer; - nframes_t _overlen; - jack_default_audio_sample_t _peak; - float _peak_db; - uint32_t _short_overs; - uint32_t _long_overs; + nframes_t _overlen; + Sample _peak; + float _peak_db; + uint32_t _short_overs; + uint32_t _long_overs; - static nframes_t _long_over_length; - static nframes_t _short_over_length; + static nframes_t _long_over_length; + static nframes_t _short_over_length; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index cb5a6d72ce..17ba9f9614 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -51,7 +51,7 @@ class AudioEngine : public sigc::trackable AudioEngine (std::string client_name); virtual ~AudioEngine (); - jack_client_t* jack() const { return _jack; } + jack_client_t* jack() const; bool connected() const { return _jack != 0; } bool is_realtime () const; @@ -219,6 +219,8 @@ class AudioEngine : public sigc::trackable SerializedRCUManager ports; + Port *register_port (DataType type, const std::string& portname, bool input); + int process_callback (nframes_t nframes); void remove_all_ports (); diff --git a/libs/ardour/ardour/jack_audio_port.h b/libs/ardour/ardour/jack_audio_port.h new file mode 100644 index 0000000000..8a636bb7aa --- /dev/null +++ b/libs/ardour/ardour/jack_audio_port.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ +*/ + +#ifndef __ardour_jack_audio_port_h__ +#define __ardour_jack_audio_port_h__ + +#include +#include +#include +#include +#include + +namespace ARDOUR { + +class AudioEngine; +class JackAudioPort : public AudioPort, public JackPort { + public: + void cycle_start(nframes_t nframes) { + _buffer.set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes); + } + + int reestablish (); + + protected: + friend class AudioEngine; + + JackAudioPort (const std::string& name, Flags flags); +}; + +} // namespace ARDOUR + +#endif /* __ardour_jack_audio_port_h__ */ diff --git a/libs/ardour/ardour/jack_midi_port.h b/libs/ardour/ardour/jack_midi_port.h new file mode 100644 index 0000000000..5508ae2b17 --- /dev/null +++ b/libs/ardour/ardour/jack_midi_port.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ +*/ + +#ifndef __ardour_jack_midi_port_h__ +#define __ardour_jack_midi_port_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ARDOUR { + +class MidiEngine; + +class JackMidiPort : public JackPort, public MidiPort { + public: + void cycle_start(nframes_t nframes); + void cycle_end(); + + protected: + friend class AudioEngine; + + JackMidiPort (const std::string&, Flags); + + nframes_t _nframes_this_cycle; +}; + +} // namespace ARDOUR + +#endif /* __ardour_jack_midi_port_h__ */ diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h index b7730f0d16..48ebf31eef 100644 --- a/libs/ardour/ardour/midi_port.h +++ b/libs/ardour/ardour/midi_port.h @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -33,11 +31,11 @@ namespace ARDOUR { class MidiEngine; -class MidiPort : public Port { +class MidiPort : public virtual Port { public: virtual ~MidiPort(); - DataType type() const { return DataType(DataType::MIDI); } + DataType type() const { return DataType::MIDI; } Buffer& get_buffer() { return _buffer; @@ -47,21 +45,17 @@ class MidiPort : public Port { return _buffer; } - void cycle_start(nframes_t nframes); - void cycle_end(); - size_t capacity() { return _buffer.capacity(); } size_t size() { return _buffer.size(); } protected: friend class AudioEngine; - MidiPort (jack_port_t *port); + MidiPort (nframes_t bufsize); /* engine isn't supposed to access below here */ MidiBuffer _buffer; - nframes_t _nframes_this_cycle; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index cae198758b..c1e502727f 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -31,65 +31,39 @@ namespace ARDOUR { class AudioEngine; class Buffer; -/** Abstract base for all outside ports (eg Jack ports) +/** Abstract base for ports */ -class Port : public sigc::trackable { +class Port : public virtual sigc::trackable { public: - virtual ~Port() { - free (_port); - } - - virtual DataType type() const = 0; + enum Flags { + IsInput = JackPortIsInput, + IsOutput = JackPortIsOutput, + IsPhysical = JackPortIsPhysical, + IsTerminal = JackPortIsTerminal, + CanMonitor = JackPortCanMonitor + }; - virtual void cycle_start(nframes_t nframes) {} - virtual void cycle_end() {} + virtual ~Port() {} - virtual Buffer& get_buffer() = 0; - std::string name() const { return _name; } - std::string short_name() { - return jack_port_short_name (_port); - } - - int set_name (std::string str); - JackPortFlags flags() const { + Flags flags() const { return _flags; } - bool is_mine (jack_client_t *client) { - return jack_port_is_mine (client, _port); - } - - int connected () const { - return jack_port_connected (_port); - } - - bool connected_to (const std::string& portname) const { - return jack_port_connected_to (_port, portname.c_str()); - } - - const char ** get_connections () const { - return jack_port_get_connections (_port); - } - bool receives_input() const { - return _flags & JackPortIsInput; + return _flags & IsInput; } bool sends_output () const { return _flags & JackPortIsOutput; } - - bool monitoring_input () const { - return jack_port_monitoring_input (_port); - } bool can_monitor () const { - return _flags & JackPortCanMonitor; + return _flags & CanMonitor; } void enable_metering() { @@ -100,28 +74,23 @@ class Port : public sigc::trackable { if (_metering) { _metering--; } } - void ensure_monitor_input (bool yn) { - -#ifdef HAVE_JACK_PORT_ENSURE_MONITOR - jack_port_ensure_monitor (_port, yn); -#else - jack_port_request_monitor(_port, yn); -#endif - - } - - /*XXX completely bloody useless imho*/ - void request_monitor_input (bool yn) { - jack_port_request_monitor (_port, yn); - } - - nframes_t latency () const { - return jack_port_get_latency (_port); - } - - void set_latency (nframes_t nframes) { - jack_port_set_latency (_port, nframes); - } + virtual DataType type() const = 0; + virtual void cycle_start(nframes_t nframes) {} + virtual void cycle_end() {} + virtual Buffer& get_buffer() = 0; + virtual std::string short_name() = 0; + virtual int set_name (std::string str) = 0; + virtual bool is_mine (jack_client_t *client) = 0; + virtual int reestablish () = 0; + virtual int connected () const = 0; + virtual bool connected_to (const std::string& portname) const = 0; + virtual const char ** get_connections () const = 0; + virtual bool monitoring_input () const = 0; + virtual void ensure_monitor_input (bool yn) = 0; + virtual void request_monitor_input (bool yn) = 0; + virtual nframes_t latency () const = 0; + virtual nframes_t total_latency () const = 0; + virtual void set_latency (nframes_t nframes) = 0; sigc::signal MonitorInputChanged; sigc::signal ClockSyncChanged; @@ -129,22 +98,19 @@ class Port : public sigc::trackable { protected: friend class AudioEngine; - Port (jack_port_t *port); - + Port (); + + virtual int disconnect () = 0; + virtual void recompute_total_latency() const = 0; virtual void reset (); /* engine isn't supposed to access below here */ - /* cache these 3 from JACK so we can access them for reconnecting */ - JackPortFlags _flags; - std::string _type; - std::string _name; - - jack_port_t* _port; - + Flags _flags; + std::string _type; + std::string _name; unsigned short _metering; - - bool _last_monitor : 1; + bool _last_monitor; }; } // namespace ARDOUR diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc index ae64995000..23c8ab8335 100644 --- a/libs/ardour/audio_port.cc +++ b/libs/ardour/audio_port.cc @@ -26,13 +26,10 @@ using namespace std; nframes_t AudioPort::_short_over_length = 2; nframes_t AudioPort::_long_over_length = 10; -AudioPort::AudioPort(jack_port_t* p) - : Port(p) - , _buffer(0) +AudioPort::AudioPort() + : _buffer (0) { - DataType dt(_type); - assert(dt == DataType::AUDIO); - + _type = DataType::AUDIO; reset(); } @@ -40,7 +37,7 @@ void AudioPort::reset() { Port::reset(); - if (_flags & JackPortIsOutput) { + if (_flags & IsOutput) { if (_buffer.capacity() > 0) { _buffer.clear(); } diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 2a4b36f7d8..63a51b76c4 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -83,6 +83,7 @@ AudioEngine::AudioEngine (string client_name) start_metering_thread(); + JackPort::set_engine (this); } AudioEngine::~AudioEngine () @@ -99,6 +100,12 @@ AudioEngine::~AudioEngine () } } +jack_client_t* +AudioEngine::jack() const +{ + return _jack; +} + void _thread_init_callback (void *arg) { @@ -501,89 +508,45 @@ AudioEngine::remove_session () } Port * -AudioEngine::register_input_port (DataType type, const string& portname) +AudioEngine::register_port (DataType type, const string& portname, bool input) { - if (!_running) { - if (!_has_run) { - fatal << _("register input port called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return 0; - } - } - - jack_port_t *p = jack_port_register (_jack, portname.c_str(), type.to_jack_type(), JackPortIsInput, 0); - - if (p) { + Port* newport = 0; - Port* newport = 0; - + try { if (type == DataType::AUDIO) - newport = new AudioPort (p); + newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput)); else if (type == DataType::MIDI) - newport = new MidiPort (p); + newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput)); else throw unknown_type(); - + if (newport != 0) { RCUWriter writer (ports); boost::shared_ptr ps = writer.get_copy (); ps->insert (ps->begin(), newport); /* writer goes out of scope, forces update */ } - + return newport; + } - } else { + catch (...) { throw PortRegistrationFailure(); } +} - return 0; +Port * +AudioEngine::register_input_port (DataType type, const string& portname) +{ + return register_port (type, portname, true); } Port * AudioEngine::register_output_port (DataType type, const string& portname) { - if (!_running) { - if (!_has_run) { - fatal << _("register output port called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return 0; - } - } - - jack_port_t* p = 0; - - if ((p = jack_port_register (_jack, portname.c_str(), - type.to_jack_type(), JackPortIsOutput, 0)) != 0) { - - Port* newport = 0; - - if (type == DataType::AUDIO) - newport = new AudioPort (p); - else if (type == DataType::MIDI) - newport = new MidiPort (p); - else - throw unknown_type (); - - if (newport != 0) { - RCUWriter writer (ports); - boost::shared_ptr ps = writer.get_copy (); - ps->insert (ps->begin(), newport); - /* writer goes out of scope, forces update */ - } - - return newport; - - } else { - throw PortRegistrationFailure (); - } - - return 0; + return register_port (type, portname, false); } - int AudioEngine::unregister_port (Port& port) { @@ -594,29 +557,25 @@ AudioEngine::unregister_port (Port& port) return 0; } - int ret = jack_port_unregister (_jack, port._port); - - if (ret == 0) { - - { - - RCUWriter writer (ports); - boost::shared_ptr ps = writer.get_copy (); - - for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) { - if ((*i) == &port) { - ps->erase (i); - break; - } + { + + RCUWriter writer (ports); + boost::shared_ptr ps = writer.get_copy (); + + for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) { + if ((*i) == &port) { + remove_connections_for (port); + cerr << "eraseing " << (*i)->name() << endl; + delete *i; + ps->erase (i); + break; } - - /* writer goes out of scope, forces update */ } - - remove_connections_for (port); + + /* writer goes out of scope, forces update */ } - return ret; + return 0; } int @@ -693,7 +652,7 @@ AudioEngine::disconnect (Port& port) } } - int ret = jack_port_disconnect (_jack, port._port); + int ret = port.disconnect (); if (ret == 0) { remove_connections_for (port); @@ -916,22 +875,9 @@ AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag) ARDOUR::nframes_t AudioEngine::get_port_total_latency (const Port& port) { - if (!_jack) { - fatal << _("get_port_total_latency() called with no JACK client connection") << endmsg; - /*NOTREACHED*/ - } - - if (!_running) { - if (!_has_run) { - fatal << _("get_port_total_latency() called before engine was started") << endmsg; - /*NOTREACHED*/ - } - } - - return jack_port_get_total_latency (_jack, port._port); + return port.total_latency (); } - void AudioEngine::update_total_latency (const Port& port) { @@ -947,9 +893,7 @@ AudioEngine::update_total_latency (const Port& port) } } -#ifdef HAVE_JACK_RECOMPUTE_LATENCY - jack_recompute_total_latency (_jack, port._port); -#endif + port.recompute_total_latency (); } void @@ -1025,14 +969,6 @@ AudioEngine::remove_all_ports () { /* process lock MUST be held */ - if (_jack) { - boost::shared_ptr p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - jack_port_unregister (_jack, (*i)->_port); - } - } - { RCUWriter writer (ports); boost::shared_ptr ps = writer.get_copy (); @@ -1152,31 +1088,14 @@ AudioEngine::reconnect_to_jack () for (i = p->begin(); i != p->end(); ++i) { - /* XXX hack hack hack */ - - string long_name = (*i)->name(); - string short_name; - - short_name = long_name.substr (long_name.find_last_of (':') + 1); - - if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type().to_jack_type(), (*i)->flags(), 0)) == 0) { - error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg; + if ((*i)->reestablish ()) { break; - } else { - } - - (*i)->reset (); - - if ((*i)->flags() & JackPortIsOutput) { - (*i)->get_buffer().silence (jack_get_buffer_size (_jack), 0); - } + } } if (i != p->end()) { /* failed */ - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - jack_port_unregister (_jack, (*i)->_port); - } + remove_all_ports (); return -1; } diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index bff8c18bc9..0c4ee41496 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -198,6 +198,8 @@ IO::IO (Session& s, const XMLNode& node, DataType dt) IO::~IO () { + cerr << "Deleting IO called " << _name << endl; + Glib::Mutex::Lock guard (m_meter_signal_lock); Glib::Mutex::Lock lm (io_lock); diff --git a/libs/ardour/jack_audio_port.cc b/libs/ardour/jack_audio_port.cc new file mode 100644 index 0000000000..83a6875f7d --- /dev/null +++ b/libs/ardour/jack_audio_port.cc @@ -0,0 +1,41 @@ +/* + Copyright (C) 2006 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include + +using namespace ARDOUR; + +JackAudioPort::JackAudioPort(const std::string& name, Flags flgs) + : JackPort (name, DataType::AUDIO, flgs) +{ + +} + +int +JackAudioPort::reestablish () +{ + int ret = JackPort::reestablish (); + + if (ret == 0 && _flags & IsOutput) { + _buffer.silence (jack_get_buffer_size (engine->jack())); + } + + return ret; +} diff --git a/libs/ardour/jack_midi_port.cc b/libs/ardour/jack_midi_port.cc new file mode 100644 index 0000000000..90ee93371d --- /dev/null +++ b/libs/ardour/jack_midi_port.cc @@ -0,0 +1,94 @@ +/* + Copyright (C) 2006 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include + +using namespace ARDOUR; +JackMidiPort::JackMidiPort (const std::string& name, Flags flgs) + : JackPort (name, DataType::MIDI, flgs) + , MidiPort (4096) // FIXME FIXME FIXME Jack needs to tell us this + , _nframes_this_cycle(0) +{ +} + +void +JackMidiPort::cycle_start (nframes_t nframes) +{ + _buffer.clear(); + assert(_buffer.size() == 0); + + _nframes_this_cycle = nframes; + + if (_flags & JackPortIsOutput) { + _buffer.silence(nframes); + assert(_buffer.size() == 0); + return; + } + + // We're an input - copy Jack events to internal buffer + + void* jack_buffer = jack_port_get_buffer(_port, nframes); + const nframes_t event_count + = jack_midi_get_event_count(jack_buffer); + + assert(event_count < _buffer.capacity()); + + jack_midi_event_t ev; + + for (nframes_t i=0; i < event_count; ++i) { + + jack_midi_event_get(&ev, jack_buffer, i); + + _buffer.push_back(ev); + } + + assert(_buffer.size() == event_count); + + //if (_buffer.size() > 0) + // cerr << "MIDIPort got " << event_count << " events." << endl; +} + +void +JackMidiPort::cycle_end() +{ + if (_flags & JackPortIsInput) { + _nframes_this_cycle = 0; + return; + } + + // We're an output - copy events from internal buffer to Jack buffer + + void* jack_buffer = jack_port_get_buffer(_port, _nframes_this_cycle); + + //const nframes_t event_count = _buffer.size(); + //if (event_count > 0) + // cerr << "MIDIPort writing " << event_count << " events." << endl; + + jack_midi_clear_buffer(jack_buffer); + + for (MidiBuffer::iterator i = _buffer.begin(); i != _buffer.end(); ++i) { + const MidiEvent& ev = *i; + // event times should be frames, relative to cycle start + assert(ev.time() >= 0); + assert(ev.time() < _nframes_this_cycle); + jack_midi_event_write(jack_buffer, (jack_nframes_t)ev.time(), ev.buffer(), ev.size()); + } + + _nframes_this_cycle = 0; +} diff --git a/libs/ardour/jack_port.cc b/libs/ardour/jack_port.cc new file mode 100644 index 0000000000..7f56e396ce --- /dev/null +++ b/libs/ardour/jack_port.cc @@ -0,0 +1,111 @@ +/* + Copyright (C) 2002-2006 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +#include +#include + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace std; + +AudioEngine* JackPort::engine = 0; + +JackPort::JackPort (const std::string& name, DataType type, Flags flgs) + : _port (0) +{ + _port = jack_port_register (engine->jack(), name.c_str(), type.to_jack_type(), flgs, 0); + + if (_port == 0) { + throw failed_constructor(); + } + + _flags = flgs; + _type = type; + _name = jack_port_name (_port); +} + +JackPort::~JackPort () +{ + cerr << "deleting jack port " << _name << endl; + + jack_port_unregister (engine->jack(), _port); +} + +int +JackPort::set_name (string str) +{ + int ret; + + if ((ret = jack_port_set_name (_port, str.c_str())) == 0) { + _name = str; + } + + return ret; +} + +int +JackPort::disconnect () +{ + return jack_port_disconnect (engine->jack(), _port); +} + +void +JackPort::set_engine (AudioEngine* e) +{ + engine = e; +} + +nframes_t +JackPort::total_latency () const +{ + return jack_port_get_total_latency (engine->jack(), _port); +} + +int +JackPort::reestablish () +{ + string short_name; + + short_name = _name.substr (_name.find_last_of (':') + 1); + + _port = jack_port_register (engine->jack(), short_name.c_str(), type().to_jack_type(), _flags, 0); + + if (_port == 0) { + error << string_compose (_("could not reregister %1"), _name) << endmsg; + return -1; + } + + reset (); + + + return 0; +} + +void +JackPort::recompute_total_latency () const +{ +#ifdef HAVE_JACK_RECOMPUTE_LATENCY + jack_recompute_total_latency (engine->jack(), _port); +#endif +} + diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index 3f03cfe880..df4ab19008 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -25,87 +25,16 @@ using namespace ARDOUR; using namespace std; -MidiPort::MidiPort(jack_port_t* p) - : Port(p) - , _buffer(4096) // FIXME FIXME FIXME Jack needs to tell us this - , _nframes_this_cycle(0) +MidiPort::MidiPort (nframes_t bufsize) + : _buffer (bufsize) { - DataType dt(_type); - assert(dt == DataType::MIDI); - + _type = DataType::MIDI; reset(); } - MidiPort::~MidiPort() { } -void -MidiPort::cycle_start (nframes_t nframes) -{ - _buffer.clear(); - assert(_buffer.size() == 0); - - _nframes_this_cycle = nframes; - - if (_flags & JackPortIsOutput) { - _buffer.silence(nframes); - assert(_buffer.size() == 0); - return; - } - - // We're an input - copy Jack events to internal buffer - - void* jack_buffer = jack_port_get_buffer(_port, nframes); - - const nframes_t event_count - = jack_midi_get_event_count(jack_buffer); - - assert(event_count < _buffer.capacity()); - - jack_midi_event_t ev; - - for (nframes_t i=0; i < event_count; ++i) { - - jack_midi_event_get(&ev, jack_buffer, i); - - _buffer.push_back(ev); - } - - assert(_buffer.size() == event_count); - - //if (_buffer.size() > 0) - // cerr << "MIDIPort got " << event_count << " events." << endl; -} - -void -MidiPort::cycle_end() -{ - if (_flags & JackPortIsInput) { - _nframes_this_cycle = 0; - return; - } - - // We're an output - copy events from internal buffer to Jack buffer - - void* jack_buffer = jack_port_get_buffer(_port, _nframes_this_cycle); - - //const nframes_t event_count = _buffer.size(); - //if (event_count > 0) - // cerr << "MIDIPort writing " << event_count << " events." << endl; - - jack_midi_clear_buffer(jack_buffer); - - for (MidiBuffer::iterator i = _buffer.begin(); i != _buffer.end(); ++i) { - const MidiEvent& ev = *i; - // event times should be frames, relative to cycle start - assert(ev.time() >= 0); - assert(ev.time() < _nframes_this_cycle); - jack_midi_event_write(jack_buffer, (jack_nframes_t)ev.time(), ev.buffer(), ev.size()); - } - - _nframes_this_cycle = 0; -} diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index d9c93c250b..bfc1eaf279 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -22,20 +22,10 @@ using namespace ARDOUR; using namespace std; -Port::Port (jack_port_t *p) - : _port (p) - , _metering(0) - , _last_monitor(false) +Port::Port () + : _metering (0) + , _last_monitor (false) { - if (_port == 0) { - throw failed_constructor(); - } - - _flags = JackPortFlags (jack_port_flags (_port)); - _type = jack_port_type (_port); - _name = jack_port_name (_port); - - reset (); } void @@ -43,17 +33,3 @@ Port::reset () { _last_monitor = false; } - -int -Port::set_name (string str) -{ - int ret; - - if ((ret = jack_port_set_name (_port, str.c_str())) == 0) { - _name = str; - } - - return ret; -} - - diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index abd8a0abba..1382fa3f0a 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2089,13 +2089,14 @@ Session::remove_route (shared_ptr route) find_current_end (); + // We need to disconnect the routes inputs and outputs + + route->disconnect_inputs (0); + route->disconnect_outputs (0); + update_latency_compensation (false, false); set_dirty(); - // We need to disconnect the routes inputs and outputs - route->disconnect_inputs(NULL); - route->disconnect_outputs(NULL); - /* get rid of it from the dead wood collection in the route list manager */ /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */ @@ -4240,3 +4241,4 @@ Session::foreach_bundle (sigc::slot > sl) sl (*i); } } + -- cgit v1.2.3