diff options
author | Carl Hetherington <carl@carlh.net> | 2011-10-28 17:04:09 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2011-10-28 17:04:09 +0000 |
commit | 7bdcc127e3e42bd76b997b56ecd938b1127d790b (patch) | |
tree | f1e9856094ee5a54cc28957508f2b693fbcd043a /libs | |
parent | f65e3f287b48fef6d4fdb8c4456c0eada4c4431c (diff) |
Use shared_ptr for Port in the AudioEngine; improves thread-safety of the audio engine's port list as a writer cannot destroy a port in one thread while the port list is being iterated in another.
git-svn-id: svn://localhost/ardour2/branches/3.0@10327 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 16 | ||||
-rw-r--r-- | libs/ardour/ardour/export_channel.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/io.h | 18 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_diskstream.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/port_set.h | 24 | ||||
-rw-r--r-- | libs/ardour/audio_diskstream.cc | 4 | ||||
-rw-r--r-- | libs/ardour/audioengine.cc | 79 | ||||
-rw-r--r-- | libs/ardour/bundle.cc | 4 | ||||
-rw-r--r-- | libs/ardour/delivery.cc | 6 | ||||
-rw-r--r-- | libs/ardour/export_channel.cc | 15 | ||||
-rw-r--r-- | libs/ardour/io.cc | 32 | ||||
-rw-r--r-- | libs/ardour/midi_diskstream.cc | 23 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 2 | ||||
-rw-r--r-- | libs/ardour/port.cc | 2 | ||||
-rw-r--r-- | libs/ardour/port_set.cc | 31 | ||||
-rw-r--r-- | libs/ardour/session.cc | 8 |
16 files changed, 128 insertions, 142 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 9df37c2fe6..7d9cb3f28a 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -63,7 +63,7 @@ class ProcessThread; class AudioEngine : public SessionHandlePtr { public: - typedef std::set<Port*> Ports; + typedef std::set<boost::shared_ptr<Port> > Ports; AudioEngine (std::string client_name, std::string session_uuid); virtual ~AudioEngine (); @@ -161,9 +161,9 @@ public: virtual const char *what() const throw() { return "could not connect to engine backend"; } }; - Port *register_input_port (DataType, const std::string& portname); - Port *register_output_port (DataType, const std::string& portname); - int unregister_port (Port &); + boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname); + boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname); + int unregister_port (boost::shared_ptr<Port>); bool port_is_physical (const std::string&) const; void ensure_monitor_input (const std::string&, bool) const; @@ -172,7 +172,7 @@ public: int connect (const std::string& source, const std::string& destination); int disconnect (const std::string& source, const std::string& destination); - int disconnect (Port &); + int disconnect (boost::shared_ptr<Port>); const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags); @@ -184,7 +184,7 @@ public: void get_physical_outputs (DataType type, std::vector<std::string>&); void get_physical_inputs (DataType type, std::vector<std::string>&); - Port *get_port_by_name (const std::string &); + boost::shared_ptr<Port> get_port_by_name (const std::string &); enum TransportState { TransportStopped = JackTransportStopped, @@ -247,7 +247,7 @@ _ the regular process() call to session->process() is not made. * The std::string parameters are the (long) port names. * The bool parameter is true if ports were connected, or false for disconnected. */ - PBD::Signal5<void, Port *, std::string, Port *, std::string, bool> PortConnectedOrDisconnected; + PBD::Signal5<void, boost::weak_ptr<Port>, std::string, boost::weak_ptr<Port>, std::string, bool> PortConnectedOrDisconnected; std::string make_port_name_relative (std::string) const; std::string make_port_name_non_relative (std::string) const; @@ -283,7 +283,7 @@ private: SerializedRCUManager<Ports> ports; - 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); int process_callback (pframes_t nframes); void* process_thread (); diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h index c13580e25c..a10bdfc290 100644 --- a/libs/ardour/ardour/export_channel.h +++ b/libs/ardour/ardour/export_channel.h @@ -65,7 +65,7 @@ class ExportChannel : public boost::less_than_comparable<ExportChannel> class PortExportChannel : public ExportChannel { public: - typedef std::set<AudioPort *> PortSet; + typedef std::set<boost::weak_ptr<AudioPort> > PortSet; PortExportChannel (); void set_max_buffer_size(framecnt_t frames); @@ -78,7 +78,7 @@ class PortExportChannel : public ExportChannel bool operator< (ExportChannel const & other) const; - void add_port (AudioPort * port) { ports.insert (port); } + void add_port (boost::weak_ptr<AudioPort> port) { ports.insert (port); } PortSet const & get_ports () { return ports; } private: diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index e318258e19..c7c91a6cf3 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -102,9 +102,9 @@ class IO : public SessionObject, public Latent boost::shared_ptr<Bundle> bundle () { return _bundle; } int add_port (std::string connection, void *src, DataType type = DataType::NIL); - int remove_port (Port *, void *src); - int connect (Port *our_port, std::string other_port, void *src); - int disconnect (Port *our_port, std::string other_port, void *src); + int remove_port (boost::shared_ptr<Port>, void *src); + int connect (boost::shared_ptr<Port> our_port, std::string other_port, void *src); + int disconnect (boost::shared_ptr<Port> our_port, std::string other_port, void *src); int disconnect (void *src); bool connected_to (boost::shared_ptr<const IO>) const; bool connected_to (const std::string&) const; @@ -117,20 +117,20 @@ class IO : public SessionObject, public Latent PortSet& ports() { return _ports; } const PortSet& ports() const { return _ports; } - bool has_port (Port *) const; + bool has_port (boost::shared_ptr<Port>) const; - Port *nth (uint32_t n) const { + boost::shared_ptr<Port> nth (uint32_t n) const { if (n < _ports.num_ports()) { return _ports.port(n); } else { - return 0; + return boost::shared_ptr<Port> (); } } - Port* port_by_name (const std::string& str) const; + boost::shared_ptr<Port> port_by_name (const std::string& str) const; - AudioPort* audio(uint32_t n) const; - MidiPort* midi(uint32_t n) const; + boost::shared_ptr<AudioPort> audio(uint32_t n) const; + boost::shared_ptr<MidiPort> midi(uint32_t n) const; const ChanCount& n_ports () const { return _ports.count(); } diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 0454b55e01..9ce1ee0eb1 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -184,7 +184,7 @@ class MidiDiskstream : public Diskstream MidiRingBuffer<framepos_t>* _playback_buf; MidiRingBuffer<framepos_t>* _capture_buf; - MidiPort* _source_port; + boost::weak_ptr<MidiPort> _source_port; boost::shared_ptr<SMFSource> _write_source; NoteMode _note_mode; volatile gint _frames_written_to_ringbuffer; diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h index 199c650f2b..a6a0593946 100644 --- a/libs/ardour/ardour/port_set.h +++ b/libs/ardour/ardour/port_set.h @@ -42,20 +42,20 @@ public: size_t num_ports() const; size_t num_ports(DataType type) const { return _ports[type].size(); } - void add(Port* port); - bool remove(Port* port); + void add (boost::shared_ptr<Port> port); + bool remove (boost::shared_ptr<Port> port); /** nth port */ - Port* port(size_t index) const; + boost::shared_ptr<Port> port(size_t index) const; /** nth port of type @a t, or nth port if t = NIL */ - Port* port(DataType t, size_t index) const; + boost::shared_ptr<Port> port(DataType t, size_t index) const; - AudioPort* nth_audio_port(size_t n) const; + boost::shared_ptr<AudioPort> nth_audio_port(size_t n) const; - MidiPort* nth_midi_port(size_t n) const; + boost::shared_ptr<MidiPort> nth_midi_port(size_t n) const; - bool contains(const Port* port) const; + bool contains (boost::shared_ptr<const Port> port) const; /** Remove all ports from the PortSet. Ports are not deregistered with * the engine, it's the caller's responsibility to not leak here! @@ -69,8 +69,8 @@ public: template<typename PS, typename P> class iterator_base { public: - P& operator*() { return *_set.port(_type, _index); } - P* operator->() { return _set.port(_type, _index); } + boost::shared_ptr<P> operator*() { return _set.port(_type, _index); } + boost::shared_ptr<P> operator->() { return _set.port(_type, _index); } iterator_base<PS,P>& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const iterator_base<PS,P>& other) { return (_index == other._index); } bool operator!=(const iterator_base<PS,P>& other) { return (_index != other._index); } @@ -109,8 +109,8 @@ public: class audio_iterator { public: - AudioPort& operator*() { return *_set.nth_audio_port(_index); } - AudioPort* operator->() { return _set.nth_audio_port(_index); } + boost::shared_ptr<AudioPort> operator*() { return _set.nth_audio_port(_index); } + boost::shared_ptr<AudioPort> operator->() { return _set.nth_audio_port(_index); } audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const audio_iterator& other) { return (_index == other._index); } bool operator!=(const audio_iterator& other) { return (_index != other._index); } @@ -128,7 +128,7 @@ public: audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); } private: - typedef std::vector<Port*> PortVec; + typedef std::vector<boost::shared_ptr<Port> > PortVec; // Vector of vectors, indexed by DataType::to_index() std::vector<PortVec> _ports; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 80b484f926..a7c8558fdc 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -489,7 +489,7 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& n for recording, and use rec_offset */ - AudioPort* const ap = _io->audio (n); + boost::shared_ptr<AudioPort> const ap = _io->audio (n); assert(ap); assert(rec_nframes <= (framecnt_t) ap->get_audio_buffer(nframes).capacity()); @@ -505,7 +505,7 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& n goto out; } - AudioPort* const ap = _io->audio (n); + boost::shared_ptr<AudioPort> const ap = _io->audio (n); assert(ap); Sample* buf = ap->get_audio_buffer(nframes).data (rec_offset); diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index a264449706..e4f31478a4 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -382,8 +382,8 @@ AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int co jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a); jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b); - Port* port_a = 0; - Port* port_b = 0; + boost::shared_ptr<Port> port_a; + boost::shared_ptr<Port> port_b; boost::shared_ptr<Ports> pr = ae->ports.reader (); Ports::iterator i = pr->begin (); @@ -530,15 +530,14 @@ AudioEngine::process_callback (pframes_t nframes) for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - Port *port = (*i); bool x; - if (port->last_monitor() != (x = port->monitoring_input ())) { - port->set_last_monitor (x); + if ((*i)->last_monitor() != (x = (*i)->monitoring_input ())) { + (*i)->set_last_monitor (x); /* XXX I think this is dangerous, due to a likely mutex in the signal handlers ... */ - port->MonitorInputChanged (x); /* EMIT SIGNAL */ + (*i)->MonitorInputChanged (x); /* EMIT SIGNAL */ } } last_monitor_check = next_processed_frames; @@ -550,10 +549,8 @@ AudioEngine::process_callback (pframes_t nframes) for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - Port *port = (*i); - - if (port->sends_output()) { - port->get_buffer(nframes).silence(nframes); + if ((*i)->sends_output()) { + (*i)->get_buffer(nframes).silence(nframes); } } } @@ -774,16 +771,16 @@ AudioEngine::port_registration_failure (const std::string& portname) throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str()); } -Port* +boost::shared_ptr<Port> AudioEngine::register_port (DataType dtype, const string& portname, bool input) { - Port* newport; + boost::shared_ptr<Port> newport; try { if (dtype == DataType::AUDIO) { - newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)); + newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput))); } else if (dtype == DataType::MIDI) { - newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)); + newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput))); } else { throw PortRegistrationFailure("unable to create port (unknown type)"); } @@ -807,20 +804,20 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input) } } -Port * +boost::shared_ptr<Port> AudioEngine::register_input_port (DataType type, const string& portname) { return register_port (type, portname, true); } -Port * +boost::shared_ptr<Port> AudioEngine::register_output_port (DataType type, const string& portname) { return register_port (type, portname, false); } int -AudioEngine::unregister_port (Port& port) +AudioEngine::unregister_port (boost::shared_ptr<Port> port) { /* caller must hold process lock */ @@ -834,18 +831,13 @@ AudioEngine::unregister_port (Port& port) { RCUWriter<Ports> writer (ports); boost::shared_ptr<Ports> ps = writer.get_copy (); - - for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) { - if ((*i) == &port) { - delete *i; - ps->erase (i); - break; - } - } + ps->erase (port); /* writer goes out of scope, forces update */ } + ports.flush (); + return 0; } @@ -867,8 +859,8 @@ AudioEngine::connect (const string& source, const string& destination) string d = make_port_name_non_relative (destination); - Port* src = get_port_by_name (s); - Port* dst = get_port_by_name (d); + boost::shared_ptr<Port> src = get_port_by_name (s); + boost::shared_ptr<Port> dst = get_port_by_name (d); if (src) { ret = src->connect (d); @@ -907,8 +899,8 @@ AudioEngine::disconnect (const string& source, const string& destination) string s = make_port_name_non_relative (source); string d = make_port_name_non_relative (destination); - Port* src = get_port_by_name (s); - Port* dst = get_port_by_name (d); + boost::shared_ptr<Port> src = get_port_by_name (s); + boost::shared_ptr<Port> dst = get_port_by_name (d); if (src) { ret = src->disconnect (d); @@ -922,7 +914,7 @@ AudioEngine::disconnect (const string& source, const string& destination) } int -AudioEngine::disconnect (Port& port) +AudioEngine::disconnect (boost::shared_ptr<Port> port) { GET_PRIVATE_JACK_POINTER_RET (_jack,-1); @@ -935,7 +927,7 @@ AudioEngine::disconnect (Port& port) } } - return port.disconnect_all (); + return port->disconnect_all (); } ARDOUR::framecnt_t @@ -968,10 +960,10 @@ AudioEngine::frames_per_cycle () const } /** @param name Full or short name of port - * @return Corresponding Port* or 0. This object remains the property of the AudioEngine - * so must not be deleted. + * @return Corresponding Port or 0. */ -Port* + +boost::shared_ptr<Port> AudioEngine::get_port_by_name (const string& portname) { if (!_running) { @@ -979,13 +971,13 @@ AudioEngine::get_port_by_name (const string& portname) fatal << _("get_port_by_name() called before engine was started") << endmsg; /*NOTREACHED*/ } else { - return 0; + boost::shared_ptr<Port> (); } } if (!port_is_mine (portname)) { /* not an ardour port */ - return 0; + return boost::shared_ptr<Port> (); } std::string const rel = make_port_name_relative (portname); @@ -998,7 +990,7 @@ AudioEngine::get_port_by_name (const string& portname) } } - return 0; + return boost::shared_ptr<Port> (); } const char ** @@ -1241,14 +1233,9 @@ AudioEngine::remove_all_ports () /* process lock MUST be held by caller */ - vector<Port*> to_be_deleted; - { RCUWriter<Ports> writer (ports); boost::shared_ptr<Ports> ps = writer.get_copy (); - for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) { - to_be_deleted.push_back (*i); - } ps->clear (); } @@ -1256,14 +1243,6 @@ AudioEngine::remove_all_ports () ports.flush (); - /* now do the actual deletion, given that "ports" is now empty, thus - preventing anyone else from getting a handle on a Port - */ - - for (vector<Port*>::iterator p = to_be_deleted.begin(); p != to_be_deleted.end(); ++p) { - delete *p; - } - port_remove_in_progress = false; } diff --git a/libs/ardour/bundle.cc b/libs/ardour/bundle.cc index 37e4733e14..1948024d91 100644 --- a/libs/ardour/bundle.cc +++ b/libs/ardour/bundle.cc @@ -421,8 +421,8 @@ Bundle::connected_to (boost::shared_ptr<Bundle> other, AudioEngine & engine) for (uint32_t j = 0; j < A.size(); ++j) { for (uint32_t k = 0; k < B.size(); ++k) { - Port* p = engine.get_port_by_name (A[j]); - Port* q = engine.get_port_by_name (B[k]); + boost::shared_ptr<Port> p = engine.get_port_by_name (A[j]); + boost::shared_ptr<Port> q = engine.get_port_by_name (B[k]); if (!p && !q) { return false; diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 72429e472d..3d808563de 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -461,7 +461,7 @@ Delivery::flush_buffers (framecnt_t nframes, framepos_t time) PortSet& ports (_output->ports()); for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).flush_buffers (nframes, time); + i->flush_buffers (nframes, time); } } @@ -478,7 +478,7 @@ Delivery::transport_stopped (framepos_t now) PortSet& ports (_output->ports()); for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).transport_stopped (); + i->transport_stopped (); } } } @@ -490,7 +490,7 @@ Delivery::realtime_locate () PortSet& ports (_output->ports()); for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) { - (*i).realtime_locate (); + i->realtime_locate (); } } } diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc index 4593c4de9f..8f83c0a7fb 100644 --- a/libs/ardour/export_channel.cc +++ b/libs/ardour/export_channel.cc @@ -62,15 +62,17 @@ PortExportChannel::read (Sample const *& data, framecnt_t frames) const assert(frames <= buffer_size); if (ports.size() == 1) { - data = (*ports.begin())->get_audio_buffer(frames).data(); + boost::shared_ptr<AudioPort> p = ports.begin()->lock (); + data = p->get_audio_buffer(frames).data(); return; } memset (buffer.get(), 0, frames * sizeof (Sample)); for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) { - if (*it != 0) { - Sample* port_buffer = (*it)->get_audio_buffer(frames).data(); + boost::shared_ptr<AudioPort> p = it->lock (); + if (p) { + Sample* port_buffer = p->get_audio_buffer(frames).data(); for (uint32_t i = 0; i < frames; ++i) { buffer[i] += (float) port_buffer[i]; @@ -86,8 +88,9 @@ PortExportChannel::get_state (XMLNode * node) const { XMLNode * port_node; for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) { - if ((port_node = node->add_child ("Port"))) { - port_node->add_property ("name", (*it)->name()); + boost::shared_ptr<Port> p = it->lock (); + if (p && (port_node = node->add_child ("Port"))) { + port_node->add_property ("name", p->name()); } } } @@ -100,7 +103,7 @@ PortExportChannel::set_state (XMLNode * node, Session & session) for (XMLNodeList::iterator it = xml_ports.begin(); it != xml_ports.end(); ++it) { if ((prop = (*it)->property ("name"))) { std::string const & name = prop->value(); - AudioPort * port = dynamic_cast<AudioPort *> (session.engine().get_port_by_name (name)); + boost::shared_ptr<AudioPort> port = boost::dynamic_pointer_cast<AudioPort> (session.engine().get_port_by_name (name)); if (port) { ports.insert (port); } else { diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 7655f9d656..4f1b03dfda 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -163,7 +163,7 @@ IO::check_bundles_connected () int -IO::disconnect (Port* our_port, string other_port, void* src) +IO::disconnect (boost::shared_ptr<Port> our_port, string other_port, void* src) { if (other_port.length() == 0 || our_port == 0) { return 0; @@ -196,7 +196,7 @@ IO::disconnect (Port* our_port, string other_port, void* src) } int -IO::connect (Port* our_port, string other_port, void* src) +IO::connect (boost::shared_ptr<Port> our_port, string other_port, void* src) { if (other_port.length() == 0 || our_port == 0) { return 0; @@ -223,7 +223,7 @@ IO::connect (Port* our_port, string other_port, void* src) } int -IO::remove_port (Port* port, void* src) +IO::remove_port (boost::shared_ptr<Port> port, void* src) { ChanCount before = _ports.count (); ChanCount after = before; @@ -251,7 +251,7 @@ IO::remove_port (Port* port, void* src) change.type = IOChange::Type (change.type | IOChange::ConnectionsChanged); } - _session.engine().unregister_port (*port); + _session.engine().unregister_port (port); check_bundles_connected (); } } @@ -286,7 +286,7 @@ IO::remove_port (Port* port, void* src) int IO::add_port (string destination, void* src, DataType type) { - Port* our_port; + boost::shared_ptr<Port> our_port; if (type == DataType::NIL) { type = _default_type; @@ -364,7 +364,7 @@ IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) { assert (!AudioEngine::instance()->process_lock().trylock()); - Port* port = 0; + boost::shared_ptr<Port> port; changed = false; @@ -378,7 +378,7 @@ IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) assert(port); _ports.remove(port); - _session.engine().unregister_port (*port); + _session.engine().unregister_port (port); changed = true; } @@ -894,7 +894,7 @@ IO::make_connections (const XMLNode& node, int version, bool in) continue; } - Port* p = port_by_name (prop->value()); + boost::shared_ptr<Port> p = port_by_name (prop->value()); if (p) { for (XMLNodeConstIterator c = (*i)->children().begin(); c != (*i)->children().end(); ++c) { @@ -1337,14 +1337,14 @@ IO::find_port_hole (const char* base) } -AudioPort* +boost::shared_ptr<AudioPort> IO::audio(uint32_t n) const { return _ports.nth_audio_port (n); } -MidiPort* +boost::shared_ptr<MidiPort> IO::midi(uint32_t n) const { return _ports.nth_midi_port (n); @@ -1599,21 +1599,19 @@ IO::copy_to_outputs (BufferSet& bufs, DataType type, pframes_t nframes, framecnt } } -Port* +boost::shared_ptr<Port> IO::port_by_name (const std::string& str) const { /* to be called only from ::set_state() - no locking */ for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) { - const Port& p(*i); - - if (p.name() == str) { - return const_cast<Port*>(&p); + if (i->name() == str) { + return boost::const_pointer_cast<Port> (*i); } } - return 0; + return boost::shared_ptr<Port> (); } bool @@ -1629,7 +1627,7 @@ IO::physically_connected () const } bool -IO::has_port (Port* p) const +IO::has_port (boost::shared_ptr<Port> p) const { Glib::Mutex::Lock lm (io_lock); return _ports.contains (p); diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index d9e7c54f2d..901aefcf17 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -74,7 +74,6 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F : Diskstream(sess, name, flag) , _playback_buf(0) , _capture_buf(0) - , _source_port(0) , _note_mode(Sustained) , _frames_written_to_ringbuffer(0) , _frames_read_from_ringbuffer(0) @@ -94,7 +93,6 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node) : Diskstream(sess, node) , _playback_buf(0) , _capture_buf(0) - , _source_port(0) , _note_mode(Sustained) , _frames_written_to_ringbuffer(0) , _frames_read_from_ringbuffer(0) @@ -171,7 +169,7 @@ MidiDiskstream::non_realtime_input_change () } if (ni == 0) { - _source_port = 0; + _source_port.reset (); } else { _source_port = _io->midi(0); } @@ -496,7 +494,9 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& ne return 0; } - if (_source_port == 0) { + boost::shared_ptr<MidiPort> sp = _source_port.lock (); + + if (sp == 0) { return 1; } @@ -527,7 +527,7 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& ne if (nominally_recording || rec_nframes) { // Pump entire port buffer into the ring buffer (FIXME: split cycles?) - MidiBuffer& buf = _source_port->get_midi_buffer(nframes); + MidiBuffer& buf = sp->get_midi_buffer(nframes); for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) { const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false); assert(ev.buffer()); @@ -1196,8 +1196,10 @@ MidiDiskstream::engage_record_enable () g_atomic_int_set (&_record_enabled, 1); - if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) { - _source_port->request_monitor_input (!(_session.config.get_auto_input() && rolling)); + boost::shared_ptr<MidiPort> sp = _source_port.lock (); + + if (sp && Config->get_monitoring_model() == HardwareMonitoring) { + sp->request_monitor_input (!(_session.config.get_auto_input() && rolling)); } RecordEnableChanged (); /* EMIT SIGNAL */ @@ -1372,8 +1374,11 @@ MidiDiskstream::allocate_temporary_buffers () void MidiDiskstream::monitor_input (bool yn) { - if (_source_port) - _source_port->ensure_monitor_input (yn); + boost::shared_ptr<MidiPort> sp = _source_port.lock (); + + if (sp) { + sp->ensure_monitor_input (yn); + } } void diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 469d994768..dcea38521b 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -690,7 +690,7 @@ MidiTrack::map_input_active (bool yn) PortSet& ports (_input->ports()); for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) { - MidiPort* mp = dynamic_cast<MidiPort*> (&*p); + boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p); if (yn != mp->input_active()) { mp->set_input_active (yn); } diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index b418943bba..f36984a523 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -383,7 +383,7 @@ Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) c latency compensation. */ - Port* remote_port = AudioEngine::instance()->get_port_by_name (*c); + boost::shared_ptr<Port> remote_port = AudioEngine::instance()->get_port_by_name (*c); if (remote_port) { lr = remote_port->private_latency_range ((playback ? JackPlaybackLatency : JackCaptureLatency)); DEBUG_TRACE (DEBUG::Latency, string_compose ( diff --git a/libs/ardour/port_set.cc b/libs/ardour/port_set.cc index 44a5f436a9..8ad8531f5d 100644 --- a/libs/ardour/port_set.cc +++ b/libs/ardour/port_set.cc @@ -32,7 +32,7 @@ PortSet::PortSet() _ports.push_back( PortVec() ); } -static bool sort_ports_by_name (Port* a, Port* b) +static bool sort_ports_by_name (boost::shared_ptr<Port> a, boost::shared_ptr<Port> b) { string aname (a->name()); string bname (b->name()); @@ -72,7 +72,7 @@ static bool sort_ports_by_name (Port* a, Port* b) } void -PortSet::add(Port* port) +PortSet::add (boost::shared_ptr<Port> port) { PortVec& v = _ports[port->type()]; @@ -84,7 +84,7 @@ PortSet::add(Port* port) } bool -PortSet::remove(Port* port) +PortSet::remove (boost::shared_ptr<Port> port) { for (std::vector<PortVec>::iterator l = _ports.begin(); l != _ports.end(); ++l) { PortVec::iterator i = find(l->begin(), l->end(), port); @@ -112,16 +112,16 @@ PortSet::num_ports() const } bool -PortSet::contains(const Port* port) const +PortSet::contains (boost::shared_ptr<const Port> port) const { for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) - if (find((*l).begin(), (*l).end(), port) != (*l).end()) + if (find (l->begin(), l->end(), port) != l->end()) return true; return false; } -Port* +boost::shared_ptr<Port> PortSet::port(size_t n) const { // This is awesome. Awesomely slow. @@ -129,16 +129,17 @@ PortSet::port(size_t n) const size_t size_so_far = 0; for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) { - if (n < size_so_far + (*l).size()) + if (n < size_so_far + l->size()) { return (*l)[n - size_so_far]; - else - size_so_far += (*l).size(); + } else { + size_so_far += l->size(); + } } - return NULL; // n out of range + return boost::shared_ptr<Port> (); // n out of range } -Port* +boost::shared_ptr<Port> PortSet::port(DataType type, size_t n) const { if (type == DataType::NIL) { @@ -150,16 +151,16 @@ PortSet::port(DataType type, size_t n) const } } -AudioPort* +boost::shared_ptr<AudioPort> PortSet::nth_audio_port(size_t n) const { - return dynamic_cast<AudioPort*>(port(DataType::AUDIO, n)); + return boost::dynamic_pointer_cast<AudioPort> (port (DataType::AUDIO, n)); } -MidiPort* +boost::shared_ptr<MidiPort> PortSet::nth_midi_port(size_t n) const { - return dynamic_cast<MidiPort*>(port(DataType::MIDI, n)); + return boost::dynamic_pointer_cast<MidiPort> (port (DataType::MIDI, n)); } } // namepace ARDOUR diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 5ac2446d03..618f553a28 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -546,7 +546,7 @@ Session::when_engine_running () uint32_t limit = _master_out->n_outputs().n_total(); for (uint32_t n = 0; n < limit; ++n) { - Port* p = _master_out->output()->nth (n); + boost::shared_ptr<Port> p = _master_out->output()->nth (n); string connect_to; if (outputs[p->type()].size() > n) { connect_to = outputs[p->type()][n]; @@ -576,8 +576,8 @@ Session::when_engine_running () if (_master_out) { for (uint32_t n = 0; n < limit; ++n) { - AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n); - AudioPort* o = _master_out->output()->ports().nth_audio_port (n); + boost::shared_ptr<AudioPort> p = _monitor_out->input()->ports().nth_audio_port (n); + boost::shared_ptr<AudioPort> o = _master_out->output()->ports().nth_audio_port (n); if (o) { string connect_to = o->name(); @@ -617,7 +617,7 @@ Session::when_engine_running () for (uint32_t n = 0; n < limit; ++n) { - Port* p = _monitor_out->output()->ports().port(DataType::AUDIO, n); + boost::shared_ptr<Port> p = _monitor_out->output()->ports().port(DataType::AUDIO, n); string connect_to; if (outputs[DataType::AUDIO].size() > (n % mod)) { connect_to = outputs[DataType::AUDIO][n % mod]; |