* radically cleaned up / refactored midi_clock_slave.cc
[ardour.git] / libs / ardour / io.cc
index 40bf86b5d99c39f1b953a604dac777d4a313b186..66023f1f4d67979995e0a5efd2675c58d89a286e 100644 (file)
@@ -138,10 +138,9 @@ IO::IO (Session& s, const string& name,
        deferred_state = 0;
 
        boost::shared_ptr<AutomationList> gl(
-                       new AutomationList(Parameter(GainAutomation)));
+                       new AutomationList(Evoral::Parameter(GainAutomation)));
 
-       _gain_control = boost::shared_ptr<GainControl>(
-                       new GainControl(X_("gaincontrol"), *this, gl));
+       _gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
 
        add_control(_gain_control);
 
@@ -180,10 +179,10 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
        apply_gain_automation = false;
        
        boost::shared_ptr<AutomationList> gl(
-                       new AutomationList(Parameter(GainAutomation)));
+                       new AutomationList(Evoral::Parameter(GainAutomation)));
 
        _gain_control = boost::shared_ptr<GainControl>(
-                       new GainControl(X_("gaincontrol"), *this, gl));
+                       new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl));
 
        add_control(_gain_control);
 
@@ -232,7 +231,7 @@ IO::silence (nframes_t nframes, 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->get_buffer().silence (nframes, offset);
+               i->get_buffer(nframes,offset).silence (nframes, offset);
        }
 }
 
@@ -265,10 +264,10 @@ IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
                if (dg != _gain || dg != 1.0)
                        Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert);
        }
-       
+
        // 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);
+       if( _panner && _panner->npanners() && !_panner->bypassed()) {
+               _panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
        } else {
                const DataType type = DataType::AUDIO;
                
@@ -324,8 +323,7 @@ IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
                
                BufferSet::iterator o = outs.begin(*t);
                for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
-                       (*i)->prepare_inputs (nframes, offset);
-                       o->read_from(i->get_buffer(), nframes, offset);
+                       o->read_from(i->get_buffer(nframes,offset), nframes, offset);
                }
 
        }
@@ -1402,6 +1400,7 @@ IO::set_state (const XMLNode& node)
 
        for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
 
+               // Old school Panner.
                if ((*iter)->name() == "Panner") {
                        if (_panner == 0) {
                                _panner = new Panner (_name, _session);
@@ -1409,9 +1408,18 @@ IO::set_state (const XMLNode& node)
                        _panner->set_state (**iter);
                }
 
+               if ((*iter)->name() == "Processor") {
+                       if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
+                               if (_panner == 0) {
+                                       _panner = new Panner (_name, _session);
+                               }
+                               _panner->set_state (**iter);
+                       }
+               }
+
                if ((*iter)->name() == X_("Automation")) {
 
-                       set_automation_state (*(*iter), Parameter(GainAutomation));
+                       set_automation_state (*(*iter), Evoral::Parameter(GainAutomation));
                }
 
                if ((*iter)->name() == X_("controllable")) {
@@ -1432,6 +1440,8 @@ IO::set_state (const XMLNode& node)
                port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
        }
 
+       if( !_panner )
+           _panner = new Panner( _name, _session );
        if (panners_legal) {
                reset_panner ();
        } else {
@@ -2223,10 +2233,9 @@ IO::GainControl::set_value (float val)
        if (val > 1.99526231f)
                val = 1.99526231f;
 
-       _user_value = val;
-       _io.set_gain (val, this);
+       _io->set_gain (val, this);
        
-       Changed(); /* EMIT SIGNAL */
+       AutomationControl::set_value(val);
 }
 
 float
@@ -2270,11 +2279,11 @@ void
 IO::clear_automation ()
 {
        data().clear (); // clears gain automation
-       _panner->clear_automation ();
+       _panner->data().clear();
 }
 
 void
-IO::set_parameter_automation_state (Parameter param, AutoState state)
+IO::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
 {
        // XXX: would be nice to get rid of this special hack
 
@@ -2322,8 +2331,9 @@ void
 IO::set_gain (gain_t val, void *src)
 {
        // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05))
-       if (val > 1.99526231f)
+       if (val > 1.99526231f) {
                val = 1.99526231f;
+       }
 
        if (src != _gain_control.get()) {
                _gain_control->set_value(val);
@@ -2338,13 +2348,15 @@ IO::set_gain (gain_t val, void *src)
        }
 
        if (_session.transport_stopped()) {
-               _gain = val;
+               // _gain = val;
        }
        
+       /*
        if (_session.transport_stopped() && src != 0 && src != this && _gain_control->automation_write()) {
                _gain_control->list()->add (_session.transport_frame(), val);
                
        }
+       */
 
        _session.set_dirty();
 }
@@ -2352,16 +2364,16 @@ IO::set_gain (gain_t val, void *src)
 void
 IO::start_pan_touch (uint32_t which)
 {
-       if (which < _panner->size()) {
-               (*_panner)[which]->pan_control()->start_touch();
+       if (which < _panner->npanners()) {
+               (*_panner).pan_control(which)->start_touch();
        }
 }
 
 void
 IO::end_pan_touch (uint32_t which)
 {
-       if (which < _panner->size()) {
-               (*_panner)[which]->pan_control()->stop_touch();
+       if (which < _panner->npanners()) {
+               (*_panner).pan_control(which)->stop_touch();
        }
 
 }
@@ -2370,12 +2382,17 @@ void
 IO::automation_snapshot (nframes_t now, bool force)
 {
        AutomatableControls::automation_snapshot (now, force);
+       // XXX: This seems to be wrong. 
+       // drobilla: shouldnt automation_snapshot for panner be called
+       //           "automagically" because its an Automatable now ?
+       //
+       //           we could dump this whole method then. <3
 
        if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
-               _panner->snapshot (now);
+               _panner->automation_snapshot (now, force);
        }
        
-       _panner->snapshot (now);
+       _panner->automation_snapshot (now, force);
        _last_automation_snapshot = now;
 }
 
@@ -2525,7 +2542,6 @@ IO::set_active (bool yn)
         active_changed(); /* EMIT SIGNAL */
 }
 
-
 AudioPort*
 IO::audio_input(uint32_t n) const
 {
@@ -2749,8 +2765,20 @@ void
 IO::prepare_inputs (nframes_t nframes, nframes_t offset)
 {
        /* io_lock, not taken: function must be called from Session::process() calltree */
+}
 
-       for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
-               (*i).cycle_start (nframes, offset);
+void
+IO::flush_outputs (nframes_t nframes, 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) {
+
+               /* Only run cycle_start() on output ports, because 
+                  inputs must be done in the correct processing order,
+                  which requires interleaving with route processing.
+               */
+
+               (*i).flush_buffers (nframes, offset);
        }
+               
 }