Loop.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <iostream>
  2. #include <thread>
  3. #include <mutex>
  4. #include <chrono>
  5. #include <vector>
  6. #include "Bar.h"
  7. class Loop
  8. {
  9. std::thread loopThread;
  10. std::chrono::milliseconds lastBeatTime;
  11. unsigned short bpm;
  12. std::mutex bpmLock;
  13. bool stopNext;
  14. public:
  15. bool enabled;
  16. unsigned short currentBarIndex;
  17. unsigned short currentBeatIndex;
  18. std::vector<Bar> bars;
  19. Loop()
  20. : loopThread(&Loop::loop, this),
  21. bpm(60), stopNext(false), enabled(false),
  22. currentBarIndex(0), currentBeatIndex(0),
  23. lastBeatTime(0), bars(1)
  24. {
  25. }
  26. ~Loop()
  27. {
  28. stopNext = true;
  29. loopThread.join();
  30. }
  31. void setBpm(unsigned short b)
  32. {
  33. bpmLock.lock();
  34. bpm = b;
  35. bpmLock.unlock();
  36. }
  37. unsigned short getBpm()
  38. {
  39. bpmLock.lock();
  40. unsigned short r = bpm;
  41. bpmLock.unlock();
  42. return r;
  43. }
  44. std::chrono::milliseconds getBeatDuration()
  45. {
  46. return std::chrono::milliseconds(
  47. (long long)((double)60 * 1000 / bpm)
  48. );
  49. }
  50. void start()
  51. {
  52. enabled = true;
  53. }
  54. void stop()
  55. {
  56. enabled = false;
  57. }
  58. private:
  59. std::chrono::milliseconds getMillisecondsSinceEpoch()
  60. {
  61. std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
  62. std::chrono::system_clock::duration duration = now.time_since_epoch();
  63. return std::chrono::duration_cast<std::chrono::milliseconds>(duration);
  64. }
  65. void beat()
  66. {
  67. // std::cout << "\a" << lastBeatTime.count() << std::endl;
  68. if(bars.size() > 0) {
  69. if(currentBarIndex >= bars.size()) {
  70. currentBarIndex = 0;
  71. }
  72. if(currentBeatIndex >= bars[currentBarIndex].beatsCount) {
  73. currentBeatIndex = 0;
  74. currentBarIndex++;
  75. if(currentBarIndex >= bars.size()) {
  76. currentBarIndex = 0;
  77. }
  78. }
  79. std::cout << "trigger bar#" << currentBarIndex << " beat#" << currentBeatIndex << std::endl;
  80. bars[currentBarIndex].beats[currentBeatIndex].trigger();
  81. currentBeatIndex++;
  82. }
  83. lastBeatTime = getMillisecondsSinceEpoch();
  84. }
  85. void loop()
  86. {
  87. while(!stopNext) {
  88. if(enabled && (getMillisecondsSinceEpoch() - lastBeatTime) >= getBeatDuration()) {
  89. beat();
  90. }
  91. }
  92. }
  93. };