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/discovery/NetworkByteStreamSerializable.hpp> 23 #include <cmath> 24 #include <cstdint> 25 #include <tuple> 26 27 namespace ableton 28 { 29 namespace link 30 { 31 32 struct Beats : std::tuple<std::int64_t> 33 { 34 Beats() = default; 35 Beatsableton::link::Beats36 explicit Beats(const double beats) 37 : std::tuple<std::int64_t>(llround(beats * 1e6)) 38 { 39 } 40 Beatsableton::link::Beats41 explicit Beats(const std::int64_t microBeats) 42 : std::tuple<std::int64_t>(microBeats) 43 { 44 } 45 floatingableton::link::Beats46 double floating() const 47 { 48 return microBeats() / 1e6; 49 } 50 microBeatsableton::link::Beats51 std::int64_t microBeats() const 52 { 53 return std::get<0>(*this); 54 } 55 operator -ableton::link::Beats56 Beats operator-() const 57 { 58 return Beats{-microBeats()}; 59 } 60 abs(const Beats b)61 friend Beats abs(const Beats b) 62 { 63 return Beats{std::abs(b.microBeats())}; 64 } 65 operator +(const Beats lhs,const Beats rhs)66 friend Beats operator+(const Beats lhs, const Beats rhs) 67 { 68 return Beats{lhs.microBeats() + rhs.microBeats()}; 69 } 70 operator -(const Beats lhs,const Beats rhs)71 friend Beats operator-(const Beats lhs, const Beats rhs) 72 { 73 return Beats{lhs.microBeats() - rhs.microBeats()}; 74 } 75 operator %(const Beats lhs,const Beats rhs)76 friend Beats operator%(const Beats lhs, const Beats rhs) 77 { 78 return rhs == Beats{0.} ? Beats{0.} : Beats{lhs.microBeats() % rhs.microBeats()}; 79 } 80 81 // Model the NetworkByteStreamSerializable concept sizeInByteStream(const Beats beats)82 friend std::uint32_t sizeInByteStream(const Beats beats) 83 { 84 return discovery::sizeInByteStream(beats.microBeats()); 85 } 86 87 template <typename It> toNetworkByteStream(const Beats beats,It out)88 friend It toNetworkByteStream(const Beats beats, It out) 89 { 90 return discovery::toNetworkByteStream(beats.microBeats(), std::move(out)); 91 } 92 93 template <typename It> fromNetworkByteStreamableton::link::Beats94 static std::pair<Beats, It> fromNetworkByteStream(It begin, It end) 95 { 96 auto result = discovery::Deserialize<std::int64_t>::fromNetworkByteStream( 97 std::move(begin), std::move(end)); 98 return std::make_pair(Beats{result.first}, std::move(result.second)); 99 } 100 }; 101 102 } // namespace link 103 } // namespace ableton 104