- // This event marks a loop happening. this means that
- // the next events timestamp will be non-monotonic.
- if (ev_type == LoopEventType) {
- ev_time -= start;
- ev_time += offset;
- Evoral::MIDIEvent<T> loopevent(LoopEventType, ev_time);
- dst.push_back(loopevent);
-
- // We can safely return, without reading the data, because
- // a LoopEvent does not have data.
- return count + 1;
+ // write MIDI buffer contents
+
+ bool success = read_contents (ev_size, write_loc);
+#ifndef NDEBUG
+ if (DEBUG_ENABLED (DEBUG::MidiRingBuffer)) {
+ DEBUG_STR_DECL(a);
+ DEBUG_STR_APPEND(a, string_compose ("wrote MidiEvent to Buffer (time=%1, start=%2 offset=%3) ", ev_time, start, offset));
+ for (size_t i=0; i < ev_size; ++i) {
+ DEBUG_STR_APPEND(a,hex);
+ DEBUG_STR_APPEND(a,"0x");
+ DEBUG_STR_APPEND(a,(int)write_loc[i]);
+ DEBUG_STR_APPEND(a,' ');
+ }
+ DEBUG_STR_APPEND(a,'\n');
+ DEBUG_TRACE (DEBUG::MidiRingBuffer, DEBUG_STR(a).str());
+ }
+#endif
+ if (success) {
+ _tracker.track(write_loc);
+ ++count;
+ } else {
+ cerr << "WARNING: error reading event contents from MIDI ring" << endl;
+ }
+ }
+
+ return count;
+}
+
+template<typename T>
+size_t
+MidiRingBuffer<T>::skip_to(framepos_t start)
+{
+ if (this->read_space() == 0) {
+ return 0;
+ }
+
+ T ev_time;
+ uint32_t ev_size;
+ size_t count = 0;
+ const size_t prefix_size = sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t);
+
+ while (this->read_space() >= prefix_size) {
+
+ uint8_t peekbuf[prefix_size];
+ this->peek (peekbuf, prefix_size);
+
+ ev_time = *(reinterpret_cast<T*>((uintptr_t)peekbuf));
+ ev_size = *(reinterpret_cast<uint32_t*>((uintptr_t)(peekbuf + sizeof(T) + sizeof (Evoral::EventType))));
+
+ if (ev_time >= start) {
+ return count;
+ }
+
+ if (this->read_space() < ev_size) {
+ continue;