BeatSequence.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "BeatSequence.h"
  2. #include <sstream>
  3. namespace midi {
  4. BeatSequence::BeatSequence()
  5. : BeatSequence(0)
  6. {
  7. }
  8. BeatSequence::BeatSequence(BeatIndex size)
  9. : parent(size)
  10. {
  11. }
  12. void BeatSequence::expand(BeatIndex factor)
  13. {
  14. if(factor < 1) {
  15. throw "factor may not be less than 1.";
  16. }
  17. resize(size() * factor);
  18. for(signed int targetIndex = (size() - factor); targetIndex > 0; targetIndex -= factor)
  19. {
  20. BeatIndex sourceIndex = targetIndex / factor;
  21. at(sourceIndex).swap(at(targetIndex));
  22. }
  23. }
  24. void BeatSequence::reduce(BeatIndex factor)
  25. {
  26. reduce(factor, 0, 0);
  27. }
  28. void BeatSequence::reduce(BeatIndex factor, ReducationConflictCallback conflictCallback, void* conflictCallbackData)
  29. {
  30. if(factor < 1) {
  31. throw "factor may not be less than 1.";
  32. }
  33. if(conflictCallback != 0) {
  34. for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
  35. if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
  36. conflictCallback(*this, factor, beatIndex, conflictCallbackData);
  37. }
  38. }
  39. }
  40. for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
  41. if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
  42. throw new UnresolvedBeatSequenceReducationConflict(beatIndex);
  43. }
  44. }
  45. BeatIndex targetSize = (size() + factor - 1) / factor;
  46. for(BeatIndex targetIndex = 0; targetIndex < targetSize; targetIndex++) {
  47. BeatIndex sourceIndex = targetIndex * factor;
  48. at(sourceIndex).swap(at(targetIndex));
  49. }
  50. resize(targetSize);
  51. }
  52. void BeatSequence::print(std::ostream& stream) const
  53. {
  54. if(size() == 0) {
  55. stream << "beat sequence of length 0\n";
  56. } else {
  57. stream << "beat sequence:\n";
  58. for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
  59. std::stringstream beatLabelStream;
  60. beatLabelStream << "beat #" << beatIndex << ": ";
  61. std::string beatLabel = beatLabelStream.str();
  62. stream << beatLabel;
  63. std::string spacer(beatLabel.size(), ' ');
  64. const MessageList& beat = at(beatIndex);
  65. if(beat.size() == 0) {
  66. stream << "no message" << "\n";
  67. } else {
  68. for(MessageList::const_iterator msg_it = beat.begin(); msg_it != beat.end(); msg_it++) {
  69. if(msg_it != beat.begin()) {
  70. stream << spacer;
  71. }
  72. (*msg_it)->print(stream);
  73. }
  74. }
  75. }
  76. }
  77. stream << "\n";
  78. stream.flush();
  79. }
  80. UnresolvedBeatSequenceReducationConflict::UnresolvedBeatSequenceReducationConflict(BeatSequence::BeatIndex beatIndex)
  81. : parent("unresolved beat sequence reducation conflict"), beatIndex(beatIndex)
  82. {
  83. }
  84. const char* UnresolvedBeatSequenceReducationConflict::what() const throw()
  85. {
  86. std::stringstream info;
  87. info << parent::what() << " at beat #" << getBeatIndex();
  88. return info.str().c_str();
  89. }
  90. BeatSequence::BeatIndex UnresolvedBeatSequenceReducationConflict::getBeatIndex() const
  91. {
  92. return beatIndex;
  93. }
  94. } // namepsace