From d746b78319b142bf7b79efd1560f991394321c71 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Sat, 29 Nov 2008 05:40:17 +0000 Subject: [PATCH] * sending MIDI clock works, hooray\! git-svn-id: svn://localhost/ardour2/branches/3.0@4268 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/ticker.h | 18 +++++++- libs/ardour/ticker.cc | 82 ++++++++++++++++++++++++++++++++++--- libs/midi++2/midi++/jack.h | 2 + 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index 7faba49a14..249f6b885f 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -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); }; } diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index 866fa83e07..587f6503df 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -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); - nframes_t next_tick = _last_tick + one_ppqn_in_frames; - nframes_t next_tick_offset = next_tick - transport_frames; + double next_tick = _last_tick + one_ppqn_in_frames; + nframes_t next_tick_offset = nframes_t(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; } diff --git a/libs/midi++2/midi++/jack.h b/libs/midi++2/midi++/jack.h index 6c08621089..9e779b2198 100644 --- a/libs/midi++2/midi++/jack.h +++ b/libs/midi++2/midi++/jack.h @@ -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;