Respond to MMC even when synced to JACK. Fixes #3700.
[ardour.git] / libs / ardour / ardour / panner.h
index 3bfe2cf713a116e3b6bc72556091c11ed31f3bcb..b07167862e038a4ca721f5b7b9d7d62566c693eb 100644 (file)
@@ -56,8 +56,8 @@ class StreamPanner : public PBD::Stateful
        void set_position (const PBD::AngularVector&, bool link_call = false);
        void set_diffusion (double);
 
-       void distribute (AudioBuffer &, BufferSet &, gain_t, nframes_t);
-       void distribute_automated (AudioBuffer &, BufferSet &, nframes_t, nframes_t, nframes_t, pan_t **);
+       void distribute (AudioBuffer &, BufferSet &, gain_t, pframes_t);
+       void distribute_automated (AudioBuffer &, BufferSet &, framepos_t, framepos_t, pframes_t, pan_t **);
 
        /* the basic StreamPanner API */
 
@@ -69,9 +69,9 @@ class StreamPanner : public PBD::Stateful
         *  @param gain_coeff Gain coefficient to apply to output samples.
         *  @param nframes Number of frames in the input.
         */
-       virtual void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0;
+       virtual void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes) = 0;
        virtual void do_distribute_automated (AudioBuffer& src, BufferSet& obufs,
-                                             nframes_t start, nframes_t end, nframes_t nframes,
+                                             framepos_t start, framepos_t end, pframes_t nframes,
                                              pan_t** buffers) = 0;
 
        boost::shared_ptr<AutomationControl> pan_control()  { return _control; }
@@ -88,14 +88,14 @@ class StreamPanner : public PBD::Stateful
        virtual int load (std::istream&, std::string path, uint32_t&) = 0;
 
        struct PanControllable : public AutomationControl {
-               PanControllable (Session& s, std::string name, StreamPanner& p, Evoral::Parameter param)
+               PanControllable (Session& s, std::string name, StreamPanner* p, Evoral::Parameter param)
                        : AutomationControl (s, param,
                                              boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
                        , streampanner (p)
                { assert (param.type() == PanAutomation); }
                 
                AutomationList* alist() { return (AutomationList*)_list.get(); }
-               StreamPanner& streampanner;
+               StreamPanner* streampanner;
 
                void set_value (double);
                double get_value (void) const;
@@ -135,18 +135,28 @@ class BaseStereoPanner : public StreamPanner
           and a type name. See EqualPowerStereoPanner as an example.
        */
 
-       void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
+       void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes);
 
        static double azimuth_to_lr_fract (double azi) { 
                /* 180.0 degrees=> left => 0.0 */
                /* 0.0 degrees => right => 1.0 */
-               return 1.0 - (azi/180.0);
+
+                /* humans can only distinguish 1 degree of arc between two positions,
+                   so force azi back to an integral value before computing
+                */
+
+               return 1.0 - (rint(azi)/180.0);
        }
 
        static double lr_fract_to_azimuth (double fract) { 
                /* fract = 0.0 => degrees = 180.0 => left */
                /* fract = 1.0 => degrees = 0.0 => right */
-               return 180.0 - (fract * 180.0);
+
+                /* humans can only distinguish 1 degree of arc between two positions,
+                   so force azi back to an integral value after computing
+                */
+
+               return rint (180.0 - (fract * 180.0));
        }
        
        /* old school automation loading */
@@ -169,7 +179,7 @@ class EqualPowerStereoPanner : public BaseStereoPanner
        ~EqualPowerStereoPanner ();
 
        void do_distribute_automated (AudioBuffer& src, BufferSet& obufs,
-                                     nframes_t start, nframes_t end, nframes_t nframes,
+                                     framepos_t start, framepos_t end, pframes_t nframes,
                                      pan_t** buffers);
 
        void get_current_coefficients (pan_t*) const;
@@ -219,7 +229,7 @@ public:
        bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; };
 
        /// The fundamental Panner function
-       void run (BufferSet& src, BufferSet& dest, framepos_t start_frame, framepos_t end_frames, nframes_t nframes);
+       void run (BufferSet& src, BufferSet& dest, framepos_t start_frame, framepos_t end_frames, pframes_t nframes);
 
        bool bypassed() const { return _bypassed; }
        void set_bypassed (bool yn);
@@ -300,7 +310,7 @@ public:
        /* disallow copy construction */
        Panner (Panner const &);
 
-       void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, gain_t gain_coeff);
+       void distribute_no_automation(BufferSet& src, BufferSet& dest, pframes_t nframes, gain_t gain_coeff);
        std::vector<StreamPanner*> _streampanners; ///< one StreamPanner per input
        std::vector<Output> outputs;
        uint32_t     current_outs;