possibly fix deadlocking issues with tempo map by rearranging code and adding RT...
[ardour.git] / libs / ardour / session_time.cc
index 7bd0ad1164cea6c7f91cb5d4dfab48d34f46fd60..38eb0b4b28859005a5f42f9a440e136169db7a1d 100644 (file)
@@ -484,20 +484,26 @@ Session::jack_timebase_callback (jack_transport_state_t /*state*/,
        if (_tempo_map) {
 
                TempoMetric metric (_tempo_map->metric_at (_transport_frame));
-               _tempo_map->bbt_time_with_metric (_transport_frame, bbt, metric);
 
-               pos->bar = bbt.bars;
-               pos->beat = bbt.beats;
-               pos->tick = bbt.ticks;
-
-               // XXX still need to set bar_start_tick
-
-               pos->beats_per_bar = metric.meter().beats_per_bar();
-               pos->beat_type = metric.meter().note_divisor();
-               pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
-               pos->beats_per_minute = metric.tempo().beats_per_minute();
-
-               pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
+               try {
+                       _tempo_map->bbt_time_rt (_transport_frame, bbt);
+
+                       pos->bar = bbt.bars;
+                       pos->beat = bbt.beats;
+                       pos->tick = bbt.ticks;
+                       
+                       // XXX still need to set bar_start_tick
+                       
+                       pos->beats_per_bar = metric.meter().divisions_per_bar();
+                       pos->beat_type = metric.meter().note_divisor();
+                       pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_bar_division;
+                       pos->beats_per_minute = metric.tempo().beats_per_minute();
+                       
+                       pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
+
+               } catch (...) {
+                       warning << _("failed to set tempo map information for JACK due to issues with tempo map") << endmsg;
+               }
        }
 
 #ifdef HAVE_JACK_VIDEO_SUPPORT
@@ -547,21 +553,56 @@ Session::jack_timebase_callback (jack_transport_state_t /*state*/,
 }
 
 ARDOUR::framecnt_t
-Session::convert_to_frames_at (framepos_t /*position*/, AnyTime const & any)
+Session::convert_to_frames (AnyTime const & position)
+{
+       double secs;
+
+       switch (position.type) {
+       case AnyTime::BBT:
+               return _tempo_map->frame_time_rt (position.bbt);
+               break;
+
+       case AnyTime::Timecode:
+               /* XXX need to handle negative values */
+               secs = position.timecode.hours * 60 * 60;
+               secs += position.timecode.minutes * 60;
+               secs += position.timecode.seconds;
+               secs += position.timecode.frames / timecode_frames_per_second();
+               if (config.get_timecode_offset_negative()) {
+                       return (framecnt_t) floor (secs * frame_rate()) - config.get_timecode_offset();
+               } else {
+                       return (framecnt_t) floor (secs * frame_rate()) + config.get_timecode_offset();
+               }
+               break;
+
+       case AnyTime::Seconds:
+               return (framecnt_t) floor (position.seconds * frame_rate());
+               break;
+
+       case AnyTime::Frames:
+               return position.frames;
+               break;
+       }
+
+       return position.frames;
+}
+
+ARDOUR::framecnt_t
+Session::any_duration_to_frames (framepos_t position, AnyTime const & duration)
 {
        double secs;
 
-       switch (any.type) {
+       switch (duration.type) {
        case AnyTime::BBT:
-               return _tempo_map->frame_time (any.bbt);
+               return (framecnt_t) ( _tempo_map->framepos_plus_bbt (position, duration.bbt) - position);
                break;
 
        case AnyTime::Timecode:
                /* XXX need to handle negative values */
-               secs = any.timecode.hours * 60 * 60;
-               secs += any.timecode.minutes * 60;
-               secs += any.timecode.seconds;
-               secs += any.timecode.frames / timecode_frames_per_second();
+               secs = duration.timecode.hours * 60 * 60;
+               secs += duration.timecode.minutes * 60;
+               secs += duration.timecode.seconds;
+               secs += duration.timecode.frames / timecode_frames_per_second();
                if (config.get_timecode_offset_negative()) {
                        return (framecnt_t) floor (secs * frame_rate()) - config.get_timecode_offset();
                } else {
@@ -570,13 +611,13 @@ Session::convert_to_frames_at (framepos_t /*position*/, AnyTime const & any)
                break;
 
        case AnyTime::Seconds:
-               return (framecnt_t) floor (any.seconds * frame_rate());
+                return (framecnt_t) floor (duration.seconds * frame_rate());
                break;
 
        case AnyTime::Frames:
-               return any.frames;
+               return duration.frames;
                break;
        }
 
-       return any.frames;
+       return duration.frames;
 }