diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-12-21 14:48:25 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-12-21 14:48:25 +0000 |
commit | 2315c433e276110d8c1ac7cc5c8935c31b6f5879 (patch) | |
tree | e588fa9f1be957f6e9995c142b94911718378ff9 | |
parent | 1fca71fd283c912bbb0d88fcb95fb8e3b330c09e (diff) |
new tempo handling from drmoore; don't follow playhead when doing requested_return stuff; if selected marker is end of range, do the right thing when computing edit point
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2806 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/editor.cc | 18 | ||||
-rw-r--r-- | gtk2_ardour/editor_mixer.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_tempodisplay.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/tempo_dialog.cc | 100 | ||||
-rw-r--r-- | gtk2_ardour/tempo_dialog.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 30 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 20 | ||||
-rw-r--r-- | libs/ardour/ladspa_plugin.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 2 | ||||
-rw-r--r-- | libs/ardour/tempo.cc | 37 |
10 files changed, 171 insertions, 57 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 14c89e8ee4..87b5f16d7f 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2731,7 +2731,7 @@ Editor::setup_toolbar () ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session")); zoom_focus_selector.set_name ("ZoomFocusSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Playhead", FUDGE, 0); + Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, _("Playhead"), FUDGE, 0); set_popdown_strings (zoom_focus_selector, zoom_focus_strings); zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus")); @@ -2745,19 +2745,19 @@ Editor::setup_toolbar () snap_box.set_border_width (2); snap_type_selector.set_name ("SnapTypeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, _("SMPTE Seconds"), 2+FUDGE, 10); set_popdown_strings (snap_type_selector, snap_type_strings); snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Snap/Grid Units")); snap_mode_selector.set_name ("SnapModeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, _("Magnetic Snap"), 2+FUDGE, 10); set_popdown_strings (snap_mode_selector, snap_mode_strings); snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (snap_mode_selector, _("Snap/Grid Mode")); edit_point_selector.set_name ("SnapModeSelector"); - Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, "Playhead", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, _("Playhead"), 2+FUDGE, 10); set_popdown_strings (edit_point_selector, edit_point_strings); edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point")); @@ -4140,10 +4140,14 @@ Editor::get_preferred_edit_position (bool ignore_playhead) case EditAtSelectedMarker: if (!selection->markers.empty()) { - bool whocares; - Location* loc = find_location_from_marker (selection->markers.front(), whocares); + bool is_start; + Location* loc = find_location_from_marker (selection->markers.front(), is_start); if (loc) { - where = loc->start(); + if (is_start) { + where = loc->start(); + } else { + where = loc->end(); + } break; } } diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 0e41fcaeac..2f6e9d5704 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -183,7 +183,7 @@ Editor::update_current_screen () /* only update if the playhead is on screen or we are following it */ - if (_follow_playhead) { + if (_follow_playhead && session->requested_return_frame() < 0) { playhead_cursor->canvas_item.show(); diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 854f670121..26363b9997 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -308,13 +308,14 @@ Editor::mouse_add_new_tempo_event (nframes_t frame) BBT_Time requested; bpm = tempo_dialog.get_bpm (); + double nt = tempo_dialog.get_note_type(); bpm = max (0.01, bpm); tempo_dialog.get_bbt_time (requested); begin_reversible_command (_("add tempo mark")); XMLNode &before = map.get_state(); - map.add_tempo (Tempo (bpm), requested); + map.add_tempo (Tempo (bpm,nt), requested); XMLNode &after = map.get_state(); session->add_command(new MementoCommand<TempoMap>(map, &before, &after)); commit_reversible_command (); @@ -429,13 +430,14 @@ Editor::edit_tempo_section (TempoSection* section) } double bpm = tempo_dialog.get_bpm (); + double nt = tempo_dialog.get_note_type (); BBT_Time when; tempo_dialog.get_bbt_time(when); bpm = max (0.01, bpm); begin_reversible_command (_("replace tempo mark")); XMLNode &before = session->tempo_map().get_state(); - session->tempo_map().replace_tempo (*section, Tempo (bpm)); + session->tempo_map().replace_tempo (*section, Tempo (bpm,nt)); session->tempo_map().move_tempo (*section, when); XMLNode &after = session->tempo_map().get_state(); session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after)); diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc index aee3dc44e6..9d5ba926c5 100644 --- a/gtk2_ardour/tempo_dialog.cc +++ b/gtk2_ardour/tempo_dialog.cc @@ -37,6 +37,7 @@ TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action) bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0, 1.0), bpm_spinner (bpm_adjustment), bpm_frame (_("Beats per minute")), + note_frame (_("BPM denominator")), ok_button (action), cancel_button (_("Cancel")), when_bar_label (_("Bar")), @@ -48,7 +49,7 @@ TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action) Tempo tempo (map.tempo_at (frame)); map.bbt_time (frame, when); - init (when, tempo.beats_per_minute(), true); + init (when, tempo.beats_per_minute(), tempo.note_type(), true); } TempoDialog::TempoDialog (TempoSection& section, const string & action) @@ -63,23 +64,62 @@ TempoDialog::TempoDialog (TempoSection& section, const string & action) when_table (2, 2), when_frame (_("Location")) { - init (section.start(), section.beats_per_minute(), section.movable()); + init (section.start(), section.beats_per_minute(), section.note_type(), section.movable()); } void -TempoDialog::init (const BBT_Time& when, double bpm, bool movable) +TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool movable) { bpm_spinner.set_numeric (true); bpm_spinner.set_digits (2); bpm_spinner.set_wrap (true); bpm_spinner.set_value (bpm); + strings.push_back (_("whole (1)")); + strings.push_back (_("second (2)")); + strings.push_back (_("third (3)")); + strings.push_back (_("quarter (4)")); + strings.push_back (_("eighth (8)")); + strings.push_back (_("sixteenth (16)")); + strings.push_back (_("thirty-second (32)")); + + /* the string here needs to be the longest one to display */ + const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button + // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical + // descender to make sure the height gets computed properly. + Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirtq-second (32)", 7+FUDGE, 15); + + set_popdown_strings (note_types, strings); + + if (note_type==1.0f) + note_types.set_active_text (_("whole (1)")); + else if (note_type==2.0f) + note_types.set_active_text (_("second (2)")); + else if (note_type==3.0f) + note_types.set_active_text (_("third (3)")); + else if (note_type==4.0f) + note_types.set_active_text (_("quarter (4)")); + else if (note_type==8.0f) + note_types.set_active_text (_("eighth (8)")); + else if (note_type==16.0f) + note_types.set_active_text (_("sixteenth (16)")); + else if (note_type==32.0f) + note_types.set_active_text (_("thirty-second (32)")); + else + note_types.set_active_text (_("quarter (4)")); + hspacer1.set_border_width (5); hspacer1.pack_start (bpm_spinner, false, false); vspacer1.set_border_width (5); vspacer1.pack_start (hspacer1, false, false); + hspacer2.set_border_width (5); + hspacer2.pack_start (note_types, false, false); + vspacer2.set_border_width (5); + vspacer2.pack_start (hspacer2, false, false); + bpm_frame.add (vspacer1); + note_frame.add (vspacer2); if (movable) { snprintf (buf, sizeof (buf), "%" PRIu32, when.bars); @@ -115,9 +155,12 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable) bpm_frame.set_name ("MetricDialogFrame"); bpm_spinner.set_name ("MetricEntry"); + note_frame.set_name ("MetricDialogFrame"); + get_vbox()->set_border_width (12); get_vbox()->pack_start (bpm_frame, false, false); - + get_vbox()->pack_start (note_frame, false, false); + add_button (Stock::CANCEL, RESPONSE_CANCEL); add_button (Stock::APPLY, RESPONSE_ACCEPT); set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); @@ -131,6 +174,7 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable) bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT)); bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false); bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false); + note_types.signal_changed().connect (mem_fun (*this, &TempoDialog::note_types_change)); } bool @@ -168,6 +212,41 @@ TempoDialog::get_bbt_time (BBT_Time& requested) return true; } +double +TempoDialog::get_note_type () +{ + double note_type = 0; + vector<string>::iterator i; + string text = note_types.get_active_text(); + + for (i = strings.begin(); i != strings.end(); ++i) { + if (text == *i) { + if (sscanf (text.c_str(), "%*[^0-9]%lf", ¬e_type) != 1) { + error << string_compose(_("garbaged note type entry (%1)"), text) << endmsg; + return 0; + } else { + break; + } + } + } + + if (i == strings.end()) { + if (sscanf (text.c_str(), "%lf", ¬e_type) != 1) { + error << string_compose(_("incomprehensible note type entry (%1)"), text) << endmsg; + return 0; + } + } + + cerr << "returning " << note_type << " based on " << text << endl; + return note_type; +} + +void +TempoDialog::note_types_change () +{ + set_response_sensitive (Gtk::RESPONSE_ACCEPT, true); +} + MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action) : ArdourDialog ("meter dialog"), @@ -216,6 +295,13 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova strings.push_back (_("sixteenth (16)")); strings.push_back (_("thirty-second (32)")); + /* the string here needs to be the longest one to display */ + const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button + + // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical + // descender to make sure the height gets computed properly. + Gtkmm2ext::set_size_request_to_display_given_text (note_types, _("thirtq-second (32)"), 7+FUDGE, 15); + set_popdown_strings (note_types, strings); if (note_type==1.0f) @@ -235,10 +321,6 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova else note_types.set_active_text (_("quarter (4)")); - /* the string here needs to be the longest one to display */ - const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button - Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirty-second (32)", 7+FUDGE, 7); - hspacer1.set_border_width (5); hspacer1.pack_start (note_types, false, false); vspacer1.set_border_width (5); @@ -283,6 +365,8 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova get_vbox()->pack_start (when_frame, false, false); } + + get_vbox()->set_border_width (12); get_vbox()->pack_start (bpb_frame, false, false); get_vbox()->pack_start (note_frame, false, false); diff --git a/gtk2_ardour/tempo_dialog.h b/gtk2_ardour/tempo_dialog.h index b9f6a16b24..a92f26f8e3 100644 --- a/gtk2_ardour/tempo_dialog.h +++ b/gtk2_ardour/tempo_dialog.h @@ -37,6 +37,9 @@ struct TempoDialog : public ArdourDialog { + Gtk::ComboBoxText note_types; + vector<string> strings; + Gtk::Frame note_frame; Gtk::Adjustment bpm_adjustment; Gtk::SpinButton bpm_spinner; Gtk::Frame bpm_frame; @@ -44,8 +47,8 @@ struct TempoDialog : public ArdourDialog Gtk::Button ok_button; Gtk::Button cancel_button; Gtk::HBox button_box; - Gtk::HBox hspacer1; - Gtk::VBox vspacer1; + Gtk::HBox hspacer1, hspacer2; + Gtk::VBox vspacer1, vspacer2; Gtk::Entry when_bar_entry; Gtk::Entry when_beat_entry; Gtk::Label when_bar_label; @@ -58,13 +61,15 @@ struct TempoDialog : public ArdourDialog TempoDialog (ARDOUR::TempoSection&, const string & action); double get_bpm (); + double get_note_type (); bool get_bbt_time (ARDOUR::BBT_Time&); private: - void init (const ARDOUR::BBT_Time& start, double, bool); + void init (const ARDOUR::BBT_Time& start, double, double, bool); void bpm_changed (); bool bpm_button_press (GdkEventButton* ); bool bpm_button_release (GdkEventButton* ); + void note_types_change (); }; struct MeterDialog : public ArdourDialog diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 42ad79f3c0..8aea492910 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -966,35 +966,35 @@ class Session : public PBD::StatefulDestructible typedef void (Session::*process_function_type)(nframes_t); - AudioEngine &_engine; - mutable gint processing_prohibited; + AudioEngine& _engine; + mutable gint processing_prohibited; process_function_type process_function; process_function_type last_process_function; bool waiting_for_sync_offset; - nframes_t _base_frame_rate; - nframes_t _current_frame_rate; //this includes video pullup offset + nframes_t _base_frame_rate; + nframes_t _current_frame_rate; //this includes video pullup offset int transport_sub_state; - mutable gint _record_status; - nframes_t _transport_frame; + mutable gint _record_status; + volatile nframes_t _transport_frame; Location* end_location; Location* start_location; - Slave *_slave; + Slave* _slave; bool _silent; volatile float _transport_speed; volatile float _desired_transport_speed; float _last_transport_speed; bool auto_play_legal; - nframes_t _last_slave_transport_frame; - nframes_t maximum_output_latency; - nframes_t last_stop_frame; - nframes64_t _requested_return_frame; + nframes_t _last_slave_transport_frame; + nframes_t maximum_output_latency; + nframes_t last_stop_frame; + volatile nframes64_t _requested_return_frame; vector<Sample *> _passthru_buffers; vector<Sample *> _silent_buffers; vector<Sample *> _send_buffers; - nframes_t current_block_size; - nframes_t _worst_output_latency; - nframes_t _worst_input_latency; - nframes_t _worst_track_latency; + nframes_t current_block_size; + nframes_t _worst_output_latency; + nframes_t _worst_input_latency; + nframes_t _worst_track_latency; bool _have_captured; float _meter_hold; float _meter_falloff; diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 5e3e93e48b..fcd42734b0 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -40,27 +40,29 @@ using std::list; using std::vector; namespace ARDOUR { - +class Meter; class Tempo { public: - Tempo (double bpm) - : _beats_per_minute (bpm) {} + Tempo (double bpm, double type=4.0) // defaulting to quarter note + : _beats_per_minute (bpm), _note_type(type) {} Tempo (const Tempo& other) { _beats_per_minute = other._beats_per_minute; + _note_type = other._note_type; } void operator= (const Tempo& other) { if (&other != this) { _beats_per_minute = other._beats_per_minute; + _note_type = other._note_type; } } - double beats_per_minute () const { return _beats_per_minute; } - double frames_per_beat (nframes_t sr) const { - return ((60.0 * sr) / _beats_per_minute); - } + double beats_per_minute () const { return _beats_per_minute;} + double note_type () const { return _note_type;} + double frames_per_beat (nframes_t sr, const Meter& meter) const; protected: double _beats_per_minute; + double _note_type; }; class Meter { @@ -149,8 +151,8 @@ class MeterSection : public MetricSection, public Meter { class TempoSection : public MetricSection, public Tempo { public: - TempoSection (const BBT_Time& start, double qpm) - : MetricSection (start), Tempo (qpm) {} + TempoSection (const BBT_Time& start, double qpm, double note_type) + : MetricSection (start), Tempo (qpm, note_type) {} TempoSection (const XMLNode&); static const string xml_state_node_name; diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index a7aab441e0..3b32d62dc7 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -161,7 +161,7 @@ string LadspaPlugin::unique_id() const { char buf[32]; - snprintf (buf, sizeof (buf), "%u", descriptor->UniqueID); + snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID); return string (buf); } diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 635e32de62..2422918753 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -478,7 +478,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } - PositionChanged (_transport_frame); /* EMIT SIGNAL */ + PositionChanged ((nframes_t) _transport_frame); /* EMIT SIGNAL */ TransportStateChange (); /* EMIT SIGNAL */ /* and start it up again if relevant */ diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index cd59e93054..780f5c6a5d 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -43,12 +43,17 @@ Tempo TempoMap::_default_tempo (120.0); const double Meter::ticks_per_beat = 1920.0; +double Tempo::frames_per_beat (nframes_t sr, const Meter& meter) const +{ + return ((60.0 * sr) / (_beats_per_minute * meter.note_divisor()/_note_type)); +} + /***********************************************************************/ double Meter::frames_per_bar (const Tempo& tempo, nframes_t sr) const { - return ((60.0 * sr * _beats_per_bar) / tempo.beats_per_minute()); + return ((60.0 * sr * _beats_per_bar) / (tempo.beats_per_minute() * _note_type/tempo.note_type())); } /***********************************************************************/ @@ -86,6 +91,16 @@ TempoSection::TempoSection (const XMLNode& node) error << _("TempoSection XML node has an illegal \"beats_per_minute\" value") << endmsg; throw failed_constructor(); } + + if ((prop = node.property ("note-type")) == 0) { + /* older session, make note type be quarter by default */ + _note_type = 4.0; + } else { + if (sscanf (prop->value().c_str(), "%lf", &_note_type) != 1 || _note_type < 1.0) { + error << _("TempoSection XML node has an illegal \"note-type\" value") << endmsg; + throw failed_constructor(); + } + } if ((prop = node.property ("movable")) == 0) { error << _("TempoSection XML node has no \"movable\" property") << endmsg; @@ -109,6 +124,8 @@ TempoSection::get_state() const root->add_property ("start", buf); snprintf (buf, sizeof (buf), "%f", _beats_per_minute); root->add_property ("beats-per-minute", buf); + snprintf (buf, sizeof (buf), "%f", _note_type); + root->add_property ("note-type", buf); snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no"); root->add_property ("movable", buf); @@ -210,7 +227,7 @@ TempoMap::TempoMap (nframes_t fr) start.beats = 1; start.ticks = 0; - TempoSection *t = new TempoSection (start, _default_tempo.beats_per_minute()); + TempoSection *t = new TempoSection (start, _default_tempo.beats_per_minute(), _default_tempo.note_type()); MeterSection *m = new MeterSection (start, _default_meter.beats_per_bar(), _default_meter.note_divisor()); t->set_movable (false); @@ -359,7 +376,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where) where.ticks = 0; - do_insert (new TempoSection (where, tempo.beats_per_minute())); + do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type())); } StateChanged (Change (0)); @@ -614,7 +631,7 @@ TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const Metric& me const double beats_per_bar = metric.meter().beats_per_bar(); const double frames_per_bar = metric.meter().frames_per_bar (metric.tempo(), _frame_rate); - const double beat_frames = metric.tempo().frames_per_beat (_frame_rate); + const double beat_frames = metric.tempo().frames_per_beat (_frame_rate, metric.meter()); /* now compute how far beyond that point we actually are. */ @@ -667,7 +684,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con + start.ticks/Meter::ticks_per_beat; - start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate)); + start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); m = metric_at(end); @@ -676,7 +693,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) + end.ticks/Meter::ticks_per_beat; - end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate)); + end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); frames = end_frame - start_frame; @@ -697,7 +714,7 @@ TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, double beat_frames = 0; beats_per_bar = meter.beats_per_bar(); - beat_frames = tempo.frames_per_beat (_frame_rate); + beat_frames = tempo.frames_per_beat (_frame_rate,meter); frames = 0; @@ -1088,7 +1105,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const beats_per_bar = meter->beats_per_bar (); frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate, *meter); if (meter->frame() > tempo->frame()) { bar = meter->start().bars; @@ -1198,7 +1215,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const beats_per_bar = meter->beats_per_bar (); frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate, *meter); ++i; } @@ -1304,7 +1321,7 @@ TempoMap::dump (std::ostream& o) const for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) { - o << "Tempo @ " << *i << ' ' << t->beats_per_minute() << " BPM at " << t->start() << " frame= " << t->frame() << " (move? " + o << "Tempo @ " << *i << ' ' << t->beats_per_minute() << " BPM (denom = " << t->note_type() << ") at " << t->start() << " frame= " << t->frame() << " (move? " << t->movable() << ')' << endl; } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { o << "Meter @ " << *i << ' ' << m->beats_per_bar() << '/' << m->note_divisor() << " at " << m->start() << " frame= " << m->frame() |