Remove dubious Evoral::Event methods that exposed non-const references to members.

git-svn-id: svn://localhost/ardour2/branches/3.0@10239 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2011-10-19 18:11:31 +00:00
parent a189d3e43b
commit 18c2ee4a26
6 changed files with 120 additions and 96 deletions

View file

@ -99,7 +99,7 @@ MidiStretch::run (boost::shared_ptr<Region> r, Progress*)
// FIXME: double copy // FIXME: double copy
Evoral::Event<MidiModel::TimeType> ev(*i, true); Evoral::Event<MidiModel::TimeType> ev(*i, true);
ev.time() = new_time; ev.set_time(new_time);
new_model->append(ev, Evoral::next_event_id()); new_model->append(ev, Evoral::next_event_id());
} }

View file

@ -497,7 +497,7 @@ SMFSource::load_model (bool lock, bool force_reload)
uint64_t time = 0; /* in SMF ticks */ uint64_t time = 0; /* in SMF ticks */
Evoral::Event<double> ev; 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 delta_t = 0;
uint32_t size = 0; uint32_t size = 0;
@ -547,11 +547,9 @@ SMFSource::load_model (bool lock, bool force_reload)
_model->append (ev, event_id); _model->append (ev, event_id);
if (ev.size() > scratch_size) { // Set size to max capacity to minimize allocs in read_event
scratch_size = ev.size(); scratch_size = std::max(size, scratch_size);
} size = scratch_size;
ev.size() = scratch_size; // ensure read_event only allocates if necessary
_length_beats = max(_length_beats, ev.time()); _length_beats = max(_length_beats, ev.time());
} }

View file

@ -19,11 +19,12 @@
#ifndef EVORAL_EVENT_HPP #ifndef EVORAL_EVENT_HPP
#define EVORAL_EVENT_HPP #define EVORAL_EVENT_HPP
#include <stdint.h> #include <assert.h>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <assert.h> #include <stdint.h>
#include "evoral/types.hpp" #include "evoral/types.hpp"
/** If this is not defined, all methods of MidiEvent are RT safe /** If this is not defined, all methods of MidiEvent are RT safe
@ -36,7 +37,7 @@ namespace Evoral {
event_id_t event_id_counter(); event_id_t event_id_counter();
event_id_t next_event_id(); 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) /** An event (much like a type generic jack_midi_event_t)
* *
@ -57,43 +58,9 @@ struct Event {
~Event(); ~Event();
inline const Event& operator=(const Event& copy) { 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; void set(uint8_t* buf, uint32_t size, Time t);
return *this;
}
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;
}
inline bool operator==(const Event& other) const { inline bool operator==(const Event& other) const {
if (_type != other._type) if (_type != other._type)
@ -158,35 +125,31 @@ struct Event {
#endif // EVORAL_EVENT_ALLOC #endif // EVORAL_EVENT_ALLOC
inline EventType event_type() const { return _type; } 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() const { return _nominal_time; } inline Time original_time() const { return _original_time; }
inline Time& time() { return _nominal_time; } inline uint32_t size() const { return _size; }
inline Time original_time() const { return _original_time; } inline const uint8_t* buffer() const { return _buf; }
inline Time& original_time() { return _original_time; } inline uint8_t* buffer() { return _buf; }
inline uint32_t size() const { return _size; }
inline uint32_t& size() { return _size; }
inline const uint8_t* buffer() const { return _buf; } inline void set_event_type(EventType t) { _type = t; }
inline uint8_t*& buffer() { return _buf; }
void set_time (Time); void set_time(Time);
void set_original_time (Time); void set_original_time(Time);
inline event_id_t id() const { return _id; } inline event_id_t id() const { return _id; }
inline void set_id (event_id_t n) { _id = n; } inline void set_id(event_id_t n) { _id = n; }
protected: protected:
EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */ EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
Time _original_time; /**< Sample index (or beat time) at which event is valid */ Time _original_time; /**< Sample index (or beat time) at which event is valid */
Time _nominal_time; /**< Quantized version of _time, used in preference */ Time _nominal_time; /**< Quantized version of _time, used in preference */
uint32_t _size; /**< Number of uint8_ts of data in \a buffer */ uint32_t _size; /**< Number of uint8_ts of data in \a buffer */
uint8_t* _buf; /**< Raw MIDI data */ 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 #ifdef EVORAL_EVENT_ALLOC
bool _owns_buf; /**< Whether buffer is locally allocated */ bool _owns_buf; /**< Whether buffer is locally allocated */
#endif #endif
event_id_t _id; /** UUID for each event, should probably be 64bit or at least unsigned */
}; };
} // namespace Evoral } // namespace Evoral

