Ticker: apply patch from lincoln, Thanks!
[ardour.git] / libs / ardour / ardour / ticker.h
1 /*
2     Copyright (C) 2008 Hans Baier 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <sigc++/sigc++.h>
22
23 #include "ardour/types.h"
24 #include "midi++/jack.h"
25
26 #ifndef TICKER_H_
27 #define TICKER_H_
28
29 namespace ARDOUR
30 {
31
32 class Session;
33
34 class Ticker : public sigc::trackable
35 {
36 public:
37         Ticker() : _session(0) {};
38         virtual ~Ticker() {};
39         
40         virtual void tick(
41                 const nframes_t& transport_frames, 
42                 const BBT_Time& transport_bbt, 
43                 const SMPTE::Time& transport_smpte) = 0;
44         
45         virtual void set_session(Session& s);
46         virtual void going_away() { _session = 0; }
47
48 protected:
49         Session* _session;
50 };
51
52 class MidiClockTicker : public Ticker
53 {
54         /// Singleton
55 private:
56         MidiClockTicker() : _midi_port(0), _ppqn(24), _last_tick(0.0) {};
57         MidiClockTicker( const MidiClockTicker& );
58         MidiClockTicker& operator= (const MidiClockTicker&);
59         
60 public:
61         virtual ~MidiClockTicker() {};
62         
63         static MidiClockTicker& instance() {
64                 static MidiClockTicker _instance;
65                 return _instance;
66         }
67         
68         void tick(
69                 const nframes_t& transport_frames, 
70                 const BBT_Time& transport_bbt, 
71                 const SMPTE::Time& transport_smpte);
72         
73         void set_session(Session& s);
74         void going_away() { _midi_port = 0; Ticker::going_away(); }
75
76         /// slot for the signal session::MIDIClock_PortChanged
77         void update_midi_clock_port();
78         
79         /// slot for the signal session::TransportStateChange
80         void transport_state_changed();
81         
82         /// slot for the signal session::PositionChanged
83         void position_changed(nframes_t position);
84
85         /// slot for the signal session::TransportLooped
86         void transport_looped();
87         
88         /// pulses per quarter note (default 24)
89         void set_ppqn(int ppqn) { _ppqn = ppqn; }
90
91 private:        
92         MIDI::Port*  _midi_port;
93         int          _ppqn;
94         double       _last_tick;
95
96         double one_ppqn_in_frames(nframes_t transport_position);
97         
98         void send_midi_clock_event(nframes_t offset);
99         void send_start_event(nframes_t offset);
100         void send_continue_event(nframes_t offset);
101         void send_stop_event(nframes_t offset);
102 };
103
104 }
105
106 #endif /* TICKER_H_ */