diff --git a/libs/ardour/ardour/vestige/aeffectx.h b/libs/ardour/ardour/vestige/aeffectx.h index 5238df1c75..2fb7df9065 100644 --- a/libs/ardour/ardour/vestige/aeffectx.h +++ b/libs/ardour/ardour/vestige/aeffectx.h @@ -250,27 +250,26 @@ struct _AEffect typedef struct _AEffect AEffect; -struct _VstTimeInfo +typedef struct _VstTimeInfo { - // 00 - double samplePos; - // 08 - double sampleRate; - // unconfirmed 10 18 - char empty1[8 + 8]; - // 20? - double tempo; - // unconfirmed 28 30 38 - char empty2[8 + 8 + 8]; - // 40? - int timeSigNumerator; - // 44? - int timeSigDenominator; - // unconfirmed 48 4c 50 - char empty3[4 + 4 + 4]; - // 54 - int flags; -}; + /* info from online documentation of VST provided by Steinberg */ + + double samplePos; + double sampleRate; + double nanoSeconds; + double ppqPos; + double tempo; + double barStartPos; + double cycleStartPos; + double cycleEndPos; + int32_t timeSigNumerator; + int32_t timeSigDenominator; + int32_t smpteOffset; + int32_t smpteFrameRate; + int32_t samplesToNextClock; + int32_t flags; + +} VstTimeInfo; typedef struct _VstTimeInfo VstTimeInfo; diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index 06a6b80e99..b2e9b14c1a 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -131,21 +131,56 @@ intptr_t Session::vst_callback ( // conversions memset(&_timeInfo, 0, sizeof(_timeInfo)); if (session) { - _timeInfo.samplePos = session->transport_frame(); + framepos_t now = session->transport_frame(); + _timeInfo.samplePos = now; _timeInfo.sampleRate = session->frame_rate(); _timeInfo.flags = 0; + const TempoMetric& tm (session->tempo_map().metric_at (now)); + if (value & (kVstTempoValid)) { - const Tempo& t (session->tempo_map().tempo_at (session->transport_frame())); + const Tempo& t (tm.tempo()); _timeInfo.tempo = t.beats_per_minute (); _timeInfo.flags |= (kVstTempoValid); } if (value & (kVstBarsValid)) { - const Meter& m (session->tempo_map().meter_at (session->transport_frame())); + const Meter& m (tm.meter()); _timeInfo.timeSigNumerator = m.divisions_per_bar (); _timeInfo.timeSigDenominator = m.note_divisor (); _timeInfo.flags |= (kVstBarsValid); } + if (value & (kVstPpqPosValid)) { + Timecode::BBT_Time bbt; + try { + session->tempo_map().bbt_time_rt (now, bbt); + + /* Note that this assumes constant + meter/tempo throughout the session. We + can do better than this, because + progressive rock fans demand it. + */ + double ppqBar = double(bbt.bars - 1) * tm.meter().divisions_per_bar(); + double ppqBeat = double(bbt.beats - 1); + double ppqTick = double(bbt.ticks) / Timecode::BBT_Time::ticks_per_beat; + // PPQ Pos + _timeInfo.ppqPos = ppqBar + ppqBeat + ppqTick; + _timeInfo.flags |= (kVstPpqPosValid); + } catch (...) { + /* relax */ + } + } + + _timeInfo.tempo = tm.tempo().beats_per_minute(); + _timeInfo.flags |= kVstTempoValid; + + // Bars + // _timeInfo.barStartPos = ppqBar; + // _timeInfo.flags |= kVstBarsValid; + + // Time Signature + _timeInfo.timeSigNumerator = tm.meter().divisions_per_bar(); + _timeInfo.timeSigDenominator = tm.meter().note_divisor(); + _timeInfo.flags |= kVstTimeSigValid; if (session->transport_speed() != 0.0f) { _timeInfo.flags |= kVstTransportPlaying;