* sending MIDI clock works, hooray\!
authorHans Baier <hansfbaier@googlemail.com>
Sat, 29 Nov 2008 05:40:17 +0000 (05:40 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Sat, 29 Nov 2008 05:40:17 +0000 (05:40 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@4268 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/ticker.h
libs/ardour/ticker.cc
libs/midi++2/midi++/jack.h

index 7faba49a14014f5f952fd2bc10cebc5370423c92..249f6b885f850a01305ebb3a69578165633898b1 100644 (file)
@@ -52,7 +52,7 @@ protected:
 class MidiClockTicker : public Ticker
 {
 public:
-       MidiClockTicker() : _jack_port(0), _ppqn(24) {};
+       MidiClockTicker() : _jack_port(0), _ppqn(24), _last_tick(0.0) {};
        virtual ~MidiClockTicker() {};
        
        void tick(
@@ -66,13 +66,27 @@ public:
        /// slot for the signal session::MIDIClock_PortChanged
        void update_midi_clock_port();
        
+       /// slot for the signal session::TransportStateChange
+       void transport_state_changed();
+       
+       /// slot for the signal session::PositionChanged
+       void position_changed(nframes_t position);
+
+       /// slot for the signal session::TransportLooped
+       void transport_looped();
+       
        /// pulses per quarter note (default 24)
        void set_ppqn(int ppqn) { _ppqn = ppqn; }
 
 private:       
        MIDI::JACK_MidiPort* _jack_port;
-       nframes_t            _last_tick;
        int                  _ppqn;
+       double               _last_tick;
+       
+       void send_midi_clock_event(nframes_t offset);
+       void send_start_event(nframes_t offset);
+       void send_continue_event(nframes_t offset);
+       void send_stop_event(nframes_t offset);
 };
 
 }
index 866fa83e07057ad1e0e9c9eea7c29d051cac67f3..587f6503dfb4897b61086b72359ea127b1a1c2c5 100644 (file)
@@ -42,6 +42,9 @@ void MidiClockTicker::set_session(Session& s)
         
         if(_session) {
                 _session->MIDIClock_PortChanged.connect(mem_fun (*this, &MidiClockTicker::update_midi_clock_port));
+                _session->TransportStateChange .connect(mem_fun (*this, &MidiClockTicker::transport_state_changed));
+                _session->PositionChanged      .connect(mem_fun (*this, &MidiClockTicker::position_changed));           
+                _session->TransportLooped      .connect(mem_fun (*this, &MidiClockTicker::transport_looped));           
                 update_midi_clock_port();
         }
 }
@@ -51,6 +54,70 @@ void MidiClockTicker::update_midi_clock_port()
         _jack_port = (MIDI::JACK_MidiPort*) _session->midi_clock_port();
 }
 
+void MidiClockTicker::transport_state_changed()
+{
+       float     speed     = _session->transport_speed();
+       nframes_t position  = _session->transport_frame();
+       //cerr << "Transport state change, speed:" << speed << "position:" << position << endl;
+       if (speed == 1.0f) {
+               _last_tick = position;
+               
+               if (!Config->get_send_midi_clock()) 
+                       return;
+               
+               if (position == 0) {
+                       send_start_event(0);
+               } else {
+                       send_continue_event(0);
+               }
+               
+               send_midi_clock_event(0);
+               
+       } else if (speed == 0.0f) {
+               if (!Config->get_send_midi_clock()) 
+                       return;
+               
+               send_stop_event(0);
+       }
+}
+
+void MidiClockTicker::position_changed(nframes_t position)
+{
+       cerr << "Position changed:" << position << endl;
+       _last_tick = position;
+}
+
+void MidiClockTicker::transport_looped()
+{
+       nframes_t position  = _session->transport_frame();
+       
+       cerr << "Transport looped, position:" <<  position << endl;
+}
+
+void MidiClockTicker::send_midi_clock_event(nframes_t offset)
+{
+       static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK };
+       _jack_port->write(_midi_clock_tick, 1, offset);
+}
+
+void MidiClockTicker::send_start_event(nframes_t offset)
+{
+       static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
+       _jack_port->write(_midi_clock_tick, 1, offset);
+}
+
+void MidiClockTicker::send_continue_event(nframes_t offset)
+{
+       static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
+       _jack_port->write(_midi_clock_tick, 1, offset);
+}
+
+void MidiClockTicker::send_stop_event(nframes_t offset)
+{
+       static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
+       _jack_port->write(_midi_clock_tick, 1, offset);
+}
+
 void MidiClockTicker::tick(const nframes_t& transport_frames, const BBT_Time& transport_bbt, const SMPTE::Time& transport_smpt)
 {      
        if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f)
@@ -65,14 +132,19 @@ void MidiClockTicker::tick(const nframes_t& transport_frames, const BBT_Time& tr
        double quarter_notes_per_beat = 4.0 / current_tempo.note_type();
        double frames_per_quarter_note = frames_per_beat / quarter_notes_per_beat;
 
-       nframes_t one_ppqn_in_frames = frames_per_quarter_note / double (_ppqn);
+       double one_ppqn_in_frames = frames_per_quarter_note / double (_ppqn);
+       
+       double next_tick = _last_tick + one_ppqn_in_frames;
+       nframes_t next_tick_offset = nframes_t(next_tick) - transport_frames;
        
-       nframes_t next_tick = _last_tick + one_ppqn_in_frames;
-       nframes_t next_tick_offset = next_tick - transport_frames;
+       //cerr << "Transport:" << transport_frames << ":Next tick time:" << next_tick << ":" << "Offset:" << next_tick_offset << endl; 
+       
+       if (next_tick_offset >= _jack_port->nframes_this_cycle())
+               return;
        
        assert(_jack_port->is_process_thread());
-       static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_TICK };
-       _jack_port->write(_midi_clock_tick, 1, next_tick_offset);
+
+       send_midi_clock_event(next_tick_offset);
        
        _last_tick = next_tick;
 }
index 6c086210892992bfdb3c6b76979c6a31446bb425..9e779b2198c7b74de9d5eac495071c2fbfd4516e 100644 (file)
@@ -63,6 +63,8 @@ public:
        static pthread_t get_process_thread () { return _process_thread; }
        static bool is_process_thread();
        
+       nframes_t nframes_this_cycle() const {  return _nframes_this_cycle; }
+       
   protected:
        std::string get_typestring () const {
                return typestring;