2 Copyright (C) 2000,2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "pbd/xml++.h"
24 #include "ardour/audio_port.h"
25 #include "ardour/audioengine.h"
26 #include "ardour/delivery.h"
27 #include "ardour/io.h"
28 #include "ardour/mtdm.h"
29 #include "ardour/port_insert.h"
30 #include "ardour/session.h"
31 #include "ardour/types.h"
36 using namespace ARDOUR;
40 PortInsert::name_and_id_new_insert (Session& s, uint32_t& bitslot)
42 bitslot = s.next_insert_id ();
43 return string_compose (_("insert %1"), bitslot+ 1);
46 PortInsert::PortInsert (Session& s, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster> mm)
47 : IOProcessor (s, true, true, name_and_id_new_insert (s, _bitslot), "", DataType::AUDIO, true)
48 , _out (new Delivery (s, _output, pannable, mm, _name, Delivery::Insert))
51 _latency_detect = false;
52 _latency_flush_samples = 0;
53 _measured_latency = 0;
56 PortInsert::~PortInsert ()
58 _session.unmark_insert_id (_bitslot);
63 PortInsert::set_pre_fader (bool p)
65 Processor::set_pre_fader (p);
66 _out->set_pre_fader (p);
70 PortInsert::start_latency_detection ()
73 _mtdm = new MTDM (_session.sample_rate());
74 _latency_flush_samples = 0;
75 _latency_detect = true;
76 _measured_latency = 0;
80 PortInsert::stop_latency_detection ()
82 _latency_flush_samples = signal_latency() + _session.engine().samples_per_cycle();
83 _latency_detect = false;
87 PortInsert::set_measured_latency (samplecnt_t n)
89 _measured_latency = n;
93 PortInsert::latency() const
95 /* because we deliver and collect within the same cycle,
96 all I/O is necessarily delayed by at least samples_per_cycle().
98 if the return port for insert has its own latency, we
99 need to take that into account too.
102 if (_measured_latency == 0) {
103 return _session.engine().samples_per_cycle() + _input->latency();
105 return _measured_latency;
110 PortInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
112 if (_output->n_ports().n_total() == 0) {
116 if (_latency_detect) {
118 if (_input->n_ports().n_audio() != 0) {
120 AudioBuffer& outbuf (_output->ports().nth_audio_port(0)->get_audio_buffer (nframes));
121 Sample* in = _input->ports().nth_audio_port(0)->get_audio_buffer (nframes).data();
122 Sample* out = outbuf.data();
124 _mtdm->process (nframes, in, out);
126 outbuf.set_written (true);
131 } else if (_latency_flush_samples) {
133 /* wait for the entire input buffer to drain before picking up input again so that we can't
134 hear the remnants of whatever MTDM pumped into the pipeline.
137 silence (nframes, start_sample);
139 if (_latency_flush_samples > nframes) {
140 _latency_flush_samples -= nframes;
142 _latency_flush_samples = 0;
148 if (!_active && !_pending_active) {
149 /* deliver silence */
150 silence (nframes, start_sample);
154 _out->run (bufs, start_sample, end_sample, speed, nframes, true);
155 _input->collect_input (bufs, nframes, ChanCount::ZERO);
158 _active = _pending_active;
164 XMLNode& node = IOProcessor::state ();
165 node.set_property ("type", "port");
166 node.set_property ("bitslot", _bitslot);
167 node.set_property ("latency", _measured_latency);
168 node.set_property ("block-size", _session.get_block_size());
174 PortInsert::set_state (const XMLNode& node, int version)
176 XMLNodeList nlist = node.children();
177 XMLNodeIterator niter;
178 XMLPropertyList plist;
180 const XMLNode* insert_node = &node;
182 // legacy sessions: search for child Redirect node
183 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
184 if ((*niter)->name() == "Redirect") {
185 insert_node = *niter;
190 IOProcessor::set_state (*insert_node, version);
192 std::string type_str;
193 if (!node.get_property ("type", type_str)) {
194 error << _("XML node describing port insert is missing the `type' field") << endmsg;
198 if (type_str != "port") {
199 error << _("non-port insert XML used for port plugin insert") << endmsg;
203 uint32_t blocksize = 0;
204 node.get_property ("block-size", blocksize);
206 //if the jack period is the same as when the value was saved, we can recall our latency..
207 if ( (_session.get_block_size() == blocksize) ) {
208 node.get_property ("latency", _measured_latency);
211 if (!node.property ("ignore-bitslot")) {
213 if (node.get_property ("bitslot", bitslot)) {
214 _session.unmark_insert_id (_bitslot);
216 _session.mark_insert_id (_bitslot);
218 _bitslot = _session.next_insert_id();
226 PortInsert::signal_latency() const
228 /* because we deliver and collect within the same cycle,
229 all I/O is necessarily delayed by at least samples_per_cycle().
231 if the return port for insert has its own latency, we
232 need to take that into account too.
235 if (_measured_latency == 0) {
236 return _session.engine().samples_per_cycle() + _input->signal_latency();
238 return _measured_latency;
242 /** Caller must hold process lock */
244 PortInsert::configure_io (ChanCount in, ChanCount out)
246 #ifndef PLATFORM_WINDOWS
247 assert (!AudioEngine::instance()->process_lock().trylock());
250 /* for an insert, processor input corresponds to IO output, and vice versa */
252 if (_input->ensure_io (in, false, this) != 0) {
256 if (_output->ensure_io (out, false, this) != 0) {
260 return Processor::configure_io (in, out);
264 PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
271 PortInsert::set_name (const std::string& name)
273 bool ret = Processor::set_name (name);
275 ret = (ret && _input->set_name (name) && _output->set_name (name));
281 PortInsert::activate ()
283 IOProcessor::activate ();
289 PortInsert::deactivate ()
291 IOProcessor::deactivate ();