mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 08:14:58 +01:00
* Code readability: Template parameter <T> -> <Time>
git-svn-id: svn://localhost/ardour2/branches/3.0@4521 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
7666413e18
commit
494e7feec6
12 changed files with 218 additions and 218 deletions
|
|
@ -38,12 +38,12 @@ namespace Evoral {
|
||||||
|
|
||||||
/** An event (much like a type generic jack_midi_event_t)
|
/** An event (much like a type generic jack_midi_event_t)
|
||||||
*
|
*
|
||||||
* Template parameter Timestamp is the type of the time stamp used for this event.
|
* Template parameter Time is the type of the time stamp used for this event.
|
||||||
*/
|
*/
|
||||||
template<typename Timestamp>
|
template<typename Time>
|
||||||
struct Event {
|
struct Event {
|
||||||
#ifdef EVORAL_EVENT_ALLOC
|
#ifdef EVORAL_EVENT_ALLOC
|
||||||
Event(EventType type=0, Timestamp timestamp=0, uint32_t size=0, uint8_t* buffer=NULL, bool alloc=false);
|
Event(EventType type=0, Time timestamp=0, uint32_t size=0, uint8_t* buffer=NULL, bool alloc=false);
|
||||||
|
|
||||||
/** Copy \a copy.
|
/** Copy \a copy.
|
||||||
*
|
*
|
||||||
|
|
@ -89,7 +89,7 @@ struct Event {
|
||||||
_buf = copy._buf;
|
_buf = copy._buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set(uint8_t* buf, uint32_t size, Timestamp t) {
|
inline void set(uint8_t* buf, uint32_t size, Time t) {
|
||||||
if (_owns_buf) {
|
if (_owns_buf) {
|
||||||
if (_size < size) {
|
if (_size < size) {
|
||||||
_buf = (uint8_t*) ::realloc(_buf, size);
|
_buf = (uint8_t*) ::realloc(_buf, size);
|
||||||
|
|
@ -164,8 +164,8 @@ struct Event {
|
||||||
|
|
||||||
inline EventType event_type() const { return _type; }
|
inline EventType event_type() const { return _type; }
|
||||||
inline void set_event_type(EventType t) { _type = t; }
|
inline void set_event_type(EventType t) { _type = t; }
|
||||||
inline Timestamp time() const { return _time; }
|
inline Time time() const { return _time; }
|
||||||
inline Timestamp& time() { return _time; }
|
inline Time& time() { return _time; }
|
||||||
inline uint32_t size() const { return _size; }
|
inline uint32_t size() const { return _size; }
|
||||||
inline uint32_t& size() { return _size; }
|
inline uint32_t& size() { return _size; }
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ struct Event {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
|
EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
|
||||||
Timestamp _time; /**< Sample index (or beat time) at which event is valid */
|
Time _time; /**< Sample index (or beat time) at which event is valid */
|
||||||
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 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ namespace Evoral {
|
||||||
* This packs a timestamp, size, and size bytes of data flat into the buffer.
|
* This packs a timestamp, size, and size bytes of data flat into the buffer.
|
||||||
* Useful for MIDI events, OSC messages, etc.
|
* Useful for MIDI events, OSC messages, etc.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
class EventRingBuffer : public Evoral::RingBuffer<uint8_t>, public Evoral::EventSink<T> {
|
class EventRingBuffer : public Evoral::RingBuffer<uint8_t>, public Evoral::EventSink<Time> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** @param capacity Ringbuffer capacity in bytes.
|
/** @param capacity Ringbuffer capacity in bytes.
|
||||||
|
|
@ -45,27 +45,27 @@ public:
|
||||||
|
|
||||||
size_t capacity() const { return _size; }
|
size_t capacity() const { return _size; }
|
||||||
|
|
||||||
bool peek_time(T* time);
|
bool peek_time(Time* time);
|
||||||
|
|
||||||
uint32_t write(T time, EventType type, uint32_t size, const uint8_t* buf);
|
uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf);
|
||||||
bool read (T* time, EventType* type, uint32_t* size, uint8_t* buf);
|
bool read (Time* time, EventType* type, uint32_t* size, uint8_t* buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
inline bool
|
inline bool
|
||||||
EventRingBuffer<T>::peek_time(T* time)
|
EventRingBuffer<Time>::peek_time(Time* time)
|
||||||
{
|
{
|
||||||
bool success = RingBuffer<uint8_t>::full_peek(sizeof(T), (uint8_t*)time);
|
bool success = RingBuffer<uint8_t>::full_peek(sizeof(Time), (uint8_t*)time);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
inline bool
|
inline bool
|
||||||
EventRingBuffer<T>::read(T* time, EventType* type, uint32_t* size, uint8_t* buf)
|
EventRingBuffer<Time>::read(Time* time, EventType* type, uint32_t* size, uint8_t* buf)
|
||||||
{
|
{
|
||||||
bool success = RingBuffer<uint8_t>::full_read(sizeof(T), (uint8_t*)time);
|
bool success = RingBuffer<uint8_t>::full_read(sizeof(Time), (uint8_t*)time);
|
||||||
if (success)
|
if (success)
|
||||||
success = RingBuffer<uint8_t>::full_read(sizeof(EventType), (uint8_t*)type);
|
success = RingBuffer<uint8_t>::full_read(sizeof(EventType), (uint8_t*)type);
|
||||||
if (success)
|
if (success)
|
||||||
|
|
@ -77,14 +77,14 @@ EventRingBuffer<T>::read(T* time, EventType* type, uint32_t* size, uint8_t* buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
inline uint32_t
|
inline uint32_t
|
||||||
EventRingBuffer<T>::write(T time, EventType type, uint32_t size, const uint8_t* buf)
|
EventRingBuffer<Time>::write(Time time, EventType type, uint32_t size, const uint8_t* buf)
|
||||||
{
|
{
|
||||||
if (write_space() < (sizeof(T) + sizeof(EventType) + sizeof(uint32_t) + size)) {
|
if (write_space() < (sizeof(Time) + sizeof(EventType) + sizeof(uint32_t) + size)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
RingBuffer<uint8_t>::write(sizeof(T), (uint8_t*)&time);
|
RingBuffer<uint8_t>::write(sizeof(Time), (uint8_t*)&time);
|
||||||
RingBuffer<uint8_t>::write(sizeof(EventType), (uint8_t*)&type);
|
RingBuffer<uint8_t>::write(sizeof(EventType), (uint8_t*)&type);
|
||||||
RingBuffer<uint8_t>::write(sizeof(uint32_t), (uint8_t*)&size);
|
RingBuffer<uint8_t>::write(sizeof(uint32_t), (uint8_t*)&size);
|
||||||
RingBuffer<uint8_t>::write(size, buf);
|
RingBuffer<uint8_t>::write(size, buf);
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ namespace Evoral {
|
||||||
|
|
||||||
/** Pure virtual base for anything you can write events to.
|
/** Pure virtual base for anything you can write events to.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
class EventSink {
|
class EventSink {
|
||||||
public:
|
public:
|
||||||
virtual ~EventSink() {}
|
virtual ~EventSink() {}
|
||||||
virtual uint32_t write(T time, EventType type, uint32_t size, const uint8_t* buf) = 0;
|
virtual uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,14 @@ namespace Evoral {
|
||||||
* but the application must make sure the event actually contains
|
* but the application must make sure the event actually contains
|
||||||
* valid MIDI data for these functions to make sense.
|
* valid MIDI data for these functions to make sense.
|
||||||
*/
|
*/
|
||||||
template<typename Timestamp>
|
template<typename Time>
|
||||||
struct MIDIEvent : public Event<Timestamp> {
|
struct MIDIEvent : public Event<Time> {
|
||||||
MIDIEvent(EventType type=0, Timestamp timestamp=0, uint32_t size=0, uint8_t* buffer=NULL, bool alloc=false)
|
MIDIEvent(EventType type=0, Time timestamp=0, uint32_t size=0, uint8_t* buffer=NULL, bool alloc=false)
|
||||||
: Event<Timestamp>(type, timestamp, size, buffer, alloc)
|
: Event<Time>(type, timestamp, size, buffer, alloc)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MIDIEvent(const Event<Timestamp>& copy, bool alloc)
|
MIDIEvent(const Event<Time>& copy, bool alloc)
|
||||||
: Event<Timestamp>(copy, alloc)
|
: Event<Time>(copy, alloc)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#ifdef EVORAL_MIDI_XML
|
#ifdef EVORAL_MIDI_XML
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,16 @@ namespace Evoral {
|
||||||
*
|
*
|
||||||
* Currently a note is defined as (on event, length, off event).
|
* Currently a note is defined as (on event, length, off event).
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
class Note {
|
class Note {
|
||||||
public:
|
public:
|
||||||
Note(uint8_t chan=0, T time=0, EventLength len=0, uint8_t note=0, uint8_t vel=0x40);
|
Note(uint8_t chan=0, Time time=0, EventLength len=0, uint8_t note=0, uint8_t vel=0x40);
|
||||||
Note(const Note<T>& copy);
|
Note(const Note<Time>& copy);
|
||||||
~Note();
|
~Note();
|
||||||
|
|
||||||
const Note<T>& operator=(const Note<T>& copy);
|
const Note<Time>& operator=(const Note<Time>& copy);
|
||||||
|
|
||||||
inline bool operator==(const Note<T>& other) {
|
inline bool operator==(const Note<Time>& other) {
|
||||||
return time() == other.time() &&
|
return time() == other.time() &&
|
||||||
note() == other.note() &&
|
note() == other.note() &&
|
||||||
length() == other.length() &&
|
length() == other.length() &&
|
||||||
|
|
@ -46,8 +46,8 @@ public:
|
||||||
channel() == other.channel();
|
channel() == other.channel();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T time() const { return _on_event.time(); }
|
inline Time time() const { return _on_event.time(); }
|
||||||
inline T 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 EventLength length() const { return _off_event.time() - _on_event.time(); }
|
inline EventLength length() const { return _off_event.time() - _on_event.time(); }
|
||||||
|
|
@ -56,21 +56,21 @@ public:
|
||||||
return _on_event.channel();
|
return _on_event.channel();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_time(T t) { _off_event.time() = t + length(); _on_event.time() = t; }
|
inline void set_time(Time t) { _off_event.time() = t + length(); _on_event.time() = t; }
|
||||||
inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; }
|
inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; }
|
||||||
inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; }
|
inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; }
|
||||||
inline void set_length(EventLength l) { _off_event.time() = _on_event.time() + l; }
|
inline void set_length(EventLength l) { _off_event.time() = _on_event.time() + l; }
|
||||||
inline void set_channel(uint8_t c) { _on_event.set_channel(c); _off_event.set_channel(c); }
|
inline void set_channel(uint8_t c) { _on_event.set_channel(c); _off_event.set_channel(c); }
|
||||||
|
|
||||||
inline Event<T>& on_event() { return _on_event; }
|
inline Event<Time>& on_event() { return _on_event; }
|
||||||
inline const Event<T>& on_event() const { return _on_event; }
|
inline const Event<Time>& on_event() const { return _on_event; }
|
||||||
inline Event<T>& off_event() { return _off_event; }
|
inline Event<Time>& off_event() { return _off_event; }
|
||||||
inline const Event<T>& 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<T> _on_event;
|
MIDIEvent<Time> _on_event;
|
||||||
MIDIEvent<T> _off_event;
|
MIDIEvent<Time> _off_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Evoral {
|
||||||
* Read/Write realtime safe.
|
* Read/Write realtime safe.
|
||||||
* Single-reader Single-writer thread safe.
|
* Single-reader Single-writer thread safe.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename Time>
|
||||||
class RingBuffer {
|
class RingBuffer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ public:
|
||||||
*/
|
*/
|
||||||
RingBuffer(size_t size)
|
RingBuffer(size_t size)
|
||||||
: _size(size)
|
: _size(size)
|
||||||
, _buf(new T[size])
|
, _buf(new Time[size])
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
assert(read_space() == 0);
|
assert(read_space() == 0);
|
||||||
|
|
@ -96,7 +96,7 @@ public:
|
||||||
* read-pointer---^
|
* read-pointer---^
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
size_t peek(size_t size, T* dst);
|
size_t peek(size_t size, Time* dst);
|
||||||
|
|
||||||
/** Peek at the ringbuffer (read w/o advancing read pointer).
|
/** Peek at the ringbuffer (read w/o advancing read pointer).
|
||||||
* @return how much has been peeked (wraps around if read exceeds
|
* @return how much has been peeked (wraps around if read exceeds
|
||||||
|
|
@ -106,32 +106,32 @@ public:
|
||||||
* read-pointer---^
|
* read-pointer---^
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
bool full_peek(size_t size, T* dst);
|
bool full_peek(size_t size, Time* dst);
|
||||||
|
|
||||||
/** Read from the ringbuffer. (advances read pointer)
|
/** Read from the ringbuffer. (advances read pointer)
|
||||||
* @return how much has been read (read cannot exceed the end
|
* @return how much has been read (read cannot exceed the end
|
||||||
* of the buffer):
|
* of the buffer):
|
||||||
*/
|
*/
|
||||||
size_t read(size_t size, T* dst);
|
size_t read(size_t size, Time* dst);
|
||||||
|
|
||||||
/** Read from the ringbuffer. (advances read pointer)
|
/** Read from the ringbuffer. (advances read pointer)
|
||||||
* @return how much has been peeked (wraps around if read exceeds
|
* @return how much has been peeked (wraps around if read exceeds
|
||||||
* the end of the buffer):
|
* the end of the buffer):
|
||||||
*/
|
*/
|
||||||
bool full_read(size_t size, T* dst);
|
bool full_read(size_t size, Time* dst);
|
||||||
|
|
||||||
/** Advance read pointer by size
|
/** Advance read pointer by size
|
||||||
*/
|
*/
|
||||||
bool skip(size_t size);
|
bool skip(size_t size);
|
||||||
|
|
||||||
void write(size_t size, const T* src);
|
void write(size_t size, const Time* src);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable int _write_ptr;
|
mutable int _write_ptr;
|
||||||
mutable int _read_ptr;
|
mutable int _read_ptr;
|
||||||
|
|
||||||
size_t _size; ///< Size (capacity) in bytes
|
size_t _size; ///< Size (capacity) in bytes
|
||||||
T* _buf; ///< size, event, size, event...
|
Time* _buf; ///< size, event, size, event...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -141,9 +141,9 @@ protected:
|
||||||
* Caller must check return value and call again if necessary, or use the
|
* Caller must check return value and call again if necessary, or use the
|
||||||
* full_peek method which does this automatically.
|
* full_peek method which does this automatically.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
size_t
|
size_t
|
||||||
RingBuffer<T>::peek(size_t size, T* dst)
|
RingBuffer<Time>::peek(size_t size, Time* dst)
|
||||||
{
|
{
|
||||||
const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
|
const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
|
||||||
|
|
||||||
|
|
@ -157,9 +157,9 @@ RingBuffer<T>::peek(size_t size, T* dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
RingBuffer<T>::full_peek(size_t size, T* dst)
|
RingBuffer<Time>::full_peek(size_t size, Time* dst)
|
||||||
{
|
{
|
||||||
if (read_space() < size) {
|
if (read_space() < size) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -181,9 +181,9 @@ RingBuffer<T>::full_peek(size_t size, T* dst)
|
||||||
* Caller must check return value and call again if necessary, or use the
|
* Caller must check return value and call again if necessary, or use the
|
||||||
* full_read method which does this automatically.
|
* full_read method which does this automatically.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
size_t
|
size_t
|
||||||
RingBuffer<T>::read(size_t size, T* dst)
|
RingBuffer<Time>::read(size_t size, Time* dst)
|
||||||
{
|
{
|
||||||
const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
|
const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
|
||||||
|
|
||||||
|
|
@ -199,9 +199,9 @@ RingBuffer<T>::read(size_t size, T* dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
RingBuffer<T>::full_read(size_t size, T* dst)
|
RingBuffer<Time>::full_read(size_t size, Time* dst)
|
||||||
{
|
{
|
||||||
if (read_space() < size) {
|
if (read_space() < size) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -217,9 +217,9 @@ RingBuffer<T>::full_read(size_t size, T* dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
RingBuffer<T>::skip(size_t size)
|
RingBuffer<Time>::skip(size_t size)
|
||||||
{
|
{
|
||||||
if (read_space() < size) {
|
if (read_space() < size) {
|
||||||
std::cerr << "WARNING: Attempt to skip past end of MIDI ring buffer" << std::endl;
|
std::cerr << "WARNING: Attempt to skip past end of MIDI ring buffer" << std::endl;
|
||||||
|
|
@ -233,9 +233,9 @@ RingBuffer<T>::skip(size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
inline void
|
inline void
|
||||||
RingBuffer<T>::write(size_t size, const T* src)
|
RingBuffer<Time>::write(size_t size, const Time* src)
|
||||||
{
|
{
|
||||||
const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr);
|
const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename T> class Event;
|
template<typename Time> class Event;
|
||||||
template<typename T> class EventRingBuffer;
|
template<typename Time> class EventRingBuffer;
|
||||||
|
|
||||||
|
|
||||||
/** Standard Midi File (Type 0)
|
/** Standard Midi File (Type 0)
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
class SMF {
|
class SMF {
|
||||||
public:
|
public:
|
||||||
SMF();
|
SMF();
|
||||||
|
|
@ -42,10 +42,10 @@ public:
|
||||||
bool is_empty() const { return _empty; }
|
bool is_empty() const { return _empty; }
|
||||||
bool eof() const { return feof(_fd); }
|
bool eof() const { return feof(_fd); }
|
||||||
|
|
||||||
T last_event_time() const { return _last_ev_time; }
|
Time last_event_time() const { return _last_ev_time; }
|
||||||
|
|
||||||
void begin_write(FrameTime start_time);
|
void begin_write(FrameTime start_time);
|
||||||
void append_event_unlocked(uint32_t delta_t, const Event<T>& ev);
|
void append_event_unlocked(uint32_t delta_t, const Event<Time>& ev);
|
||||||
void end_write();
|
void end_write();
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
@ -73,7 +73,7 @@ private:
|
||||||
static const uint16_t _ppqn = 19200;
|
static const uint16_t _ppqn = 19200;
|
||||||
|
|
||||||
FILE* _fd;
|
FILE* _fd;
|
||||||
T _last_ev_time; ///< last frame time written, relative to source start
|
Time _last_ev_time; ///< last frame time written, relative to source start
|
||||||
uint32_t _track_size;
|
uint32_t _track_size;
|
||||||
uint32_t _header_size; ///< size of SMF header, including MTrk chunk header
|
uint32_t _header_size; ///< size of SMF header, including MTrk chunk header
|
||||||
bool _empty; ///< true iff file contains(non-empty) events
|
bool _empty; ///< true iff file contains(non-empty) events
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
class TypeMap;
|
class TypeMap;
|
||||||
template<typename T> class EventSink;
|
template<typename Time> class EventSink;
|
||||||
template<typename T> class Note;
|
template<typename Time> class Note;
|
||||||
template<typename T> class Event;
|
template<typename Time> class Event;
|
||||||
|
|
||||||
/** An iterator over (the x axis of) a 2-d double coordinate space.
|
/** An iterator over (the x axis of) a 2-d double coordinate space.
|
||||||
*/
|
*/
|
||||||
|
|
@ -58,7 +58,7 @@ public:
|
||||||
/** This is a higher level view of events, with separate representations for
|
/** This is a higher level view of events, with separate representations for
|
||||||
* notes (instead of just unassociated note on/off events) and controller data.
|
* notes (instead of just unassociated note on/off events) and controller data.
|
||||||
* Controller data is represented as a list of time-stamped float values. */
|
* Controller data is represented as a list of time-stamped float values. */
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
class Sequence : virtual public ControlSet {
|
class Sequence : virtual public ControlSet {
|
||||||
public:
|
public:
|
||||||
Sequence(const TypeMap& type_map, size_t size=0);
|
Sequence(const TypeMap& type_map, size_t size=0);
|
||||||
|
|
@ -80,54 +80,54 @@ public:
|
||||||
bool writing() const { return _writing; }
|
bool writing() const { return _writing; }
|
||||||
void end_write(bool delete_stuck=false);
|
void end_write(bool delete_stuck=false);
|
||||||
|
|
||||||
size_t read(EventSink<T>& dst,
|
size_t read(EventSink<Time>& dst,
|
||||||
timestamp_t start,
|
timestamp_t start,
|
||||||
timedur_t length,
|
timedur_t length,
|
||||||
timestamp_t stamp_offset) const;
|
timestamp_t stamp_offset) const;
|
||||||
|
|
||||||
/** Resizes vector if necessary (NOT realtime safe) */
|
/** Resizes vector if necessary (NOT realtime safe) */
|
||||||
void append(const Event<T>& ev);
|
void append(const Event<Time>& ev);
|
||||||
|
|
||||||
inline const boost::shared_ptr< const Note<T> > note_at(unsigned i) const { return _notes[i]; }
|
inline const boost::shared_ptr< const Note<Time> > note_at(unsigned i) const { return _notes[i]; }
|
||||||
inline const boost::shared_ptr< Note<T> > note_at(unsigned i) { return _notes[i]; }
|
inline const boost::shared_ptr< Note<Time> > note_at(unsigned i) { return _notes[i]; }
|
||||||
|
|
||||||
inline size_t n_notes() const { return _notes.size(); }
|
inline size_t n_notes() const { return _notes.size(); }
|
||||||
inline bool empty() const { return _notes.size() == 0 && ControlSet::empty(); }
|
inline bool empty() const { return _notes.size() == 0 && ControlSet::empty(); }
|
||||||
|
|
||||||
inline static bool note_time_comparator(const boost::shared_ptr< const Note<T> >& a,
|
inline static bool note_time_comparator(const boost::shared_ptr< const Note<Time> >& a,
|
||||||
const boost::shared_ptr< const Note<T> >& b) {
|
const boost::shared_ptr< const Note<Time> >& b) {
|
||||||
return a->time() < b->time();
|
return a->time() < b->time();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LaterNoteEndComparator {
|
struct LaterNoteEndComparator {
|
||||||
typedef const Note<T>* value_type;
|
typedef const Note<Time>* value_type;
|
||||||
inline bool operator()(const boost::shared_ptr< const Note<T> > a,
|
inline bool operator()(const boost::shared_ptr< const Note<Time> > a,
|
||||||
const boost::shared_ptr< const Note<T> > b) const {
|
const boost::shared_ptr< const Note<Time> > b) const {
|
||||||
return a->end_time() > b->end_time();
|
return a->end_time() > b->end_time();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< boost::shared_ptr< Note<T> > > Notes;
|
typedef std::vector< boost::shared_ptr< Note<Time> > > Notes;
|
||||||
inline Notes& notes() { return _notes; }
|
inline Notes& notes() { return _notes; }
|
||||||
inline const Notes& notes() const { return _notes; }
|
inline const Notes& notes() const { return _notes; }
|
||||||
|
|
||||||
// useful for storing SysEx / Meta events
|
// useful for storing SysEx / Meta events
|
||||||
typedef std::vector< boost::shared_ptr< Event<T> > > SysExes;
|
typedef std::vector< boost::shared_ptr< Event<Time> > > SysExes;
|
||||||
inline SysExes& sysexes() { return _sysexes; }
|
inline SysExes& sysexes() { return _sysexes; }
|
||||||
inline const SysExes& sysexes() const { return _sysexes; }
|
inline const SysExes& sysexes() const { return _sysexes; }
|
||||||
|
|
||||||
/** Read iterator */
|
/** Read iterator */
|
||||||
class const_iterator {
|
class const_iterator {
|
||||||
public:
|
public:
|
||||||
const_iterator(const Sequence<T>& seq, T t);
|
const_iterator(const Sequence<Time>& seq, Time t);
|
||||||
~const_iterator();
|
~const_iterator();
|
||||||
|
|
||||||
inline bool valid() const { return !_is_end && _event; }
|
inline bool valid() const { return !_is_end && _event; }
|
||||||
inline bool locked() const { return _locked; }
|
inline bool locked() const { return _locked; }
|
||||||
|
|
||||||
const Event<T>& operator*() const { return *_event; }
|
const Event<Time>& operator*() const { return *_event; }
|
||||||
const boost::shared_ptr< Event<T> > operator->() const { return _event; }
|
const boost::shared_ptr< Event<Time> > operator->() const { return _event; }
|
||||||
const boost::shared_ptr< Event<T> > get_event_pointer() { return _event; }
|
const boost::shared_ptr< Event<Time> > get_event_pointer() { return _event; }
|
||||||
|
|
||||||
const const_iterator& operator++(); // prefix only
|
const const_iterator& operator++(); // prefix only
|
||||||
bool operator==(const const_iterator& other) const;
|
bool operator==(const const_iterator& other) const;
|
||||||
|
|
@ -136,15 +136,15 @@ public:
|
||||||
const_iterator& operator=(const const_iterator& other);
|
const_iterator& operator=(const const_iterator& other);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Sequence<T>;
|
friend class Sequence<Time>;
|
||||||
|
|
||||||
enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX };
|
enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX };
|
||||||
|
|
||||||
const Sequence<T>* _seq;
|
const Sequence<Time>* _seq;
|
||||||
boost::shared_ptr< Event<T> > _event;
|
boost::shared_ptr< Event<Time> > _event;
|
||||||
|
|
||||||
typedef std::priority_queue< boost::shared_ptr< Note<T> >,
|
typedef std::priority_queue< boost::shared_ptr< Note<Time> >,
|
||||||
std::deque< boost::shared_ptr< Note<T> > >,
|
std::deque< boost::shared_ptr< Note<Time> > >,
|
||||||
LaterNoteEndComparator >
|
LaterNoteEndComparator >
|
||||||
ActiveNotes;
|
ActiveNotes;
|
||||||
|
|
||||||
|
|
@ -160,13 +160,13 @@ public:
|
||||||
ControlIterators::iterator _control_iter;
|
ControlIterators::iterator _control_iter;
|
||||||
};
|
};
|
||||||
|
|
||||||
const_iterator begin(T t=0) const { return const_iterator(*this, t); }
|
const_iterator begin(Time t=0) const { return const_iterator(*this, t); }
|
||||||
const const_iterator& end() const { return _end_iter; }
|
const const_iterator& end() const { return _end_iter; }
|
||||||
|
|
||||||
void read_seek(T t) { _read_iter = begin(t); }
|
void read_seek(Time t) { _read_iter = begin(t); }
|
||||||
T read_time() const { return _read_iter.valid() ? _read_iter->time() : 0.0; }
|
Time read_time() const { return _read_iter.valid() ? _read_iter->time() : 0.0; }
|
||||||
|
|
||||||
bool control_to_midi_event(boost::shared_ptr< Event<T> >& ev,
|
bool control_to_midi_event(boost::shared_ptr< Event<Time> >& ev,
|
||||||
const ControlIterator& iter) const;
|
const ControlIterator& iter) const;
|
||||||
|
|
||||||
bool edited() const { return _edited; }
|
bool edited() const { return _edited; }
|
||||||
|
|
@ -176,8 +176,8 @@ public:
|
||||||
bool is_sorted() const;
|
bool is_sorted() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void add_note_unlocked(const boost::shared_ptr< Note<T> > note);
|
void add_note_unlocked(const boost::shared_ptr< Note<Time> > note);
|
||||||
void remove_note_unlocked(const boost::shared_ptr< const Note<T> > note);
|
void remove_note_unlocked(const boost::shared_ptr< const Note<Time> > note);
|
||||||
|
|
||||||
uint8_t lowest_note() const { return _lowest_note; }
|
uint8_t lowest_note() const { return _lowest_note; }
|
||||||
uint8_t highest_note() const { return _highest_note; }
|
uint8_t highest_note() const { return _highest_note; }
|
||||||
|
|
@ -189,10 +189,10 @@ protected:
|
||||||
private:
|
private:
|
||||||
friend class const_iterator;
|
friend class const_iterator;
|
||||||
|
|
||||||
void append_note_on_unlocked(uint8_t chan, T time, uint8_t note, uint8_t velocity);
|
void append_note_on_unlocked(uint8_t chan, Time time, uint8_t note, uint8_t velocity);
|
||||||
void append_note_off_unlocked(uint8_t chan, T time, uint8_t note);
|
void append_note_off_unlocked(uint8_t chan, Time time, uint8_t note);
|
||||||
void append_control_unlocked(const Parameter& param, T time, double value);
|
void append_control_unlocked(const Parameter& param, Time time, double value);
|
||||||
void append_sysex_unlocked(const MIDIEvent<T>& ev);
|
void append_sysex_unlocked(const MIDIEvent<Time>& ev);
|
||||||
|
|
||||||
mutable Glib::RWLock _lock;
|
mutable Glib::RWLock _lock;
|
||||||
|
|
||||||
|
|
@ -217,7 +217,7 @@ private:
|
||||||
uint8_t _highest_note;
|
uint8_t _highest_note;
|
||||||
|
|
||||||
typedef std::priority_queue<
|
typedef std::priority_queue<
|
||||||
boost::shared_ptr< Note<T> >, std::deque< boost::shared_ptr< Note<T> > >,
|
boost::shared_ptr< Note<Time> >, std::deque< boost::shared_ptr< Note<Time> > >,
|
||||||
LaterNoteEndComparator>
|
LaterNoteEndComparator>
|
||||||
ActiveNotes;
|
ActiveNotes;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ namespace Evoral {
|
||||||
|
|
||||||
#ifdef EVORAL_MIDI_XML
|
#ifdef EVORAL_MIDI_XML
|
||||||
|
|
||||||
template<typename Timestamp>
|
template<typename Time>
|
||||||
MIDIEvent<Timestamp>::MIDIEvent(const XMLNode& event)
|
MIDIEvent<Time>::MIDIEvent(const XMLNode& event)
|
||||||
: Event<Timestamp>()
|
: Event<Time>()
|
||||||
{
|
{
|
||||||
string name = event.name();
|
string name = event.name();
|
||||||
|
|
||||||
|
|
@ -51,9 +51,9 @@ MIDIEvent<Timestamp>::MIDIEvent(const XMLNode& event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Timestamp>
|
template<typename Time>
|
||||||
boost::shared_ptr<XMLNode>
|
boost::shared_ptr<XMLNode>
|
||||||
MIDIEvent<Timestamp>::to_xml() const
|
MIDIEvent<Time>::to_xml() const
|
||||||
{
|
{
|
||||||
XMLNode *result = 0;
|
XMLNode *result = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Note<T>::Note(uint8_t chan, T t, EventLength l, uint8_t n, uint8_t v)
|
Note<Time>::Note(uint8_t chan, Time t, EventLength l, uint8_t n, uint8_t v)
|
||||||
// FIXME: types?
|
// FIXME: types?
|
||||||
: _on_event(0xDE, t, 3, NULL, true)
|
: _on_event(0xDE, t, 3, NULL, true)
|
||||||
, _off_event(0xAD, t + l, 3, NULL, true)
|
, _off_event(0xAD, t + l, 3, NULL, true)
|
||||||
|
|
@ -46,8 +46,8 @@ Note<T>::Note(uint8_t chan, T t, EventLength l, uint8_t n, uint8_t v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Note<T>::Note(const Note<T>& copy)
|
Note<Time>::Note(const Note<Time>& copy)
|
||||||
: _on_event(copy._on_event, true)
|
: _on_event(copy._on_event, true)
|
||||||
, _off_event(copy._off_event, true)
|
, _off_event(copy._off_event, true)
|
||||||
{
|
{
|
||||||
|
|
@ -73,15 +73,15 @@ Note<T>::Note(const Note<T>& copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Note<T>::~Note()
|
Note<Time>::~Note()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
const Note<T>&
|
const Note<Time>&
|
||||||
Note<T>::operator=(const Note<T>& copy)
|
Note<Time>::operator=(const Note<Time>& copy)
|
||||||
{
|
{
|
||||||
_on_event = copy._on_event;
|
_on_event = copy._on_event;
|
||||||
_off_event = copy._off_event;
|
_off_event = copy._off_event;
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ using namespace std;
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
SMF<T>::SMF()
|
SMF<Time>::SMF()
|
||||||
: _fd(0)
|
: _fd(0)
|
||||||
, _last_ev_time(0)
|
, _last_ev_time(0)
|
||||||
, _track_size(4) // 4 bytes for the ever-present EOT event
|
, _track_size(4) // 4 bytes for the ever-present EOT event
|
||||||
|
|
@ -42,8 +42,8 @@ SMF<T>::SMF()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
SMF<T>::~SMF()
|
SMF<Time>::~SMF()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,9 +55,9 @@ SMF<T>::~SMF()
|
||||||
* -1 if the file can not be opened for reading,
|
* -1 if the file can not be opened for reading,
|
||||||
* -2 if the file can not be opened for writing
|
* -2 if the file can not be opened for writing
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
int
|
int
|
||||||
SMF<T>::open(const std::string& path)
|
SMF<Time>::open(const std::string& path)
|
||||||
{
|
{
|
||||||
//cerr << "Opening SMF file " << path() << " writeable: " << writable() << endl;
|
//cerr << "Opening SMF file " << path() << " writeable: " << writable() << endl;
|
||||||
_fd = fopen(path.c_str(), "r+");
|
_fd = fopen(path.c_str(), "r+");
|
||||||
|
|
@ -90,9 +90,9 @@ SMF<T>::open(const std::string& path)
|
||||||
return (_fd == 0) ? -1 : 0;
|
return (_fd == 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::close()
|
SMF<Time>::close()
|
||||||
{
|
{
|
||||||
if (_fd) {
|
if (_fd) {
|
||||||
flush_header();
|
flush_header();
|
||||||
|
|
@ -102,16 +102,16 @@ SMF<T>::close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::seek_to_start() const
|
SMF<Time>::seek_to_start() const
|
||||||
{
|
{
|
||||||
fseek(_fd, _header_size, SEEK_SET);
|
fseek(_fd, _header_size, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::seek_to_footer_position()
|
SMF<Time>::seek_to_footer_position()
|
||||||
{
|
{
|
||||||
uint8_t buffer[4];
|
uint8_t buffer[4];
|
||||||
|
|
||||||
|
|
@ -132,16 +132,16 @@ SMF<T>::seek_to_footer_position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::flush()
|
SMF<Time>::flush()
|
||||||
{
|
{
|
||||||
fflush(_fd);
|
fflush(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
int
|
int
|
||||||
SMF<T>::flush_header()
|
SMF<Time>::flush_header()
|
||||||
{
|
{
|
||||||
// FIXME: write timeline position somehow?
|
// FIXME: write timeline position somehow?
|
||||||
|
|
||||||
|
|
@ -169,9 +169,9 @@ SMF<T>::flush_header()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
int
|
int
|
||||||
SMF<T>::flush_footer()
|
SMF<Time>::flush_footer()
|
||||||
{
|
{
|
||||||
//cerr << path() << " SMF Flushing footer\n";
|
//cerr << path() << " SMF Flushing footer\n";
|
||||||
seek_to_footer_position();
|
seek_to_footer_position();
|
||||||
|
|
@ -181,9 +181,9 @@ SMF<T>::flush_footer()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::write_footer()
|
SMF<Time>::write_footer()
|
||||||
{
|
{
|
||||||
write_var_len(0);
|
write_var_len(0);
|
||||||
char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event
|
char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event
|
||||||
|
|
@ -206,9 +206,9 @@ SMF<T>::write_footer()
|
||||||
* Returns event length (including status byte) on success, 0 if event was
|
* Returns event length (including status byte) on success, 0 if event was
|
||||||
* skipped (eg a meta event), or -1 on EOF (or end of track).
|
* skipped (eg a meta event), or -1 on EOF (or end of track).
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
int
|
int
|
||||||
SMF<T>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
SMF<Time>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
||||||
{
|
{
|
||||||
if (feof(_fd)) {
|
if (feof(_fd)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -278,9 +278,9 @@ SMF<T>::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
|
||||||
return (int)*size;
|
return (int)*size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::append_event_unlocked(uint32_t delta_t, const Event<T>& ev)
|
SMF<Time>::append_event_unlocked(uint32_t delta_t, const Event<Time>& ev)
|
||||||
{
|
{
|
||||||
if (ev.size() == 0)
|
if (ev.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -301,25 +301,25 @@ SMF<T>::append_event_unlocked(uint32_t delta_t, const Event<T>& ev)
|
||||||
_empty = false;
|
_empty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::begin_write(FrameTime start_frame)
|
SMF<Time>::begin_write(FrameTime start_frame)
|
||||||
{
|
{
|
||||||
_last_ev_time = 0;
|
_last_ev_time = 0;
|
||||||
fseek(_fd, _header_size, SEEK_SET);
|
fseek(_fd, _header_size, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::end_write()
|
SMF<Time>::end_write()
|
||||||
{
|
{
|
||||||
flush_header();
|
flush_header();
|
||||||
flush_footer();
|
flush_footer();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::write_chunk_header(const char id[4], uint32_t length)
|
SMF<Time>::write_chunk_header(const char id[4], uint32_t length)
|
||||||
{
|
{
|
||||||
const uint32_t length_be = GUINT32_TO_BE(length);
|
const uint32_t length_be = GUINT32_TO_BE(length);
|
||||||
|
|
||||||
|
|
@ -327,9 +327,9 @@ SMF<T>::write_chunk_header(const char id[4], uint32_t length)
|
||||||
fwrite(&length_be, 4, 1, _fd);
|
fwrite(&length_be, 4, 1, _fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
SMF<T>::write_chunk(const char id[4], uint32_t length, void* data)
|
SMF<Time>::write_chunk(const char id[4], uint32_t length, void* data)
|
||||||
{
|
{
|
||||||
write_chunk_header(id, length);
|
write_chunk_header(id, length);
|
||||||
|
|
||||||
|
|
@ -337,9 +337,9 @@ SMF<T>::write_chunk(const char id[4], uint32_t length, void* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the size (in bytes) of the value written. */
|
/** Returns the size (in bytes) of the value written. */
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
size_t
|
size_t
|
||||||
SMF<T>::write_var_len(uint32_t value)
|
SMF<Time>::write_var_len(uint32_t value)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,25 +35,25 @@ using namespace std;
|
||||||
|
|
||||||
namespace Evoral {
|
namespace Evoral {
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void Sequence<T>::write_lock() {
|
void Sequence<Time>::write_lock() {
|
||||||
_lock.writer_lock();
|
_lock.writer_lock();
|
||||||
_control_lock.lock();
|
_control_lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void Sequence<T>::write_unlock() {
|
void Sequence<Time>::write_unlock() {
|
||||||
_lock.writer_unlock();
|
_lock.writer_unlock();
|
||||||
_control_lock.unlock();
|
_control_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void Sequence<T>::read_lock() const {
|
void Sequence<Time>::read_lock() const {
|
||||||
_lock.reader_lock();
|
_lock.reader_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void Sequence<T>::read_unlock() const {
|
void Sequence<Time>::read_unlock() const {
|
||||||
_lock.reader_unlock();
|
_lock.reader_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,8 +68,8 @@ static ostream& errorout = cerr;
|
||||||
|
|
||||||
// Read iterator (const_iterator)
|
// Read iterator (const_iterator)
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t)
|
||||||
: _seq(&seq)
|
: _seq(&seq)
|
||||||
, _is_end( (t == DBL_MAX) || seq.empty() )
|
, _is_end( (t == DBL_MAX) || seq.empty() )
|
||||||
, _locked( !_is_end )
|
, _locked( !_is_end )
|
||||||
|
|
@ -84,7 +84,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
|
|
||||||
// find first note which begins after t
|
// find first note which begins after t
|
||||||
_note_iter = seq.notes().end();
|
_note_iter = seq.notes().end();
|
||||||
for (typename Sequence<T>::Notes::const_iterator i = seq.notes().begin();
|
for (typename Sequence<Time>::Notes::const_iterator i = seq.notes().begin();
|
||||||
i != seq.notes().end(); ++i) {
|
i != seq.notes().end(); ++i) {
|
||||||
if ((*i)->time() >= t) {
|
if ((*i)->time() >= t) {
|
||||||
_note_iter = i;
|
_note_iter = i;
|
||||||
|
|
@ -95,7 +95,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
|
|
||||||
// find first sysex which begins after t
|
// find first sysex which begins after t
|
||||||
_sysex_iter = seq.sysexes().end();
|
_sysex_iter = seq.sysexes().end();
|
||||||
for (typename Sequence<T>::SysExes::const_iterator i = seq.sysexes().begin();
|
for (typename Sequence<Time>::SysExes::const_iterator i = seq.sysexes().begin();
|
||||||
i != seq.sysexes().end(); ++i) {
|
i != seq.sysexes().end(); ++i) {
|
||||||
if ((*i)->time() >= t) {
|
if ((*i)->time() >= t) {
|
||||||
_sysex_iter = i;
|
_sysex_iter = i;
|
||||||
|
|
@ -159,7 +159,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MIDIMessageType type = NIL;
|
MIDIMessageType type = NIL;
|
||||||
T earliest_t = t;
|
Time earliest_t = t;
|
||||||
|
|
||||||
// if the note comes before anything else set the iterator to the note
|
// if the note comes before anything else set the iterator to the note
|
||||||
if (_note_iter != seq.notes().end() && (*_note_iter)->on_event().time() >= t) {
|
if (_note_iter != seq.notes().end() && (*_note_iter)->on_event().time() >= t) {
|
||||||
|
|
@ -188,7 +188,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
if (type == NOTE_ON) {
|
if (type == NOTE_ON) {
|
||||||
debugout << "Reading note on event @ " << earliest_t << endl;
|
debugout << "Reading note on event @ " << earliest_t << endl;
|
||||||
// initialize the event pointer with a new event
|
// initialize the event pointer with a new event
|
||||||
_event = boost::shared_ptr< Event<T> >(new Event<T>((*_note_iter)->on_event(), true));
|
_event = boost::shared_ptr< Event<Time> >(new Event<Time>((*_note_iter)->on_event(), true));
|
||||||
_active_notes.push(*_note_iter);
|
_active_notes.push(*_note_iter);
|
||||||
++_note_iter;
|
++_note_iter;
|
||||||
_control_iter = _control_iters.end();
|
_control_iter = _control_iters.end();
|
||||||
|
|
@ -198,7 +198,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
} else if (type == SYSEX) {
|
} else if (type == SYSEX) {
|
||||||
debugout << "Reading system exclusive event @ " << earliest_t << endl;
|
debugout << "Reading system exclusive event @ " << earliest_t << endl;
|
||||||
// initialize the event pointer with a new event
|
// initialize the event pointer with a new event
|
||||||
_event = boost::shared_ptr< Event<T> >(new Event<T>(*(*_sysex_iter), true));
|
_event = boost::shared_ptr< Event<Time> >(new Event<Time>(*(*_sysex_iter), true));
|
||||||
++_sysex_iter;
|
++_sysex_iter;
|
||||||
_control_iter = _control_iters.end();
|
_control_iter = _control_iters.end();
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +216,7 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debugout << "New Iterator = " << _event->event_type();
|
debugout << "New Iterator = " << _event->event_type();
|
||||||
debugout << " : " << hex << (int)((MIDIEvent<T>*)_event.get())->type();
|
debugout << " : " << hex << (int)((MIDIEvent<Time>*)_event.get())->type();
|
||||||
debugout << " @ " << _event->time() << endl;
|
debugout << " @ " << _event->time() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,17 +225,17 @@ Sequence<T>::const_iterator::const_iterator(const Sequence<T>& seq, T t)
|
||||||
//assert(_is_end || (_event->buffer() && _event->buffer()[0] != '\0'));
|
//assert(_is_end || (_event->buffer() && _event->buffer()[0] != '\0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Sequence<T>::const_iterator::~const_iterator()
|
Sequence<Time>::const_iterator::~const_iterator()
|
||||||
{
|
{
|
||||||
if (_locked) {
|
if (_locked) {
|
||||||
_seq->read_unlock();
|
_seq->read_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
const typename Sequence<T>::const_iterator&
|
const typename Sequence<Time>::const_iterator&
|
||||||
Sequence<T>::const_iterator::operator++()
|
Sequence<Time>::const_iterator::operator++()
|
||||||
{
|
{
|
||||||
if (_is_end) {
|
if (_is_end) {
|
||||||
throw std::logic_error("Attempt to iterate past end of Sequence");
|
throw std::logic_error("Attempt to iterate past end of Sequence");
|
||||||
|
|
@ -244,7 +244,7 @@ Sequence<T>::const_iterator::operator++()
|
||||||
debugout << "Iterator ++" << endl;
|
debugout << "Iterator ++" << endl;
|
||||||
assert(_event && _event->buffer() && _event->size() > 0);
|
assert(_event && _event->buffer() && _event->size() > 0);
|
||||||
|
|
||||||
const MIDIEvent<T>& ev = *((MIDIEvent<T>*)_event.get());
|
const MIDIEvent<Time>& ev = *((MIDIEvent<Time>*)_event.get());
|
||||||
|
|
||||||
//debugout << "const_iterator::operator++: " << _event->to_string() << endl;
|
//debugout << "const_iterator::operator++: " << _event->to_string() << endl;
|
||||||
|
|
||||||
|
|
@ -291,7 +291,7 @@ Sequence<T>::const_iterator::operator++()
|
||||||
}
|
}
|
||||||
|
|
||||||
MIDIMessageType type = NIL;
|
MIDIMessageType type = NIL;
|
||||||
T earliest_t = 0;
|
Time earliest_t = 0;
|
||||||
|
|
||||||
// Next earliest note on
|
// Next earliest note on
|
||||||
if (_note_iter != _seq->notes().end()) {
|
if (_note_iter != _seq->notes().end()) {
|
||||||
|
|
@ -349,9 +349,9 @@ Sequence<T>::const_iterator::operator++()
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
Sequence<T>::const_iterator::operator==(const const_iterator& other) const
|
Sequence<Time>::const_iterator::operator==(const const_iterator& other) const
|
||||||
{
|
{
|
||||||
if (_is_end || other._is_end) {
|
if (_is_end || other._is_end) {
|
||||||
return (_is_end == other._is_end);
|
return (_is_end == other._is_end);
|
||||||
|
|
@ -360,9 +360,9 @@ Sequence<T>::const_iterator::operator==(const const_iterator& other) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
typename Sequence<T>::const_iterator&
|
typename Sequence<Time>::const_iterator&
|
||||||
Sequence<T>::const_iterator::operator=(const const_iterator& other)
|
Sequence<Time>::const_iterator::operator=(const const_iterator& other)
|
||||||
{
|
{
|
||||||
if (_locked && _seq != other._seq) {
|
if (_locked && _seq != other._seq) {
|
||||||
_seq->read_unlock();
|
_seq->read_unlock();
|
||||||
|
|
@ -382,7 +382,7 @@ Sequence<T>::const_iterator::operator=(const const_iterator& other)
|
||||||
if (_event) {
|
if (_event) {
|
||||||
*_event = *other._event.get();
|
*_event = *other._event.get();
|
||||||
} else {
|
} else {
|
||||||
_event = boost::shared_ptr< Event<T> >(new Event<T>(*other._event, true));
|
_event = boost::shared_ptr< Event<Time> >(new Event<Time>(*other._event, true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_event) {
|
if (_event) {
|
||||||
|
|
@ -395,8 +395,8 @@ Sequence<T>::const_iterator::operator=(const const_iterator& other)
|
||||||
|
|
||||||
// Sequence
|
// Sequence
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
Sequence<T>::Sequence(const TypeMap& type_map, size_t size)
|
Sequence<Time>::Sequence(const TypeMap& type_map, size_t size)
|
||||||
: _read_iter(*this, DBL_MAX)
|
: _read_iter(*this, DBL_MAX)
|
||||||
, _edited(false)
|
, _edited(false)
|
||||||
, _type_map(type_map)
|
, _type_map(type_map)
|
||||||
|
|
@ -417,9 +417,9 @@ Sequence<T>::Sequence(const TypeMap& type_map, size_t size)
|
||||||
* adding \a offset to each event's timestamp.
|
* adding \a offset to each event's timestamp.
|
||||||
* \return number of events written to \a dst
|
* \return number of events written to \a dst
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
size_t
|
size_t
|
||||||
Sequence<T>::read(EventSink<T>& dst, timestamp_t start, timedur_t nframes, timestamp_t offset) const
|
Sequence<Time>::read(EventSink<Time>& dst, timestamp_t start, timedur_t nframes, timestamp_t offset) const
|
||||||
{
|
{
|
||||||
debugout << this << " read @ " << start << " * " << nframes << " + " << offset << endl;
|
debugout << this << " read @ " << start << " * " << nframes << " + " << offset << endl;
|
||||||
debugout << this << " # notes: " << n_notes() << endl;
|
debugout << this << " # notes: " << n_notes() << endl;
|
||||||
|
|
@ -462,16 +462,16 @@ Sequence<T>::read(EventSink<T>& dst, timestamp_t start, timedur_t nframes, times
|
||||||
* The event_type of \a ev should be set to the expected output type.
|
* The event_type of \a ev should be set to the expected output type.
|
||||||
* \return true on success
|
* \return true on success
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
Sequence<T>::control_to_midi_event(boost::shared_ptr< Event<T> >& ev, const ControlIterator& iter) const
|
Sequence<Time>::control_to_midi_event(boost::shared_ptr< Event<Time> >& ev, const ControlIterator& iter) const
|
||||||
{
|
{
|
||||||
assert(iter.list.get());
|
assert(iter.list.get());
|
||||||
const uint32_t event_type = iter.list->parameter().type();
|
const uint32_t event_type = iter.list->parameter().type();
|
||||||
|
|
||||||
// initialize the event pointer with a new event, if necessary
|
// initialize the event pointer with a new event, if necessary
|
||||||
if (!ev) {
|
if (!ev) {
|
||||||
ev = boost::shared_ptr< Event<T> >(new Event<T>(event_type, 0, 3, NULL, true));
|
ev = boost::shared_ptr< Event<Time> >(new Event<Time>(event_type, 0, 3, NULL, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t midi_type = _type_map.parameter_midi_type(iter.list->parameter());
|
uint8_t midi_type = _type_map.parameter_midi_type(iter.list->parameter());
|
||||||
|
|
@ -533,9 +533,9 @@ Sequence<T>::control_to_midi_event(boost::shared_ptr< Event<T> >& ev, const Cont
|
||||||
|
|
||||||
/** Clear all events from the model.
|
/** Clear all events from the model.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::clear()
|
Sequence<Time>::clear()
|
||||||
{
|
{
|
||||||
_lock.writer_lock();
|
_lock.writer_lock();
|
||||||
_notes.clear();
|
_notes.clear();
|
||||||
|
|
@ -553,9 +553,9 @@ Sequence<T>::clear()
|
||||||
* stored; note off events are discarded entirely and all contained notes will
|
* stored; note off events are discarded entirely and all contained notes will
|
||||||
* have length 0.
|
* have length 0.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::start_write()
|
Sequence<Time>::start_write()
|
||||||
{
|
{
|
||||||
debugout << this << " START WRITE, PERCUSSIVE = " << _percussive << endl;
|
debugout << this << " START WRITE, PERCUSSIVE = " << _percussive << endl;
|
||||||
write_lock();
|
write_lock();
|
||||||
|
|
@ -573,9 +573,9 @@ Sequence<T>::start_write()
|
||||||
* that were never resolved with a corresonding note off will be deleted.
|
* that were never resolved with a corresonding note off will be deleted.
|
||||||
* Otherwise they will remain as notes with length 0.
|
* Otherwise they will remain as notes with length 0.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::end_write(bool delete_stuck)
|
Sequence<Time>::end_write(bool delete_stuck)
|
||||||
{
|
{
|
||||||
write_lock();
|
write_lock();
|
||||||
assert(_writing);
|
assert(_writing);
|
||||||
|
|
@ -597,7 +597,7 @@ Sequence<T>::end_write(bool delete_stuck)
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
if (!_write_notes[i].empty()) {
|
if (!_write_notes[i].empty()) {
|
||||||
errorout << "WARNING: Sequence<T>::end_write: Channel " << i << " has "
|
errorout << "WARNING: Sequence<Time>::end_write: Channel " << i << " has "
|
||||||
<< _write_notes[i].size() << " stuck notes" << endl;
|
<< _write_notes[i].size() << " stuck notes" << endl;
|
||||||
}
|
}
|
||||||
_write_notes[i].clear();
|
_write_notes[i].clear();
|
||||||
|
|
@ -617,14 +617,14 @@ Sequence<T>::end_write(bool delete_stuck)
|
||||||
* the start of this model (t=0) and MUST be monotonically increasing
|
* the start of this model (t=0) and MUST be monotonically increasing
|
||||||
* and MUST be >= the latest event currently in the model.
|
* and MUST be >= the latest event currently in the model.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::append(const Event<T>& event)
|
Sequence<Time>::append(const Event<Time>& event)
|
||||||
{
|
{
|
||||||
write_lock();
|
write_lock();
|
||||||
_edited = true;
|
_edited = true;
|
||||||
|
|
||||||
const MIDIEvent<T>& ev = (const MIDIEvent<T>&)event;
|
const MIDIEvent<Time>& ev = (const MIDIEvent<Time>&)event;
|
||||||
|
|
||||||
assert(_notes.empty() || ev.time() >= _notes.back()->time());
|
assert(_notes.empty() || ev.time() >= _notes.back()->time());
|
||||||
assert(_writing);
|
assert(_writing);
|
||||||
|
|
@ -666,9 +666,9 @@ Sequence<T>::append(const Event<T>& event)
|
||||||
write_unlock();
|
write_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::append_note_on_unlocked(uint8_t chan, T time, uint8_t note_num, uint8_t velocity)
|
Sequence<Time>::append_note_on_unlocked(uint8_t chan, Time time, uint8_t note_num, uint8_t velocity)
|
||||||
{
|
{
|
||||||
debugout << this << " c" << (int)chan << " note " << (int)note_num << " off @ " << time << endl;
|
debugout << this << " c" << (int)chan << " note " << (int)note_num << " off @ " << time << endl;
|
||||||
assert(note_num <= 127);
|
assert(note_num <= 127);
|
||||||
|
|
@ -681,7 +681,7 @@ Sequence<T>::append_note_on_unlocked(uint8_t chan, T time, uint8_t note_num, uin
|
||||||
if (note_num > _highest_note)
|
if (note_num > _highest_note)
|
||||||
_highest_note = note_num;
|
_highest_note = note_num;
|
||||||
|
|
||||||
boost::shared_ptr< Note<T> > new_note(new Note<T>(chan, time, 0, note_num, velocity));
|
boost::shared_ptr< Note<Time> > new_note(new Note<Time>(chan, time, 0, note_num, velocity));
|
||||||
_notes.push_back(new_note);
|
_notes.push_back(new_note);
|
||||||
if (!_percussive) {
|
if (!_percussive) {
|
||||||
debugout << "Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl;
|
debugout << "Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl;
|
||||||
|
|
@ -691,9 +691,9 @@ Sequence<T>::append_note_on_unlocked(uint8_t chan, T time, uint8_t note_num, uin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::append_note_off_unlocked(uint8_t chan, T time, uint8_t note_num)
|
Sequence<Time>::append_note_off_unlocked(uint8_t chan, Time time, uint8_t note_num)
|
||||||
{
|
{
|
||||||
debugout << this << " c" << (int)chan << " note " << (int)note_num << " off @ " << time << endl;
|
debugout << this << " c" << (int)chan << " note " << (int)note_num << " off @ " << time << endl;
|
||||||
assert(note_num <= 127);
|
assert(note_num <= 127);
|
||||||
|
|
@ -715,7 +715,7 @@ Sequence<T>::append_note_off_unlocked(uint8_t chan, T time, uint8_t note_num)
|
||||||
|
|
||||||
for (WriteNotes::iterator n = _write_notes[chan].begin(); n
|
for (WriteNotes::iterator n = _write_notes[chan].begin(); n
|
||||||
!= _write_notes[chan].end(); ++n) {
|
!= _write_notes[chan].end(); ++n) {
|
||||||
Note<T>& note = *_notes[*n].get();
|
Note<Time>& note = *_notes[*n].get();
|
||||||
if (note.note() == note_num) {
|
if (note.note() == note_num) {
|
||||||
assert(time >= note.time());
|
assert(time >= note.time());
|
||||||
note.set_length(time - note.time());
|
note.set_length(time - note.time());
|
||||||
|
|
@ -732,9 +732,9 @@ Sequence<T>::append_note_off_unlocked(uint8_t chan, T time, uint8_t note_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::append_control_unlocked(const Parameter& param, T time, double value)
|
Sequence<Time>::append_control_unlocked(const Parameter& param, Time time, double value)
|
||||||
{
|
{
|
||||||
debugout << this << " " << _type_map.to_symbol(param) << " @ " << time << " \t= \t" << value
|
debugout << this << " " << _type_map.to_symbol(param) << " @ " << time << " \t= \t" << value
|
||||||
<< " # controls: " << _controls.size() << endl;
|
<< " # controls: " << _controls.size() << endl;
|
||||||
|
|
@ -742,9 +742,9 @@ Sequence<T>::append_control_unlocked(const Parameter& param, T time, double valu
|
||||||
c->list()->rt_add(time, value);
|
c->list()->rt_add(time, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::append_sysex_unlocked(const MIDIEvent<T>& ev)
|
Sequence<Time>::append_sysex_unlocked(const MIDIEvent<Time>& ev)
|
||||||
{
|
{
|
||||||
debugout << this << " SysEx @ " << ev.time() << " \t= \t [ " << hex;
|
debugout << this << " SysEx @ " << ev.time() << " \t= \t [ " << hex;
|
||||||
for (size_t i=0; i < ev.size(); ++i) {
|
for (size_t i=0; i < ev.size(); ++i) {
|
||||||
|
|
@ -752,13 +752,13 @@ Sequence<T>::append_sysex_unlocked(const MIDIEvent<T>& ev)
|
||||||
}
|
}
|
||||||
debugout << "]" << endl;
|
debugout << "]" << endl;
|
||||||
|
|
||||||
boost::shared_ptr<MIDIEvent<T> > event(new MIDIEvent<T>(ev, true));
|
boost::shared_ptr<MIDIEvent<Time> > event(new MIDIEvent<Time>(ev, true));
|
||||||
_sysexes.push_back(event);
|
_sysexes.push_back(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::add_note_unlocked(const boost::shared_ptr< Note<T> > note)
|
Sequence<Time>::add_note_unlocked(const boost::shared_ptr< Note<Time> > note)
|
||||||
{
|
{
|
||||||
debugout << this << " add note " << (int)note->note() << " @ " << note->time() << endl;
|
debugout << this << " add note " << (int)note->note() << " @ " << note->time() << endl;
|
||||||
_edited = true;
|
_edited = true;
|
||||||
|
|
@ -767,15 +767,15 @@ Sequence<T>::add_note_unlocked(const boost::shared_ptr< Note<T> > note)
|
||||||
_notes.insert(i, note);
|
_notes.insert(i, note);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
void
|
void
|
||||||
Sequence<T>::remove_note_unlocked(const boost::shared_ptr< const Note<T> > note)
|
Sequence<Time>::remove_note_unlocked(const boost::shared_ptr< const Note<Time> > note)
|
||||||
{
|
{
|
||||||
_edited = true;
|
_edited = true;
|
||||||
debugout << this << " remove note " << (int)note->note() << " @ " << note->time() << endl;
|
debugout << this << " remove note " << (int)note->note() << " @ " << note->time() << endl;
|
||||||
for (typename Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
for (typename Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
||||||
Note<T>& _n = *(*n);
|
Note<Time>& _n = *(*n);
|
||||||
const Note<T>& _note = *note;
|
const Note<Time>& _note = *note;
|
||||||
// TODO: There is still the issue, that after restarting ardour
|
// TODO: There is still the issue, that after restarting ardour
|
||||||
// persisted undo does not work, because of rounding errors in the
|
// persisted undo does not work, because of rounding errors in the
|
||||||
// event times after saving/restoring to/from MIDI files
|
// event times after saving/restoring to/from MIDI files
|
||||||
|
|
@ -794,9 +794,9 @@ Sequence<T>::remove_note_unlocked(const boost::shared_ptr< const Note<T> > note)
|
||||||
|
|
||||||
/** Slow! for debugging only. */
|
/** Slow! for debugging only. */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
template<typename T>
|
template<typename Time>
|
||||||
bool
|
bool
|
||||||
Sequence<T>::is_sorted() const {
|
Sequence<Time>::is_sorted() const {
|
||||||
bool t = 0;
|
bool t = 0;
|
||||||
for (typename Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n)
|
for (typename Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n)
|
||||||
if ((*n)->time() < t)
|
if ((*n)->time() < t)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue