diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-10-30 02:52:55 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-10-30 02:52:55 +0000 |
commit | 69ac5b3c33af095ef198ea0a726d56a6a3adea68 (patch) | |
tree | 7e03ddfd5e16287c4d8250664b4df77e1a0ab886 | |
parent | 2442aa577ac4a717d9cdc88aaf2d14657906ecaf (diff) |
lots of deep but hard to spot changes to transport control, primarily relating to looping and transitions between loop, play-range and regular roll/stop ; add GUI option for seamless looping control (under Options). Needs to be forward ported to 3.0. Please TEST THE HELL out of this one - changes were deeper and wider than i would like, but did consolidate some of the GUI transport control code in a good way
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5976 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | ardour.rc.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour.menus.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 160 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui2.cc | 60 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_dialogs.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_options.cc | 25 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 28 | ||||
-rw-r--r-- | gtk2_ardour/public_editor.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 12 | ||||
-rw-r--r-- | libs/ardour/io.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_events.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 63 |
15 files changed, 197 insertions, 176 deletions
diff --git a/ardour.rc.in b/ardour.rc.in index 4f7c56510d..bd692fa5a0 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -41,6 +41,7 @@ <Option name="default-narrow_ms" value="0"/> <Option name="smpte-format" value="6"/> <Option name="font-scale" value="102400"/> + <Option name="seamless-loop" value="1"/> </Config> <extra> <RulerVisibility smpte="yes" bbt="yes" frames="no" minsec="no" tempo="yes" meter="yes" marker="yes" rangemarker="no" transportmarker="yes" cdmarker="no"/> diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index 606b79f26e..eb87c2c92e 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -549,6 +549,7 @@ </menu> </menu> <menu action='MiscOptions'> + <menuitem action='toggle-seamless-loop'/> <menuitem action='UseOSC'/> <menuitem action='NewPluginsActive'/> <menuitem action='LatchedRecordEnable'/> diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index eaa1e1d0c8..41f4fbcec2 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1449,35 +1449,102 @@ ARDOUR_UI::transport_record (bool roll) //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl; } -void +void ARDOUR_UI::transport_roll () { - bool rolling; - if (!session) { return; } - rolling = session->transport_rolling (); + if (session->is_auditioning()) { + return; + } + + switch (Config->get_slave_source()) { + case None: + case JACK: + break; + default: + /* transport controlled by the master */ + return; + } - //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl; + bool rolling = session->transport_rolling(); + bool relocate = true; if (session->get_play_loop()) { - // session->request_play_loop (false); - auto_loop_button.set_visual_state (1); - roll_button.set_visual_state (1); + session->request_play_loop (false, true); + relocate = false; } else if (session->get_play_range ()) { - session->request_play_range (false); - play_selection_button.set_visual_state (0); - } else if (rolling) { - session->request_locate (session->last_transport_start(), true); + session->request_play_range (false, true); + relocate = false; + } + + if (rolling) { + if (relocate) { + session->request_locate (session->last_transport_start(), true); + } + } else { + session->request_transport_speed (1.0f); + } + + map_transport_state (); +} + +void +ARDOUR_UI::toggle_roll (bool with_abort) +{ + + if (!session) { + return; + } + + if (session->is_auditioning()) { + session->cancel_audition (); + return; + } + + switch (Config->get_slave_source()) { + case None: + case JACK: + break; + default: + /* transport controlled by the master */ + return; + } + + bool rolling = session->transport_rolling(); + bool affect_transport = true; + + if (rolling) { + /* drop out of loop/range playback but leave transport rolling */ + if (session->get_play_loop()) { + affect_transport = false; + session->request_play_loop (false, true); + } else if (session->get_play_range ()) { + affect_transport = false; + session->request_play_range (false, true); + } + } + + if (affect_transport) { + + if (rolling) { + session->request_locate (session->last_transport_start(), true); + } + + if (rolling) { + session->request_stop (with_abort); + } else { + session->request_transport_speed (1.0f); + } } - session->request_transport_speed (1.0f); + map_transport_state (); } void -ARDOUR_UI::transport_loop() +ARDOUR_UI::toggle_session_auto_loop () { if (session) { if (session->get_play_loop()) { @@ -1486,10 +1553,14 @@ ARDOUR_UI::transport_loop() if (looploc) { session->request_locate (looploc->start(), true); } + } else { + session->request_play_loop (false); + } + } else { + Location * looploc = session->locations()->auto_loop_location(); + if (looploc) { + session->request_play_loop (true); } - } - else { - session->request_play_loop (true); } } } @@ -1501,10 +1572,6 @@ ARDOUR_UI::transport_play_selection () return; } - if (!session->get_play_range()) { - session->request_stop (); - } - editor->play_selection (); } @@ -1593,17 +1660,56 @@ ARDOUR_UI::queue_transport_change () void ARDOUR_UI::map_transport_state () { + if (!session) { + auto_loop_button.set_visual_state (0); + play_selection_button.set_visual_state (0); + roll_button.set_visual_state (0); + stop_button.set_visual_state (1); + return; + } + float sp = session->transport_speed(); if (sp == 1.0f) { - transport_rolling (); - } else if (sp < 0.0f) { - transport_rewinding (); - } else if (sp > 0.0f) { - transport_forwarding (); + shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ + shuttle_box.queue_draw (); + } else if (sp == 0.0f) { + shuttle_fract = 0; + shuttle_box.queue_draw (); + update_disk_space (); + } + + if (sp != 0.0) { + + if (session->get_play_range()) { + + play_selection_button.set_visual_state (1); + roll_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); + + } else if (session->get_play_loop ()) { + + auto_loop_button.set_visual_state (1); + play_selection_button.set_visual_state (0); + roll_button.set_visual_state (0); + + } else { + + roll_button.set_visual_state (1); + play_selection_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); + } + + stop_button.set_visual_state (0); + } else { - transport_stopped (); + + stop_button.set_visual_state (1); + roll_button.set_visual_state (0); + play_selection_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); } + } void diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 6da33722f6..03d433351a 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -578,11 +578,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void transport_forward (int option); void transport_rewind (int option); void transport_loop (); - - void transport_rolling (); - void transport_rewinding (); - void transport_forwarding (); - void transport_stopped (); + void toggle_roll (bool with_abort); bool _session_is_new; void connect_to_session (ARDOUR::Session *); @@ -714,6 +710,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void set_remote_model (ARDOUR::RemoteModel); void set_denormal_model (ARDOUR::DenormalModel); + void toggle_seamless_loop (); void toggle_sync_order_keys (); void toggle_new_plugins_active(); void toggle_StopPluginsWithTransport(); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 374de94048..06efb00c62 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -126,66 +126,6 @@ ARDOUR_UI::display_message (const char *prefix, gint prefix_len, RefPtr<TextBuff } void -ARDOUR_UI::transport_stopped () -{ - stop_button.set_visual_state (1); - - roll_button.set_visual_state (0); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - - shuttle_fract = 0; - shuttle_box.queue_draw (); - - update_disk_space (); -} - -void -ARDOUR_UI::transport_rolling () -{ - stop_button.set_visual_state (0); - if (session->get_play_range()) { - play_selection_button.set_visual_state (1); - roll_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - - } else if (session->get_play_loop ()) { - auto_loop_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - roll_button.set_visual_state (0); - - } else { - - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - } - - /* reset shuttle controller */ - - shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ - shuttle_box.queue_draw (); -} - -void -ARDOUR_UI::transport_rewinding () -{ - stop_button.set_visual_state (0); - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); -} - -void -ARDOUR_UI::transport_forwarding () -{ - stop_button.set_visual_state (0); - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); -} - -void ARDOUR_UI::setup_transport () { transport_tearoff = manage (new TearOff (transport_tearoff_hbox)); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index b96e832a0e..d4c4ce8113 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -156,7 +156,7 @@ ARDOUR_UI::connect_to_session (Session *s) start_clocking (); start_blinking (); - transport_stopped (); + map_transport_state (); second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000); point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 929f87ffc2..ad1dda3de5 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -249,10 +249,10 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - ActionManager::register_action (transport_actions, X_("ToggleRoll"), _("Start/Stop"), bind (mem_fun (*editor, &PublicEditor::toggle_playback), false)); + ActionManager::register_action (transport_actions, X_("ToggleRoll"), _("Start/Stop"), bind (mem_fun (*this, &ARDOUR_UI::toggle_roll), false)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - ActionManager::register_action (transport_actions, X_("ToggleRollForgetCapture"), _("Stop + Forget Capture"), bind (mem_fun(*editor, &PublicEditor::toggle_playback), true)); + ActionManager::register_action (transport_actions, X_("ToggleRollForgetCapture"), _("Stop + Forget Capture"), bind (mem_fun(*this, &ARDOUR_UI::toggle_roll), true)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); @@ -445,6 +445,8 @@ ARDOUR_UI::install_actions () act = ActionManager::register_toggle_action (option_actions, X_("SendMIDIfeedback"), _("Send MIDI feedback"), mem_fun (*this, &ARDOUR_UI::toggle_send_midi_feedback)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_toggle_action (option_actions, X_("toggle-seamless-loop"), _("Seamless Looping"), mem_fun (*this, &ARDOUR_UI::toggle_seamless_loop)); + act = ActionManager::register_toggle_action (option_actions, X_("UseOSC"), _("Use OSC"), mem_fun (*this, &ARDOUR_UI::toggle_use_osc)); #ifndef HAVE_LIBLO act->set_sensitive (false); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 92454c3253..2ce5eb9bdc 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -71,6 +71,12 @@ ARDOUR_UI::toggle_use_osc () } void +ARDOUR_UI::toggle_seamless_loop () +{ + ActionManager::toggle_config_state ("options", "toggle-seamless-loop", &Configuration::set_seamless_loop, &Configuration::get_seamless_loop); +} + +void ARDOUR_UI::toggle_send_midi_feedback () { ActionManager::toggle_config_state ("options", "SendMIDIfeedback", &Configuration::set_midi_feedback, &Configuration::get_midi_feedback); @@ -372,22 +378,6 @@ ARDOUR_UI::toggle_click () } void -ARDOUR_UI::toggle_session_auto_loop () -{ - if (session) { - if (session->get_play_loop()) { - if (session->transport_rolling()) { - transport_roll(); - } else { - session->request_play_loop (false); - } - } else { - session->request_play_loop (true); - } - } -} - -void ARDOUR_UI::unset_dual_punch () { Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch"); @@ -1170,6 +1160,9 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) ActionManager::map_some_state ("options", "UseOSC", &Configuration::get_use_osc); + } else if (PARAM_IS ("seamless-loop")) { + ActionManager::map_some_state ("options", "toggle-seamless-loop", &Configuration::get_seamless_loop); + } else if (PARAM_IS ("mmc-control")) { ActionManager::map_some_state ("options", "UseMMC", &Configuration::get_mmc_control); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index c1077b4f1b..3a246e2f2d 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -194,7 +194,6 @@ class Editor : public PublicEditor void separate_region_from_punch (); void separate_region_from_loop (); void separate_regions_using_location (ARDOUR::Location&); - void toggle_playback (bool with_abort); void transition_to_rolling (bool forward); /* undo related */ diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index d5fac43bc6..8669b44a7a 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2386,34 +2386,6 @@ Editor::transition_to_rolling (bool fwd) } void -Editor::toggle_playback (bool with_abort) -{ - if (!session) { - return; - } - - switch (Config->get_slave_source()) { - case None: - case JACK: - break; - default: - /* transport controlled by the master */ - return; - } - - if (session->is_auditioning()) { - session->cancel_audition (); - return; - } - - if (session->transport_rolling()) { - session->request_stop (with_abort); - } else { - session->request_transport_speed (1.0f); - } -} - -void Editor::play_from_start () { session->request_locate (session->current_start_frame(), true); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index d876a605bc..737ae75f6f 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -109,7 +109,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual bool show_waveforms_recording() const = 0; virtual void new_region_from_selection () = 0; virtual void separate_region_from_selection () = 0; - virtual void toggle_playback (bool with_abort) = 0; virtual void transition_to_rolling (bool fwd) = 0; virtual nframes64_t unit_to_frame (double unit) const = 0; // XXX remove me when libardour goes nframes64_t diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 808dd3c915..61ee454e7c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -155,8 +155,8 @@ class Session : public PBD::StatefulDestructible Type type; Action action; - nframes_t action_frame; - nframes_t target_frame; + nframes_t action_frame; + nframes_t target_frame; float speed; union { @@ -374,7 +374,7 @@ class Session : public PBD::StatefulDestructible void request_stop (bool abort = false); void request_locate (nframes_t frame, bool with_roll = false); - void request_play_loop (bool yn); + void request_play_loop (bool yn, bool leave_rolling = false); bool get_play_loop () const { return play_loop; } nframes_t last_transport_start() const { return _last_roll_location; } @@ -926,7 +926,7 @@ class Session : public PBD::StatefulDestructible void set_audio_range (list<AudioRange>&); void set_music_range (list<MusicRange>&); - void request_play_range (bool yn); + void request_play_range (bool yn, bool leave_rolling = false); bool get_play_range () const { return _play_range; } /* favorite dirs */ @@ -1453,7 +1453,7 @@ class Session : public PBD::StatefulDestructible void change_midi_ports (); int use_config_midi_ports (); - void set_play_loop (bool yn); + void set_play_loop (bool yn, bool leave_rolling); void overwrite_some_buffers (Diskstream*); void flush_all_redirects (); int micro_locate (nframes_t distance); @@ -1735,7 +1735,7 @@ class Session : public PBD::StatefulDestructible list<AudioRange> current_audio_range; bool _play_range; - void set_play_range (bool yn); + void set_play_range (bool yn, bool leave_rolling); void setup_auto_play (); /* main outs */ diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 0678c4aff8..395cabd4e9 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -2720,7 +2720,7 @@ IO::build_legal_port_name (bool in) { const int name_size = jack_port_name_size(); int limit; - char* suffix; + const char* suffix; int maxports; /* note that if "in" or "out" are translated it will break a session diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index f52a458a15..95a2f8b2e7 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -317,7 +317,7 @@ Session::process_event (Event* ev) switch (ev->type) { case Event::SetLoop: - set_play_loop (ev->yes_or_no); + set_play_loop (ev->yes_or_no, (ev->speed == 1.0f)); break; case Event::AutoLoop: @@ -432,7 +432,7 @@ Session::process_event (Event* ev) break; case Event::SetPlayRange: - set_play_range (ev->yes_or_no); + set_play_range (ev->yes_or_no, (ev->speed == 1.0f)); break; default: diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index b29816be1b..640184ae79 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -66,9 +66,8 @@ Session::request_slave_source (SlaveSource src) if (src == JACK) { /* could set_seamless_loop() be disposed of entirely?*/ Config->set_seamless_loop (false); - } else { - Config->set_seamless_loop (true); - } + } + ev->slave = src; queue_event (ev); } @@ -110,7 +109,7 @@ Session::force_locate (nframes_t target_frame, bool with_roll) } void -Session::request_play_loop (bool yn) +Session::request_play_loop (bool yn, bool leave_rolling) { Event* ev; Location *location = _locations.auto_loop_location(); @@ -121,14 +120,14 @@ Session::request_play_loop (bool yn) return; } - ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn); + ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); queue_event (ev); - - if (!yn && Config->get_seamless_loop() && transport_rolling()) { + + if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) { // request an immediate locate to refresh the diskstreams // after disabling looping request_locate (_transport_frame-1, false); - } + } } void @@ -535,31 +534,35 @@ Session::check_declick_out () } void -Session::set_play_loop (bool yn) +Session::set_play_loop (bool yn, bool leave_rolling) { /* Called from event-handling context */ - + Location *loc; + if (yn == play_loop) { + return; + } + if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) { return; } set_dirty(); - + if (yn && Config->get_seamless_loop() && synced_to_jack()) { warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n" "Recommend changing the configured options") << endmsg; return; } - if ((play_loop = yn)) { - if (loc) { + set_play_range (false, true); + if (Config->get_seamless_loop()) { // set all diskstreams to use internal looping boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); @@ -602,6 +605,8 @@ Session::set_play_loop (bool yn) } } + + TransportStateChange (); } void @@ -755,7 +760,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { // cancel looping directly, this is called from event handling context - set_play_loop (false); + set_play_loop (false, false); } else if (al && _transport_frame == al->start()) { if (with_loop) { @@ -1124,27 +1129,33 @@ Session::set_audio_range (list<AudioRange>& range) } void -Session::request_play_range (bool yn) +Session::request_play_range (bool yn, bool leave_rolling) { - Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn); + Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); queue_event (ev); } void -Session::set_play_range (bool yn) +Session::set_play_range (bool yn, bool leave_rolling) { /* Called from event-processing context */ - if (_play_range != yn) { - _play_range = yn; - setup_auto_play (); + if (yn) { + /* cancel loop play */ + set_play_loop (false, true); + } - if (!_play_range) { - /* stop transport */ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); - merge_event (ev); - } + _play_range = yn; + + setup_auto_play (); + + if (!_play_range && !leave_rolling) { + /* stop transport */ + Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); + merge_event (ev); } + + TransportStateChange (); } void @@ -1196,7 +1207,7 @@ Session::setup_auto_play () } } else if (sz == 1) { - + ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f); merge_event (ev); |