* added Menu for sending midi clock
authorHans Baier <hansfbaier@googlemail.com>
Wed, 26 Nov 2008 23:32:55 +0000 (23:32 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Wed, 26 Nov 2008 23:32:55 +0000 (23:32 +0000)
* hooked up MidiClockTicker to the session

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

gtk2_ardour/ardour.menus
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/ticker.h
libs/ardour/session_state.cc
libs/ardour/ticker.cc

index 8c504f5511c84124f349a4641f0e1755cb61039a..9d4f57465bddd5668fb1f7492f3db876475c2ce4 100644 (file)
                </menu>
               <menu action='SyncMenu'>
                             <menuitem action='SendMTC'/>
+                            <menuitem action='SendMidiClock'/>
                             <menuitem action='SendMMC'/>
                             <menuitem action='UseMMC'/>
               </menu>
index 64cdf1348f2490c61ae66f7704e874a357ef9c6b..8243a40fd15401123ba34621e186c8a7c9f41fcf 100644 (file)
@@ -701,6 +701,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void toggle_use_mmc ();
        void toggle_send_mmc ();
        void toggle_send_mtc ();
+       void toggle_send_midi_clock ();
 
        void toggle_use_osc ();
 
index 89fa04c79bcf4aa0239981374369d87f366c1acb..4b7008e027457799f73203c14a3d2d97796bb351 100644 (file)
@@ -436,6 +436,8 @@ ARDOUR_UI::install_actions ()
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_toggle_action (option_actions, X_("UseMMC"), _("Use MMC"), mem_fun (*this, &ARDOUR_UI::toggle_use_mmc));
        ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_toggle_action (option_actions, X_("SendMidiClock"), _("Send MIDI Clock"), mem_fun (*this, &ARDOUR_UI::toggle_send_midi_clock));
+       ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_toggle_action (option_actions, X_("SendMIDIfeedback"), _("Send MIDI feedback"), mem_fun (*this, &ARDOUR_UI::toggle_send_midi_feedback));
        ActionManager::session_sensitive_actions.push_back (act);
 
index 410c39268c026b4516f046f0b163ae6c5b280270..4c80b8dd35704c107e18e9e200cf2db02708e322 100644 (file)
@@ -61,6 +61,12 @@ ARDOUR_UI::toggle_send_mmc ()
        ActionManager::toggle_config_state ("options", "SendMMC", &Configuration::set_send_mmc, &Configuration::get_send_mmc);
 }
 
+void
+ARDOUR_UI::toggle_send_midi_clock ()
+{
+       ActionManager::toggle_config_state ("options", "SendMidiClock", &Configuration::set_send_midi_clock, &Configuration::get_send_midi_clock);
+}
+
 void
 ARDOUR_UI::toggle_use_mmc ()
 {
index 055d47b7c1bf89c03caab062e150032b8e66db1a..5565e204018b0803cc7ae9b781d43df255ffae65 100644 (file)
@@ -35,6 +35,7 @@ CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
 CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
 CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
 CONFIG_VARIABLE (bool, send_mmc, "send-mmc", true)
+CONFIG_VARIABLE (bool, send_midi_clock, "send-midi-clock", false)
 CONFIG_VARIABLE (bool, mmc_control, "mmc-control", true)
 CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
 CONFIG_VARIABLE (uint8_t, mmc_receive_device_id, "mmc-receive-device-id", 0)
index 73e5046ac39089609bfd31fe8da4630a0a8efee6..7faba49a14014f5f952fd2bc10cebc5370423c92 100644 (file)
@@ -17,6 +17,7 @@
 
     $Id$
 */
+
 #include <sigc++/sigc++.h>
 
 #include "ardour/types.h"
@@ -42,31 +43,36 @@ public:
                const SMPTE::Time& transport_smpte) = 0;
        
        virtual void set_session(Session& s);
-       virtual void going_away() { _session = 0; }
+       virtual void going_away() { _session = 0;  delete this; }
 
-private:
+protected:
        Session* _session;
 };
 
 class MidiClockTicker : public Ticker
 {
-       MidiClockTicker() : _jack_port(0) {};
+public:
+       MidiClockTicker() : _jack_port(0), _ppqn(24) {};
        virtual ~MidiClockTicker() {};
        
-       
        void tick(
                const nframes_t& transport_frames, 
                const BBT_Time& transport_bbt, 
                const SMPTE::Time& transport_smpte);
        
-       
+       void set_session(Session& s);
        void going_away() { Ticker::going_away(); _jack_port = 0;}
        
-       void set_midi_port(MIDI::JACK_MidiPort &port);
+       /// slot for the signal session::MIDIClock_PortChanged
+       void update_midi_clock_port();
+       
+       /// 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;
 };
 
 }
index 099b926fa7768a3162d84d1ee695320d8411ef2c..98626d6c6c11e0d30a3ae0df21ca84c525ac2625 100644 (file)
 #include <ardour/filename_extensions.h>
 #include <ardour/directory_names.h>
 #include <ardour/template_utils.h>
+#include <ardour/ticker.h>
 
 #include <control_protocol/control_protocol.h>
 
@@ -357,6 +358,9 @@ Session::second_stage_init (bool new_session)
        _engine.transport_locate (0);
        deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
        deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
+       
+       MidiClockTicker* midi_clock_ticker = new MidiClockTicker();
+       midi_clock_ticker->set_session(*this);
 
        BootMessage (_("Reset Control Protocols"));
 
index bf84bba92b87083d719a3055fb5ba7eedcc76e04..866fa83e07057ad1e0e9c9eea7c29d051cac67f3 100644 (file)
 
     $Id$
 */
+
 #include "ardour/ticker.h"
 #include "ardour/session.h"
+#include "ardour/tempo.h"
 
 namespace ARDOUR
 {
@@ -34,10 +36,45 @@ void Ticker::set_session(Session& s)
         }
 }
 
+void MidiClockTicker::set_session(Session& s) 
+{
+        Ticker::set_session(s);
+        
+        if(_session) {
+                _session->MIDIClock_PortChanged.connect(mem_fun (*this, &MidiClockTicker::update_midi_clock_port));
+                update_midi_clock_port();
+        }
+}
 
-void MidiClockTicker::tick(const nframes_t& transport_frames, const BBT_Time& transport_bbt, const SMPTE::Time& transport_smpt)
+void MidiClockTicker::update_midi_clock_port()
 {
+        _jack_port = (MIDI::JACK_MidiPort*) _session->midi_clock_port();
+}
+
+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)
+               return;
+       
+       const Tempo& current_tempo = _session->tempo_map().tempo_at(transport_frames);
+       const Meter& current_meter = _session->tempo_map().meter_at(transport_frames);
+       double frames_per_beat =
+               current_tempo.frames_per_beat(_session->nominal_frame_rate(),
+                                             current_meter);
+
+       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);
+       
+       nframes_t next_tick = _last_tick + one_ppqn_in_frames;
+       nframes_t next_tick_offset = next_tick - transport_frames;
+       
+       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);
        
+       _last_tick = next_tick;
 }
 
 }