X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor.cc;h=bd006e13fbd4039bdc4fb5740523dd817996c4cf;hb=abf1f286d49482ade939da7e49863a3d63048b42;hp=a8b40087382f6d0e0caa3395ade4727822efd73c;hpb=0d32105a1ec0a09f0676d06c133b66ec4a6b21f5;p=ardour.git diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index a8b4008738..bd006e13fb 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2208,41 +2208,15 @@ Editor::snap_mode() const } void -Editor::set_grid_to (GridType gt) +Editor::show_rulers_for_grid () { - if (_grid_type == gt) { // already set - return; - } - - unsigned int grid_ind = (unsigned int)gt; - - if (internal_editing() && UIConfiguration::instance().get_grid_follows_internal()) { - internal_grid_type = gt; - } else { - pre_internal_grid_type = gt; - } - - _grid_type = gt; - - if (grid_ind > grid_type_strings.size() - 1) { - grid_ind = 0; - _grid_type = (GridType)grid_ind; - } - - string str = grid_type_strings[grid_ind]; - - if (str != grid_type_selector.get_text()) { - grid_type_selector.set_text (str); - } - - /* show appropriate rulers for this grid setting. - */ + /* show appropriate rulers for this grid setting. */ if (grid_musical()) { ruler_tempo_action->set_active(true); ruler_meter_action->set_active(true); ruler_bbt_action->set_active(true); - if ( UIConfiguration::instance().get_rulers_follow_grid() ) { + if (UIConfiguration::instance().get_rulers_follow_grid()) { ruler_timecode_action->set_active(false); ruler_minsec_action->set_active(false); ruler_samples_action->set_active(false); @@ -2250,7 +2224,7 @@ Editor::set_grid_to (GridType gt) } else if (_grid_type == GridTypeTimecode) { ruler_timecode_action->set_active(true); - if ( UIConfiguration::instance().get_rulers_follow_grid() ) { + if (UIConfiguration::instance().get_rulers_follow_grid()) { ruler_tempo_action->set_active(false); ruler_meter_action->set_active(false); ruler_bbt_action->set_active(false); @@ -2260,7 +2234,7 @@ Editor::set_grid_to (GridType gt) } else if (_grid_type == GridTypeMinSec) { ruler_minsec_action->set_active(true); - if ( UIConfiguration::instance().get_rulers_follow_grid() ) { + if (UIConfiguration::instance().get_rulers_follow_grid()) { ruler_tempo_action->set_active(false); ruler_meter_action->set_active(false); ruler_bbt_action->set_active(false); @@ -2271,7 +2245,7 @@ Editor::set_grid_to (GridType gt) ruler_cd_marker_action->set_active(true); ruler_minsec_action->set_active(true); - if ( UIConfiguration::instance().get_rulers_follow_grid() ) { + if (UIConfiguration::instance().get_rulers_follow_grid()) { ruler_tempo_action->set_active(false); ruler_meter_action->set_active(false); ruler_bbt_action->set_active(false); @@ -2279,6 +2253,39 @@ Editor::set_grid_to (GridType gt) ruler_samples_action->set_active(false); } } +} + +void +Editor::set_grid_to (GridType gt) +{ + if (_grid_type == gt) { // already set + return; + } + + unsigned int grid_ind = (unsigned int)gt; + + if (internal_editing() && UIConfiguration::instance().get_grid_follows_internal()) { + internal_grid_type = gt; + } else { + pre_internal_grid_type = gt; + } + + _grid_type = gt; + + if (grid_ind > grid_type_strings.size() - 1) { + grid_ind = 0; + _grid_type = (GridType)grid_ind; + } + + string str = grid_type_strings[grid_ind]; + + if (str != grid_type_selector.get_text()) { + grid_type_selector.set_text (str); + } + + if (UIConfiguration::instance().get_show_grids_ruler()) { + show_rulers_for_grid (); + } instant_save (); @@ -2571,7 +2578,7 @@ Editor::set_state (const XMLNode& node, int version) } } - return LuaInstance::instance()->set_state(node); + return 0; } XMLNode& @@ -2639,8 +2646,6 @@ Editor::get_state () node->set_property ("nudge-clock-value", nudge_clock->current_duration()); - node->add_child_nocopy (LuaInstance::instance()->get_action_state()); - node->add_child_nocopy (LuaInstance::instance()->get_hook_state()); node->add_child_nocopy (_locations->get_state ()); return *node; @@ -2692,7 +2697,7 @@ Editor::set_snapped_cursor_position (samplepos_t pos) * @param event Event to get current key modifier information from, or 0. */ void -Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, RoundMode direction, SnapPref pref, bool for_mark) +Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, RoundMode direction, SnapPref pref) { if (!_session || !event) { return; @@ -2700,16 +2705,16 @@ Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, Round if (ArdourKeyboard::indicates_snap (event->button.state)) { if (_snap_mode == SnapOff) { - snap_to_internal (start, direction, pref, for_mark); + snap_to_internal (start, direction, pref); } else { start.set (start.sample, 0); } } else { if (_snap_mode != SnapOff) { - snap_to_internal (start, direction, pref, for_mark); + snap_to_internal (start, direction, pref); } else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) { /* SnapOff, but we pressed the snap_delta modifier */ - snap_to_internal (start, direction, pref, for_mark); + snap_to_internal (start, direction, pref); } else { start.set (start.sample, 0); } @@ -2717,14 +2722,14 @@ Editor::snap_to_with_modifier (MusicSample& start, GdkEvent const * event, Round } void -Editor::snap_to (MusicSample& start, RoundMode direction, SnapPref pref, bool for_mark, bool ensure_snap) +Editor::snap_to (MusicSample& start, RoundMode direction, SnapPref pref, bool ensure_snap) { if (!_session || (_snap_mode == SnapOff && !ensure_snap)) { start.set (start.sample, 0); return; } - snap_to_internal (start, direction, pref, for_mark, ensure_snap); + snap_to_internal (start, direction, pref, ensure_snap); } void @@ -2739,61 +2744,239 @@ check_best_snap (samplepos_t presnap, samplepos_t &test, samplepos_t &dist, samp test = max_samplepos; // reset this so it doesn't get accidentally reused } -samplepos_t -Editor::snap_to_grid (vector marks, samplepos_t presnap, RoundMode direction) +MusicSample +Editor::snap_to_timecode (MusicSample presnap, RoundMode direction, SnapPref gpref) { - if (marks.empty()) return presnap; + samplepos_t start = presnap.sample; + const samplepos_t one_timecode_second = (samplepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame()); + samplepos_t one_timecode_minute = (samplepos_t)(rint(_session->timecode_frames_per_second()) * _session->samples_per_timecode_frame() * 60); - samplepos_t before; - samplepos_t after; - samplepos_t test = presnap; + TimecodeRulerScale scale = (gpref != SnapToGrid_Unscaled) ? timecode_ruler_scale : timecode_show_samples; - before = after = max_samplepos; + switch (scale) { + case timecode_show_bits: + case timecode_show_samples: + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + fmod((double)start, (double)_session->samples_per_timecode_frame()) == 0) { + /* start is already on a whole timecode frame, do nothing */ + } else if (((direction == 0) && (fmod((double)start, (double)_session->samples_per_timecode_frame()) > (_session->samples_per_timecode_frame() / 2))) || (direction > 0)) { + start = (samplepos_t) (ceil ((double) start / _session->samples_per_timecode_frame()) * _session->samples_per_timecode_frame()); + } else { + start = (samplepos_t) (floor ((double) start / _session->samples_per_timecode_frame()) * _session->samples_per_timecode_frame()); + } + break; - /* get marks to either side of presnap */ - vector::const_iterator m = marks.begin(); - while (m != marks.end() && (m->position < presnap)) { - ++m; - } + case timecode_show_seconds: + if (_session->config.get_timecode_offset_negative()) { + start += _session->config.get_timecode_offset (); + } else { + start -= _session->config.get_timecode_offset (); + } + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + (start % one_timecode_second == 0)) { + /* start is already on a whole second, do nothing */ + } else if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) { + start = (samplepos_t) ceil ((double) start / one_timecode_second) * one_timecode_second; + } else { + start = (samplepos_t) floor ((double) start / one_timecode_second) * one_timecode_second; + } - if (m == marks.end ()) { - /* ran out of marks */ - before = marks.back().position; + if (_session->config.get_timecode_offset_negative()) { + start -= _session->config.get_timecode_offset (); + } else { + start += _session->config.get_timecode_offset (); + } + break; + + case timecode_show_minutes: + case timecode_show_hours: + case timecode_show_many_hours: + if (_session->config.get_timecode_offset_negative()) { + start += _session->config.get_timecode_offset (); + } else { + start -= _session->config.get_timecode_offset (); + } + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + (start % one_timecode_minute == 0)) { + /* start is already on a whole minute, do nothing */ + } else if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) { + start = (samplepos_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute; + } else { + start = (samplepos_t) floor ((double) start / one_timecode_minute) * one_timecode_minute; + } + if (_session->config.get_timecode_offset_negative()) { + start -= _session->config.get_timecode_offset (); + } else { + start += _session->config.get_timecode_offset (); + } + break; + default: + fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg; } - after = m->position; + MusicSample ret(start,0); + return ret; +} - if (m != marks.begin ()) { - --m; - before = m->position; - } +MusicSample +Editor::snap_to_minsec (MusicSample presnap, RoundMode direction, SnapPref gpref) +{ + MusicSample ret(presnap); + + const samplepos_t one_second = _session->sample_rate(); + const samplepos_t one_minute = one_second * 60; + const samplepos_t one_hour = one_minute * 60; - if (before == max_samplepos && after == max_samplepos) { - /* No grid to snap to, so just don't snap */ - return presnap; - } else if (before == max_samplepos) { - test = after; - } else if (after == max_samplepos) { - test = before; - } else { - if ((direction == RoundUpMaybe || direction == RoundUpAlways)) - test = after; - else if ((direction == RoundDownMaybe || direction == RoundDownAlways)) - test = before; - else if (direction == 0) { - if ((presnap - before) < (after - presnap)) { - test = before; + MinsecRulerScale scale = (gpref != SnapToGrid_Unscaled) ? minsec_ruler_scale : minsec_show_seconds; + + switch (scale) { + case minsec_show_msecs: + case minsec_show_seconds: { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + presnap.sample % one_second == 0) { + /* start is already on a whole second, do nothing */ + } else if (((direction == 0) && (presnap.sample % one_second > one_second / 2)) || (direction > 0)) { + ret.sample = (samplepos_t) ceil ((double) presnap.sample / one_second) * one_second; } else { - test = after; + ret.sample = (samplepos_t) floor ((double) presnap.sample / one_second) * one_second; + } + } break; + + case minsec_show_minutes: { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + presnap.sample % one_minute == 0) { + /* start is already on a whole minute, do nothing */ + } else if (((direction == 0) && (presnap.sample % one_minute > one_minute / 2)) || (direction > 0)) { + ret.sample = (samplepos_t) ceil ((double) presnap.sample / one_minute) * one_minute; + } else { + ret.sample = (samplepos_t) floor ((double) presnap.sample / one_minute) * one_minute; + } + } break; + + default: { + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + presnap.sample % one_hour == 0) { + /* start is already on a whole hour, do nothing */ + } else if (((direction == 0) && (presnap.sample % one_hour > one_hour / 2)) || (direction > 0)) { + ret.sample = (samplepos_t) ceil ((double) presnap.sample / one_hour) * one_hour; + } else { + ret.sample = (samplepos_t) floor ((double) presnap.sample / one_hour) * one_hour; } + } break; + } + + return ret; +} + +MusicSample +Editor::snap_to_cd_frames (MusicSample presnap, RoundMode direction, SnapPref gpref) +{ + if ((gpref != SnapToGrid_Unscaled) && (minsec_ruler_scale != minsec_show_msecs)) { + return snap_to_minsec (presnap, direction, gpref); + } + + const samplepos_t one_second = _session->sample_rate(); + + MusicSample ret(presnap); + + if ((direction == RoundUpMaybe || direction == RoundDownMaybe) && + presnap.sample % (one_second/75) == 0) { + /* start is already on a whole CD sample, do nothing */ + } else if (((direction == 0) && (presnap.sample % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) { + ret.sample = (samplepos_t) ceil ((double) presnap.sample / (one_second / 75)) * (one_second / 75); + } else { + ret.sample = (samplepos_t) floor ((double) presnap.sample / (one_second / 75)) * (one_second / 75); + } + + return ret; +} + +MusicSample +Editor::snap_to_bbt (MusicSample presnap, RoundMode direction, SnapPref gpref) +{ + MusicSample ret(presnap); + + if (gpref != SnapToGrid_Unscaled) { // use the visual grid lines which are limited by the zoom scale that the user selected + + int divisor = 2; + switch (_grid_type) { + case GridTypeBeatDiv3: + case GridTypeBeatDiv6: + case GridTypeBeatDiv12: + case GridTypeBeatDiv24: + divisor = 3; + break; + case GridTypeBeatDiv5: + case GridTypeBeatDiv10: + case GridTypeBeatDiv20: + divisor = 5; + break; + case GridTypeBeatDiv7: + case GridTypeBeatDiv14: + case GridTypeBeatDiv28: + divisor = 7; + break; + default: + divisor = 2; + }; + + BBTRulerScale scale = bbt_ruler_scale; + switch (scale) { + case bbt_show_many: + case bbt_show_64: + case bbt_show_16: + case bbt_show_4: + case bbt_show_1: + ret = _session->tempo_map().round_to_bar (presnap.sample, direction); + break; + case bbt_show_quarters: + ret = _session->tempo_map().round_to_beat (presnap.sample, direction); + break; + case bbt_show_eighths: + ret = _session->tempo_map().round_to_quarter_note_subdivision (presnap.sample, 1 * divisor, direction); + break; + case bbt_show_sixteenths: + ret = _session->tempo_map().round_to_quarter_note_subdivision (presnap.sample, 2 * divisor, direction); + break; + case bbt_show_thirtyseconds: + ret = _session->tempo_map().round_to_quarter_note_subdivision (presnap.sample, 4 * divisor, direction); + break; } + } else { + ret = _session->tempo_map().round_to_quarter_note_subdivision (presnap.sample, get_grid_beat_divisions(_grid_type), direction); } + + return ret; +} - return test; +ARDOUR::MusicSample +Editor::snap_to_grid (MusicSample presnap, RoundMode direction, SnapPref gpref) +{ + MusicSample ret(presnap); + + if (grid_musical()) { + ret = snap_to_bbt (presnap, direction, gpref); + } + + switch (_grid_type) { + case GridTypeTimecode: + ret = snap_to_timecode(presnap, direction, gpref); + break; + case GridTypeMinSec: + ret = snap_to_minsec(presnap, direction, gpref); + break; + case GridTypeCDFrame: + ret = snap_to_cd_frames(presnap, direction, gpref); + break; + default: + {} + }; + + return ret; } samplepos_t -Editor::marker_snap_to_internal (samplepos_t presnap, RoundMode direction) +Editor::snap_to_marker (samplepos_t presnap, RoundMode direction) { samplepos_t before; samplepos_t after; @@ -2826,7 +3009,7 @@ Editor::marker_snap_to_internal (samplepos_t presnap, RoundMode direction) } void -Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref, bool for_mark, bool ensure_snap) +Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref, bool ensure_snap) { const samplepos_t presnap = start.sample; @@ -2835,18 +3018,14 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref samplepos_t best = max_samplepos; // this records the best snap-result we've found so far /* check snap-to-marker */ - if ( (pref == SnapToAny) && UIConfiguration::instance().get_snap_to_marks()) { - if (for_mark) { - return; - } - - test = marker_snap_to_internal (presnap, direction); + if ((pref == SnapToAny_Visual) && UIConfiguration::instance().get_snap_to_marks()) { + test = snap_to_marker (presnap, direction); check_best_snap(presnap, test, dist, best); } /* check snap-to-region-{start/end/sync} */ if ( - (pref == SnapToAny) && + (pref == SnapToAny_Visual) && (UIConfiguration::instance().get_snap_to_region_start() || UIConfiguration::instance().get_snap_to_region_end() || UIConfiguration::instance().get_snap_to_region_sync()) ) { if (!region_boundary_cache.empty()) { @@ -2877,8 +3056,9 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref /* check Grid */ if (UIConfiguration::instance().get_snap_to_grid() && (_grid_type != GridTypeNone)) { - test = snap_to_grid (grid_marks, presnap, direction); - check_best_snap(presnap, test, dist, best); + MusicSample pre(presnap, 0); + MusicSample post = snap_to_grid (pre, direction, pref); + check_best_snap(presnap, post.sample, dist, best); } /* now check "magnetic" state: is the grid within reasonable on-screen distance to trigger a snap? @@ -3989,6 +4169,8 @@ Editor::get_grid_beat_divisions(samplepos_t position) case GridTypeBeatDiv4: return 4; case GridTypeBeatDiv3: return 3; case GridTypeBeatDiv2: return 2; + case GridTypeBeat: return 1; + case GridTypeBar: return 1; case GridTypeNone: return 0; case GridTypeTimecode: return 0; @@ -5758,7 +5940,7 @@ Editor::super_rapid_screen_update () _last_update_time = 0; } - if (!_session->transport_rolling ()) { + if (!_session->transport_rolling () || _session->is_auditioning ()) { /* Do not interpolate the playhead position; just set it */ _last_update_time = 0; }