Fix some more doxygen warnings
[ardour.git] / libs / ardour / ardour / tempo.h
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
68                 : _note_types_per_minute (npm), _note_type (type), _end_note_types_per_minute (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
72         double note_types_per_minute () const { return _note_types_per_minute; }
73         double note_types_per_minute (double note_type) const { return (_note_types_per_minute / _note_type) * note_type; }
74         void set_note_types_per_minute (double npm) { _note_types_per_minute = npm; }
75         double note_type () const { return _note_type; }
76
77         double quarter_notes_per_minute () const { return note_types_per_minute (4.0); }
78         double pulses_per_minute () const { return note_types_per_minute (1.0); }
79
80         double end_note_types_per_minute () const { return _end_note_types_per_minute; }
81         double end_note_types_per_minute (double note_type) const { return (_end_note_types_per_minute / _note_type) * note_type; }
82         void set_end_note_types_per_minute (double npm) { _end_note_types_per_minute = npm; }
83
84         double end_quarter_notes_per_minute () const { return end_note_types_per_minute (4.0); }
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          */
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          */
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:
111         Meter (double dpb, double bt)
112                 : _divisions_per_bar (dpb), _note_type (bt) {}
113
114         double divisions_per_bar () const { return _divisions_per_bar; }
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:
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
142         virtual ~MetricSection() {}
143
144         const double& pulse () const { return _pulse; }
145         void set_pulse (double pulse) { _pulse = pulse; }
146
147         double minute() const { return _minute; }
148         virtual void set_minute (double m) {
149                 _minute = m;
150         }
151
152         samplepos_t sample () const { return sample_at_minute (_minute); }
153
154         void set_initial (bool yn) { _initial = yn; }
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
165         PositionLockStyle position_lock_style () const { return _position_lock_style; }
166         void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; }
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:
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
197         void set_beat (std::pair<double, Timecode::BBT_Time>& w) {
198                 _beat = w.first;
199                 _bbt = w.second;
200         }
201
202         const Timecode::BBT_Time& bbt() const { return _bbt; }
203         const double& beat () const { return _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
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
228         double c () const { return _c; }
229         void set_c (double c) { _c = c; }
230
231         Type type () const { if (note_types_per_minute() == end_note_types_per_minute()) { return Constant; } else { return Ramp; } }
232
233         bool active () const { return _active; }
234         void set_active (bool yn) { _active = yn; }
235
236         bool locked_to_meter ()  const { return _locked_to_meter; }
237         void set_locked_to_meter (bool yn) { _locked_to_meter = yn; }
238
239         bool clamped ()  const { return _clamped; }
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
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:
300         TempoMetric (const Meter& m, const Tempo& t)
301                 : _meter (&m), _tempo (&t), _minute (0.0), _pulse (0.0) {}
302
303         void set_tempo (const Tempo& t)              { _tempo = &t; }
304         void set_meter (const Meter& m)              { _meter = &m; }
305         void set_minute (double m)                   { _minute = m; }
306         void set_pulse (const double& p)             { _pulse = p; }
307
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
321         const Meter&              meter() const { return *_meter; }
322         const Tempo&              tempo() const { return *_tempo; }
323         double                    minute() const { return _minute; }
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
359                 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
363                 Timecode::BBT_Time bbt() const { return Timecode::BBT_Time (bar, beat, 0); }
364                 operator Timecode::BBT_Time() const { return bbt(); }
365                 operator samplepos_t() const { return sample; }
366                 bool is_bar() const { return beat == 1; }
367         };
368
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         static const Tempo& default_tempo() { return _default_tempo; }
378         static const Meter& default_meter() { return _default_meter; }
379
380         /* because tempi may be ramped, this is only valid for the instant requested.*/
381         double samples_per_quarter_note_at (const samplepos_t, const samplecnt_t sr) const;
382
383         const TempoSection& tempo_section_at_sample (samplepos_t sample) const;
384         TempoSection& tempo_section_at_sample (samplepos_t sample);
385         const MeterSection& meter_section_at_sample (samplepos_t sample) const;
386         const MeterSection& meter_section_at_beat (double beat) const;
387
388         TempoSection* previous_tempo_section (TempoSection*) const;
389         TempoSection* next_tempo_section (TempoSection*) const;
390
391         /** add a tempo section locked to pls. ignored values will be set in recompute_tempi()
392          * @param pulse pulse position of new section. ignored if \param pls == AudioTime
393          * @param sample frame position of new section. ignored if \param pls == MusicTime
394          * @param pls the position lock style
395          */
396         TempoSection* add_tempo (const Tempo&, const double& pulse, const samplepos_t sample, PositionLockStyle pls);
397
398         /** add a meter section locked to \param pls . ignored values will be set in recompute_meters()
399          * @param meter the Meter to be added
400          * @param where bbt position of new section
401          * @param sample frame position of new section. ignored if \param pls == MusicTime
402          *
403          * note that \param sample may also be ignored if it would create an un-solvable map
404          * (previous audio-locked tempi may place the requested beat at an earlier time than sample)
405          * in which case the new meter will be placed at the specified BBT.
406          * @param pls the position lock style
407          *
408          * adding an audio-locked meter will add a meter-locked tempo section at the meter position.
409          * the meter-locked tempo tempo will be the Tempo at the beat
410          */
411         MeterSection* add_meter (const Meter& meter, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls);
412
413         void remove_tempo (const TempoSection&, bool send_signal);
414         void remove_meter (const MeterSection&, bool send_signal);
415
416         void replace_tempo (TempoSection&, const Tempo&, const double& pulse, const samplepos_t sample, PositionLockStyle pls);
417
418         void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls);
419
420         MusicSample round_to_bar  (samplepos_t sample, RoundMode dir);
421         MusicSample round_to_beat (samplepos_t sample, RoundMode dir);
422         MusicSample round_to_quarter_note_subdivision (samplepos_t fr, int sub_num, RoundMode dir);
423
424         void set_length (samplepos_t samples);
425
426         XMLNode& get_state (void);
427         int set_state (const XMLNode&, int version);
428
429         void dump (std::ostream&) const;
430         void clear ();
431
432         TempoMetric metric_at (Timecode::BBT_Time bbt) const;
433
434         /** Return the TempoMetric at sample @p t, and point @p last to the latest
435          * metric change <= t, if it is non-NULL.
436          */
437         TempoMetric metric_at (samplepos_t, Metrics::const_iterator* last=NULL) const;
438
439         Metrics::const_iterator metrics_end() { return _metrics.end(); }
440
441         void change_existing_tempo_at (samplepos_t, double bpm, double note_type, double end_ntpm);
442         void change_initial_tempo (double ntpm, double note_type, double end_ntpm);
443
444         void insert_time (samplepos_t, samplecnt_t);
445         bool remove_time (samplepos_t where, samplecnt_t amount);  //returns true if anything was moved
446
447         int n_tempos () const;
448         int n_meters () const;
449
450         samplecnt_t sample_rate () const { return _sample_rate; }
451
452         /* TEMPO- AND METER-SENSITIVE FUNCTIONS
453
454            bbt_at_sample(), sample_at_bbt(), beat_at_sample(), sample_at_beat()
455            and bbt_duration_at()
456            are all sensitive to tempo and meter, and will give answers
457            that align with the grid formed by tempo and meter sections.
458
459            They SHOULD NOT be used to determine the position of events
460            whose location is canonically defined in Temporal::Beats.
461         */
462
463         double beat_at_sample (const samplecnt_t sample) const;
464         samplepos_t sample_at_beat (const double& beat) const;
465
466         const Meter& meter_at_sample (samplepos_t) const;
467
468         /* bbt - it's nearly always better to use meter-based beat (above)
469            unless tick resolution is desirable.
470         */
471         Timecode::BBT_Time bbt_at_sample (samplepos_t when);
472         Timecode::BBT_Time bbt_at_sample_rt (samplepos_t when);
473         samplepos_t sample_at_bbt (const Timecode::BBT_Time&);
474
475         double beat_at_bbt (const Timecode::BBT_Time& bbt);
476         Timecode::BBT_Time bbt_at_beat (const double& beats);
477
478         double quarter_note_at_bbt (const Timecode::BBT_Time& bbt);
479         double quarter_note_at_bbt_rt (const Timecode::BBT_Time& bbt);
480         Timecode::BBT_Time bbt_at_quarter_note (const double& quarter_note);
481
482         samplecnt_t bbt_duration_at (samplepos_t, const Timecode::BBT_Time&, int dir);
483         samplepos_t samplepos_plus_bbt (samplepos_t pos, Timecode::BBT_Time b) const;
484
485         /* TEMPO-SENSITIVE FUNCTIONS
486
487            These next 2 functions will all take tempo in account and should be
488            used to determine position (and in the last case, distance in beats)
489            when tempo matters but meter does not.
490
491            They SHOULD be used to determine the position of events
492            whose location is canonically defined in Temporal::Beats.
493         */
494
495         samplepos_t samplepos_plus_qn (samplepos_t, Temporal::Beats) const;
496         Temporal::Beats framewalk_to_qn (samplepos_t pos, samplecnt_t distance) const;
497
498         /* quarter note related functions are also tempo-sensitive and ignore meter.
499            quarter notes may be compared with and assigned to Temporal::Beats.
500         */
501         double quarter_note_at_sample (const samplepos_t sample) const;
502         double quarter_note_at_sample_rt (const samplepos_t sample) const;
503         samplepos_t sample_at_quarter_note (const double quarter_note) const;
504
505         samplecnt_t samples_between_quarter_notes (const double start, const double end) const;
506         double     quarter_notes_between_samples (const samplecnt_t start, const samplecnt_t end) const;
507
508         double quarter_note_at_beat (const double beat) const;
509         double beat_at_quarter_note (const double beat) const;
510
511         /* obtain a musical subdivision via a sample position and magic note divisor.*/
512         double exact_qn_at_sample (const samplepos_t sample, const int32_t sub_num) const;
513         double exact_beat_at_sample (const samplepos_t sample, const int32_t sub_num) const;
514
515         Tempo tempo_at_sample (const samplepos_t sample) const;
516         samplepos_t sample_at_tempo (const Tempo& tempo) const;
517         Tempo tempo_at_quarter_note (const double& beat) const;
518         double quarter_note_at_tempo (const Tempo& tempo) const;
519
520         void gui_set_tempo_position (TempoSection*, const samplepos_t sample, const int& sub_num);
521         void gui_set_meter_position (MeterSection*, const samplepos_t sample);
522         bool gui_change_tempo (TempoSection*, const Tempo& bpm);
523         void gui_stretch_tempo (TempoSection* tempo, const samplepos_t sample, const samplepos_t end_sample, const double start_qnote, const double end_qnote);
524         void gui_stretch_tempo_end (TempoSection* tempo, const samplepos_t sample, const samplepos_t end_sample);
525         bool gui_twist_tempi (TempoSection* first, const Tempo& bpm, const samplepos_t sample, const samplepos_t end_sample);
526
527         std::pair<double, samplepos_t> predict_tempo_position (TempoSection* section, const Timecode::BBT_Time& bbt);
528         bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt);
529
530         PBD::Signal1<void,const PBD::PropertyChange&> MetricPositionChanged;
531         void fix_legacy_session();
532         void fix_legacy_end_session();
533
534         samplepos_t music_origin ();
535
536 private:
537         /* prevent copy construction */
538         TempoMap (TempoMap const&);
539
540         TempoSection* previous_tempo_section_locked (const Metrics& metrics, TempoSection*) const;
541         TempoSection* next_tempo_section_locked (const Metrics& metrics, TempoSection*) const;
542
543         double beat_at_minute_locked (const Metrics& metrics, const double& minute) const;
544         double minute_at_beat_locked (const Metrics& metrics, const double& beat) const;
545
546         double pulse_at_beat_locked (const Metrics& metrics, const double& beat) const;
547         double beat_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
548
549         double pulse_at_minute_locked (const Metrics& metrics, const double& minute) const;
550         double minute_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
551
552         Tempo tempo_at_minute_locked (const Metrics& metrics, const double& minute) const;
553         double minute_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const;
554
555         Tempo tempo_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
556         double pulse_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const;
557
558         Timecode::BBT_Time bbt_at_minute_locked (const Metrics& metrics, const double& minute) const;
559         double minute_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time&) const;
560
561         double beat_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const ;
562         Timecode::BBT_Time bbt_at_beat_locked (const Metrics& metrics, const double& beats) const;
563
564         double pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const;
565         Timecode::BBT_Time bbt_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
566
567         double minutes_between_quarter_notes_locked (const Metrics& metrics, const double start_qn, const double end_qn) const;
568         double quarter_notes_between_samples_locked (const Metrics& metrics, const samplecnt_t  start, const samplecnt_t end) const;
569
570         const TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute) const;
571         TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute);
572         const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const;
573
574         const MeterSection& meter_section_at_minute_locked (const Metrics& metrics, double minute) const;
575         const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const;
576
577         bool check_solved (const Metrics& metrics) const;
578         bool set_active_tempi (const Metrics& metrics, const samplepos_t sample);
579
580         bool solve_map_minute (Metrics& metrics, TempoSection* section, const double& minute);
581         bool solve_map_pulse (Metrics& metrics, TempoSection* section, const double& pulse);
582         bool solve_map_minute (Metrics& metrics, MeterSection* section, const double& minute);
583         bool solve_map_bbt (Metrics& metrics, MeterSection* section, const Timecode::BBT_Time& bbt);
584
585         double exact_beat_at_sample_locked (const Metrics& metrics, const samplepos_t sample, const int32_t sub_num) const;
586         double exact_qn_at_sample_locked (const Metrics& metrics, const samplepos_t sample, const int32_t sub_num) const;
587
588         double minute_at_sample (const samplepos_t sample) const;
589         samplepos_t sample_at_minute (const double minute) const;
590
591         friend class ::BBTTest;
592         friend class ::FrameposPlusBeatsTest;
593         friend class ::FrameposMinusBeatsTest;
594         friend class ::TempoTest;
595
596         static Tempo    _default_tempo;
597         static Meter    _default_meter;
598
599         Metrics                       _metrics;
600         samplecnt_t                   _sample_rate;
601         mutable Glib::Threads::RWLock lock;
602
603         void recompute_tempi (Metrics& metrics);
604         void recompute_meters (Metrics& metrics);
605         void recompute_map (Metrics& metrics, samplepos_t end = -1);
606
607         MusicSample round_to_type (samplepos_t fr, RoundMode dir, BBTPointType);
608
609         const MeterSection& first_meter() const;
610         MeterSection&       first_meter();
611         const TempoSection& first_tempo() const;
612         TempoSection&       first_tempo();
613
614         void do_insert (MetricSection* section);
615
616         TempoSection* add_tempo_locked (const Tempo&, double pulse, double minute
617                                         , PositionLockStyle pls, bool recompute, bool locked_to_meter = false, bool clamped = false);
618
619         MeterSection* add_meter_locked (const Meter&, const Timecode::BBT_Time& where, samplepos_t sample, PositionLockStyle pls, bool recompute);
620
621         bool remove_tempo_locked (const TempoSection&);
622         bool remove_meter_locked (const MeterSection&);
623
624         TempoSection* copy_metrics_and_point (const Metrics& metrics, Metrics& copy, TempoSection* section) const;
625         MeterSection* copy_metrics_and_point (const Metrics& metrics, Metrics& copy, MeterSection* section) const;
626 };
627
628 }; /* namespace ARDOUR */
629
630 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Meter&);
631 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Tempo&);
632 LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::MetricSection&);
633
634 namespace PBD {
635         DEFINE_ENUM_CONVERT (ARDOUR::TempoSection::Type)
636 }
637
638 #endif /* __ardour_tempo_h__ */