diff options
author | Hans Baier <hansfbaier@googlemail.com> | 2009-02-03 08:46:24 +0000 |
---|---|---|
committer | Hans Baier <hansfbaier@googlemail.com> | 2009-02-03 08:46:24 +0000 |
commit | 5c73fc42c46ffd82789eef6647a820fe6b24d0e7 (patch) | |
tree | 695c1e1192b9226ed0d2fd5f9d90e3cf27f05a06 | |
parent | 5e3cced3e776bca1444c6b5647f89c6fd0d65e00 (diff) |
* midi_event_size(uchar status): return size including status / handle sysex
git-svn-id: svn://localhost/ardour2/branches/3.0@4486 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/ardour/ardour/midi_buffer.h | 26 | ||||
-rw-r--r-- | libs/evoral/evoral/midi_util.h | 34 | ||||
-rw-r--r-- | libs/evoral/src/SMF.cpp | 2 | ||||
-rw-r--r-- | libs/evoral/src/SMFReader.cpp | 2 |
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; } |