#include "ardour/session.h"
#include "ardour/user_bundle.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
#define BLOCK_PROCESS_CALLBACK() Glib::Threads::Mutex::Lock em (AudioEngine::instance()->process_lock())
#endif
boost::shared_ptr<Port> port;
+ vector<boost::shared_ptr<Port> > deleted_ports;
changed = false;
assert(port);
_ports.remove(port);
+
+ /* hold a reference to the port so that we can ensure
+ * that this thread, and not a JACK notification thread,
+ * holds the final reference.
+ */
+
+ deleted_ports.push_back (port);
_session.engine().unregister_port (port);
changed = true;
}
+ /* this will drop the final reference to the deleted ports,
+ * which will in turn call their destructors, which will in
+ * turn call the backend to unregister them.
+ *
+ * There will no connect/disconnect or register/unregister
+ * callbacks from the backend until we get here, because
+ * they are driven by the Port destructor. The destructor
+ * will not execute until we drop the final reference,
+ * which all happens right .... here.
+ */
+ deleted_ports.clear ();
+
/* create any necessary new ports */
while (n_ports().get(*t) < n) {
char buf[64];
string str;
int n;
- LocaleGuard lg (X_("C"));
+ LocaleGuard lg;
Glib::Threads::Mutex::Lock lm (io_lock);
node->add_property("name", _name);
XMLProperty const * prop;
XMLNodeConstIterator iter;
- LocaleGuard lg (X_("C"));
+ LocaleGuard lg;
/* force use of non-localized representation of decimal point,
since we use it a lot in XML files and so forth.
{
XMLProperty const * prop;
XMLNodeConstIterator iter;
- LocaleGuard lg (X_("C"));
+ LocaleGuard lg;
/* force use of non-localized representation of decimal point,
since we use it a lot in XML files and so forth.
case 2:
return c == 0 ? _("L") : _("R");
default:
- snprintf (buf, sizeof(buf), _("%d"), (c + 1));
+ snprintf (buf, sizeof(buf), "%d", (c + 1));
return buf;
}
} else {
- snprintf (buf, sizeof(buf), _("%d"), (c + 1));
+ snprintf (buf, sizeof(buf), "%d", (c + 1));
return buf;
}
* Caller must hold process lock.
*/
void
-IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, framepos_t end_frame, pframes_t nframes)
+IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes)
{
/* don't read the data into new buffers - just use the port buffers directly */
_buffers.get_backend_port_addresses (_ports, nframes);
if (proc) {
- proc->run (_buffers, start_frame, end_frame, nframes, true);
+ proc->run (_buffers, start_frame, end_frame, speed, nframes, true);
}
}
void
IO::copy_to_outputs (BufferSet& bufs, DataType type, pframes_t nframes, framecnt_t offset)
{
- // Copy any buffers 1:1 to outputs
-
PortSet::iterator o = _ports.begin(type);
BufferSet::iterator i = bufs.begin(type);
BufferSet::iterator prev = i;
+ assert(i != bufs.end(type)); // or second loop will crash
+
+ // Copy any buffers 1:1 to outputs
+
while (i != bufs.end(type) && o != _ports.end (type)) {
Buffer& port_buffer (o->get_buffer (nframes));
port_buffer.read_from (*i, nframes, offset);