- also make locations and regions use a double beat rather than bbt for musical position.
}
// Update color in case velocity has changed
- ev->set_fill_color(ev->base_color());
- ev->set_outline_color(ev->calculate_outline(ev->base_color(), ev->selected()));
+ //ev->set_fill_color(ev->base_color());
+ //ev->set_outline_color(ev->calculate_outline(ev->base_color(), ev->selected()));
if (update_ghost_regions) {
for (std::vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
private:
std::string _name;
framepos_t _start;
- Timecode::BBT_Time _bbt_start;
+ double _bbt_start;
framepos_t _end;
- Timecode::BBT_Time _bbt_end;
+ double _bbt_end;
Flags _flags;
bool _locked;
PositionLockStyle _position_lock_style;
#include "pbd/undo.h"
#include "pbd/signals.h"
-
#include "ardour/ardour.h"
#include "ardour/data_type.h"
#include "ardour/automatable.h"
framecnt_t _last_length;
framepos_t _last_position;
mutable RegionEditState _first_edit;
- Timecode::BBT_Time _bbt_time;
+ double _beat;
layer_t _layer;
void register_properties ();
TempoMap *_tempo_map;
void tempo_map_changed (const PBD::PropertyChange&);
+ void gui_tempo_map_changed ();
/* edit/mix groups */
start_changed (this); /* EMIT SIGNAL */
StartChanged (); /* EMIT SIGNAL */
- end_changed (this); /* EMIT SIGNAL */
- EndChanged (); /* EMIT SIGNAL */
+ //end_changed (this); /* EMIT SIGNAL */
+ //EndChanged (); /* EMIT SIGNAL */
}
/* moving the start (position) of a marker with a scene change
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
- start_changed (this); /* EMIT SIGNAL */
- StartChanged (); /* EMIT SIGNAL */
+ //start_changed (this); /* EMIT SIGNAL */
+ //StartChanged (); /* EMIT SIGNAL */
end_changed (this); /* EMIT SIGNAL */
EndChanged (); /* EMIT SIGNAL */
}
assert (_end >= 0);
}
- if (start_change) {
+ if (start_change && end_change) {
+ changed (this);
+ Changed ();
+ } else if (start_change) {
start_changed(this); /* EMIT SIGNAL */
StartChanged(); /* EMIT SIGNAL */
- }
-
- if (end_change) {
+ } else if (end_change) {
end_changed(this); /* EMIT SIGNAL */
EndChanged(); /* EMIT SIGNAL */
}
- if (start_change && end_change) {
- changed (this);
- Changed ();
- }
-
return 0;
}
return;
}
- _session.bbt_time (_start, _bbt_start);
- _session.bbt_time (_end, _bbt_end);
+ _bbt_start = _session.tempo_map().beat_at_frame (_start);
+ _bbt_end = _session.tempo_map().beat_at_frame (_end);
}
void
}
TempoMap& map (_session.tempo_map());
- set (map.frame_time (_bbt_start), map.frame_time (_bbt_end), false);
+ set (map.frame_at_beat (_bbt_start), map.frame_at_beat (_bbt_end), false);
}
void
_position_lock_style = ps;
if (_position_lock_style == MusicTime) {
- _session.bbt_time (_position, _bbt_time);
+ _beat = _session.tempo_map().beat_at_frame (_position);
}
send_change (Properties::position_lock_style);
if (!pl || _position_lock_style != MusicTime) {
return;
}
-
TempoMap& map (_session.tempo_map());
- framepos_t pos = map.frame_time (_bbt_time);
+ framepos_t pos = map.frame_at_beat (_beat);
set_position_internal (pos, false);
/* do this even if the position is the same. this helps out
Region::recompute_position_from_lock_style ()
{
if (_position_lock_style == MusicTime) {
- _session.bbt_time (_position, _bbt_time);
+ _beat = _session.tempo_map().beat_at_frame (_position);
}
}
if (_position_lock_style != AudioTime) {
stringstream str;
- str << _bbt_time;
- node->add_property ("bbt-position", str.str());
+ str << _beat;
+ node->add_property ("beat", str.str());
}
for (uint32_t n=0; n < _sources.size(); ++n) {
Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_changed, bool send)
{
XMLProperty const * prop;
+ Timecode::BBT_Time bbt_time;
Stateful::save_extra_xml (node);
_position_lock_style = AudioTime;
} else {
if (sscanf (prop->value().c_str(), "%d|%d|%d",
- &_bbt_time.bars,
- &_bbt_time.beats,
- &_bbt_time.ticks) != 3) {
+ &bbt_time.bars,
+ &bbt_time.beats,
+ &bbt_time.ticks) != 3) {
+ _position_lock_style = AudioTime;
+ }
+ _beat = _session.tempo_map().bbt_to_beats (bbt_time);
+ }
+ }
+
+ if (_position_lock_style == MusicTime) {
+ if ((prop = node.property ("beat")) == 0) {
+ /* missing BBT info, revert to audio time locking */
+ _position_lock_style = AudioTime;
+ } else {
+ if (sscanf (prop->value().c_str(), "%lf", &_beat) != 1) {
_position_lock_style = AudioTime;
}
}
set_dirty ();
}
+void
+Session::gui_tempo_map_changed ()
+{
+ //clear_clicks (); ?
+
+ playlists->update_after_tempo_map_change ();
+
+ _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
+}
+
void
Session::update_locations_after_tempo_map_change (const Locations::LocationList& loc)
{
delete _tempo_map;
_tempo_map = new TempoMap (_current_frame_rate);
_tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
+ _tempo_map->MetricPositionChanged.connect_same_thread (*this, boost::bind (&Session::gui_tempo_map_changed, this));
/* MidiClock requires a tempo map */
bbt().beats,
bbt().ticks);
root->add_property ("bbt", buf);
- snprintf (buf, sizeof (buf), "%f", start());
+ snprintf (buf, sizeof (buf), "%lf", start());
root->add_property ("start", buf);
snprintf (buf, sizeof (buf), "%f", _note_type);
root->add_property ("note-type", buf);
start.beats = 1;
start.ticks = 0;
- TempoSection *t = new TempoSection (0.0, _default_tempo.beats_per_minute(), _default_tempo.note_type(), TempoSection::Type::Ramp);
+ TempoSection *t = new TempoSection (0.0, _default_tempo.beats_per_minute(), _default_tempo.note_type(), TempoSection::Type::Constant);
MeterSection *m = new MeterSection (0.0, start, _default_meter.divisions_per_bar(), _default_meter.note_divisor());
t->set_movable (false);
pair<double, BBT_Time> corrected = make_pair (m->start(), m->bbt());
corrected.second.beats = 1;
corrected.second.ticks = 0;
-
+ corrected.first = bbt_to_beats (corrected.second);
warning << string_compose (_("Meter changes can only be positioned on the first beat of a bar. Moving from %1 to %2"),
m->bbt(), corrected.second) << endmsg;
m->set_start (corrected);
double
TempoMap::tick_at_frame (framecnt_t frame) const
{
+ /* HOLD (at least) THE READER LOCK */
Metrics::const_iterator i;
- const TempoSection* prev_ts = 0;
+ TempoSection* prev_ts = 0;
double accumulated_ticks = 0.0;
for (i = metrics.begin(); i != metrics.end(); ++i) {
if ((prev_ts) && frame < t->frame()) {
/*the previous ts is the one containing the frame */
- framepos_t time = frame - prev_ts->frame();
- framepos_t last_frame = t->frame() - prev_ts->frame();
- double last_beats_per_minute = t->beats_per_minute();
+ framepos_t const time = frame - prev_ts->frame();
+ framepos_t const last_frame = t->frame() - prev_ts->frame();
+ double const last_beats_per_minute = t->beats_per_minute();
return prev_ts->tick_at_frame (time, last_beats_per_minute, last_frame, _frame_rate) + accumulated_ticks;
}
if (prev_ts && t->frame() > prev_ts->frame()) {
- framepos_t time = t->frame() - prev_ts->frame();
- framepos_t last_frame = t->frame() - prev_ts->frame();
- double last_beats_per_minute = t->beats_per_minute();
- accumulated_ticks += prev_ts->tick_at_frame (time, last_beats_per_minute, last_frame, _frame_rate);
+ accumulated_ticks = t->beat() * BBT_Time::ticks_per_beat;
}
prev_ts = t;
}
}
- /* treated s linear for this ts */
- framecnt_t frames_in_section = frame - prev_ts->frame();
- double ticks_in_section = (frames_in_section / prev_ts->frames_per_beat (_frame_rate)) * Timecode::BBT_Time::ticks_per_beat;
+ /* treated as constant for this ts */
+ framecnt_t const frames_in_section = frame - prev_ts->frame();
+ double const ticks_in_section = (frames_in_section / prev_ts->frames_per_beat (_frame_rate)) * Timecode::BBT_Time::ticks_per_beat;
return ticks_in_section + accumulated_ticks;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
if (prev_ts && t->frame() > prev_ts->frame()) {
- framepos_t const time = t->frame() - prev_ts->frame();
- framepos_t const last_time = t->frame() - prev_ts->frame();
- double const last_beats_per_minute = t->beats_per_minute();
- accumulated_ticks += prev_ts->tick_at_frame (time, last_beats_per_minute, last_time, _frame_rate);
+ accumulated_ticks = t->beat() * BBT_Time::ticks_per_beat;
}
if (prev_ts && tick < accumulated_ticks) {
/* prev_ts is the one affecting us. */
double const ticks_in_section = tick - accumulated_ticks_to_prev;
- framepos_t const section_start = prev_ts->frame();
framepos_t const last_time = t->frame() - prev_ts->frame();
double const last_beats_per_minute = t->beats_per_minute();
- return prev_ts->frame_at_tick (ticks_in_section, last_beats_per_minute, last_time, _frame_rate) + section_start;
+ return prev_ts->frame_at_tick (ticks_in_section, last_beats_per_minute, last_time, _frame_rate) + prev_ts->frame();
}
accumulated_ticks_to_prev = accumulated_ticks;
prev_ts = t;
}
}
+ /* must be treated as constant, irrespective of _type */
double const ticks_in_section = tick - accumulated_ticks_to_prev;
- double const dtime = (ticks_in_section / BBT_Time::ticks_per_beat) * prev_ts->frames_per_beat(_frame_rate);
+ double const dtime = (ticks_in_section / BBT_Time::ticks_per_beat) * prev_ts->frames_per_beat (_frame_rate);
+
framecnt_t const ret = ((framecnt_t) floor (dtime)) + prev_ts->frame();
return ret;