diff options
-rw-r--r-- | gtk2_ardour/ardour.menus | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_options.cc | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/ticker.h | 20 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ticker.cc | 39 |
8 files changed, 66 insertions, 8 deletions
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 8c504f5511..9d4f57465b 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -430,6 +430,7 @@ </menu> <menu action='SyncMenu'> <menuitem action='SendMTC'/> + <menuitem action='SendMidiClock'/> <menuitem action='SendMMC'/> <menuitem action='UseMMC'/> </menu> diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 64cdf1348f..8243a40fd1 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -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 (); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 89fa04c79b..4b7008e027 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -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); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 410c39268c..4c80b8dd35 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -62,6 +62,12 @@ ARDOUR_UI::toggle_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 () { ActionManager::toggle_config_state ("options", "UseMMC", &Configuration::set_mmc_control, &Configuration::get_mmc_control); diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 055d47b7c1..5565e20401 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -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) diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index 73e5046ac3..7faba49a14 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -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; }; } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 099b926fa7..98626d6c6c 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -101,6 +101,7 @@ #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")); diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index bf84bba92b..866fa83e07 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -17,8 +17,10 @@ $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; } } |