* radically cleaned up / refactored midi_clock_slave.cc
authorHans Baier <hansfbaier@googlemail.com>
Thu, 1 Jan 2009 11:00:18 +0000 (11:00 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Thu, 1 Jan 2009 11:00:18 +0000 (11:00 +0000)
* debug statements in session_process.cc and midi_clock_slave.cc as
  conditional compilation instead of comments

git-svn-id: svn://localhost/ardour2/branches/3.0@4366 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/slave.h
libs/ardour/midi_clock_slave.cc
libs/ardour/session_process.cc

index db66e428be1cf74e591e36f63e7d2acfe864b8d0..1f21e28f406e60f1469383c94914ef7dda2c391f 100644 (file)
@@ -231,18 +231,14 @@ class MIDIClock_Slave : public Slave, public sigc::trackable {
        double      one_ppqn_in_frames;
 
        /// the time stamp and transport position of the last inbound MIDI clock message
-       SafeTime    current;
-       /// since current.position is integral, we need to keep track of decimal places
-       /// to be precise
-       double      current_position;
+       nframes_t   last_timestamp;
+       double      last_position;
        
        /// The duration of the current MIDI clock frame in frames
        nframes_t   current_midi_clock_frame_duration;
-       /// the timestamp of the last inbound MIDI clock message
-       nframes_t   last_inbound_frame;             
 
        /// how many MIDI clock frames to average over
-       static const int32_t accumulator_size = 4;
+       static const int32_t accumulator_size = 1;
        double  accumulator[accumulator_size];
        int32_t accumulator_index;
        
@@ -257,7 +253,7 @@ class MIDIClock_Slave : public Slave, public sigc::trackable {
        void calculate_one_ppqn_in_frames_at(nframes_t time);
        void update_midi_clock (MIDI::Parser& parser, nframes_t timestamp);
        void read_current (SafeTime *) const;
-       bool stop_if_no_more_clock_events(nframes_t& pos, nframes_t now, SafeTime& last);
+       bool stop_if_no_more_clock_events(nframes_t& pos, nframes_t now);
 
        /// whether transport should be rolling
        bool _started;
index e6639446d58a78d82a7a992e4a7fe9a43c876bf7..e7cd5a37841c86f3639c624dc78ff043a77a018e 100644 (file)
@@ -67,9 +67,9 @@ MIDIClock_Slave::rebind (MIDI::Port& p)
 
        port = &p;
 
-#ifdef DEBUG_MIDI_CLOCK                
-       std::cerr << "MIDIClock_Slave: connecting to port " << port->name() << std::endl;
-#endif
+       #ifdef DEBUG_MIDI_CLOCK         
+               std::cerr << "MIDIClock_Slave: connecting to port " << port->name() << std::endl;
+       #endif
 
        connections.push_back (port->input()->timing.connect   (mem_fun (*this, &MIDIClock_Slave::update_midi_clock)));
        connections.push_back (port->input()->start.connect    (mem_fun (*this, &MIDIClock_Slave::start)));
@@ -94,88 +94,77 @@ MIDIClock_Slave::calculate_one_ppqn_in_frames_at(nframes_t time)
 
 void
 MIDIClock_Slave::update_midi_clock (Parser& parser, nframes_t timestamp)
-{      
-       nframes_t now = timestamp;
-
-       SafeTime last;
-       read_current (&last);
-       
-       if (_starting) {
-               assert(last.timestamp == 0);
-               // let ardour go after first MIDI Clock Event
-               _starting = false;
-       }
-               
-       calculate_one_ppqn_in_frames_at(now);
+{                      
+       calculate_one_ppqn_in_frames_at(last_position);
        
        // for the first MIDI clock event we don't have any past
        // data, so we assume a sane tempo
-       if(last.timestamp == 0) {
+       if(_starting) {
                current_midi_clock_frame_duration = one_ppqn_in_frames;
        } else {
-               current_midi_clock_frame_duration = now - last.timestamp;
+               current_midi_clock_frame_duration = timestamp - last_timestamp;
        }
                
        // moving average over incoming intervals
        accumulator[accumulator_index++] = current_midi_clock_frame_duration;
-       if(accumulator_index == accumulator_size)
+       if(accumulator_index == accumulator_size) {
                accumulator_index = 0;
-       
+       }
        average_midi_clock_frame_duration = 0.0;
-       for(int i = 0; i < accumulator_size; i++)
+       for(int i = 0; i < accumulator_size; i++) {
                average_midi_clock_frame_duration += accumulator[i];
-       average_midi_clock_frame_duration /= double(accumulator_size);
-       
-#ifdef DEBUG_MIDI_CLOCK                
-#ifdef WITH_JACK_MIDI
-       JACK_MidiPort* jack_port = dynamic_cast<JACK_MidiPort*>(port);
-       pthread_t process_thread_id = 0;
-       if(jack_port) {
-               process_thread_id = jack_port->get_process_thread();
        }
+       average_midi_clock_frame_duration /= double(accumulator_size);
        
-       std::cerr 
-                 << " got MIDI Clock message at time " << now  
-                 << " session time: " << session.engine().frame_time() 
-                 << " transport position: " << session.transport_frame()
-                 << " real delta: " << current_midi_clock_frame_duration 
-                 << " reference: " << one_ppqn_in_frames
-                 << " average: " << average_midi_clock_frame_duration
-                 << std::endl;
-#endif // DEBUG_MIDI_CLOCK
-#endif // WITH_JACK_MIDI
+       #ifdef DEBUG_MIDI_CLOCK         
+               std::cerr 
+                                 << " got MIDI Clock message at time " << timestamp  
+                                 << " engine time: " << session.engine().frame_time() 
+                                 << " transport position: " << session.transport_frame()
+                                 << " real delta: " << current_midi_clock_frame_duration 
+                                 << " reference: " << one_ppqn_in_frames
+                                 << " average: " << average_midi_clock_frame_duration
+                                 << std::endl;
+       #endif // DEBUG_MIDI_CLOCK
        
-       current.guard1++;
-       current.position += one_ppqn_in_frames;
-       current_position += one_ppqn_in_frames;
-       current.timestamp = now;
-       current.guard2++;
+       if (_starting) {
+               assert(last_timestamp == 0);
+               assert(last_position == 0);
+               
+               last_position = 0;
+               last_timestamp = timestamp;
+               
+               // let ardour go after first MIDI Clock Event
+               _starting = false;
+               session.request_transport_speed (1.0);
+       } else {;
+               last_position  += double(one_ppqn_in_frames);
+               last_timestamp = timestamp;
+       }
 
-       last_inbound_frame = now;
 }
 
 void
 MIDIClock_Slave::start (Parser& parser, nframes_t timestamp)
-{
-       
-       nframes_t now = timestamp;
-       
-#ifdef DEBUG_MIDI_CLOCK        
-       cerr << "MIDIClock_Slave got start message at time "  <<  now << " session time: " << session.engine().frame_time() << endl;
-#endif
+{      
+       #ifdef DEBUG_MIDI_CLOCK 
+               cerr << "MIDIClock_Slave got start message at time "  <<  timestamp << " session time: " << session.engine().frame_time() << endl;
+       #endif
        
        if(!locked()) {
                cerr << "Did not start because not locked!" << endl;
                return;
        }
        
-       current_midi_clock_frame_duration = 0;
+       // initialize accumulator to sane values
+       calculate_one_ppqn_in_frames_at(0);
+       
+       for(int i = 0; i < accumulator_size; i++) {
+               accumulator[i] = one_ppqn_in_frames;
+       }
        
-       current.guard1++;
-       current.position = 0;
-       current_position = 0;   
-       current.timestamp = 0;
-       current.guard2++;
+       last_position = 0;
+       last_timestamp = 0;
        
        _started = true;
        _starting = true;
@@ -184,9 +173,9 @@ MIDIClock_Slave::start (Parser& parser, nframes_t timestamp)
 void
 MIDIClock_Slave::contineu (Parser& parser, nframes_t timestamp)
 {
-#ifdef DEBUG_MIDI_CLOCK        
-       std::cerr << "MIDIClock_Slave got continue message" << endl;
-#endif
+       #ifdef DEBUG_MIDI_CLOCK 
+               std::cerr << "MIDIClock_Slave got continue message" << endl;
+       #endif
        start(parser, timestamp);
 }
 
@@ -194,39 +183,19 @@ MIDIClock_Slave::contineu (Parser& parser, nframes_t timestamp)
 void
 MIDIClock_Slave::stop (Parser& parser, nframes_t timestamp)
 {
-#ifdef DEBUG_MIDI_CLOCK        
-       std::cerr << "MIDIClock_Slave got stop message" << endl;
-#endif
+       #ifdef DEBUG_MIDI_CLOCK 
+               std::cerr << "MIDIClock_Slave got stop message" << endl;
+       #endif
        
        current_midi_clock_frame_duration = 0;
 
-       current.guard1++;
-       current.position = 0;
-       current_position = 0;   
-       current.timestamp = 0;
-       current.guard2++;
+       last_position = 0;
+       last_timestamp = 0;
        
        _started = false;
        reset();
 }
 
-void
-MIDIClock_Slave::read_current (SafeTime *st) const
-{
-       int tries = 0;
-       do {
-               if (tries == 10) {
-                       error << _("MIDI Clock Slave: atomic read of current time failed, sleeping!") << endmsg;
-                       usleep (20);
-                       tries = 0;
-               }
-
-               *st = current;
-               tries++;
-
-       } while (st->guard1 != st->guard2);
-}
-
 bool
 MIDIClock_Slave::locked () const
 {
@@ -242,20 +211,20 @@ MIDIClock_Slave::ok() const
 bool
 MIDIClock_Slave::starting() const
 {
-       return _starting;
+       return false;
 }
 
 bool
-MIDIClock_Slave::stop_if_no_more_clock_events(nframes_t& pos, nframes_t now, SafeTime& last)
+MIDIClock_Slave::stop_if_no_more_clock_events(nframes_t& pos, nframes_t now)
 {
        /* no timecode for 1/4 second ? conclude that its stopped */
-       if (last_inbound_frame && 
-           now > last_inbound_frame && 
-           now - last_inbound_frame > session.frame_rate() / 4) {
-#ifdef DEBUG_MIDI_CLOCK                        
-               cerr << "No MIDI Clock frames received for some time, stopping!" << endl;
-#endif         
-               pos = last.position;
+       if (last_timestamp && 
+           now > last_timestamp && 
+           now - last_timestamp > session.frame_rate() / 4) {
+        #ifdef DEBUG_MIDI_CLOCK                        
+                       cerr << "No MIDI Clock frames received for some time, stopping!" << endl;
+        #endif         
+               pos = last_position;
                session.request_locate (pos, false);
                session.request_transport_speed (0);
                this->stop(*port->input(), now);
@@ -269,42 +238,46 @@ MIDIClock_Slave::stop_if_no_more_clock_events(nframes_t& pos, nframes_t now, Saf
 bool
 MIDIClock_Slave::speed_and_position (float& speed, nframes_t& pos)
 {
-       if (!_started) {
+       if (!_started || _starting) {
                speed = 0.0;
                pos = 0;
                return true;
        }
                
-       nframes_t now = session.engine().frame_time();
-       SafeTime last;
-       read_current (&last);
+       nframes_t engine_now = session.engine().frame_time();
 
-       if (stop_if_no_more_clock_events(pos, now, last)) {
+       if (stop_if_no_more_clock_events(pos, engine_now)) {
                return false;
        }
-       //cerr << " now: " << now << " last: " << last.timestamp;
-
+       
+       #ifdef DEBUG_MIDI_CLOCK 
+               cerr << "speed_and_position: engine time: " << engine_now << " last message timestamp: " << last_timestamp;
+       #endif
+       
        // calculate speed
        double speed_double = one_ppqn_in_frames / average_midi_clock_frame_duration;
        speed = float(speed_double);
-       //cerr << " final speed: " << speed;
+       
+    #ifdef DEBUG_MIDI_CLOCK    
+               cerr << " final speed: " << speed;
+    #endif
        
        // calculate position
-       if (now > last.timestamp) {
+       if (engine_now > last_timestamp) {
                // we are in between MIDI clock messages
                // so we interpolate position according to speed
-               nframes_t elapsed = now - last.timestamp;
-               pos = nframes_t (current_position + double(elapsed) * speed_double);
+               nframes_t elapsed = engine_now - last_timestamp;
+               pos = nframes_t (last_position + double(elapsed) * speed_double);
        } else {
                // A new MIDI clock message has arrived this cycle
-               pos = current_position;
+               pos = last_position;
        }
        
-       /*
-   cerr << " transport position now: " <<  session.transport_frame(); 
-   cerr << " calculated position: " << pos; 
-   cerr << endl;
-   */
+   #ifdef DEBUG_MIDI_CLOCK     
+          cerr << " transport position engine_now: " <<  session.transport_frame(); 
+          cerr << " calculated position: " << pos; 
+          cerr << endl;
+   #endif
    
        return true;
 }
@@ -320,12 +293,8 @@ void
 MIDIClock_Slave::reset ()
 {
 
-       last_inbound_frame = 0;
-       current.guard1++;
-       current.position = 0;
-       current_position = 0;           
-       current.timestamp = 0;
-       current.guard2++;
+       last_position = 0;              
+       last_timestamp = 0;
        
        session.request_locate(0, false);
 }
index 5ca77f02f176770b53751123c8b553aff69972fb..1ceb2b70faa09cc5ede76b18f6c5fa0633b5de12 100644 (file)
@@ -495,7 +495,8 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                slave_speed = 0.0f;
        }
 
-#if 0
+#ifdef DEBUG_SLAVES
+       if (slave_speed != 0.0)
        cerr << "delta = " << (int) (dir * this_delta)
             << " speed = " << slave_speed 
             << " ts = " << _transport_speed 
@@ -542,7 +543,6 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                        } else {
                                average_dir = 1;
                        }
-                       // cerr << "avgdelta = " << average_slave_delta*average_dir << endl;
                }
        }
 
@@ -585,10 +585,13 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
 
                if (slave_state == Waiting) {
 
-                       // cerr << "waiting at " << slave_transport_frame << endl;
+#ifdef DEBUG_SLAVES
+                       cerr << "waiting at " << slave_transport_frame << endl;
+#endif                 
                        if (slave_transport_frame >= slave_wait_end) {
-                               // cerr << "\tstart at " << _transport_frame << endl;
-
+#ifdef DEBUG_SLAVES
+                               cerr << "\tstart at " << _transport_frame << endl;
+#endif
                                slave_state = Running;
 
                                bool ok = true;
@@ -610,7 +613,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                                        _transport_frame += frame_delta;
                                       
                                } else {
-                                       // cerr << "cannot micro-seek\n";
+                                       cerr << "cannot micro-seek\n";
                                        /* XXX what? */
                                }
 
@@ -622,8 +625,9 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                
                if (slave_state == Running && _transport_speed == 0.0f) {
                        
-                       // cerr << "slave starts transport\n";
-                       
+#ifdef DEBUG_SLAVES
+                       cerr << "slave starts transport\n";
+#endif
                        start_transport ();
                } 
 
@@ -633,9 +637,10 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
 
                if (_transport_speed != 0.0f) {
 
-                       // cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame 
-                       // << " tf = " << _transport_frame
-                       // << endl;
+#ifdef DEBUG_SLAVES
+                       cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame 
+                            << " tf = " << _transport_frame << endl;
+#endif
                        
                        if (Config->get_slave_source() == JACK) {
                                last_stop_frame = _transport_frame;
@@ -645,7 +650,9 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                }
 
                if (slave_transport_frame != _transport_frame) {
-                       // cerr << "slave stopped, move to " << slave_transport_frame << endl;
+#ifdef DEBUG_SLAVES                    
+                       cerr << "slave stopped, move to " << slave_transport_frame << endl;
+#endif
                        force_locate (slave_transport_frame, false);
                }
 
@@ -675,7 +682,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                        float adjusted_speed = slave_speed +
                                (delta / (adjust_seconds * _current_frame_rate));
                        
-#if 0
+#ifdef DEBUG_DELAY_LOCKED_LOOP
                        cerr << "adjust using " << delta
                             << " towards " << adjusted_speed
                             << " ratio = " << adjusted_speed / slave_speed
@@ -686,12 +693,10 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
                        
                        request_transport_speed (adjusted_speed);
                        
-#if 1
                        if (abs(average_slave_delta) > (long) _slave->resolution()) {
                                cerr << "average slave delta greater than slave resolution, going to silent motion\n";
                                goto silent_motion;
                        }
-#endif
                }
        } 
 
@@ -701,7 +706,10 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
        }
 
   silent_motion:
-
+#ifdef DEBUG_SLAVES    
+       cerr << "reached silent_motion:" <<endl;
+#endif
+       
        if (slave_speed && _transport_speed) {
 
                /* something isn't right, but we should move with the master
@@ -743,6 +751,9 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
 
   noroll:
        /* don't move at all */
+#ifdef DEBUG_SLAVES    
+       cerr << "reached no_roll:" <<endl;
+#endif
        no_roll (nframes, 0);
        return false;
 }