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/Beats.hpp> 23 #include <chrono> 24 25 namespace ableton 26 { 27 namespace link 28 { 29 30 struct Tempo : std::tuple<double> 31 { 32 Tempo() = default; 33 34 // Beats per minute Tempoableton::link::Tempo35 explicit Tempo(const double bpm) 36 : std::tuple<double>(bpm) 37 { 38 } 39 Tempoableton::link::Tempo40 Tempo(const std::chrono::microseconds microsPerBeat) 41 : std::tuple<double>(60. * 1e6 / microsPerBeat.count()) 42 { 43 } 44 bpmableton::link::Tempo45 double bpm() const 46 { 47 return std::get<0>(*this); 48 } 49 microsPerBeatableton::link::Tempo50 std::chrono::microseconds microsPerBeat() const 51 { 52 return std::chrono::microseconds{llround(60. * 1e6 / bpm())}; 53 } 54 55 // Given the tempo, convert a time to a beat value microsToBeatsableton::link::Tempo56 Beats microsToBeats(const std::chrono::microseconds micros) const 57 { 58 return Beats{micros.count() / static_cast<double>(microsPerBeat().count())}; 59 } 60 61 // Given the tempo, convert a beat to a time value beatsToMicrosableton::link::Tempo62 std::chrono::microseconds beatsToMicros(const Beats beats) const 63 { 64 return std::chrono::microseconds{llround(beats.floating() * microsPerBeat().count())}; 65 } 66 67 // Model the NetworkByteStreamSerializable concept sizeInByteStream(const Tempo tempo)68 friend std::uint32_t sizeInByteStream(const Tempo tempo) 69 { 70 return discovery::sizeInByteStream(tempo.microsPerBeat()); 71 } 72 73 template <typename It> toNetworkByteStream(const Tempo tempo,It out)74 friend It toNetworkByteStream(const Tempo tempo, It out) 75 { 76 return discovery::toNetworkByteStream(tempo.microsPerBeat(), std::move(out)); 77 } 78 79 template <typename It> fromNetworkByteStreamableton::link::Tempo80 static std::pair<Tempo, It> fromNetworkByteStream(It begin, It end) 81 { 82 auto result = 83 discovery::Deserialize<std::chrono::microseconds>::fromNetworkByteStream( 84 std::move(begin), std::move(end)); 85 return std::make_pair(Tempo{std::move(result.first)}, std::move(result.second)); 86 } 87 }; 88 89 } // namespace link 90 } // namespace ableton 91