* 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
This commit is contained in:
Hans Baier 2009-02-03 08:46:24 +00:00
parent 5e3cced3e7
commit 5c73fc42c4
4 changed files with 46 additions and 18 deletions

View file

@ -52,26 +52,28 @@ public:
bool merge(const MidiBuffer& a, const MidiBuffer& b); bool merge(const MidiBuffer& a, const MidiBuffer& b);
bool merge_in_place(const MidiBuffer &other); bool merge_in_place(const MidiBuffer &other);
template<typename B, typename E> template<typename BufferType, typename MIDIEventType>
struct iterator_base { struct iterator_base {
iterator_base<B,E>(B& b, size_t o) : buffer(b), offset(o) {} iterator_base<BufferType, MIDIEventType>(BufferType& b, size_t o) : buffer(b), offset(o) {}
inline E operator*() const { inline MIDIEventType operator*() const {
uint8_t* ev_start = buffer._data + offset + sizeof(TimeType); uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
assert(Evoral::midi_event_size(*ev_start) >= 0); int event_size = Evoral::midi_event_size(ev_start);
return E(EventTypeMap::instance().midi_event_type(*ev_start), assert(event_size >= 0);
return MIDIEventType(EventTypeMap::instance().midi_event_type(*ev_start),
*((TimeType*)(buffer._data + offset)), *((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); uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
assert(Evoral::midi_event_size(*ev_start) >= 0); int event_size = Evoral::midi_event_size(ev_start);
offset += sizeof(TimeType) + Evoral::midi_event_size(*ev_start) + 1; assert(event_size >= 0);
offset += sizeof(TimeType) + event_size;
return *this; 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); return (&buffer != &other.buffer) || (offset != other.offset);
} }
B& buffer; BufferType& buffer;
size_t offset; size_t offset;
}; };

View file

@ -19,11 +19,13 @@
#ifndef EVORAL_MIDI_UTIL_H #ifndef EVORAL_MIDI_UTIL_H
#define EVORAL_MIDI_UTIL_H #define EVORAL_MIDI_UTIL_H
#include <assert.h>
#include "evoral/midi_events.h" #include "evoral/midi_events.h"
namespace Evoral { 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) * or -1 if unknown (eg sysex)
*/ */
static inline int static inline int
@ -41,13 +43,13 @@ midi_event_size(unsigned char status)
case MIDI_CMD_CONTROL: case MIDI_CMD_CONTROL:
case MIDI_CMD_BENDER: case MIDI_CMD_BENDER:
case MIDI_CMD_COMMON_SONG_POS: case MIDI_CMD_COMMON_SONG_POS:
return 2; return 3;
case MIDI_CMD_PGM_CHANGE: case MIDI_CMD_PGM_CHANGE:
case MIDI_CMD_CHANNEL_PRESSURE: case MIDI_CMD_CHANNEL_PRESSURE:
case MIDI_CMD_COMMON_MTC_QUARTER: case MIDI_CMD_COMMON_MTC_QUARTER:
case MIDI_CMD_COMMON_SONG_SELECT: case MIDI_CMD_COMMON_SONG_SELECT:
return 1; return 2;
case MIDI_CMD_COMMON_TUNE_REQUEST: case MIDI_CMD_COMMON_TUNE_REQUEST:
case MIDI_CMD_COMMON_SYSEX_END: 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_STOP:
case MIDI_CMD_COMMON_SENSING: case MIDI_CMD_COMMON_SENSING:
case MIDI_CMD_COMMON_RESET: case MIDI_CMD_COMMON_RESET:
return 0; return 1;
case MIDI_CMD_COMMON_SYSEX: case MIDI_CMD_COMMON_SYSEX:
return -1; return -1;
@ -66,6 +68,30 @@ midi_event_size(unsigned char status)
return -1; 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 } // namespace Evoral
#endif // EVORAL_MIDI_UTIL_H #endif // EVORAL_MIDI_UTIL_H

View file

@ -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) { if (event_size <= 0) {
*size = 0; *size = 0;
return 0; return 0;

View file

@ -200,7 +200,7 @@ SMFReader::read_event(size_t buf_len,
fseek(_fd, -1, SEEK_CUR); fseek(_fd, -1, SEEK_CUR);
} else { } else {
last_status = status; last_status = status;
*ev_size = midi_event_size(status) + 1; *ev_size = midi_event_size(status);
last_size = *ev_size; last_size = *ev_size;
} }