1 /* 2 * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2006 Hans Fugal <hans@fugal.net> 4 * Copyright (C) 2007-2015 David Robillard <d@drobilla.net> 5 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 6 * Copyright (C) 2015-2017 Ben Loftis <ben@harrisonconsoles.com> 7 * Copyright (C) 2015-2017 Nick Mainsbridge <mainsbridge@gmail.com> 8 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org> 9 * Copyright (C) 2015 Colin Fletcher <colin.m.fletcher@googlemail.com> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with this program; if not, write to the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 */ 25 26 #ifndef __ardour_tempo_h__ 27 #define __ardour_tempo_h__ 28 29 #include <list> 30 #include <string> 31 #include <vector> 32 #include <cmath> 33 #include <glibmm/threads.h> 34 35 #include "pbd/undo.h" 36 #include "pbd/enum_convert.h" 37 38 #include "pbd/stateful.h" 39 #include "pbd/statefuldestructible.h" 40 41 #include "temporal/beats.h" 42 43 #include "ardour/ardour.h" 44 45 class BBTTest; 46 class FrameposPlusBeatsTest; 47 class FrameposMinusBeatsTest; 48 class TempoTest; 49 class XMLNode; 50 51 namespace ARDOUR { 52 53 class Meter; 54 class TempoMap; 55 56 // Find a better place for these 57 LIBARDOUR_API bool bbt_time_to_string (const Timecode::BBT_Time& bbt, std::string& str); 58 LIBARDOUR_API bool string_to_bbt_time (const std::string& str, Timecode::BBT_Time& bbt); 59 60 /** Tempo, the speed at which musical time progresses (BPM). */ 61 class LIBARDOUR_API Tempo { 62 public: 63 /** 64 * @param npm Note Types per minute 65 * @param type Note Type (default `4': quarter note) 66 */ 67 Tempo (double npm, double type=4.0) // defaulting to quarter note _note_types_per_minute(npm)68 : _note_types_per_minute (npm), _note_type (type), _end_note_types_per_minute (npm) {} Tempo(double start_npm,double type,double end_npm)69 Tempo (double start_npm, double type, double end_npm) 70 : _note_types_per_minute (start_npm), _note_type (type), _end_note_types_per_minute (end_npm) {} 71 note_types_per_minute()72 double note_types_per_minute () const { return _note_types_per_minute; } note_types_per_minute(double note_type)73 double note_types_per_minute (double note_type) const { return (_note_types_per_minute / _note_type) * note_type; } set_note_types_per_minute(double npm)74 void set_note_types_per_minute (double npm) { _note_types_per_minute = npm; } note_type()75 double note_type () const { return _note_type; } 76 quarter_notes_per_minute()77 double quarter_notes_per_minute () const { return note_types_per_minute (4.0); } pulses_per_minute()78 double pulses_per_minute () const { return note_types_per_minute (1.0); } 79 end_note_types_per_minute()80 double end_note_types_per_minute () const { return _end_note_types_per_minute; } end_note_types_per_minute(double note_type)81 double end_note_types_per_minute (double note_type) const { return (_end_note_types_per_minute / _note_type) * note_type; } set_end_note_types_per_minute(double npm)82 void set_end_note_types_per_minute (double npm) { _end_note_types_per_minute = npm; } 83 end_quarter_notes_per_minute()84 double end_quarter_notes_per_minute () const { return end_note_types_per_minute (4.0); } end_pulses_per_minute()85 double end_pulses_per_minute () const { return end_note_types_per_minute (1.0); } 86 87 /** audio samples per note type. 88 * if you want an instantaneous value for this, use TempoMap::samples_per_quarter_note_at() instead. 89 * @param sr samplerate 90 */ samples_per_note_type(samplecnt_t sr)91 double samples_per_note_type (samplecnt_t sr) const { 92 return (60.0 * sr) / _note_types_per_minute; 93 } 94 /** audio samples per quarter note. 95 * if you want an instantaneous value for this, use TempoMap::samples_per_quarter_note_at() instead. 96 * @param sr samplerate 97 */ samples_per_quarter_note(samplecnt_t sr)98 double samples_per_quarter_note (samplecnt_t sr) const { 99 return (60.0 * sr) / quarter_notes_per_minute (); 100 } 101 102 protected: 103 double _note_types_per_minute; 104 double _note_type; 105 double _end_note_types_per_minute; 106 }; 107 108 /** Meter, or time signature (beats per bar, and which note type is a beat). */ 109 class LIBARDOUR_API Meter { 110 public: Meter(double dpb,double bt)111 Meter (double dpb, double bt) 112 : _divisions_per_bar (dpb), _note_type (bt) {} 113 divisions_per_bar()114 double divisions_per_bar () const { return _divisions_per_bar; } note_divisor()115 double note_divisor() const { return _note_type; } 116 117 double samples_per_bar (const Tempo&, samplecnt_t sr) const; 118 double samples_per_grid (const Tempo&, samplecnt_t sr) const; 119 120 inline bool operator==(const Meter& other) 121 { return _divisions_per_bar == other.divisions_per_bar() && _note_type == other.note_divisor(); } 122 123 protected: 124 /** The number of divisions in a bar. This is a floating point value because 125 there are musical traditions on our planet that do not limit 126 themselves to integral numbers of beats per bar. 127 */ 128 double _divisions_per_bar; 129 130 /** The type of "note" that a division represents. For example, 4.0 is 131 a quarter (crotchet) note, 8.0 is an eighth (quaver) note, etc. 132 */ 133 double _note_type; 134 }; 135 136 /** A section of timeline with a certain Tempo or Meter. */ 137 class LIBARDOUR_API MetricSection { 138 public: MetricSection(double pulse,double minute,PositionLockStyle pls,bool is_tempo,samplecnt_t sample_rate)139 MetricSection (double pulse, double minute, PositionLockStyle pls, bool is_tempo, samplecnt_t sample_rate) 140 : _pulse (pulse), _minute (minute), _initial (false), _position_lock_style (pls), _is_tempo (is_tempo), _sample_rate (sample_rate) {} 141 ~MetricSection()142 virtual ~MetricSection() {} 143 pulse()144 const double& pulse () const { return _pulse; } set_pulse(double pulse)145 void set_pulse (double pulse) { _pulse = pulse; } 146 minute()147 double minute() const { return _minute; } set_minute(double m)148 virtual void set_minute (double m) { 149 _minute = m; 150 } 151 sample()152 samplepos_t sample () const { return sample_at_minute (_minute); } 153 set_initial(bool yn)154 void set_initial (bool yn) { _initial = yn; } initial()155 bool initial() const { return _initial; } 156 157 /* MeterSections are not stateful in the full sense, 158 but we do want them to control their own 159 XML state information. 160 */ 161 virtual XMLNode& get_state() const = 0; 162 163 virtual int set_state (const XMLNode&, int version); 164 position_lock_style()165 PositionLockStyle position_lock_style () const { return _position_lock_style; } set_position_lock_style(PositionLockStyle ps)166 void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; } is_tempo()167 bool is_tempo () const { return _is_tempo; } 168 169 samplepos_t sample_at_minute (const double& time) const; 170 double minute_at_sample (const samplepos_t sample) const; 171 172 protected: 173 void add_state_to_node (XMLNode& node) const; 174 175 private: 176 177 double _pulse; 178 double _minute; 179 bool _initial; 180 PositionLockStyle _position_lock_style; 181 const bool _is_tempo; 182 samplecnt_t _sample_rate; 183 }; 184 185 /** A section of timeline with a certain Meter. */ 186 class LIBARDOUR_API MeterSection : public MetricSection, public Meter { 187 public: MeterSection(double pulse,double minute,double beat,const Timecode::BBT_Time & bbt,double bpb,double note_type,PositionLockStyle pls,samplecnt_t sr)188 MeterSection (double pulse, double minute, double beat, const Timecode::BBT_Time& bbt, double bpb, double note_type, PositionLockStyle pls, samplecnt_t sr) 189 : MetricSection (pulse, minute, pls, false, sr), Meter (bpb, note_type), _bbt (bbt), _beat (beat) {} 190 191 MeterSection (const XMLNode&, const samplecnt_t sample_rate); 192 193 static const std::string xml_state_node_name; 194 195 XMLNode& get_state() const; 196 set_beat(std::pair<double,Timecode::BBT_Time> & w)197 void set_beat (std::pair<double, Timecode::BBT_Time>& w) { 198 _beat = w.first; 199 _bbt = w.second; 200 } 201 bbt()202 const Timecode::BBT_Time& bbt() const { return _bbt; } beat()203 const double& beat () const { return _beat; } set_beat(double beat)204 void set_beat (double beat) { _beat = beat; } 205 206 private: 207 Timecode::BBT_Time _bbt; 208 double _beat; 209 }; 210 211 /** A section of timeline with a certain Tempo. */ 212 class LIBARDOUR_API TempoSection : public MetricSection, public Tempo { 213 public: 214 enum Type { 215 Ramp, 216 Constant, 217 }; 218 TempoSection(const double & pulse,const double & minute,Tempo tempo,PositionLockStyle pls,samplecnt_t sr)219 TempoSection (const double& pulse, const double& minute, Tempo tempo, PositionLockStyle pls, samplecnt_t sr) 220 : MetricSection (pulse, minute, pls, true, sr), Tempo (tempo), _c (0.0), _active (true), _locked_to_meter (false), _clamped (false) {} 221 222 TempoSection (const XMLNode&, const samplecnt_t sample_rate); 223 224 static const std::string xml_state_node_name; 225 226 XMLNode& get_state() const; 227 c()228 double c () const { return _c; } set_c(double c)229 void set_c (double c) { _c = c; } 230 type()231 Type type () const { if (note_types_per_minute() == end_note_types_per_minute()) { return Constant; } else { return Ramp; } } 232 active()233 bool active () const { return _active; } set_active(bool yn)234 void set_active (bool yn) { _active = yn; } 235 locked_to_meter()236 bool locked_to_meter () const { return _locked_to_meter; } set_locked_to_meter(bool yn)237 void set_locked_to_meter (bool yn) { _locked_to_meter = yn; } 238 clamped()239 bool clamped () const { return _clamped; } set_clamped(bool yn)240 void set_clamped (bool yn) { _clamped = yn; } 241 242 Tempo tempo_at_minute (const double& minute) const; 243 double minute_at_ntpm (const double& ntpm, const double& pulse) const; 244 245 Tempo tempo_at_pulse (const double& pulse) const; 246 double pulse_at_ntpm (const double& ntpm, const double& minute) const; 247 248 double pulse_at_minute (const double& minute) const; 249 double minute_at_pulse (const double& pulse) const; 250 251 double compute_c_pulse (const double& end_ntpm, const double& end_pulse) const; 252 double compute_c_minute (const double& end_ntpm, const double& end_minute) const; 253 254 double pulse_at_sample (const samplepos_t sample) const; 255 samplepos_t sample_at_pulse (const double& pulse) const; 256 legacy_bbt()257 Timecode::BBT_Time legacy_bbt () { return _legacy_bbt; } 258 259 private: 260 261 /* tempo ramp functions. zero-based with time in minutes, 262 * 'tick tempo' in ticks per minute and tempo in bpm. 263 * time relative to section start. 264 */ 265 double a_func (double end_tpm, double c_func) const; 266 double c_func (double end_tpm, double end_time) const; 267 268 double _tempo_at_time (const double& time) const; 269 double _time_at_tempo (const double& tempo) const; 270 271 double _tempo_at_pulse (const double& pulse) const; 272 double _pulse_at_tempo (const double& tempo) const; 273 274 double _pulse_at_time (const double& time) const; 275 double _time_at_pulse (const double& pulse) const; 276 277 /* this value provides a fractional offset into the bar in which 278 the tempo section is located in. A value of 0.0 indicates that 279 it occurs on the first beat of the bar, a value of 0.5 indicates 280 that it occurs halfway through the bar and so on. 281 282 this enables us to keep the tempo change at the same relative 283 position within the bar if/when the meter changes. 284 */ 285 286 double _c; 287 bool _active; 288 bool _locked_to_meter; 289 bool _clamped; 290 Timecode::BBT_Time _legacy_bbt; 291 }; 292 293 typedef std::list<MetricSection*> Metrics; 294 295 /** Helper class to keep track of the Meter *AND* Tempo in effect 296 at a given point in time. 297 */ 298 class LIBARDOUR_API TempoMetric { 299 public: TempoMetric(const Meter & m,const Tempo & t)300 TempoMetric (const Meter& m, const Tempo& t) 301 : _meter (&m), _tempo (&t), _minute (0.0), _pulse (0.0) {} 302 set_tempo(const Tempo & t)303 void set_tempo (const Tempo& t) { _tempo = &t; } set_meter(const Meter & m)304 void set_meter (const Meter& m) { _meter = &m; } set_minute(double m)305 void set_minute (double m) { _minute = m; } set_pulse(const double & p)306 void set_pulse (const double& p) { _pulse = p; } 307 set_metric(const MetricSection * section)308 void set_metric (const MetricSection* section) { 309 const MeterSection* meter; 310 const TempoSection* tempo; 311 if ((meter = dynamic_cast<const MeterSection*>(section))) { 312 set_meter(*meter); 313 } else if ((tempo = dynamic_cast<const TempoSection*>(section))) { 314 set_tempo(*tempo); 315 } 316 317 set_minute (section->minute()); 318 set_pulse (section->pulse()); 319 } 320 meter()321 const Meter& meter() const { return *_meter; } tempo()322 const Tempo& tempo() const { return *_tempo; } minute()323 double minute() const { return _minute; } pulse()324 const double& pulse() const { return _pulse; } 325 326 private: 327 const Meter* _meter; 328 const Tempo* _tempo; 329 double _minute; 330 double _pulse; 331 }; 332 333 /** Tempo Map - mapping of timecode to musical time. 334 * convert audio-samples, sample-rate to Bar/Beat/Tick, Meter/Tempo 335 */ 336 class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible 337 { 338 public: 339 TempoMap (samplecnt_t sample_rate); 340 ~TempoMap(); 341 342 TempoMap& operator= (TempoMap const &); 343 344 /* measure-based stuff */ 345 346 enum BBTPointType { 347 Bar, 348 Beat, 349 }; 350 351 struct BBTPoint { 352 Meter meter; 353 Tempo tempo; 354 samplepos_t sample; 355 uint32_t bar; 356 uint32_t beat; 357 double qn; 358 BBTPointBBTPoint359 BBTPoint (const MeterSection& m, const Tempo& t, samplepos_t f, 360 uint32_t b, uint32_t e, double qnote) 361 : meter (m), tempo (t), sample (f), bar (b), beat (e), qn (qnote) {} 362 bbtBBTPoint363 Timecode::BBT_Time bbt() const { return Timecode::BBT_Time (bar, beat, 0); } BBT_TimeBBTPoint364 operator Timecode::BBT_Time() const { return bbt(); } samplepos_tBBTPoint365 operator samplepos_t() const { return sample; } is_barBBTPoint366 bool is_bar() const { return beat == 1; } 367 }; 368 apply_with_metrics(T & obj,void (T::* method)(const Metrics &))369 template<class T> void apply_with_metrics (T& obj, void (T::*method)(const Metrics&)) { 370 Glib::Threads::RWLock::ReaderLock lm (lock); 371 (obj.*method)(_metrics); 372 } 373 374 void get_grid (std::vector<BBTPoint>&, 375 samplepos_t start, samplepos_t end, uint32_t bar_mod = 0); 376 377 void midi_clock_beat_at_of_after (samplepos_t const pos, samplepos_t& clk_pos, uint32_t& clk_beat); 378 default_tempo()379 static const Tempo& default_tempo() { return _default_tempo; } default_meter()380 static const Meter& default_meter() { return _default_meter; } 381 382 /* because tempi may be ramped, this is only valid for the instant requested.*/ 383 double samples_per_quarter_note_at (const samplepos_t, const samplecnt_t sr) const; 384 385 const TempoSection& tempo_section_at_sample (samplepos_t sample) const; 386 TempoSection& tempo_section_at_sample (samplepos_t sample); 387 const MeterSection& meter_section_at_sample (samplepos_t sample) const; 388 const MeterSection& meter_section_at_beat (double beat) const; 389 390 TempoSection* previous_tempo_section (TempoSection*) const; 391 TempoSection* next_tempo_section (TempoSection*) const; 392 393 /** add a tempo section locked to pls. ignored values will be set in recompute_tempi() 394 * @param pulse pulse position of new section. ignored if \p pls == AudioTime 395 * @param sample frame position of new section. ignored if \p pls == MusicTime 396 * @param pls the position lock style 397 */ 398 TempoSection* add_tempo (const Tempo&, const double& pulse, const samplepos_t sample, PositionLockStyle pls); 399 400 /** add a meter section locked to \p pls . ignored values will be set in recompute_meters() 401 * @param meter the Meter to be added 402 * @param where bbt position of new section 403 * @param sample frame position of new section. ignored if \p pls == MusicTime 404 * 405 * note that \p sample may also be ignored if it would create an un-solvable map 406 * (previous audio-locked tempi may place the requested beat at an earlier time than sample) 407 * in which case the new meter will be placed at the specified BBT. 408 * @param pls the position lock style 409 * 410 * adding an audio-locked meter will add a meter-locked tempo section at the meter position. 411 * the meter-locked tempo tempo will be the Tempo at the beat 412 */ 413 MeterSection* add_meter (const Meter& meter, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls); 414 415 void remove_tempo (const TempoSection&, bool send_signal); 416 void remove_meter (const MeterSection&, bool send_signal); 417 418 void replace_tempo (TempoSection&, const Tempo&, const double& pulse, const samplepos_t sample, PositionLockStyle pls); 419 420 void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls); 421 422 MusicSample round_to_bar (samplepos_t sample, RoundMode dir); 423 MusicSample round_to_beat (samplepos_t sample, RoundMode dir); 424 MusicSample round_to_quarter_note_subdivision (samplepos_t fr, int sub_num, RoundMode dir); 425 426 void set_length (samplepos_t samples); 427 428 XMLNode& get_state (void); 429 int set_state (const XMLNode&, int version); 430 431 void dump (std::ostream&) const; 432 void clear (); 433 434 TempoMetric metric_at (Timecode::BBT_Time bbt) const; 435 436 /** Return the TempoMetric at sample @p t, and point @p last to the latest 437 * metric change <= t, if it is non-NULL. 438 */ 439 TempoMetric metric_at (samplepos_t, Metrics::const_iterator* last=NULL) const; 440 metrics_end()441 Metrics::const_iterator metrics_end() { return _metrics.end(); } 442 443 void change_existing_tempo_at (samplepos_t, double bpm, double note_type, double end_ntpm); 444 void change_initial_tempo (double ntpm, double note_type, double end_ntpm); 445 446 void insert_time (samplepos_t, samplecnt_t); 447 bool remove_time (samplepos_t where, samplecnt_t amount); //returns true if anything was moved 448 449 int n_tempos () const; 450 int n_meters () const; 451 sample_rate()452 samplecnt_t sample_rate () const { return _sample_rate; } 453 454 /* TEMPO- AND METER-SENSITIVE FUNCTIONS 455 456 bbt_at_sample(), sample_at_bbt(), beat_at_sample(), sample_at_beat() 457 and bbt_duration_at() 458 are all sensitive to tempo and meter, and will give answers 459 that align with the grid formed by tempo and meter sections. 460 461 They SHOULD NOT be used to determine the position of events 462 whose location is canonically defined in Temporal::Beats. 463 */ 464 465 double beat_at_sample (const samplecnt_t sample) const; 466 samplepos_t sample_at_beat (const double& beat) const; 467 468 const Meter& meter_at_sample (samplepos_t) const; 469 470 /* bbt - it's nearly always better to use meter-based beat (above) 471 unless tick resolution is desirable. 472 */ 473 Timecode::BBT_Time bbt_at_sample (samplepos_t when) const; 474 Timecode::BBT_Time bbt_at_sample_rt (samplepos_t when) const; 475 samplepos_t sample_at_bbt (const Timecode::BBT_Time&); 476 477 double beat_at_bbt (const Timecode::BBT_Time& bbt); 478 Timecode::BBT_Time bbt_at_beat (const double& beats); 479 480 double quarter_note_at_bbt (const Timecode::BBT_Time& bbt); 481 double quarter_note_at_bbt_rt (const Timecode::BBT_Time& bbt); 482 Timecode::BBT_Time bbt_at_quarter_note (const double& quarter_note); 483 484 samplecnt_t bbt_duration_at (samplepos_t, const Timecode::BBT_Time&, int dir); 485 samplepos_t samplepos_plus_bbt (samplepos_t pos, Timecode::BBT_Time b) const; 486 487 /* TEMPO-SENSITIVE FUNCTIONS 488 489 These next 2 functions will all take tempo in account and should be 490 used to determine position (and in the last case, distance in beats) 491 when tempo matters but meter does not. 492 493 They SHOULD be used to determine the position of events 494 whose location is canonically defined in Temporal::Beats. 495 */ 496 497 samplepos_t samplepos_plus_qn (samplepos_t, Temporal::Beats) const; 498 Temporal::Beats framewalk_to_qn (samplepos_t pos, samplecnt_t distance) const; 499 500 /* quarter note related functions are also tempo-sensitive and ignore meter. 501 quarter notes may be compared with and assigned to Temporal::Beats. 502 */ 503 double quarter_note_at_sample (const samplepos_t sample) const; 504 double quarter_note_at_sample_rt (const samplepos_t sample) const; 505 samplepos_t sample_at_quarter_note (const double quarter_note) const; 506 507 samplecnt_t samples_between_quarter_notes (const double start, const double end) const; 508 double quarter_notes_between_samples (const samplecnt_t start, const samplecnt_t end) const; 509 510 double quarter_note_at_beat (const double beat) const; 511 double beat_at_quarter_note (const double beat) const; 512 513 /* obtain a musical subdivision via a sample position and magic note divisor.*/ 514 double exact_qn_at_sample (const samplepos_t sample, const int32_t sub_num) const; 515 double exact_beat_at_sample (const samplepos_t sample, const int32_t sub_num) const; 516 517 Tempo tempo_at_sample (const samplepos_t sample) const; 518 samplepos_t sample_at_tempo (const Tempo& tempo) const; 519 Tempo tempo_at_quarter_note (const double& beat) const; 520 double quarter_note_at_tempo (const Tempo& tempo) const; 521 522 void gui_set_tempo_position (TempoSection*, const samplepos_t sample, const int& sub_num); 523 void gui_set_meter_position (MeterSection*, const samplepos_t sample); 524 bool gui_change_tempo (TempoSection*, const Tempo& bpm); 525 void gui_stretch_tempo (TempoSection* tempo, const samplepos_t sample, const samplepos_t end_sample, const double start_qnote, const double end_qnote); 526 void gui_stretch_tempo_end (TempoSection* tempo, const samplepos_t sample, const samplepos_t end_sample); 527 bool gui_twist_tempi (TempoSection* first, const Tempo& bpm, const samplepos_t sample, const samplepos_t end_sample); 528 529 std::pair<double, samplepos_t> predict_tempo_position (TempoSection* section, const Timecode::BBT_Time& bbt); 530 bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt); 531 532 PBD::Signal1<void,const PBD::PropertyChange&> MetricPositionChanged; 533 void fix_legacy_session(); 534 void fix_legacy_end_session(); 535 536 samplepos_t music_origin (); 537 538 private: 539 /* prevent copy construction */ 540 TempoMap (TempoMap const&); 541 542 TempoSection* previous_tempo_section_locked (const Metrics& metrics, TempoSection*) const; 543 TempoSection* next_tempo_section_locked (const Metrics& metrics, TempoSection*) const; 544 545 double beat_at_minute_locked (const Metrics& metrics, const double& minute) const; 546 double minute_at_beat_locked (const Metrics& metrics, const double& beat) const; 547 548 double pulse_at_beat_locked (const Metrics& metrics, const double& beat) const; 549 double beat_at_pulse_locked (const Metrics& metrics, const double& pulse) const; 550 551 double pulse_at_minute_locked (const Metrics& metrics, const double& minute) const; 552 double minute_at_pulse_locked (const Metrics& metrics, const double& pulse) const; 553 554 Tempo tempo_at_minute_locked (const Metrics& metrics, const double& minute) const; 555 double minute_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const; 556 557 Tempo tempo_at_pulse_locked (const Metrics& metrics, const double& pulse) const; 558 double pulse_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const; 559 560 Timecode::BBT_Time bbt_at_minute_locked (const Metrics& metrics, const double& minute) const; 561 double minute_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time&) const; 562 563 double beat_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const ; 564 Timecode::BBT_Time bbt_at_beat_locked (const Metrics& metrics, const double& beats) const; 565 566 double pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const; 567 Timecode::BBT_Time bbt_at_pulse_locked (const Metrics& metrics, const double& pulse) const; 568 569 double minutes_between_quarter_notes_locked (const Metrics& metrics, const double start_qn, const double end_qn) const; 570 double quarter_notes_between_samples_locked (const Metrics& metrics, const samplecnt_t start, const samplecnt_t end) const; 571 572 const TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute) const; 573 TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute); 574 const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const; 575 576 const MeterSection& meter_section_at_minute_locked (const Metrics& metrics, double minute) const; 577 const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const; 578 579 bool check_solved (const Metrics& metrics) const; 580 bool set_active_tempi (const Metrics& metrics, const samplepos_t sample); 581 582 bool solve_map_minute (Metrics& metrics, TempoSection* section, const double& minute); 583 bool solve_map_pulse (Metrics& metrics, TempoSection* section, const double& pulse); 584 bool solve_map_minute (Metrics& metrics, MeterSection* section, const double& minute); 585 bool solve_map_bbt (Metrics& metrics, MeterSection* section, const Timecode::BBT_Time& bbt); 586 587 double exact_beat_at_sample_locked (const Metrics& metrics, const samplepos_t sample, const int32_t sub_num) const; 588 double exact_qn_at_sample_locked (const Metrics& metrics, const samplepos_t sample, const int32_t sub_num) const; 589 590 double minute_at_sample (const samplepos_t sample) const; 591 samplepos_t sample_at_minute (const double minute) const; 592 593 friend class ::BBTTest; 594 friend class ::FrameposPlusBeatsTest; 595 friend class ::FrameposMinusBeatsTest; 596 friend class ::TempoTest; 597 598 static Tempo _default_tempo; 599 static Meter _default_meter; 600 601 Metrics _metrics; 602 samplecnt_t _sample_rate; 603 mutable Glib::Threads::RWLock lock; 604 605 void recompute_tempi (Metrics& metrics); 606 void recompute_meters (Metrics& metrics); 607 void recompute_map (Metrics& metrics, samplepos_t end = -1); 608 609 MusicSample round_to_type (samplepos_t fr, RoundMode dir, BBTPointType); 610 611 const MeterSection& first_meter() const; 612 MeterSection& first_meter(); 613 const TempoSection& first_tempo() const; 614 TempoSection& first_tempo(); 615 616 void do_insert (MetricSection* section); 617 618 TempoSection* add_tempo_locked (const Tempo&, double pulse, double minute 619 , PositionLockStyle pls, bool recompute, bool locked_to_meter = false, bool clamped = false); 620 621 MeterSection* add_meter_locked (const Meter&, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls, bool recompute); 622 623 bool remove_tempo_locked (const TempoSection&); 624 bool remove_meter_locked (const MeterSection&); 625 626 TempoSection* copy_metrics_and_point (const Metrics& metrics, Metrics& copy, TempoSection* section) const; 627 MeterSection* copy_metrics_and_point (const Metrics& metrics, Metrics& copy, MeterSection* section) const; 628 }; 629 630 }; /* namespace ARDOUR */ 631 632 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Meter&); 633 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Tempo&); 634 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::MetricSection&); 635 636 namespace PBD { 637 DEFINE_ENUM_CONVERT (ARDOUR::TempoSection::Type) 638 } 639 640 #endif /* __ardour_tempo_h__ */ 641