diff options
author | Hans Baier <hansfbaier@googlemail.com> | 2009-02-12 10:14:22 +0000 |
---|---|---|
committer | Hans Baier <hansfbaier@googlemail.com> | 2009-02-12 10:14:22 +0000 |
commit | b1cd1835113a21670efc0ad1264c7df160a93147 (patch) | |
tree | 3cc049e723e48b03759135a7e739502c9188d455 | |
parent | 0522149d208d92bd68898dda521a6ebda4999c93 (diff) |
* MIDI clock slave: issues 2541 and 2542 ready for testing (cant test myself due to lack of hardware)
* tempo.cc/tempo.h: formatting / whitespace
git-svn-id: svn://localhost/ardour2/branches/3.0@4538 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/ardour/ardour/slave.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 2 | ||||
-rw-r--r-- | libs/ardour/midi_clock_slave.cc | 94 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 20 |
4 files changed, 82 insertions, 38 deletions
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 1f2610e028..fe764d555d 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -266,10 +266,12 @@ class MIDIClock_Slave : public Slave, public sigc::trackable { void reset (); void start (MIDI::Parser& parser, nframes_t timestamp); + void contineu (MIDI::Parser& parser, nframes_t timestamp); void stop (MIDI::Parser& parser, nframes_t timestamp); + void position (MIDI::Parser& parser, MIDI::byte* message, size_t size); // we can't use continue because it is a C++ keyword - void contineu (MIDI::Parser& parser, nframes_t timestamp); void calculate_one_ppqn_in_frames_at(nframes_t time); + nframes_t calculate_song_position(uint16_t song_position_in_sixteenth_notes); void calculate_filter_coefficients(); void update_midi_clock (MIDI::Parser& parser, nframes_t timestamp); void read_current (SafeTime *) const; diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index c4915072c5..f5cadb840a 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -137,7 +137,7 @@ class MetricSection { private: BBT_Time _start; - nframes_t _frame; + nframes_t _frame; bool _movable; }; diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc index f1ec1ad924..ef3aacb4c6 100644 --- a/libs/ardour/midi_clock_slave.cc +++ b/libs/ardour/midi_clock_slave.cc @@ -72,6 +72,7 @@ MIDIClock_Slave::rebind (MIDI::Port& p) connections.push_back (port->input()->start.connect (mem_fun (*this, &MIDIClock_Slave::start))); connections.push_back (port->input()->contineu.connect (mem_fun (*this, &MIDIClock_Slave::contineu))); connections.push_back (port->input()->stop.connect (mem_fun (*this, &MIDIClock_Slave::stop))); + connections.push_back (port->input()->position.connect (mem_fun (*this, &MIDIClock_Slave::position))); } void @@ -89,6 +90,19 @@ MIDIClock_Slave::calculate_one_ppqn_in_frames_at(nframes_t time) one_ppqn_in_frames = frames_per_quarter_note / double (ppqn); } +ARDOUR::nframes_t +MIDIClock_Slave::calculate_song_position(uint16_t song_position_in_sixteenth_notes) +{ + nframes_t song_position_frames = 0; + for (uint16_t i = 1; i <= song_position_in_sixteenth_notes; ++i) { + // one quarter note contains ppqn pulses, so a sixteenth note is ppqn / 4 pulses + calculate_one_ppqn_in_frames_at(song_position_frames); + song_position_frames += one_ppqn_in_frames * nframes_t(ppqn / 4); + } + + return song_position_frames; +} + void MIDIClock_Slave::calculate_filter_coefficients() { @@ -108,13 +122,11 @@ MIDIClock_Slave::update_midi_clock (Parser& parser, nframes_t timestamp) nframes_t timestamp_relative_to_transport = timestamp - first_timestamp; - if (_starting) { + if (_starting || last_timestamp == 0) { midi_clock_count = 0; - assert(last_timestamp == 0); - assert(last_position == 0); first_timestamp = timestamp; - timestamp_relative_to_transport = 0; + timestamp_relative_to_transport = last_position; // calculate filter coefficients calculate_filter_coefficients(); @@ -141,8 +153,7 @@ MIDIClock_Slave::update_midi_clock (Parser& parser, nframes_t timestamp) // update DLL t0 = t1; t1 += b * e + e2; - e2 += c * e; - + e2 += c * e; } #ifdef DEBUG_MIDI_CLOCK @@ -171,11 +182,25 @@ MIDIClock_Slave::start (Parser& parser, nframes_t timestamp) cerr << "MIDIClock_Slave got start message at time " << timestamp << " session time: " << session.engine().frame_time() << endl; #endif - last_position = 0; + if (!_started) { + reset(); + + _started = true; + _starting = true; + } +} + +void +MIDIClock_Slave::reset () +{ + + last_position = 0; last_timestamp = 0; - _started = true; - _starting = true; + _starting = false; + _started = false; + + session.request_locate(0, false); } void @@ -184,7 +209,10 @@ MIDIClock_Slave::contineu (Parser& parser, nframes_t timestamp) #ifdef DEBUG_MIDI_CLOCK std::cerr << "MIDIClock_Slave got continue message" << endl; #endif - start(parser, timestamp); + if (!_started) { + _starting = true; + _started = true; + } } @@ -195,11 +223,36 @@ MIDIClock_Slave::stop (Parser& parser, nframes_t timestamp) std::cerr << "MIDIClock_Slave got stop message" << endl; #endif - last_position = 0; + if (_started || _starting) { + _starting = false; + _started = false; + // locate to last MIDI clock position + session.request_transport_speed(0.0); + session.request_locate(last_position, false); + last_timestamp = 0; + } +} + +void +MIDIClock_Slave::position (Parser& parser, byte* message, size_t size) +{ + // we are note supposed to get position messages while we are running + // so lets be robust and ignore those + if (_started || _starting) { + return; + } + + assert(size == 3); + byte lsb = message[0]; + byte msb = message[1]; + assert((lsb <= 0x7f) && (msb <= 0x7f)); + + uint16_t position_in_sixteenth_notes = (uint16_t(msb) << 7) | uint16_t(lsb); + nframes_t position_in_frames = calculate_song_position(position_in_sixteenth_notes); + session.request_locate(position_in_frames, false); + last_position = position_in_frames; last_timestamp = 0; - _started = false; - reset(); } bool @@ -231,10 +284,8 @@ MIDIClock_Slave::stop_if_no_more_clock_events(nframes_t& pos, nframes_t now) cerr << "No MIDI Clock frames received for some time, stopping!" << endl; #endif pos = last_position; - session.request_locate (pos, false); session.request_transport_speed (0); - this->stop(*port->input(), now); - reset(); + session.request_locate (last_position, false); return true; } else { return false; @@ -246,7 +297,7 @@ MIDIClock_Slave::speed_and_position (double& speed, nframes_t& pos) { if (!_started || _starting) { speed = 0.0; - pos = 0; + pos = last_position; return true; } @@ -280,12 +331,3 @@ MIDIClock_Slave::resolution() const return (nframes_t) one_ppqn_in_frames * ppqn; } -void -MIDIClock_Slave::reset () -{ - - last_position = 0; - last_timestamp = 0; - - session.request_locate(0, false); -} diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 5698b0afe7..b99f46385d 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -784,8 +784,8 @@ TempoMap::metric_at (BBT_Time bbt) const void TempoMap::bbt_time (nframes_t frame, BBT_Time& bbt) const { - { - Glib::RWLock::ReaderLock lm (lock); + { + Glib::RWLock::ReaderLock lm (lock); bbt_time_unlocked (frame, bbt); } } @@ -942,7 +942,7 @@ TempoMap::bbt_duration_at (nframes_t pos, const BBT_Time& bbt, int dir) const nframes_t frames = 0; BBT_Time when; - bbt_time(pos,when); + bbt_time(pos, when); { Glib::RWLock::ReaderLock lm (lock); @@ -961,7 +961,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i double beats_per_bar; BBT_Time result; - result.bars = max(1U,when.bars + dir * bbt.bars) ; + result.bars = max(1U, when.bars + dir * bbt.bars) ; result.beats = 1; result.ticks = 0; @@ -981,7 +981,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i result.beats = when.beats + bbt.beats; result.ticks = when.ticks + bbt.ticks; - while (result.beats >= (beats_per_bar+1)) { + while (result.beats >= (beats_per_bar + 1)) { result.bars++; result.beats -= (uint32_t) ceil(beats_per_bar); metric = metric_at(result); // maybe there is a meter change @@ -1003,14 +1003,14 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i while (result.ticks >= ticks_at_beat) { result.beats++; result.ticks -= ticks_at_beat; - if (result.beats >= (beats_per_bar+1)) { + if (result.beats >= (beats_per_bar + 1)) { result.bars++; result.beats = 1; metric = metric_at(result); // maybe there is a meter change beats_per_bar = metric.meter().beats_per_bar(); } ticks_at_beat= (uint32_t) ( result.beats == ceil(beats_per_bar) ? - (1 - (ceil(beats_per_bar) - beats_per_bar) )* Meter::ticks_per_beat + (1 - (ceil(beats_per_bar) - beats_per_bar) ) * Meter::ticks_per_beat : Meter::ticks_per_beat); } @@ -1029,7 +1029,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i b -= (uint32_t) ceil(beats_per_bar); } else { - b = (uint32_t) ceil(beats_per_bar)- b + when.beats ; + b = (uint32_t) ceil(beats_per_bar) - b + when.beats ; } } result.beats = when.beats - b; @@ -1046,11 +1046,11 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i do { if (result.beats == 1) { - result.bars = max(1U,result.bars-- ) ; + result.bars = max(1U, result.bars-- ) ; metric = metric_at(result); // maybe there is a meter change beats_per_bar = metric.meter().beats_per_bar(); result.beats = (uint32_t) ceil(beats_per_bar); - ticks_at_beat = (uint32_t) ((1 - (ceil(beats_per_bar) - beats_per_bar))* Meter::ticks_per_beat) ; + ticks_at_beat = (uint32_t) ((1 - (ceil(beats_per_bar) - beats_per_bar)) * Meter::ticks_per_beat) ; } else { result.beats --; ticks_at_beat = (uint32_t) Meter::ticks_per_beat; |