Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.5KB

  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. #pragma once
  20. #include <ableton/link/Beats.hpp>
  21. #include <chrono>
  22. namespace ableton
  23. {
  24. namespace link
  25. {
  26. struct Tempo : std::tuple<double>
  27. {
  28. Tempo() = default;
  29. // Beats per minute
  30. explicit Tempo(const double bpm)
  31. : std::tuple<double>(bpm)
  32. {
  33. }
  34. Tempo(const std::chrono::microseconds microsPerBeat)
  35. : std::tuple<double>(60. * 1e6 / microsPerBeat.count())
  36. {
  37. }
  38. double bpm() const
  39. {
  40. return std::get<0>(*this);
  41. }
  42. std::chrono::microseconds microsPerBeat() const
  43. {
  44. return std::chrono::microseconds{llround(60. * 1e6 / bpm())};
  45. }
  46. // Given the tempo, convert a time to a beat value
  47. Beats microsToBeats(const std::chrono::microseconds micros) const
  48. {
  49. return Beats{micros.count() / static_cast<double>(microsPerBeat().count())};
  50. }
  51. // Given the tempo, convert a beat to a time value
  52. std::chrono::microseconds beatsToMicros(const Beats beats) const
  53. {
  54. return std::chrono::microseconds{llround(beats.floating() * microsPerBeat().count())};
  55. }
  56. // Model the NetworkByteStreamSerializable concept
  57. friend std::uint32_t sizeInByteStream(const Tempo tempo)
  58. {
  59. return discovery::sizeInByteStream(tempo.microsPerBeat());
  60. }
  61. template <typename It>
  62. friend It toNetworkByteStream(const Tempo tempo, It out)
  63. {
  64. return discovery::toNetworkByteStream(tempo.microsPerBeat(), std::move(out));
  65. }
  66. template <typename It>
  67. static std::pair<Tempo, It> fromNetworkByteStream(It begin, It end)
  68. {
  69. auto result =
  70. discovery::Deserialize<std::chrono::microseconds>::fromNetworkByteStream(
  71. std::move(begin), std::move(end));
  72. return std::make_pair(Tempo{std::move(result.first)}, std::move(result.second));
  73. }
  74. };
  75. } // namespace link
  76. } // namespace ableton