From 0b572cdd84151335594965a3f0ed16f1665dfa56 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 13 Aug 2006 03:40:04 +0000 Subject: More signal path cleanup, IO now has one deliver_output function that should do the reasonable thing in all cases. Including deliver MIDI. You can now create a MIDI Track, run some MIDI through it, and toggle the mute button on and off, hearing either silence or a large amount of stuck notes depending on your luck. Woooo. git-svn-id: svn://localhost/ardour2/branches/midi@818 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/SConscript | 4 +- libs/ardour/amp.cc | 98 +++++++++++++++++++++++ libs/ardour/ardour/amp.h | 42 ++++++++++ libs/ardour/ardour/buffer.h | 8 ++ libs/ardour/ardour/declicker.h | 40 ---------- libs/ardour/ardour/insert.h | 6 +- libs/ardour/ardour/io.h | 10 ++- libs/ardour/ardour/midi_port.h | 1 - libs/ardour/ardour/panner.h | 9 +-- libs/ardour/ardour/redirect.h | 2 +- libs/ardour/ardour/route.h | 4 - libs/ardour/ardour/send.h | 2 +- libs/ardour/audio_track.cc | 4 +- libs/ardour/buffer.cc | 4 +- libs/ardour/declicker.cc | 85 -------------------- libs/ardour/insert.cc | 4 +- libs/ardour/io.cc | 176 +++++++++++------------------------------ libs/ardour/midi_port.cc | 4 +- libs/ardour/midi_track.cc | 20 ++++- libs/ardour/panner.cc | 21 ++++- libs/ardour/route.cc | 59 +++++--------- libs/ardour/send.cc | 4 +- libs/ardour/session_click.cc | 7 +- libs/ardour/session_process.cc | 2 +- 24 files changed, 278 insertions(+), 338 deletions(-) create mode 100644 libs/ardour/amp.cc create mode 100644 libs/ardour/ardour/amp.h delete mode 100644 libs/ardour/ardour/declicker.h delete mode 100644 libs/ardour/declicker.cc (limited to 'libs/ardour') diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 5ad797550e..1128ecfde9 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -41,8 +41,9 @@ midi_port.cc port_set.cc buffer.cc buffer_set.cc -declicker.cc meter.cc +amp.cc +panner.cc audiofilesource.cc audiofilter.cc audioregion.cc @@ -75,7 +76,6 @@ ladspa_plugin.cc location.cc mtc_slave.cc named_selection.cc -panner.cc pcm_utils.cc playlist.cc playlist_factory.cc diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc new file mode 100644 index 0000000000..cfa20afe3b --- /dev/null +++ b/libs/ardour/amp.cc @@ -0,0 +1,98 @@ +/* + 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 +#include +#include + +namespace ARDOUR { + + +/** Apply a declicked gain to the audio buffers of @a bufs */ +void +Amp::run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity) +{ + if (bufs.count().get(DataType::AUDIO) == 0) + return; + + assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes); + + // if we don't need to declick, defer to apply_simple_gain + if (initial == target) { + apply_simple_gain(bufs, nframes, invert_polarity ? target : -target); + } + + const jack_nframes_t declick = std::min ((jack_nframes_t)128, nframes); + gain_t delta; + double fractional_shift = -1.0/declick; + double fractional_pos; + gain_t polscale = invert_polarity ? -1.0f : 1.0f; + + if (nframes == 0) + return; + + if (target < initial) { + /* fade out: remove more and more of delta from initial */ + delta = -(initial - target); + } else { + /* fade in: add more and more of delta from initial */ + delta = target - initial; + } + + for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { + Sample* const buffer = i->data(nframes); + + fractional_pos = 1.0; + + for (jack_nframes_t nx = 0; nx < declick; ++nx) { + buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos)))); + fractional_pos += fractional_shift; + } + + /* now ensure the rest of the buffer has the target value applied, if necessary. */ + + if (declick != nframes) { + + if (invert_polarity) { + target = -target; + } + + if (target == 0.0) { + memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick)); + } else if (target != 1.0) { + for (jack_nframes_t nx = declick; nx < nframes; ++nx) { + buffer[nx] *= target; + } + } + } + } +} + +void +Amp::apply_simple_gain (BufferSet& bufs, jack_nframes_t nframes, gain_t target) +{ + for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { + i->apply_gain(target, nframes); + } +} + + +} // namespace ARDOUR diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h new file mode 100644 index 0000000000..7cdb302a3b --- /dev/null +++ b/libs/ardour/ardour/amp.h @@ -0,0 +1,42 @@ +/* + 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. +*/ + +#ifndef __ardour_amp_h__ +#define __ardour_amp_h__ + +#include + +namespace ARDOUR { + +class BufferSet; + + +/** Applies a declick operation to all audio inputs, passing the same number of + * audio outputs, and passing through any other types unchanged. + */ +class Amp { +public: + static void run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity); + + static void apply_simple_gain(BufferSet& bufs, jack_nframes_t nframes, gain_t target); +}; + + +} // namespace ARDOUR + +#endif // __ardour_amp_h__ diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h index accdd9c181..df7f57455b 100644 --- a/libs/ardour/ardour/buffer.h +++ b/libs/ardour/ardour/buffer.h @@ -136,6 +136,14 @@ public: } } + void apply_gain(gain_t gain, jack_nframes_t len, jack_nframes_t offset=0) { + Sample* const buf = _data + offset; + + for (jack_nframes_t n = 0; n < len; ++n) { + buf[n] *= gain; + } + } + /** Set the data contained by this buffer manually (for setting directly to jack buffer). * * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks). diff --git a/libs/ardour/ardour/declicker.h b/libs/ardour/ardour/declicker.h deleted file mode 100644 index 7e4c034f5d..0000000000 --- a/libs/ardour/ardour/declicker.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - 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. -*/ - -#ifndef __ardour_declicker_h__ -#define __ardour_declicker_h__ - -#include - -namespace ARDOUR { - -class BufferSet; - - -/** Applies a declick operation to all audio inputs, passing the same number of - * audio outputs, and passing through any other types unchanged. - */ -class Declicker { -public: - static void run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity); -}; - - -} // namespace ARDOUR - -#endif // __ardour_declicker_h__ diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index b958f20b95..a8a651df24 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -53,7 +53,7 @@ class Insert : public Redirect virtual ~Insert() { } - virtual void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; + virtual void run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) = 0; virtual void activate () {} virtual void deactivate () {} @@ -75,7 +75,7 @@ class PortInsert : public Insert int set_state(const XMLNode&); void init (); - void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); jack_nframes_t latency(); @@ -113,7 +113,7 @@ class PluginInsert : public Insert StateManager::State* state_factory (std::string why) const; Change restore_state (StateManager::State&); - void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); void silence (jack_nframes_t nframes, jack_nframes_t offset); void activate (); void deactivate (); diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 0b8c84a459..7b5e72742d 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -101,11 +101,9 @@ class IO : public Stateful, public ARDOUR::StateManager virtual void silence (jack_nframes_t, jack_nframes_t offset); - void pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); - void pan_automated (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); void collect_input (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output_no_pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void deliver_output (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t nframes, jack_nframes_t offset); void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); @@ -115,6 +113,9 @@ class IO : public Stateful, public ARDOUR::StateManager void inc_gain (gain_t delta, void *src); gain_t gain () const { return _desired_gain; } virtual gain_t effective_gain () const; + + void set_phase_invert (bool yn, void *src); + bool phase_invert() const { return _phase_invert; } Panner& panner() { return *_panner; } PeakMeter& peak_meter() { return *_meter; } @@ -295,6 +296,7 @@ public: Connection* _output_connection; PBD::ID _id; bool no_panner_reset; + bool _phase_invert; XMLNode* deferred_state; DataType _default_type; diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h index a2bc259a6e..3c48f0ce9e 100644 --- a/libs/ardour/ardour/midi_port.h +++ b/libs/ardour/ardour/midi_port.h @@ -40,7 +40,6 @@ class MidiPort : public Port { DataType type() const { return DataType(DataType::MIDI); } MidiBuffer& get_buffer() { - assert(_nframes_this_cycle > 0); return *_buffer; } diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 5ea9f95f7a..a88180701e 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -241,13 +241,8 @@ class Panner : public std::vector, public Stateful, public sigc:: Panner (string name, Session&); virtual ~Panner (); - // FIXME: unify these two - /// The fundamental Panner function - void distribute (BufferSet& src, BufferSet& dest, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); - - /// The other fundamental Panner function - void distribute_automated (BufferSet& src, BufferSet& dest, jack_nframes_t start_frame, jack_nframes_t end_frames, jack_nframes_t nframes, jack_nframes_t offset); + void distribute(BufferSet& src, BufferSet& dest, jack_nframes_t start_frame, jack_nframes_t end_frames, jack_nframes_t nframes, jack_nframes_t offset); void set_name (string); @@ -311,6 +306,8 @@ class Panner : public std::vector, public Stateful, public sigc:: void set_position (float x, float y, float z, StreamPanner& orig); private: + void distribute_no_automation(BufferSet& src, BufferSet& dest, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); + string automation_path; Session& _session; diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h index 62da98aed1..b9e91e1cfd 100644 --- a/libs/ardour/ardour/redirect.h +++ b/libs/ardour/ardour/redirect.h @@ -81,7 +81,7 @@ class Redirect : public IO Placement placement() const { return _placement; } void set_placement (Placement, void *src); - virtual void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; + virtual void run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) = 0; virtual void activate () = 0; virtual void deactivate () = 0; virtual jack_nframes_t latency() { return 0; } diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index cf6b2b7c60..db5cddca39 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -124,9 +124,6 @@ class Route : public IO void set_mute_config (mute_type, bool, void *src); bool get_mute_config (mute_type); - - void set_phase_invert (bool yn, void *src); - bool phase_invert() const { return _phase_invert; } void set_edit_group (RouteGroup *, void *); void drop_edit_group (void *); @@ -269,7 +266,6 @@ class Route : public IO bool _soloed : 1; bool _solo_muted : 1; bool _solo_safe : 1; - bool _phase_invert : 1; bool _recordable : 1; bool _active : 1; bool _mute_affects_pre_fader : 1; diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 426ff5deed..8a7beb8598 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -40,7 +40,7 @@ class Send : public Redirect { Send (const Send&); ~Send (); - void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); void activate() {} void deactivate () {} diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index b2fc1081cb..52cc7726c9 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -675,7 +675,7 @@ AudioTrack::export_stuff (BufferSet& buffers, jack_nframes_t start, jack_nframes if ((insert = boost::dynamic_pointer_cast(*i)) != 0) { switch (insert->placement()) { case PreFader: - insert->run (buffers, nframes, 0); + insert->run (buffers, start, start+nframes, nframes, 0); break; case PostFader: post_fader_work = true; @@ -715,7 +715,7 @@ AudioTrack::export_stuff (BufferSet& buffers, jack_nframes_t start, jack_nframes case PreFader: break; case PostFader: - insert->run (buffers, nframes, 0); + insert->run (buffers, start, start+nframes, nframes, 0); break; } } diff --git a/libs/ardour/buffer.cc b/libs/ardour/buffer.cc index a2090d7258..85b9317f78 100644 --- a/libs/ardour/buffer.cc +++ b/libs/ardour/buffer.cc @@ -89,8 +89,8 @@ void MidiBuffer::read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t offset) { // FIXME: offsets? param semantics? - throw; - assert(src.type() == _type == DataType::MIDI); + assert(src.type() == _type); + assert(src.type() == DataType::MIDI); assert(offset == 0); MidiBuffer& msrc = (MidiBuffer&)src; _size = 0; diff --git a/libs/ardour/declicker.cc b/libs/ardour/declicker.cc deleted file mode 100644 index dd40fe83b2..0000000000 --- a/libs/ardour/declicker.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - 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 -#include -#include - -namespace ARDOUR { - - -/** Apply a declick operation to the audio buffers of @a bufs */ -void -Declicker::run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity) -{ - if (bufs.count().get(DataType::AUDIO) == 0) - return; - - assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes); - - const jack_nframes_t declick = std::min ((jack_nframes_t)4096, nframes); - gain_t delta; - double fractional_shift = -1.0/declick; - double fractional_pos; - gain_t polscale = invert_polarity ? -1.0f : 1.0f; - - if (nframes == 0) - return; - - if (target < initial) { - /* fade out: remove more and more of delta from initial */ - delta = -(initial - target); - } else { - /* fade in: add more and more of delta from initial */ - delta = target - initial; - } - - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const buffer = i->data(nframes); - - fractional_pos = 1.0; - - for (jack_nframes_t nx = 0; nx < declick; ++nx) { - buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos)))); - fractional_pos += fractional_shift; - } - - /* now ensure the rest of the buffer has the target value applied, if necessary. */ - - if (declick != nframes) { - - if (invert_polarity) { - target = -target; - } - - if (target == 0.0) { - memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick)); - } else if (target != 1.0) { - for (jack_nframes_t nx = declick; nx < nframes; ++nx) { - buffer[nx] *= target; - } - } - } - } -} - - -} // namespace ARDOUR diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index 45aa099846..f4263099eb 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -373,7 +373,7 @@ PluginInsert::silence (jack_nframes_t nframes, jack_nframes_t offset) } void -PluginInsert::run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) +PluginInsert::run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) { if (active()) { @@ -911,7 +911,7 @@ PortInsert::~PortInsert () } void -PortInsert::run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) +PortInsert::run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) { if (n_outputs().get(_default_type) == 0) { return; diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 7cc507f237..fce8c3f1d8 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include "i18n.h" @@ -119,6 +120,7 @@ IO::IO (Session& s, string name, _output_connection = 0; pending_state_node = 0; no_panner_reset = false; + _phase_invert = false; deferred_state = 0; apply_gain_automation = false; @@ -169,157 +171,58 @@ IO::silence (jack_nframes_t nframes, jack_nframes_t offset) } } +/** Deliver bufs to the IO's Jack outputs. + * + * This function should automatically do whatever it necessary to correctly deliver bufs + * to the outputs, eg applying gain or pan or whatever else needs to be done. + */ void -IO::pan_automated (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) -{ - _panner->distribute_automated(bufs, output_buffers(), start_frame, end_frame, nframes, offset); -} - -void -IO::pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff) -{ - /* the panner can be empty if there are no inputs to the route, but still outputs */ - if (_panner->bypassed() || _panner->empty()) { - // FIXME: gain - deliver_output_no_pan (bufs, nframes, offset); - return; - } else { - _panner->distribute(bufs, output_buffers(), nframes, offset, gain_coeff); - } -} - -void -IO::deliver_output (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) +IO::deliver_output (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) { - throw; -#if 0 - /* io_lock, not taken: function must be called from Session::process() calltree */ - - if (n_outputs().get(DataType::AUDIO) == 0) { - return; - } + // FIXME: type specific code doesn't actually need to be here, it will go away in time - if (_panner->bypassed() || _panner->empty()) { - deliver_output_no_pan (bufs, nbufs, nframes, offset); - return; - } + /* ********** AUDIO ********** */ - gain_t dg; - gain_t pangain = _gain; - - { - Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); + // Apply gain if gain automation isn't playing + if ( ! apply_gain_automation) { - if (dm.locked()) { - dg = _desired_gain; - } else { - dg = _gain; - } - } + gain_t dg = _gain; // desired gain - if (dg != _gain) { - Declicker::run (bufs, nbufs, nframes, _gain, dg, false); - _gain = dg; - pangain = 1.0f; - } + { + Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); - /* simple, non-automation panning to outputs */ + if (dm.locked()) { + dg = _desired_gain; + } + } - if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) { - pan (bufs, nbufs, nframes, offset, pangain * speed_quietning); - } else { - pan (bufs, nbufs, nframes, offset, pangain); + Amp::run(bufs, nframes, _gain, dg, _phase_invert); } -#endif -} - -void -IO::deliver_output_no_pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) -{ - throw; -#if 0 - /* io_lock, not taken: function must be called from Session::process() calltree */ - - if (n_outputs().get(DataType::AUDIO) == 0) { - return; + + // 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); } - gain_t dg; - gain_t old_gain = _gain; - - if (apply_gain_automation) { - - /* gain has already been applied by automation code. do nothing here except - speed quietning. - */ - _gain = 1.0f; - dg = _gain; - - } else { + /* ********** MIDI ********** */ - Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); - - if (dm.locked()) { - dg = _desired_gain; - } else { - dg = _gain; - } - } - - Sample* src; - Sample* dst; - uint32_t i; - vector outs; - gain_t actual_gain; - - if (dg != _gain) { - /* unlikely condition */ - i = 0; - for (PortSet::audio_iterator o = _outputs.audio_begin(); o != _outputs.audio_end(); ++o, ++i) { - outs.push_back ((*o)->get_audio_buffer().data (nframes, offset)); - } + // No MIDI, we're done here + if (bufs.count().get(DataType::MIDI) == 0) { + return; } - /* reduce nbufs to the index of the last input buffer */ - - nbufs--; - - if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) { - actual_gain = _gain * speed_quietning; - } else { - actual_gain = _gain; - } + const DataType type = DataType::MIDI; // type type type type... - i = 0; - for (PortSet::audio_iterator o = _outputs.audio_begin(); o != _outputs.audio_end(); ++o, ++i) { - - dst = (*o)->get_audio_buffer().data(nframes, offset); - src = bufs[min(nbufs,i)]; - - if (dg != _gain || actual_gain == 1.0f) { - memcpy (dst, src, sizeof (Sample) * nframes); - } else if (actual_gain == 0.0f) { - memset (dst, 0, sizeof (Sample) * nframes); - } else { - for (jack_nframes_t x = 0; x < nframes; ++x) { - dst[x] = src[x] * actual_gain; - } - } + // Just dump any MIDI 1-to-1, we're not at all clever with MIDI routing yet + BufferSet::iterator o = output_buffers().begin(type); + for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i) { - (*o)->mark_silence (false); - } - - if (dg != _gain) { - Declicker::run (outs, outs.size(), nframes, _gain, dg, false); - _gain = dg; - } - - if (apply_gain_automation) { - _gain = old_gain; + for (PortSet::iterator i = _inputs.begin(type); i != _inputs.end(type); ++i, ++o) { + o->read_from(i->get_buffer(), nframes, offset); + } } -#endif } void @@ -2536,3 +2439,12 @@ IO::midi_output(uint32_t n) const return dynamic_cast(output(n)); } +void +IO::set_phase_invert (bool yn, void *src) +{ + if (_phase_invert != yn) { + _phase_invert = yn; + } + // phase_invert_changed (src); /* EMIT SIGNAL */ +} + diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index e785710b01..83322dedb6 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -74,8 +74,8 @@ MidiPort::cycle_start (jack_nframes_t nframes) _buffer->set_size(event_count); - if (_buffer->size() > 0) - cerr << "MIDIPort got " << event_count << " events." << endl; + //if (_buffer->size() > 0) + // cerr << "MIDIPort got " << event_count << " events." << endl; } void diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 8cc3a453d0..cdbd441cd6 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -482,6 +482,8 @@ int MidiTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) { + passthru (start_frame, end_frame, nframes, offset, declick, false); + return 0; } @@ -512,7 +514,23 @@ MidiTrack::process_output_buffers (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, bool meter) { - // Do nothing (just bypass the Route version to avoid flaming death) + // 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 + + // Main output stage is the only stage we've got. + // I think it's a pretty good stage though, wouldn't you say? + + + 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 0d15ba84e7..3e8329cc9d 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -1489,7 +1489,7 @@ Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig) } void -Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff) +Panner::distribute_no_automation (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff) { if (outbufs.count().get(DataType::AUDIO) == 0) { // Don't want to lose audio... @@ -1561,10 +1561,10 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t nframe } void -Panner::distribute_automated (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) +Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) { if (outbufs.count().get(DataType::AUDIO) == 0) { - // Don't want to lose audio... + // Failing to deliver audio we were asked to deliver is a bug assert(inbufs.count().get(DataType::AUDIO) == 0); return; } @@ -1573,7 +1573,22 @@ Panner::distribute_automated (BufferSet& inbufs, BufferSet& outbufs, jack_nframe assert(!bypassed()); assert(!empty()); + // If we shouldn't play automation defer to distribute_no_automation + if ( !( automation_state() & Play || + ((automation_state() & Touch) && !touching()) ) ) { + + // Speed quietning + gain_t gain_coeff = 1.0; + if (fabsf(_session.transport_speed()) > 1.5f) { + gain_coeff = speed_quietning; + } + distribute_no_automation(inbufs, outbufs, nframes, offset, gain_coeff); + return; + } + + // Otherwise.. let the automation flow, baby + if (outbufs.count().get(DataType::AUDIO) == 1) { AudioBuffer& dst = outbufs.get_audio(0); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index d3ddaa4caf..757c40452f 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include "i18n.h" @@ -230,9 +230,9 @@ Route::set_gain (gain_t val, void *src) */ void Route::process_output_buffers (BufferSet& bufs, - jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, - bool meter) + jack_nframes_t start_frame, jack_nframes_t end_frame, + jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, + bool meter) { // This is definitely very audio-only for now assert(_default_type == DataType::AUDIO); @@ -279,17 +279,17 @@ Route::process_output_buffers (BufferSet& bufs, -------------------------------------------------------------------------------------------------- */ if (declick > 0) { - Declicker::run (bufs, nframes, 0.0, 1.0, _phase_invert); + Amp::run (bufs, nframes, 0.0, 1.0, _phase_invert); _pending_declick = 0; } else if (declick < 0) { - Declicker::run (bufs, nframes, 1.0, 0.0, _phase_invert); + Amp::run (bufs, nframes, 1.0, 0.0, _phase_invert); _pending_declick = 0; } else { /* no global declick */ if (solo_gain != dsg) { - Declicker::run (bufs, nframes, solo_gain, dsg, _phase_invert); + Amp::run (bufs, nframes, solo_gain, dsg, _phase_invert); solo_gain = dsg; } } @@ -304,7 +304,7 @@ Route::process_output_buffers (BufferSet& bufs, } if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) { - Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert); + Amp::run (bufs, nframes, mute_gain, dmg, _phase_invert); mute_gain = dmg; mute_declick_applied = true; } @@ -334,7 +334,7 @@ Route::process_output_buffers (BufferSet& bufs, } else { - co->deliver_output (bufs, nframes, offset); + co->deliver_output (bufs, start_frame, end_frame, nframes, offset); } } @@ -350,7 +350,7 @@ Route::process_output_buffers (BufferSet& bufs, for (i = _redirects.begin(); i != _redirects.end(); ++i) { switch ((*i)->placement()) { case PreFader: - (*i)->run (bufs, nframes, offset); + (*i)->run (bufs, start_frame, end_frame, nframes, offset); break; case PostFader: post_fader_work = true; @@ -374,7 +374,7 @@ Route::process_output_buffers (BufferSet& bufs, if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) { - Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert); + Amp::run (bufs, nframes, mute_gain, dmg, _phase_invert); mute_gain = dmg; mute_declick_applied = true; } @@ -411,7 +411,7 @@ Route::process_output_buffers (BufferSet& bufs, } else { - co->deliver_output (bufs, nframes, offset); + co->deliver_output (bufs, start_frame, end_frame, nframes, offset); } } @@ -466,7 +466,7 @@ Route::process_output_buffers (BufferSet& bufs, if (_gain != dg) { - Declicker::run (bufs, nframes, _gain, dg, _phase_invert); + Amp::run (bufs, nframes, _gain, dg, _phase_invert); _gain = dg; } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) { @@ -519,7 +519,7 @@ Route::process_output_buffers (BufferSet& bufs, case PreFader: break; case PostFader: - (*i)->run (bufs, nframes, offset); + (*i)->run (bufs, start_frame, end_frame, nframes, offset); break; } } @@ -538,7 +538,7 @@ Route::process_output_buffers (BufferSet& bufs, } if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) { - Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert); + Amp::run (bufs, nframes, mute_gain, dmg, _phase_invert); mute_gain = dmg; mute_declick_applied = true; } @@ -574,7 +574,7 @@ Route::process_output_buffers (BufferSet& bufs, } else { - co->deliver_output_no_pan (bufs, nframes, offset); + co->deliver_output (bufs, start_frame, end_frame, nframes, offset); } } @@ -583,7 +583,7 @@ Route::process_output_buffers (BufferSet& bufs, ----------------------------------------------------------------------*/ if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) { - Declicker::run (bufs, nframes, mute_gain, dmg, _phase_invert); + Amp::run (bufs, nframes, mute_gain, dmg, _phase_invert); mute_gain = dmg; mute_declick_applied = true; } @@ -631,18 +631,8 @@ Route::process_output_buffers (BufferSet& bufs, } else { - if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) { - pan (bufs, nframes, offset, speed_quietning); - } else { - // cerr << _name << " panner state = " << _panner->automation_state() << endl; - if (!_panner->empty() && - (_panner->automation_state() & Play || - ((_panner->automation_state() & Touch) && !_panner->touching()))) { - pan_automated (bufs, start_frame, end_frame, nframes, offset); - } else { - pan (bufs, nframes, offset, 1.0); - } - } + deliver_output(bufs, start_frame, end_frame, nframes, offset); + } } @@ -652,8 +642,6 @@ Route::process_output_buffers (BufferSet& bufs, -------------------------------------------------------------------------------------------------- */ if (meter && (_meter_point == MeterPostFader)) { -// cerr << "meter post" << endl; - if ((_gain == 0 && !apply_gain_automation) || dmg == 0) { _meter->reset(); } else { @@ -691,15 +679,6 @@ Route::passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nfra #undef meter_stream } -void -Route::set_phase_invert (bool yn, void *src) -{ - if (_phase_invert != yn) { - _phase_invert = yn; - } - // phase_invert_changed (src); /* EMIT SIGNAL */ -} - void Route::set_solo (bool yn, void *src) { diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index c9c91c07cd..c67e0fcdbe 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -103,7 +103,7 @@ Send::set_state(const XMLNode& node) } void -Send::run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) +Send::run (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset) { if (active()) { @@ -116,7 +116,7 @@ Send::run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) assert(sendbufs.count() == bufs.count()); assert(sendbufs.count() == _outputs.count()); - IO::deliver_output (sendbufs, nframes, offset); + IO::deliver_output (sendbufs, start_frame, end_frame, nframes, offset); if (_metering) { if (_gain == 0) { diff --git a/libs/ardour/session_click.cc b/libs/ardour/session_click.cc index b50720aa38..e04bb61c30 100644 --- a/libs/ardour/session_click.cc +++ b/libs/ardour/session_click.cc @@ -41,7 +41,6 @@ void Session::click (jack_nframes_t start, jack_nframes_t nframes, jack_nframes_t offset) { TempoMap::BBTPointList *points; - jack_nframes_t end; Sample *buf; if (_click_io == 0) { @@ -55,7 +54,7 @@ Session::click (jack_nframes_t start, jack_nframes_t nframes, jack_nframes_t off return; } - end = start + nframes; + const jack_nframes_t end = start + (jack_nframes_t)floor(nframes * _transport_speed); BufferSet& bufs = get_scratch_buffers(ChanCount(DataType::AUDIO, 1)); buf = bufs.get_audio(0).data(nframes); @@ -127,8 +126,8 @@ Session::click (jack_nframes_t start, jack_nframes_t nframes, jack_nframes_t off i = next; } - - _click_io->deliver_output (bufs, nframes, offset); + + _click_io->deliver_output (bufs, start, end, nframes, offset); } void diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 09503395e3..6d13caced8 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -131,7 +131,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset) record_active = actively_recording(); // || (get_record_enabled() && get_punch_in()); const jack_nframes_t start_frame = _transport_frame; - const jack_nframes_t end_frame = _transport_frame + lrintf(nframes * _transport_speed); + const jack_nframes_t end_frame = _transport_frame + (jack_nframes_t)floor(nframes * _transport_speed); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { -- cgit v1.2.3