// FIXME: double copy
Evoral::Event<MidiModel::TimeType> ev(*i, true);
- ev.time() = new_time;
+ ev.set_time(new_time);
new_model->append(ev, Evoral::next_event_id());
}
uint64_t time = 0; /* in SMF ticks */
Evoral::Event<double> ev;
- size_t scratch_size = 0; // keep track of scratch and minimize reallocs
+ uint32_t scratch_size = 0; // keep track of scratch and minimize reallocs
uint32_t delta_t = 0;
uint32_t size = 0;
_model->append (ev, event_id);
- if (ev.size() > scratch_size) {
- scratch_size = ev.size();
- }
-
- ev.size() = scratch_size; // ensure read_event only allocates if necessary
+ // Set size to max capacity to minimize allocs in read_event
+ scratch_size = std::max(size, scratch_size);
+ size = scratch_size;
_length_beats = max(_length_beats, ev.time());
}
#ifndef EVORAL_EVENT_HPP
#define EVORAL_EVENT_HPP
-#include <stdint.h>
+#include <assert.h>
#include <cstdlib>
#include <cstring>
#include <sstream>
-#include <assert.h>
+#include <stdint.h>
+
#include "evoral/types.hpp"
/** If this is not defined, all methods of MidiEvent are RT safe
event_id_t event_id_counter();
event_id_t next_event_id();
-void init_event_id_counter (event_id_t n);
+void init_event_id_counter(event_id_t n);
/** An event (much like a type generic jack_midi_event_t)
*
~Event();
- inline const Event& operator=(const Event& copy) {
- _id = copy.id(); // XXX is this right? do we want ID copy semantics?
- _type = copy._type;
- _original_time = copy._original_time;
- _nominal_time = copy._nominal_time;
- if (_owns_buf) {
- if (copy._buf) {
- if (copy._size > _size) {
- _buf = (uint8_t*)::realloc(_buf, copy._size);
- }
- memcpy(_buf, copy._buf, copy._size);
- } else {
- free(_buf);
- _buf = NULL;
- }
- } else {
- _buf = copy._buf;
- }
-
- _size = copy._size;
- return *this;
- }
+ const Event& operator=(const Event& copy);
- inline void set(uint8_t* buf, uint32_t size, Time t) {
- if (_owns_buf) {
- if (_size < size) {
- _buf = (uint8_t*) ::realloc(_buf, size);
- }
- memcpy (_buf, buf, size);
- } else {
- _buf = buf;
- }
-
- _original_time = t;
- _nominal_time = t;
- _size = size;
- }
+ void set(uint8_t* buf, uint32_t size, Time t);
inline bool operator==(const Event& other) const {
if (_type != other._type)
#endif // EVORAL_EVENT_ALLOC
- inline EventType event_type() const { return _type; }
- inline void set_event_type(EventType t) { _type = t; }
- inline Time time() const { return _nominal_time; }
- inline Time& time() { return _nominal_time; }
- inline Time original_time() const { return _original_time; }
- inline Time& original_time() { return _original_time; }
- inline uint32_t size() const { return _size; }
- inline uint32_t& size() { return _size; }
+ inline EventType event_type() const { return _type; }
+ inline Time time() const { return _nominal_time; }
+ inline Time original_time() const { return _original_time; }
+ inline uint32_t size() const { return _size; }
+ inline const uint8_t* buffer() const { return _buf; }
+ inline uint8_t* buffer() { return _buf; }
- inline const uint8_t* buffer() const { return _buf; }
- inline uint8_t*& buffer() { return _buf; }
+ inline void set_event_type(EventType t) { _type = t; }
- void set_time (Time);
- void set_original_time (Time);
+ void set_time(Time);
+ void set_original_time(Time);
- inline event_id_t id() const { return _id; }
- inline void set_id (event_id_t n) { _id = n; }
+ inline event_id_t id() const { return _id; }
+ inline void set_id(event_id_t n) { _id = n; }
protected:
- EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
- Time _original_time; /**< Sample index (or beat time) at which event is valid */
- Time _nominal_time; /**< Quantized version of _time, used in preference */
- uint32_t _size; /**< Number of uint8_ts of data in \a buffer */
- uint8_t* _buf; /**< Raw MIDI data */
-
+ EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
+ Time _original_time; /**< Sample index (or beat time) at which event is valid */
+ Time _nominal_time; /**< Quantized version of _time, used in preference */
+ uint32_t _size; /**< Number of uint8_ts of data in \a buffer */
+ uint8_t* _buf; /**< Raw MIDI data */
+ event_id_t _id; /** UUID for each event, should probably be 64bit or at least unsigned */
#ifdef EVORAL_EVENT_ALLOC
- bool _owns_buf; /**< Whether buffer is locally allocated */
+ bool _owns_buf; /**< Whether buffer is locally allocated */
#endif
- event_id_t _id; /** UUID for each event, should probably be 64bit or at least unsigned */
};
} // namespace Evoral
inline event_id_t id() const { return _on_event.id(); }
void set_id (event_id_t);
- inline Time time() const { return _on_event.time(); }
- inline Time end_time() const { return _off_event.time(); }
- inline uint8_t note() const { return _on_event.note(); }
- inline uint8_t velocity() const { return _on_event.velocity(); }
- inline uint8_t off_velocity() const { return _off_event.velocity(); }
- inline Time length() const { return _off_event.time() - _on_event.time(); }
- inline uint8_t channel() const {
+ inline Time time() const { return _on_event.time(); }
+ inline Time end_time() const { return _off_event.time(); }
+ inline uint8_t note() const { return _on_event.note(); }
+ inline uint8_t velocity() const { return _on_event.velocity(); }
+ inline uint8_t off_velocity() const { return _off_event.velocity(); }
+ inline Time length() const { return _off_event.time() - _on_event.time(); }
+ inline uint8_t channel() const {
assert(_on_event.channel() == _off_event.channel());
- return _on_event.channel();
+ return _on_event.channel();
}
- private:
- inline int clamp (int val, int low, int high) { return std::min (std::max (val, low), high); }
+private:
+ inline int clamp(int val, int low, int high) {
+ return std::min (std::max (val, low), high);
+ }
- public:
- inline void set_time(Time t) { _off_event.time() = t + length(); _on_event.time() = t; }
- inline void set_note(uint8_t n) { uint8_t nn = clamp (n, 0, 127); _on_event.buffer()[1] = nn; _off_event.buffer()[1] = nn; }
- inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = clamp (n, 0, 127); }
- inline void set_off_velocity(uint8_t n) { _off_event.buffer()[2] = clamp (n, 0, 127); }
- inline void set_length(Time l) { _off_event.time() = _on_event.time() + l; }
- inline void set_channel(uint8_t c) { uint8_t cc = clamp (c, 0, 16); _on_event.set_channel(cc); _off_event.set_channel(cc); }
+public:
+ inline void set_time(Time t) {
+ _off_event.set_time(t + length());
+ _on_event.set_time(t);
+ }
+ inline void set_note(uint8_t n) {
+ const uint8_t nn = clamp(n, 0, 127);
+ _on_event.buffer()[1] = nn;
+ _off_event.buffer()[1] = nn;
+ }
+ inline void set_velocity(uint8_t n) {
+ _on_event.buffer()[2] = clamp(n, 0, 127);
+ }
+ inline void set_off_velocity(uint8_t n) {
+ _off_event.buffer()[2] = clamp(n, 0, 127);
+ }
+ inline void set_length(Time l) {
+ _off_event.set_time(_on_event.time() + l);
+ }
+ inline void set_channel(uint8_t c) {
+ const uint8_t cc = clamp(c, 0, 16);
+ _on_event.set_channel(cc);
+ _off_event.set_channel(cc);
+ }
inline Event<Time>& on_event() { return _on_event; }
inline const Event<Time>& on_event() const { return _on_event; }
inline Event<Time>& off_event() { return _off_event; }
inline const Event<Time>& off_event() const { return _off_event; }
- private:
+private:
// Event buffers are self-contained
MIDIEvent<Time> _on_event;
MIDIEvent<Time> _off_event;
event_id_t
event_id_counter()
{
- return g_atomic_int_get (&_event_id_counter);
+ return g_atomic_int_get (&_event_id_counter);
}
void
init_event_id_counter(event_id_t n)
{
- g_atomic_int_set (&_event_id_counter, n);
+ g_atomic_int_set (&_event_id_counter, n);
}
event_id_t
next_event_id ()
{
- return g_atomic_int_exchange_and_add (&_event_id_counter, 1);
+ return g_atomic_int_exchange_and_add (&_event_id_counter, 1);
}
#ifdef EVORAL_EVENT_ALLOC
template<typename Timestamp>
Event<Timestamp>::Event(EventType type, Timestamp time, uint32_t size, uint8_t* buf, bool alloc)
- : _type(type)
+ : _type(type)
, _original_time(time)
, _nominal_time(time)
, _size(size)
, _buf(buf)
+ , _id(-1)
, _owns_buf(alloc)
- , _id (-1)
{
if (alloc) {
_buf = (uint8_t*)malloc(_size);
, _nominal_time(copy._nominal_time)
, _size(copy._size)
, _buf(copy._buf)
+ , _id(copy.id())
, _owns_buf(owns_buf)
- , _id (copy.id())
{
if (owns_buf) {
_buf = (uint8_t*)malloc(_size);
}
}
+template<typename Timestamp>
+const Event<Timestamp>&
+Event<Timestamp>::operator=(const Event& copy)
+{
+ _id = copy.id(); // XXX is this right? do we want ID copy semantics?
+ _type = copy._type;
+ _original_time = copy._original_time;
+ _nominal_time = copy._nominal_time;
+ if (_owns_buf) {
+ if (copy._buf) {
+ if (copy._size > _size) {
+ _buf = (uint8_t*)::realloc(_buf, copy._size);
+ }
+ memcpy(_buf, copy._buf, copy._size);
+ } else {
+ free(_buf);
+ _buf = NULL;
+ }
+ } else {
+ _buf = copy._buf;
+ }
+
+ _size = copy._size;
+ return *this;
+}
+
+template<typename Timestamp>
+void
+Event<Timestamp>::set(uint8_t* buf, uint32_t size, Timestamp t)
+{
+ if (_owns_buf) {
+ if (_size < size) {
+ _buf = (uint8_t*) ::realloc(_buf, size);
+ }
+ memcpy (_buf, buf, size);
+ } else {
+ _buf = buf;
+ }
+
+ _original_time = t;
+ _nominal_time = t;
+ _size = size;
+}
+
template<typename Timestamp>
void
Event<Timestamp>::set_time (Timestamp t)
assert(iter.list->parameter().id() <= INT8_MAX);
assert(iter.y <= INT8_MAX);
- ev->time() = iter.x;
+ ev->set_time(iter.x);
ev->realloc(3);
ev->buffer()[0] = MIDI_CMD_CONTROL + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.list->parameter().id();
assert(iter.list->parameter().channel() < 16);
assert(iter.y <= INT8_MAX);
- ev->time() = iter.x;
+ ev->set_time(iter.x);
ev->realloc(2);
ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.y;
assert(iter.list->parameter().channel() < 16);
assert(iter.y < (1<<14));
- ev->time() = iter.x;
+ ev->set_time(iter.x);
ev->realloc(3);
ev->buffer()[0] = MIDI_CMD_BENDER + iter.list->parameter().channel();
ev->buffer()[1] = uint16_t(iter.y) & 0x7F; // LSB
assert(iter.list->parameter().channel() < 16);
assert(iter.y <= INT8_MAX);
- ev->time() = iter.x;
+ ev->set_time(iter.x);
ev->realloc(2);
ev->buffer()[0] = MIDI_CMD_CHANNEL_PRESSURE + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.y;