summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/midi_buffer.h26
-rw-r--r--libs/evoral/evoral/midi_util.h34
-rw-r--r--libs/evoral/src/SMF.cpp2
-rw-r--r--libs/evoral/src/SMFReader.cpp2
4 files changed, 46 insertions, 18 deletions
diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h
index 88aac0af64..f90cbfd8e3 100644
--- a/libs/ardour/ardour/midi_buffer.h
+++ b/libs/ardour/ardour/midi_buffer.h
@@ -52,27 +52,29 @@ public:
bool merge(const MidiBuffer& a, const MidiBuffer& b);
bool merge_in_place(const MidiBuffer &other);
- template<typename B, typename E>
+ template<typename BufferType, typename MIDIEventType>
struct iterator_base {
- iterator_base<B,E>(B& b, size_t o) : buffer(b), offset(o) {}
- inline E operator*() const {
+ iterator_base<BufferType, MIDIEventType>(BufferType& b, size_t o) : buffer(b), offset(o) {}
+ inline MIDIEventType operator*() const {
uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
- assert(Evoral::midi_event_size(*ev_start) >= 0);
- return E(EventTypeMap::instance().midi_event_type(*ev_start),
+ int event_size = Evoral::midi_event_size(ev_start);
+ assert(event_size >= 0);
+ return MIDIEventType(EventTypeMap::instance().midi_event_type(*ev_start),
*((TimeType*)(buffer._data + offset)),
- Evoral::midi_event_size(*ev_start) + 1, ev_start);
+ event_size, ev_start);
}
- inline iterator_base<B,E>& operator++() {
+ inline iterator_base<BufferType, MIDIEventType>& operator++() {
uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
- assert(Evoral::midi_event_size(*ev_start) >= 0);
- offset += sizeof(TimeType) + Evoral::midi_event_size(*ev_start) + 1;
+ int event_size = Evoral::midi_event_size(ev_start);
+ assert(event_size >= 0);
+ offset += sizeof(TimeType) + event_size;
return *this;
}
- inline bool operator!=(const iterator_base<B,E>& other) const {
+ inline bool operator!=(const iterator_base<BufferType, MIDIEventType>& other) const {
return (&buffer != &other.buffer) || (offset != other.offset);
}
- B& buffer;
- size_t offset;
+ BufferType& buffer;
+ size_t offset;
};
typedef iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> > iterator;
diff --git a/libs/evoral/evoral/midi_util.h b/libs/evoral/evoral/midi_util.h
index 9a74ee6e12..1d2fe71232 100644
--- a/libs/evoral/evoral/midi_util.h
+++ b/libs/evoral/evoral/midi_util.h
@@ -19,11 +19,13 @@
#ifndef EVORAL_MIDI_UTIL_H
#define EVORAL_MIDI_UTIL_H
+#include <assert.h>
+
#include "evoral/midi_events.h"
namespace Evoral {
-/** Return the size of the given event NOT including the status byte,
+/** Return the size of the given event NOT the status byte,
* or -1 if unknown (eg sysex)
*/
static inline int
@@ -41,13 +43,13 @@ midi_event_size(unsigned char status)
case MIDI_CMD_CONTROL:
case MIDI_CMD_BENDER:
case MIDI_CMD_COMMON_SONG_POS:
- return 2;
+ return 3;
case MIDI_CMD_PGM_CHANGE:
case MIDI_CMD_CHANNEL_PRESSURE:
case MIDI_CMD_COMMON_MTC_QUARTER:
case MIDI_CMD_COMMON_SONG_SELECT:
- return 1;
+ return 2;
case MIDI_CMD_COMMON_TUNE_REQUEST:
case MIDI_CMD_COMMON_SYSEX_END:
@@ -57,7 +59,7 @@ midi_event_size(unsigned char status)
case MIDI_CMD_COMMON_STOP:
case MIDI_CMD_COMMON_SENSING:
case MIDI_CMD_COMMON_RESET:
- return 0;
+ return 1;
case MIDI_CMD_COMMON_SYSEX:
return -1;
@@ -66,6 +68,30 @@ midi_event_size(unsigned char status)
return -1;
}
+/** Return the size of the given event including the status byte
+ * (which must be the first byte in \a buffer),
+ * or -1 if unknown (eg sysex)
+ */
+static inline int
+midi_event_size(uint8_t* buffer)
+{
+ uint8_t status = buffer[0];
+
+ // if we have a channel event
+ if (status >= 0x80 && status < 0xF0) {
+ status &= 0xF0; // mask off the channel
+ }
+
+ if (status == MIDI_CMD_COMMON_SYSEX) {
+ int end;
+ for (end = 1; buffer[end] != MIDI_CMD_COMMON_SYSEX_END; end++);
+ assert(buffer[end] == MIDI_CMD_COMMON_SYSEX_END);
+ return end + 1;
+ } else {
+ return midi_event_size(status);
+ }
+}
+
} // namespace Evoral
#endif // EVORAL_MIDI_UTIL_H
diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp
index a362c602a7..f5fff726ca 100644
--- a/libs/evoral/src/SMF.cpp
+++ b/libs/evoral/src/SMF.cpp
@@ -249,7 +249,7 @@ SMF<T>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
}
}
- const int event_size = midi_event_size((unsigned char)status) + 1;
+ const int event_size = midi_event_size((unsigned char)status);
if (event_size <= 0) {
*size = 0;
return 0;
diff --git a/libs/evoral/src/SMFReader.cpp b/libs/evoral/src/SMFReader.cpp
index fa76d3aa39..e992514191 100644
--- a/libs/evoral/src/SMFReader.cpp
+++ b/libs/evoral/src/SMFReader.cpp
@@ -200,7 +200,7 @@ SMFReader::read_event(size_t buf_len,
fseek(_fd, -1, SEEK_CUR);
} else {
last_status = status;
- *ev_size = midi_event_size(status) + 1;
+ *ev_size = midi_event_size(status);
last_size = *ev_size;
}