Make send automation work (#4734).

git-svn-id: svn://localhost/ardour2/branches/3.0@12650 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2012-06-11 10:42:30 +00:00
parent 8f371cd60d
commit c40437430a
13 changed files with 56 additions and 11 deletions

View File

@ -450,6 +450,8 @@ ProcessorEntry::Control::Control (Glib::RefPtr<Gdk::Pixbuf> s, Glib::RefPtr<Gdk:
c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
}
ARDOUR_UI::RapidScreenUpdate.connect (sigc::mem_fun (*this, &Control::control_changed));
control_changed ();
set_tooltip ();
}

View File

@ -156,7 +156,7 @@ private:
PBD::ScopedConnection active_connection;
PBD::ScopedConnection name_connection;
class Control {
class Control : public sigc::trackable {
public:
Control (Glib::RefPtr<Gdk::Pixbuf>, Glib::RefPtr<Gdk::Pixbuf>, boost::shared_ptr<ARDOUR::AutomationControl>, std::string const &);

View File

@ -39,6 +39,7 @@ Amp::Amp (Session& s)
, _apply_gain(true)
, _apply_gain_automation(false)
, _current_gain(1.0)
, _gain_automation_buffer(0)
{
Evoral::Parameter p (GainAutomation);
/* gain range of -inf to +6dB, default 0dB */
@ -84,7 +85,8 @@ Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
if (_apply_gain_automation) {
gain_t* gab = _session.gain_automation_buffer ();
gain_t* gab = _gain_automation_buffer;
assert (gab);
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
Sample* const sp = i->data();
@ -440,14 +442,19 @@ Amp::GainControl::internal_to_user (double v) const
return accurate_coefficient_to_dB (v);
}
/** Write gain automation for this cycle into the buffer previously passed in to
* set_gain_automation_buffer (if we are in automation playback mode and the
* transport is rolling).
*/
void
Amp::setup_gain_automation (framepos_t start_frame, framepos_t end_frame, framecnt_t nframes)
{
Glib::Mutex::Lock am (control_lock(), Glib::TRY_LOCK);
if (am.locked() && _session.transport_rolling() && _gain_control->automation_playback()) {
assert (_gain_automation_buffer);
_apply_gain_automation = _gain_control->list()->curve().rt_safe_get_vector (
start_frame, end_frame, _session.gain_automation_buffer(), nframes);
start_frame, end_frame, _gain_automation_buffer, nframes);
} else {
_apply_gain_automation = false;
}
@ -470,4 +477,14 @@ Amp::value_as_string (boost::shared_ptr<AutomationControl> ac) const
return Automatable::value_as_string (ac);
}
/** Sets up the buffer that setup_gain_automation and ::run will use for
* gain automationc curves. Must be called before setup_gain_automation,
* and must be called with process lock held.
*/
void
Amp::set_gain_automation_buffer (gain_t* g)
{
_gain_automation_buffer = g;
}

View File

@ -48,6 +48,8 @@ public:
bool apply_gain () const { return _apply_gain; }
void apply_gain (bool yn) { _apply_gain = yn; }
void set_gain_automation_buffer (gain_t *);
void setup_gain_automation (framepos_t start_frame, framepos_t end_frame, framecnt_t nframes);
bool apply_gain_automation() const { return _apply_gain_automation; }
@ -107,6 +109,9 @@ private:
float _current_gain;
boost::shared_ptr<GainControl> _gain_control;
/** Buffer that we should use for gain automation */
gain_t* _gain_automation_buffer;
};

View File

@ -29,6 +29,7 @@ public:
static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
static gain_t* gain_automation_buffer ();
static gain_t* send_gain_automation_buffer ();
static pan_t** pan_automation_buffer ();
protected:

View File

@ -743,6 +743,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* buffers for gain and pan */
gain_t* gain_automation_buffer () const;
gain_t* send_gain_automation_buffer () const;
pan_t** pan_automation_buffer () const;
void ensure_buffer_set (BufferSet& buffers, const ChanCount& howmany);

View File

@ -21,6 +21,7 @@ public:
BufferSet* scratch_buffers;
BufferSet* mix_buffers;
gain_t* gain_automation_buffer;
gain_t* send_gain_automation_buffer;
pan_t** pan_automation_buffer;
uint32_t npan_buffers;

View File

@ -176,10 +176,8 @@ InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame
Amp::apply_simple_gain (mixbufs, nframes, tgain);
}
// Can't automate gain for sends or returns yet because we need different buffers
// so that we don't overwrite the main automation data for the route amp
// _amp->setup_gain_automation (start_frame, end_frame, nframes);
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_frame, end_frame, nframes);
_amp->run (mixbufs, start_frame, end_frame, nframes, true);
/* consider metering */

View File

@ -134,6 +134,17 @@ ProcessThread::gain_automation_buffer()
return g;
}
gain_t*
ProcessThread::send_gain_automation_buffer()
{
ThreadBuffers* tb = _private_thread_buffers->get();
assert (tb);
gain_t* g = tb->send_gain_automation_buffer;
assert (g);
return g;
}
pan_t**
ProcessThread::pan_automation_buffer()
{

View File

@ -423,6 +423,7 @@ Route::process_output_buffers (BufferSet& bufs,
/* figure out if we're going to use gain automation */
if (gain_automation_ok) {
_amp->set_gain_automation_buffer (_session.gain_automation_buffer ());
_amp->setup_gain_automation (start_frame, end_frame, nframes);
} else {
_amp->apply_gain_automation (false);

View File

@ -137,9 +137,8 @@ Send::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframe
/* gain control */
// Can't automate gain for sends or returns yet because we need different buffers
// so that we don't overwrite the main automation data for the route amp
// _amp->setup_gain_automation (start_frame, end_frame, nframes);
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_frame, end_frame, nframes);
_amp->run (sendbufs, start_frame, end_frame, nframes, true);
/* deliver to outputs */

View File

@ -4082,6 +4082,12 @@ Session::gain_automation_buffer() const
return ProcessThread::gain_automation_buffer ();
}
gain_t*
Session::send_gain_automation_buffer() const
{
return ProcessThread::send_gain_automation_buffer ();
}
pan_t**
Session::pan_automation_buffer() const
{

View File

@ -32,6 +32,7 @@ ThreadBuffers::ThreadBuffers ()
, scratch_buffers (new BufferSet)
, mix_buffers (new BufferSet)
, gain_automation_buffer (0)
, send_gain_automation_buffer (0)
, pan_automation_buffer (0)
, npan_buffers (0)
{
@ -67,6 +68,8 @@ ThreadBuffers::ensure_buffers (ChanCount howmany)
delete [] gain_automation_buffer;
gain_automation_buffer = new gain_t[_engine->raw_buffer_size (DataType::AUDIO)];
delete [] send_gain_automation_buffer;
send_gain_automation_buffer = new gain_t[_engine->raw_buffer_size (DataType::AUDIO)];
allocate_pan_automation_buffers (_engine->raw_buffer_size (DataType::AUDIO), howmany.n_audio(), false);
}