1 /* Copyright 2016, Ableton AG, Berlin. All rights reserved. 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 * If you would like to incorporate Link into a proprietary software application, 17 * please contact <link-devs@ableton.com>. 18 */ 19 20 #pragma once 21 22 #include <ableton/link/LinearRegression.hpp> 23 #include <chrono> 24 #include <vector> 25 26 namespace ableton 27 { 28 namespace link 29 { 30 31 template <class T> 32 class HostTimeFilter 33 { 34 static const std::size_t kNumPoints = 512; 35 using Points = std::vector<std::pair<double, double>>; 36 using PointIt = typename Points::iterator; 37 38 public: HostTimeFilter()39 HostTimeFilter() 40 : mIndex(0) 41 { 42 mPoints.reserve(kNumPoints); 43 } 44 45 ~HostTimeFilter() = default; 46 reset()47 void reset() 48 { 49 mIndex = 0; 50 mPoints.clear(); 51 } 52 sampleTimeToHostTime(const double sampleTime)53 std::chrono::microseconds sampleTimeToHostTime(const double sampleTime) 54 { 55 const auto micros = static_cast<double>(mHostTimeSampler.micros().count()); 56 const auto point = std::make_pair(sampleTime, micros); 57 58 if (mPoints.size() < kNumPoints) 59 { 60 mPoints.push_back(point); 61 } 62 else 63 { 64 mPoints[mIndex] = point; 65 } 66 mIndex = (mIndex + 1) % kNumPoints; 67 68 const auto result = linearRegression(mPoints.begin(), mPoints.end()); 69 70 const auto hostTime = (result.first * sampleTime) + result.second; 71 72 return std::chrono::microseconds(llround(hostTime)); 73 } 74 75 private: 76 std::size_t mIndex; 77 Points mPoints; 78 T mHostTimeSampler; 79 }; 80 81 } // namespace link 82 } // namespace ableton 83