From bd1220a46db9fe909d09c08139cfb61ba98ec9f3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 1 Sep 2006 07:38:55 +0000 Subject: Fixes for IO port adding/removing Working audio sends/port inserts Send gain, panning MIDI sends working (maybe port inserts too?) Buffer/Port fixes (related to silence) Metering bug fixes git-svn-id: svn://localhost/ardour2/branches/midi@883 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/amp.cc | 2 +- libs/ardour/ardour/audio_port.h | 10 ---------- libs/ardour/ardour/buffer.h | 24 ++++++++++++++++++++---- libs/ardour/ardour/buffer_set.h | 5 +---- libs/ardour/ardour/midi_port.h | 5 ----- libs/ardour/ardour/port.h | 11 ----------- libs/ardour/audio_port.cc | 8 ++++++-- libs/ardour/audioengine.cc | 2 +- libs/ardour/buffer.cc | 12 ++++++++---- libs/ardour/buffer_set.cc | 16 ++++++++++++++++ libs/ardour/insert.cc | 2 +- libs/ardour/io.cc | 16 +++++++++++++--- libs/ardour/midi_track.cc | 22 +++++++++++++--------- libs/ardour/panner.cc | 5 ----- libs/ardour/port.cc | 2 -- libs/ardour/route.cc | 22 ++++++++++++---------- libs/ardour/send.cc | 5 ++--- 17 files changed, 94 insertions(+), 75 deletions(-) diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index cfa20afe3b..8a73e5708e 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -37,7 +37,7 @@ Amp::run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target // if we don't need to declick, defer to apply_simple_gain if (initial == target) { - apply_simple_gain(bufs, nframes, invert_polarity ? target : -target); + apply_simple_gain(bufs, nframes, invert_polarity ? -target : target); } const jack_nframes_t declick = std::min ((jack_nframes_t)128, nframes); diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h index 45949dc59e..07dc8da442 100644 --- a/libs/ardour/ardour/audio_port.h +++ b/libs/ardour/ardour/audio_port.h @@ -75,16 +75,6 @@ class AudioPort : public Port { static void set_short_over_length (jack_nframes_t); static void set_long_over_length (jack_nframes_t); - /** Assumes that the port is an audio output port */ - void silence (jack_nframes_t nframes, jack_nframes_t offset) { - if (!_silent) { - _buffer.silence(nframes, offset); - if (offset == 0 && nframes == _buffer.capacity()) { - _silent = true; - } - } - } - protected: friend class AudioEngine; diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h index 896d6e7616..828eac4d64 100644 --- a/libs/ardour/ardour/buffer.h +++ b/libs/ardour/ardour/buffer.h @@ -56,6 +56,8 @@ public: * Based on this you can static cast a Buffer* to the desired type. */ DataType type() const { return _type; } + bool silent() const { return _silent; } + /** Clear (eg zero, or empty) buffer starting at TIME @a offset */ virtual void silence(jack_nframes_t len, jack_nframes_t offset=0) = 0; @@ -66,12 +68,13 @@ public: protected: Buffer(DataType type, size_t capacity) - : _type(type), _capacity(capacity), _size(0) + : _type(type), _capacity(capacity), _size(0), _silent(true) {} DataType _type; size_t _capacity; size_t _size; + bool _silent; private: // Prevent copies (undefined) @@ -93,9 +96,14 @@ public: void silence(jack_nframes_t len, jack_nframes_t offset=0) { - assert(_capacity > 0); - assert(offset + len <= _capacity); - memset(_data + offset, 0, sizeof (Sample) * len); + if (!_silent) { + assert(_capacity > 0); + assert(offset + len <= _capacity); + memset(_data + offset, 0, sizeof (Sample) * len); + if (offset == 0 && len == _capacity) { + _silent = true; + } + } } /** Read @a len frames FROM THE START OF @a src into self at @a offset */ @@ -105,6 +113,7 @@ public: assert(src.type() == _type == DataType::AUDIO); assert(offset + len <= _capacity); memcpy(_data + offset, ((AudioBuffer&)src).data(len), sizeof(Sample) * len); + _silent = src.silent(); } /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */ @@ -119,6 +128,8 @@ public: for (jack_nframes_t n = 0; n < len; ++n) { dst_raw[n] += src_raw[n]; } + + _silent = (src.silent() && _silent); } /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset @@ -134,6 +145,8 @@ public: for (jack_nframes_t n = 0; n < len; ++n) { dst_raw[n] += src_raw[n] * gain_coeff; } + + _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) ); } void apply_gain(gain_t gain, jack_nframes_t len, jack_nframes_t offset=0) { @@ -142,6 +155,8 @@ public: for (jack_nframes_t n = 0; n < len; ++n) { buf[n] *= gain; } + + _silent = (_silent || gain == 0); } /** Set the data contained by this buffer manually (for setting directly to jack buffer). @@ -154,6 +169,7 @@ public: _capacity = size; _size = size; _data = data; + _silent = false; } const Sample* data(jack_nframes_t nframes, jack_nframes_t offset=0) const diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h index 43df729e05..03b0b193d4 100644 --- a/libs/ardour/ardour/buffer_set.h +++ b/libs/ardour/ardour/buffer_set.h @@ -84,10 +84,7 @@ public: return (MidiBuffer&)get(DataType::MIDI, i); } - void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0) - { - throw; // FIXME: implement this with spiffy DataType iterator etc. - } + void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0); // ITERATORS diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h index f6eafe11bd..1abfd80932 100644 --- a/libs/ardour/ardour/midi_port.h +++ b/libs/ardour/ardour/midi_port.h @@ -52,11 +52,6 @@ class MidiPort : public Port { size_t capacity() { return _buffer.capacity(); } size_t size() { return _buffer.size(); } - - /** Assumes that the port is an output port */ - void silence (jack_nframes_t nframes, jack_nframes_t offset) { - _buffer.silence(nframes, offset); - } protected: friend class AudioEngine; diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index a436722cb0..2a99bdcc16 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -47,10 +47,6 @@ class Port : public sigc::trackable { virtual Buffer& get_buffer() = 0; - /** Silence/Empty the port, output ports only */ - virtual void silence (jack_nframes_t nframes, jack_nframes_t offset) = 0; - - std::string name() const { return _name; } @@ -128,12 +124,6 @@ class Port : public sigc::trackable { jack_port_set_latency (_port, nframes); } - bool is_silent() const { return _silent; } - - void mark_silence (bool yn) { - _silent = yn; - } - sigc::signal MonitorInputChanged; sigc::signal ClockSyncChanged; @@ -156,7 +146,6 @@ class Port : public sigc::trackable { unsigned short _metering; bool _last_monitor : 1; - bool _silent : 1; }; } // namespace ARDOUR diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc index 99f2b7ecae..2250c7f2a7 100644 --- a/libs/ardour/audio_port.cc +++ b/libs/ardour/audio_port.cc @@ -44,7 +44,7 @@ AudioPort::reset() if (_buffer.capacity() > 0) { _buffer.clear(); } - _silent = true; + assert(_buffer.silent()); } _metering = 0; @@ -55,8 +55,12 @@ void AudioPort::cycle_start (jack_nframes_t nframes) { if (_flags & JackPortIsOutput) { - // FIXME: do nothing, we can cache the value (but capacity needs to be set) + const bool silent = _buffer.silent(); + // FIXME: do nothing, we can cache the value (but capacity needs to be set for MIDI) _buffer.set_data((Sample*)jack_port_get_buffer (_port, nframes), nframes); + if (silent) { + _buffer.silence(nframes); + } } else { _buffer.set_data((Sample*)jack_port_get_buffer (_port, nframes), nframes); } diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 027a623301..ddb835c78f 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -1066,7 +1066,7 @@ AudioEngine::reconnect_to_jack () (*i)->reset (); if ((*i)->flags() & JackPortIsOutput) { - (*i)->silence (jack_get_buffer_size (_jack), 0); + (*i)->get_buffer().silence (jack_get_buffer_size (_jack), 0); } } diff --git a/libs/ardour/buffer.cc b/libs/ardour/buffer.cc index 7b99f2a900..d4a370685c 100644 --- a/libs/ardour/buffer.cc +++ b/libs/ardour/buffer.cc @@ -39,6 +39,7 @@ Buffer::create(DataType type, size_t capacity) AudioBuffer::AudioBuffer(size_t capacity) : Buffer(DataType::AUDIO, capacity) + , _owns_data(false) , _data(NULL) { _size = capacity; // For audio buffers, size = capacity (always) @@ -49,10 +50,8 @@ AudioBuffer::AudioBuffer(size_t capacity) posix_memalign((void**)&_data, 16, sizeof(Sample) * capacity); #endif assert(_data); - clear(); _owns_data = true; - } else { - _owns_data = false; + clear(); } } @@ -108,13 +107,15 @@ MidiBuffer::read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t clear(); assert(_size == 0); - // FIXME: This is embarrassingly slow. branch branch branch + // FIXME: slow for (size_t i=0; i < src.size(); ++i) { const MidiEvent& ev = msrc[i]; if (ev.time >= offset && ev.time < offset+nframes) { push_back(ev); } } + + _silent = src.silent(); } @@ -140,6 +141,8 @@ MidiBuffer::push_back(const MidiEvent& ev) //cerr << "MidiBuffer: pushed, size = " << _size << endl; + _silent = false; + return true; } @@ -154,6 +157,7 @@ MidiBuffer::silence(jack_nframes_t dur, jack_nframes_t offset) memset(_events, 0, sizeof(MidiEvent) * _capacity); memset(_data, 0, sizeof(RawMidi) * _capacity * MAX_EVENT_SIZE); _size = 0; + _silent = true; } diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc index 3989df2ad2..bbbf7e3b86 100644 --- a/libs/ardour/buffer_set.cc +++ b/libs/ardour/buffer_set.cc @@ -149,6 +149,22 @@ BufferSet::buffer_capacity(DataType type) const return _buffers[type.to_index()][0]->capacity(); } +// FIXME: make 'in' const +void +BufferSet::read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset) +{ + assert(available() >= in.count()); + + // Copy all buffers 1:1 + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + BufferSet::iterator o = begin(*t); + for (BufferSet::iterator i = in.begin(*t); i != in.end(*t); ++i, ++o) { + o->read_from(*i, nframes, offset); + } + } + + set_count(in.count()); +} } // namespace ARDOUR diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index c74c81f7e3..e72c1d535a 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -1045,7 +1045,7 @@ PortInsert::configure_io (int32_t ignored_magic, int32_t in, int32_t out) } // FIXME - return ensure_io (ChanCount(_default_type, out), ChanCount(_default_type, in), false, this); + return ensure_io (ChanCount(_default_type, in), ChanCount(_default_type, out), false, this); } int32_t diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 00c0f4e168..a30881b4da 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -181,7 +181,7 @@ IO::silence (jack_nframes_t nframes, jack_nframes_t offset) /* io_lock, not taken: function must be called from Session::process() calltree */ for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - i->silence (nframes, offset); + i->get_buffer().silence (nframes, offset); } } @@ -217,6 +217,15 @@ IO::deliver_output (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t // Use the panner to distribute audio to output port buffers if (_panner && !_panner->empty() && !_panner->bypassed()) { _panner->distribute(bufs, output_buffers(), start_frame, end_frame, nframes, offset); + } else { + const DataType type = DataType::AUDIO; + + // Copy any audio 1:1 to outputs + assert(bufs.count().get(DataType::AUDIO) == output_buffers().count().get(DataType::AUDIO)); + BufferSet::iterator o = output_buffers().begin(type); + for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) { + o->read_from(*i, nframes, offset); + } } @@ -228,8 +237,9 @@ IO::deliver_output (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t } const DataType type = DataType::MIDI; - - // Just dump any MIDI 1-to-1, we're not at all clever with MIDI routing yet + + // Copy any MIDI 1:1 to outputs + assert(bufs.count().get(DataType::MIDI) == output_buffers().count().get(DataType::MIDI)); BufferSet::iterator o = output_buffers().begin(type); for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) { o->read_from(*i, nframes, offset); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 2336baac75..900a4f3191 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -542,22 +542,26 @@ MidiTrack::process_output_buffers (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, bool meter) { - // There's no such thing as a MIDI bus for the time being, to avoid diverging from trunk - // too much until the SoC settles down. We'll do all the MIDI route work here for now + /* There's no such thing as a MIDI bus for the time being, to avoid diverging from trunk + * too much until the SoC settles down. We'll do all the MIDI route work here for now, + * but the long-term goal is to have Route::process_output_buffers handle everything */ - // Main output stage is the only stage we've got. - // I think it's a pretty good stage though, wouldn't you say? + // Run all redirects + if (with_redirects) { + Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK); + if (rm.locked()) { + for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { + (*i)->run (bufs, start_frame, end_frame, nframes, offset); + } + } + } + // Main output stage if (muted()) { - IO::silence(nframes, offset); - } else { - deliver_output(bufs, start_frame, end_frame, nframes, offset); - } - } int diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index 3e8329cc9d..1ced0faf89 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -1525,8 +1525,6 @@ Panner::distribute_no_automation (BufferSet& inbufs, BufferSet& outbufs, jack_nf dst.accumulate_from(*i, nframes, offset); } - //audio_output(0)->mark_silence (false); // FIXME - } else { /* mix all buffers into the output, scaling them all by the gain */ @@ -1540,7 +1538,6 @@ Panner::distribute_no_automation (BufferSet& inbufs, BufferSet& outbufs, jack_nf dst.accumulate_with_gain_from(*i, nframes, offset, gain_coeff); } - //audio_output(0)->mark_silence (false); // FIXME } return; @@ -1604,8 +1601,6 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t start_ dst.accumulate_from(*i, nframes, offset); } - //audio_output(0)->mark_silence (false); // FIXME - return; } diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 5f8b454f0f..9e77128e4c 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -27,7 +27,6 @@ Port::Port (jack_port_t *p) : _port (p) , _metering(0) , _last_monitor(false) - , _silent(false) { if (_port == 0) { throw failed_constructor(); @@ -44,7 +43,6 @@ void Port::reset () { _last_monitor = false; - _silent = false; } int diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index e0b890340a..672e0692cb 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -240,7 +240,6 @@ Route::process_output_buffers (BufferSet& bufs, bool post_fader_work = false; bool mute_declick_applied = false; gain_t dmg, dsg, dg; - vector::iterator bufiter; IO *co; bool mute_audible; bool solo_audible; @@ -338,10 +337,14 @@ Route::process_output_buffers (BufferSet& bufs, } } - /* ---------------------------------------------------------------------------------------------------- + /* --------------------------------------------------------------------------------------------------- PRE-FADER REDIRECTS -------------------------------------------------------------------------------------------------- */ + /* FIXME: Somewhere in these loops is where bufs.count() should go from n_inputs() to redirect_max_outs() + * (if they differ). Something explicit needs to be done here to make sure the list of redirects will + * give us what we need (possibly by inserting transparent 'translators' into the list to make it work) */ + if (with_redirects) { Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK); if (rm.locked()) { @@ -371,7 +374,10 @@ Route::process_output_buffers (BufferSet& bufs, } } + // FIXME: for now, just hope the redirects list did what it was supposed to + bufs.set_count(n_process_buffers()); + if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) { Amp::run (bufs, nframes, mute_gain, dmg, _phase_invert); mute_gain = dmg; @@ -652,8 +658,7 @@ Route::process_output_buffers (BufferSet& bufs, ChanCount Route::n_process_buffers () { - //return max (n_inputs(), redirect_max_outs); - return n_inputs(); // FIXME? + return max (n_inputs(), redirect_max_outs); } void @@ -761,8 +766,6 @@ Route::add_redirect (boost::shared_ptr redirect, void *src, uint32_t* redirect->set_default_type(_default_type); - ChanCount potential_max_streams; - if ((pi = boost::dynamic_pointer_cast(redirect)) != 0) { pi->set_count (1); @@ -770,8 +773,6 @@ Route::add_redirect (boost::shared_ptr redirect, void *src, uint32_t* /* generator plugin */ _have_internal_generator = true; } - - potential_max_streams = max(pi->input_streams(), pi->output_streams()); } else if ((porti = boost::dynamic_pointer_cast(redirect)) != 0) { @@ -784,13 +785,14 @@ Route::add_redirect (boost::shared_ptr redirect, void *src, uint32_t* the "outputs" of the route should match the inputs of this route. XXX shouldn't they match the number of active signal streams at the point of insertion? - */ + // FIXME: (yes, they should) porti->ensure_io (n_outputs (), n_inputs(), false, this); } - + // Ensure peak vector sizes before the plugin is activated + ChanCount potential_max_streams = max(redirect->input_streams(), redirect->output_streams()); _meter->setup(potential_max_streams); _redirects.push_back (redirect); diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 9161b0492d..6654f3c75b 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -38,7 +38,7 @@ Send::Send (Session& s, Placement p) { _metering = false; save_state (_("initial state")); - RedirectCreated (this); /* EMIT SIGNAL */ + RedirectCreated (this); /* EMIT SIGNAL */ } Send::Send (Session& s, const XMLNode& node) @@ -51,7 +51,7 @@ Send::Send (Session& s, const XMLNode& node) } save_state (_("initial state")); - RedirectCreated (this); /* EMIT SIGNAL */ + RedirectCreated (this); /* EMIT SIGNAL */ } Send::Send (const Send& other) @@ -114,7 +114,6 @@ Send::run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame sendbufs.read_from(bufs, nframes); assert(sendbufs.count() == bufs.count()); - assert(sendbufs.count() == _outputs.count()); IO::deliver_output (sendbufs, start_frame, end_frame, nframes, offset); -- cgit v1.2.3