View file

@ -51,34 +51,53 @@ public:
inline event_id_t id() const { return _on_event.id(); } inline event_id_t id() const { return _on_event.id(); }
void set_id (event_id_t); void set_id (event_id_t);
inline Time time() const { return _on_event.time(); } inline Time time() const { return _on_event.time(); }
inline Time end_time() const { return _off_event.time(); } inline Time end_time() const { return _off_event.time(); }
inline uint8_t note() const { return _on_event.note(); } inline uint8_t note() const { return _on_event.note(); }
inline uint8_t velocity() const { return _on_event.velocity(); } inline uint8_t velocity() const { return _on_event.velocity(); }
inline uint8_t off_velocity() const { return _off_event.velocity(); } inline uint8_t off_velocity() const { return _off_event.velocity(); }
inline Time length() const { return _off_event.time() - _on_event.time(); } inline Time length() const { return _off_event.time() - _on_event.time(); }
inline uint8_t channel() const { inline uint8_t channel() const {
assert(_on_event.channel() == _off_event.channel()); assert(_on_event.channel() == _off_event.channel());
return _on_event.channel(); return _on_event.channel();
} }
private: private:
inline int clamp (int val, int low, int high) { return std::min (std::max (val, low), high); } inline int clamp(int val, int low, int high) {
return std::min (std::max (val, low), high);
}
public: public:
inline void set_time(Time t) { _off_event.time() = t + length(); _on_event.time() = t; } inline void set_time(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; } _off_event.set_time(t + length());
inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = clamp (n, 0, 127); } _on_event.set_time(t);
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_note(uint8_t n) {
inline void set_channel(uint8_t c) { uint8_t cc = clamp (c, 0, 16); _on_event.set_channel(cc); _off_event.set_channel(cc); } 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 Event<Time>& on_event() { return _on_event; }
inline const Event<Time>& on_event() const { return _on_event; } inline const Event<Time>& on_event() const { return _on_event; }
inline Event<Time>& off_event() { return _off_event; } inline Event<Time>& off_event() { return _off_event; }
inline const Event<Time>& off_event() const { return _off_event; } inline const Event<Time>& off_event() const { return _off_event; }
private: private:
// Event buffers are self-contained // Event buffers are self-contained
MIDIEvent<Time> _on_event; MIDIEvent<Time> _on_event;
MIDIEvent<Time> _off_event; MIDIEvent<Time> _off_event;

View file

@ -26,32 +26,32 @@ static event_id_t _event_id_counter = 0;
event_id_t event_id_t
event_id_counter() event_id_counter()
{ {
return g_atomic_int_get (&_event_id_counter); return g_atomic_int_get (&_event_id_counter);
} }
void void
init_event_id_counter(event_id_t n) 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 event_id_t
next_event_id () 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 #ifdef EVORAL_EVENT_ALLOC
template<typename Timestamp> template<typename Timestamp>
Event<Timestamp>::Event(EventType type, Timestamp time, uint32_t size, uint8_t* buf, bool alloc) Event<Timestamp>::Event(EventType type, Timestamp time, uint32_t size, uint8_t* buf, bool alloc)
: _type(type) : _type(type)
, _original_time(time) , _original_time(time)
, _nominal_time(time) , _nominal_time(time)
, _size(size) , _size(size)
, _buf(buf) , _buf(buf)
, _id(-1)
, _owns_buf(alloc) , _owns_buf(alloc)
, _id (-1)
{ {
if (alloc) { if (alloc) {
_buf = (uint8_t*)malloc(_size); _buf = (uint8_t*)malloc(_size);
@ -70,8 +70,8 @@ Event<Timestamp>::Event(const Event& copy, bool owns_buf)
, _nominal_time(copy._nominal_time) , _nominal_time(copy._nominal_time)
, _size(copy._size) , _size(copy._size)
, _buf(copy._buf) , _buf(copy._buf)
, _id(copy.id())
, _owns_buf(owns_buf) , _owns_buf(owns_buf)
, _id (copy.id())
{ {
if (owns_buf) { if (owns_buf) {
_buf = (uint8_t*)malloc(_size); _buf = (uint8_t*)malloc(_size);
@ -90,6 +90,50 @@ Event<Timestamp>::~Event() {
} }
} }
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> template<typename Timestamp>
void void
Event<Timestamp>::set_time (Timestamp t) Event<Timestamp>::set_time (Timestamp t)

View file

@ -539,7 +539,7 @@ Sequence<Time>::control_to_midi_event(
assert(iter.list->parameter().id() <= INT8_MAX); assert(iter.list->parameter().id() <= INT8_MAX);
assert(iter.y <= INT8_MAX); assert(iter.y <= INT8_MAX);
ev->time() = iter.x; ev->set_time(iter.x);
ev->realloc(3); ev->realloc(3);
ev->buffer()[0] = MIDI_CMD_CONTROL + iter.list->parameter().channel(); ev->buffer()[0] = MIDI_CMD_CONTROL + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.list->parameter().id(); ev->buffer()[1] = (uint8_t)iter.list->parameter().id();
@ -551,7 +551,7 @@ Sequence<Time>::control_to_midi_event(
assert(iter.list->parameter().channel() < 16); assert(iter.list->parameter().channel() < 16);
assert(iter.y <= INT8_MAX); assert(iter.y <= INT8_MAX);
ev->time() = iter.x; ev->set_time(iter.x);
ev->realloc(2); ev->realloc(2);
ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.list->parameter().channel(); ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.y; ev->buffer()[1] = (uint8_t)iter.y;
@ -562,7 +562,7 @@ Sequence<Time>::control_to_midi_event(
assert(iter.list->parameter().channel() < 16); assert(iter.list->parameter().channel() < 16);
assert(iter.y < (1<<14)); assert(iter.y < (1<<14));
ev->time() = iter.x; ev->set_time(iter.x);
ev->realloc(3); ev->realloc(3);
ev->buffer()[0] = MIDI_CMD_BENDER + iter.list->parameter().channel(); ev->buffer()[0] = MIDI_CMD_BENDER + iter.list->parameter().channel();
ev->buffer()[1] = uint16_t(iter.y) & 0x7F; // LSB ev->buffer()[1] = uint16_t(iter.y) & 0x7F; // LSB
@ -574,7 +574,7 @@ Sequence<Time>::control_to_midi_event(
assert(iter.list->parameter().channel() < 16); assert(iter.list->parameter().channel() < 16);
assert(iter.y <= INT8_MAX); assert(iter.y <= INT8_MAX);
ev->time() = iter.x; ev->set_time(iter.x);
ev->realloc(2); ev->realloc(2);
ev->buffer()[0] = MIDI_CMD_CHANNEL_PRESSURE + iter.list->parameter().channel(); ev->buffer()[0] = MIDI_CMD_CHANNEL_PRESSURE + iter.list->parameter().channel();
ev->buffer()[1] = (uint8_t)iter.y; ev->buffer()[1] = (uint8_t)iter.y;