123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #include "BeatSequence.h"
- #include <sstream>
- namespace midi {
- BeatSequence::BeatSequence()
- : BeatSequence(0)
- {
- }
- BeatSequence::BeatSequence(BeatIndex size)
- : parent(size)
- {
- }
- void BeatSequence::expand(BeatIndex factor)
- {
- if(factor < 1) {
- throw "factor may not be less than 1.";
- }
- resize(size() * factor);
- for(signed int targetIndex = (size() - factor); targetIndex > 0; targetIndex -= factor)
- {
- BeatIndex sourceIndex = targetIndex / factor;
- at(sourceIndex).swap(at(targetIndex));
- }
- }
- void BeatSequence::reduce(BeatIndex factor)
- {
- reduce(factor, 0, 0);
- }
- void BeatSequence::reduce(BeatIndex factor, ReducationConflictCallback conflictCallback, void* conflictCallbackData)
- {
- if(factor < 1) {
- throw "factor may not be less than 1.";
- }
- if(conflictCallback != 0) {
- for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
- if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
- conflictCallback(*this, factor, beatIndex, conflictCallbackData);
- }
- }
- }
-
- for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
- if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
- throw new UnresolvedBeatSequenceReducationConflict(beatIndex);
- }
- }
- BeatIndex targetSize = (size() + factor - 1) / factor;
- for(BeatIndex targetIndex = 0; targetIndex < targetSize; targetIndex++) {
- BeatIndex sourceIndex = targetIndex * factor;
- at(sourceIndex).swap(at(targetIndex));
- }
- resize(targetSize);
- }
- void BeatSequence::print(std::ostream& stream) const
- {
- if(size() == 0) {
- stream << "beat sequence of length 0\n";
- } else {
- stream << "beat sequence:\n";
- for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
- std::stringstream beatLabelStream;
- beatLabelStream << "beat #" << beatIndex << ": ";
- std::string beatLabel = beatLabelStream.str();
- stream << beatLabel;
- std::string spacer(beatLabel.size(), ' ');
- const MessageList& beat = at(beatIndex);
- if(beat.size() == 0) {
- stream << "no message" << "\n";
- } else {
- for(MessageList::const_iterator msg_it = beat.begin(); msg_it != beat.end(); msg_it++) {
- if(msg_it != beat.begin()) {
- stream << spacer;
- }
- (*msg_it)->print(stream);
- }
- }
- }
- }
- stream << "\n";
- stream.flush();
- }
-
- void BeatSequence::reduceToNeighbour(BeatIndex factor)
- {
- reduce(factor, moveReducationConflictToNextNeighbour, 0);
- }
-
- void BeatSequence::moveReducationConflictToNextNeighbour(BeatSequence& sequence, BeatIndex factor, BeatIndex beatIndex, void* data)
- {
- BeatSequence::BeatIndex previousIndex = beatIndex / factor * factor;
- BeatSequence::BeatIndex targetIndex;
- if((beatIndex - previousIndex) * 2 <= factor) {
- targetIndex = previousIndex;
- } else {
- targetIndex = previousIndex + factor;
- if(targetIndex >= sequence.size()) {
- targetIndex = 0;
- }
- }
-
- MessageList& targetBeat = sequence[targetIndex];
- targetBeat.splice(targetBeat.end(), sequence[beatIndex]);
- }
- UnresolvedBeatSequenceReducationConflict::UnresolvedBeatSequenceReducationConflict(BeatSequence::BeatIndex beatIndex)
- : parent("unresolved beat sequence reducation conflict"), beatIndex(beatIndex)
- {
- }
- const char* UnresolvedBeatSequenceReducationConflict::what() const throw()
- {
- std::stringstream info;
- info << parent::what() << " at beat #" << getBeatIndex();
- return info.str().c_str();
- }
- BeatSequence::BeatIndex UnresolvedBeatSequenceReducationConflict::getBeatIndex() const
- {
- return beatIndex;
- }
- } // namepsace
|