#include "ardour/amp.h"
#include "ardour/audio_buffer.h"
#include "ardour/buffer_set.h"
-#include "ardour/configuration.h"
-#include "ardour/io.h"
#include "ardour/midi_buffer.h"
#include "ardour/session.h"
using namespace ARDOUR;
using namespace PBD;
+using std::min;
+
+/* gain range of -inf to +6dB, default 0dB */
+const float Amp::max_gain_coefficient = 1.99526231f;
Amp::Amp (Session& s)
: Processor(s, "Amp")
, _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 */
- p.set_range (0, 1.99526231f, 1, false);
+ p.set_range (0, max_gain_coefficient, 1, false);
boost::shared_ptr<AutomationList> gl (new AutomationList (p));
_gain_control = boost::shared_ptr<GainControl> (new GainControl (X_("gaincontrol"), s, this, p, gl));
+ _gain_control->set_flags (Controllable::GainLike);
+
add_control(_gain_control);
}
}
bool
-Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out)
{
out = in;
return true;
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();
for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) {
MidiBuffer& mb (*i);
-
+
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
- gain_t scale = delta * (ev.time()/(double) nframes);
+ const gain_t scale = delta * (ev.time()/(double) nframes);
ev.scale_velocity (initial+scale);
}
}
}
void
-Amp::set_gain (gain_t val, void *src)
+Amp::set_gain (gain_t val, void *)
{
- // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
- if (val > 1.99526231f) {
- val = 1.99526231f;
- }
-
- if (src != _gain_control.get()) {
- _gain_control->set_value (val);
- // bit twisty, this will come back and call us again
- // (this keeps control in sync with reality)
- return;
- }
-
- _gain_control->set_double(val, false);
- _session.set_dirty();
+ _gain_control->set_value (val);
}
XMLNode&
void
Amp::GainControl::set_value (double val)
{
- // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
- if (val > 1.99526231) {
- val = 1.99526231;
- }
-
- _amp->set_gain (val, this);
-
- AutomationControl::set_value(val);
+ AutomationControl::set_value (min (val, (double) max_gain_coefficient));
+ _amp->session().set_dirty ();
}
double
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);
+ Glib::Threads::Mutex::Lock am (control_lock(), Glib::Threads::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;
}
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;
+}