Compare commits

...

10 Commits

Author SHA1 Message Date
Paul Davis c319696ceb Revert "add patch for handling mouse grabs in gdk/quartz by foreign (nested) windows"
This reverts commit a6d67fdd56.
2016-11-21 11:21:23 +00:00
Paul Davis a6d67fdd56 add patch for handling mouse grabs in gdk/quartz by foreign (nested) windows 2016-11-19 11:44:42 +00:00
David Robillard d0e17d074a Remove dead code 2016-11-07 07:09:37 -05:00
David Robillard e3c50643d3 Remove dead code 2016-11-07 07:07:42 -05:00
David Robillard c820ce4a64 Fix event type and parameter type confusion
I'm not sure if this is really the best way to do event types (should it
just be a completely static enum in evoral, or completely dynamic and
provided by the type map, or a mix like currently?), but previously the
event type was frequently set to either total garbage, or parameter
types, which are a different thing.

This fixes all those cases, and makes Evoral::EventType an enum so the
compile will warn about implicit conversions from int.
2016-11-07 05:14:55 -05:00
David Robillard 8eb1d9df02 Fix warning 2016-11-07 04:06:26 -05:00
David Robillard ef02ba23a2 Remove Evoral::MIDIEvent
It is slightly questionable whether type specific methods like
velocity() belong on Event at all, these may be better off as free
functions.  However the code currently uses them as methods in many
places, and it seems like a step in the right direction, since, for
example, we might some day have events that have a velocity but aren't
stored as MIDI messages (e.g. if Ardour uses an internal musical model
that is more expressive).

In any case, the former inheritance and plethora of sloppy casts is
definitely not the right thing.
2016-11-06 22:08:34 -05:00
David Robillard 0b0b945652 Factor out and extend MIDIXML implementation 2016-11-06 20:28:09 -05:00
David Robillard c184998d3f Fix Sequence/Event const-correctness issues 2016-11-06 20:28:09 -05:00
David Robillard 19cdf4ccc6 Fix LV2 state:StateChanged URI 2016-11-06 20:27:55 -05:00
50 changed files with 394 additions and 500 deletions

View File

@ -41,7 +41,7 @@
#include "ardour/session.h"
#include "evoral/Parameter.hpp"
#include "evoral/MIDIEvent.hpp"
#include "evoral/Event.hpp"
#include "evoral/Control.hpp"
#include "evoral/midi_util.h"
@ -1298,14 +1298,9 @@ MidiRegionView::display_sysexes()
if (!UIConfiguration::instance().get_never_display_periodic_midi()) {
for (MidiModel::SysExes::const_iterator i = _model->sysexes().begin(); i != _model->sysexes().end(); ++i) {
const boost::shared_ptr<const Evoral::MIDIEvent<Evoral::Beats> > mev =
boost::static_pointer_cast<const Evoral::MIDIEvent<Evoral::Beats> > (*i);
if (mev) {
if (mev->is_spp() || mev->is_mtc_quarter() || mev->is_mtc_full()) {
have_periodic_system_messages = true;
break;
}
if ((*i)->is_spp() || (*i)->is_mtc_quarter() || (*i)->is_mtc_full()) {
have_periodic_system_messages = true;
break;
}
}
@ -1330,17 +1325,11 @@ MidiRegionView::display_sysexes()
}
for (MidiModel::SysExes::const_iterator i = _model->sysexes().begin(); i != _model->sysexes().end(); ++i) {
const boost::shared_ptr<const Evoral::MIDIEvent<Evoral::Beats> > mev =
boost::static_pointer_cast<const Evoral::MIDIEvent<Evoral::Beats> > (*i);
Evoral::Beats time = (*i)->time();
if (mev) {
if (mev->is_spp() || mev->is_mtc_quarter() || mev->is_mtc_full()) {
if (!display_periodic_messages) {
continue;
}
if ((*i)->is_spp() || (*i)->is_mtc_quarter() || (*i)->is_mtc_full()) {
if (!display_periodic_messages) {
continue;
}
}
@ -3957,7 +3946,7 @@ MidiRegionView::data_recorded (boost::weak_ptr<MidiSource> w)
framepos_t back = max_framepos;
for (MidiBuffer::iterator i = buf->begin(); i != buf->end(); ++i) {
Evoral::MIDIEvent<MidiBuffer::TimeType> const ev (*i, false);
const Evoral::Event<MidiBuffer::TimeType>& ev = *i;
if (ev.is_channel_event()) {
if (get_channel_mode() == FilterChannels) {

View File

@ -70,6 +70,13 @@ Amp::configure_io (ChanCount in, ChanCount out)
return Processor::configure_io (in, out);
}
static void
scale_midi_velocity(Evoral::Event<MidiBuffer::TimeType>& ev, float factor)
{
factor = std::max(factor, 0.0f);
ev.set_velocity(std::min(127L, lrintf(ev.velocity() * factor)));
}
void
Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool)
{
@ -88,10 +95,10 @@ Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) {
MidiBuffer& mb (*i);
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
Evoral::Event<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
assert(ev.time() >= 0 && ev.time() < nframes);
ev.scale_velocity (fabsf (gab[ev.time()]));
scale_midi_velocity (ev, fabsf (gab[ev.time()]));
}
}
}
@ -135,9 +142,9 @@ Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
MidiBuffer& mb (*i);
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
Evoral::Event<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
ev.scale_velocity (fabsf (_current_gain));
scale_midi_velocity (ev, fabsf (_current_gain));
}
}
}
@ -186,11 +193,11 @@ Amp::apply_gain (BufferSet& bufs, framecnt_t sample_rate, framecnt_t nframes, ga
MidiBuffer& mb (*i);
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
Evoral::Event<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
const gain_t scale = delta * (ev.time()/(double) nframes);
ev.scale_velocity (fabsf (initial+scale));
scale_midi_velocity (ev, fabsf (initial + scale));
}
}
}
@ -304,7 +311,7 @@ Amp::apply_simple_gain (BufferSet& bufs, framecnt_t nframes, gain_t target, bool
MidiBuffer& mb (*i);
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
Evoral::Event<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
ev.set_velocity (0);
}
@ -324,9 +331,9 @@ Amp::apply_simple_gain (BufferSet& bufs, framecnt_t nframes, gain_t target, bool
MidiBuffer& mb (*i);
for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
Evoral::Event<MidiBuffer::TimeType> ev = *m;
if (ev.is_note_on()) {
ev.scale_velocity (fabsf (target));
scale_midi_velocity(ev, fabsf (target));
}
}
}

View File

@ -31,7 +31,7 @@
#include "ardour/types.h"
#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
#include "evoral/MIDIEvent.hpp"
#include "evoral/Event.hpp"
struct _VstEvents;
typedef struct _VstEvents VstEvents;
struct _VstMidiEvent;
@ -196,7 +196,7 @@ private:
~VSTBuffer ();
void clear ();
void push_back (Evoral::MIDIEvent<framepos_t> const &);
void push_back (Evoral::Event<framepos_t> const &);
VstEvents* events () const {
return _events;
}

View File

@ -43,7 +43,9 @@ public:
bool type_is_midi(uint32_t type) const;
uint8_t parameter_midi_type(const Evoral::Parameter& param) const;
uint32_t midi_event_type(uint8_t status) const;
Evoral::ParameterType midi_parameter_type(const uint8_t* buf, uint32_t len) const;
Evoral::ControlList::InterpolationStyle interpolation_of(const Evoral::Parameter& param);
Evoral::Parameter from_symbol(const std::string& str) const;

View File

@ -20,8 +20,9 @@
#ifndef __ardour_midi_buffer_h__
#define __ardour_midi_buffer_h__
#include "evoral/midi_util.h"
#include "evoral/EventSink.hpp"
#include "evoral/midi_util.h"
#include "evoral/types.hpp"
#include "midi++/event.h"
@ -47,7 +48,7 @@ public:
void copy(const MidiBuffer& copy);
void copy(MidiBuffer const * const);
bool push_back(const Evoral::MIDIEvent<TimeType>& event);
bool push_back(const Evoral::Event<TimeType>& event);
bool push_back(TimeType time, size_t size, const uint8_t* data);
uint8_t* reserve(TimeType time, size_t size);
@ -56,7 +57,7 @@ public:
size_t size() const { return _size; }
bool empty() const { return _size == 0; }
bool insert_event(const Evoral::MIDIEvent<TimeType>& event);
bool insert_event(const Evoral::Event<TimeType>& event);
bool merge_in_place(const MidiBuffer &other);
/** EventSink interface for non-RT use (export, bounce). */
@ -93,7 +94,7 @@ public:
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType);
int event_size = Evoral::midi_event_size(ev_start);
assert(event_size >= 0);
return EventType(midi_parameter_type(*ev_start),
return EventType(Evoral::MIDI_EVENT,
*(reinterpret_cast<TimeType*>((uintptr_t)(buffer->_data + offset))),
event_size, ev_start);
}
@ -122,8 +123,8 @@ public:
size_t offset;
};
typedef iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> > iterator;
typedef iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> > const_iterator;
typedef iterator_base< MidiBuffer, Evoral::Event<TimeType> > iterator;
typedef iterator_base< const MidiBuffer, const Evoral::Event<TimeType> > const_iterator;
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, _size); }
@ -166,8 +167,6 @@ public:
return iterator (*this, i.offset);
}
uint8_t* data() const { return _data; }
/**
* returns true if the message with the second argument as its MIDI
* status byte should preceed the message with the first argument as
@ -176,8 +175,8 @@ public:
static bool second_simultaneous_midi_byte_is_first (uint8_t, uint8_t);
private:
friend class iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >;
friend class iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> >;
friend class iterator_base< MidiBuffer, Evoral::Event<TimeType> >;
friend class iterator_base< const MidiBuffer, const Evoral::Event<TimeType> >;
uint8_t* _data; ///< timestamp, event, timestamp, event, ...
pframes_t _size;

View File

@ -84,7 +84,7 @@ public:
uint32_t patch_Set;
uint32_t patch_property;
uint32_t patch_value;
uint32_t state_Changed;
uint32_t state_StateChanged;
#ifdef LV2_EXTENDED
uint32_t auto_event;
uint32_t auto_setup;

View File

@ -143,7 +143,7 @@ AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes)
if (!have_timer) {
when += (*b).time();
}
input_fifo.write (when, (Evoral::EventType) 0, (*b).size(), (*b).buffer());
input_fifo.write (when, Evoral::NO_EVENT, (*b).size(), (*b).buffer());
}
if (!mb.empty()) {
@ -241,14 +241,14 @@ AsyncMIDIPort::write (const MIDI::byte * msg, size_t msglen, MIDI::timestamp_t t
necessary.
*/
if (!vec.buf[0]->owns_buffer()) {
vec.buf[0]->set_buffer (0, 0, true);
}
vec.buf[0]->set_buffer (0, 0, true);
}
vec.buf[0]->set (msg, msglen, timestamp);
} else {
/* see comment in previous branch of if() statement */
if (!vec.buf[1]->owns_buffer()) {
vec.buf[1]->set_buffer (0, 0, true);
}
vec.buf[1]->set_buffer (0, 0, true);
}
vec.buf[1]->set (msg, msglen, timestamp);
}

View File

@ -1686,7 +1686,7 @@ AUPlugin::connect_and_run (BufferSet& bufs,
/* one MIDI port/buffer only */
MidiBuffer& m = bufs.get_midi (i);
for (MidiBuffer::iterator i = m.begin(); i != m.end(); ++i) {
Evoral::MIDIEvent<framepos_t> ev (*i);
Evoral::Event<framepos_t> ev (*i);
if (ev.is_channel_event()) {
const uint8_t* b = ev.buffer();
DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("%1: MIDI event %2\n", name(), ev));

View File

@ -775,12 +775,14 @@ AudioEngine::backend_discover (const string& path)
return info;
}
#ifdef NDEBUG
static bool running_from_source_tree ()
{
// dup ARDOUR_UI_UTILS::running_from_source_tree ()
gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
return x && (string (x).find ("gtk2_ardour") != string::npos);
}
#endif
vector<const AudioBackendInfo*>
AudioEngine::available_backends() const

View File

@ -389,7 +389,7 @@ BufferSet::VSTBuffer::clear ()
}
void
BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<framepos_t> const & ev)
BufferSet::VSTBuffer::push_back (Evoral::Event<framepos_t> const & ev)
{
if (ev.size() > 3) {
/* XXX: this will silently drop MIDI messages longer than 3 bytes, so

View File

@ -234,7 +234,7 @@ DelayLine::run (BufferSet& bufs, framepos_t /* start_frame */, framepos_t /* end
// move events from dly-buffer into current-buffer until nsamples
// and remove them from the dly-buffer
for (MidiBuffer::iterator m = dly->begin(); m != dly->end();) {
const Evoral::MIDIEvent<MidiBuffer::TimeType> ev (*m, false);
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
if (ev.time() >= nsamples) {
break;
}
@ -250,7 +250,7 @@ DelayLine::run (BufferSet& bufs, framepos_t /* start_frame */, framepos_t /* end
// move events after nsamples from current-buffer into dly-buffer
// and trim current-buffer after nsamples
for (MidiBuffer::iterator m = mb.begin(); m != mb.end();) {
const Evoral::MIDIEvent<MidiBuffer::TimeType> ev (*m, false);
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
if (ev.time() < nsamples) {
++m;
continue;

View File

@ -62,10 +62,10 @@ EventTypeMap::parameter_midi_type(const Evoral::Parameter& param) const
return ARDOUR::parameter_midi_type((AutomationType)param.type());
}
uint32_t
EventTypeMap::midi_event_type(uint8_t status) const
Evoral::ParameterType
EventTypeMap::midi_parameter_type(const uint8_t* buf, uint32_t len) const
{
return (uint32_t)ARDOUR::midi_parameter_type(status);
return (uint32_t)ARDOUR::midi_parameter_type(buf[0]);
}
Evoral::ControlList::InterpolationStyle

View File

@ -418,7 +418,7 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
smfs->append_event_beats(
source_lock,
Evoral::Event<Evoral::Beats>(
0,
Evoral::MIDI_EVENT,
Evoral::Beats::ticks_at_rate(t, source->ppqn()),
size,
buf));

View File

@ -442,7 +442,7 @@ LuaBindings::common (lua_State* L)
.addFunction ("size", &Evoral::Event<framepos_t>::size)
.addFunction ("set_buffer", &Evoral::Event<framepos_t>::set_buffer)
.addFunction ("buffer", (uint8_t*(Evoral::Event<framepos_t>::*)())&Evoral::Event<framepos_t>::buffer)
.addFunction ("time", (framepos_t (Evoral::Event<framepos_t>::*)())&Evoral::MIDIEvent<framepos_t>::time)
.addFunction ("time", (framepos_t (Evoral::Event<framepos_t>::*)())&Evoral::Event<framepos_t>::time)
.endClass ()
.beginClass <Evoral::Beats> ("Beats")
@ -1801,10 +1801,10 @@ LuaBindings::dsp (lua_State* L)
.addFunction ("empty", &MidiBuffer::empty)
.addFunction ("resize", &MidiBuffer::resize)
.addFunction ("copy", (void (MidiBuffer::*)(MidiBuffer const * const))&MidiBuffer::copy)
.addFunction ("push_event", (bool (MidiBuffer::*)(const Evoral::MIDIEvent<framepos_t>&))&MidiBuffer::push_back)
.addFunction ("push_event", (bool (MidiBuffer::*)(const Evoral::Event<framepos_t>&))&MidiBuffer::push_back)
.addFunction ("push_back", (bool (MidiBuffer::*)(framepos_t, size_t, const uint8_t*))&MidiBuffer::push_back)
// TODO iterators..
.addExtCFunction ("table", &luabridge::CFunc::listToTable<const Evoral::MIDIEvent<framepos_t>, MidiBuffer>)
.addExtCFunction ("table", &luabridge::CFunc::listToTable<const Evoral::Event<framepos_t>, MidiBuffer>)
.endClass()
.beginClass <BufferSet> ("BufferSet")
@ -1817,12 +1817,12 @@ LuaBindings::dsp (lua_State* L)
luabridge::getGlobalNamespace (L)
.beginNamespace ("Evoral")
.deriveClass <Evoral::MIDIEvent<framepos_t>, Evoral::Event<framepos_t> > ("MidiEvent")
.deriveClass <Evoral::Event<framepos_t>, Evoral::Event<framepos_t> > ("MidiEvent")
// add Ctor?
.addFunction ("type", &Evoral::MIDIEvent<framepos_t>::type)
.addFunction ("channel", &Evoral::MIDIEvent<framepos_t>::channel)
.addFunction ("set_type", &Evoral::MIDIEvent<framepos_t>::set_type)
.addFunction ("set_channel", &Evoral::MIDIEvent<framepos_t>::set_channel)
.addFunction ("type", &Evoral::Event<framepos_t>::type)
.addFunction ("channel", &Evoral::Event<framepos_t>::channel)
.addFunction ("set_type", &Evoral::Event<framepos_t>::set_type)
.addFunction ("set_channel", &Evoral::Event<framepos_t>::set_channel)
.endClass ()
.endNamespace ();

View File

@ -667,7 +667,7 @@ LuaProc::connect_and_run (BufferSet& bufs,
if (valid) {
for (MidiBuffer::iterator m = bufs.get_midi(idx).begin();
m != bufs.get_midi(idx).end(); ++m, ++e) {
const Evoral::MIDIEvent<framepos_t> ev(*m, false);
const Evoral::Event<framepos_t> ev(*m, false);
luabridge::LuaRef lua_midi_data (luabridge::newTable (L));
const uint8_t* data = ev.buffer();
for (uint32_t i = 0; i < ev.size(); ++i) {

View File

@ -2551,7 +2551,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
MetricSection* metric = (metric_i != tmap.metrics_end())
? *metric_i : NULL;
if (m != m_end && (!metric || metric->frame() > (*m).time())) {
const Evoral::MIDIEvent<framepos_t> ev(*m, false);
const Evoral::Event<framepos_t> ev(*m, false);
if (ev.time() < nframes) {
LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
@ -2777,7 +2777,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
if (atom->type == _uri_map.urids.atom_Blank ||
atom->type == _uri_map.urids.atom_Object) {
LV2_Atom_Object* obj = (LV2_Atom_Object*)atom;
if (obj->body.otype == _uri_map.urids.state_Changed) {
if (obj->body.otype == _uri_map.urids.state_StateChanged) {
_session.set_dirty ();
}
}

View File

@ -106,7 +106,7 @@ PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_fr
const MidiBuffer& buf (bufs.get_midi(i));
for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
const Evoral::MIDIEvent<framepos_t> ev(*e, false);
const Evoral::Event<framepos_t> ev(*e, false);
if (ev.is_note_on()) {
const float this_vel = ev.buffer()[2] / 127.0;
if (this_vel > val) {

View File

@ -85,7 +85,7 @@ MidiBuffer::copy(MidiBuffer const * const copy)
{
assert(_capacity >= copy->size ());
_size = copy->size ();
memcpy(_data, copy->data(), _size);
memcpy(_data, copy->_data, _size);
}
@ -110,7 +110,7 @@ MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, frameoffset_t dst_
}
for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) {
const Evoral::MIDIEvent<TimeType> ev(*i, false);
const Evoral::Event<TimeType> ev(*i, false);
if (dst_offset >= 0) {
/* Positive offset: shifting events from internal
@ -168,7 +168,7 @@ MidiBuffer::merge_from (const Buffer& src, framecnt_t /*nframes*/, frameoffset_t
* @return false if operation failed (not enough room)
*/
bool
MidiBuffer::push_back(const Evoral::MIDIEvent<TimeType>& ev)
MidiBuffer::push_back(const Evoral::Event<TimeType>& ev)
{
return push_back (ev.time(), ev.size(), ev.buffer());
}
@ -220,7 +220,7 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
}
bool
MidiBuffer::insert_event(const Evoral::MIDIEvent<TimeType>& ev)
MidiBuffer::insert_event(const Evoral::Event<TimeType>& ev)
{
if (size() == 0) {
return push_back(ev);
@ -273,7 +273,7 @@ MidiBuffer::insert_event(const Evoral::MIDIEvent<TimeType>& ev)
uint32_t
MidiBuffer::write(TimeType time, Evoral::EventType type, uint32_t size, const uint8_t* buf)
{
insert_event(Evoral::MIDIEvent<TimeType>(type, time, size, const_cast<uint8_t*>(buf)));
insert_event(Evoral::Event<TimeType>(type, time, size, const_cast<uint8_t*>(buf)));
return size;
}

View File

@ -42,7 +42,7 @@ MidiChannelFilter::filter(BufferSet& bufs)
MidiBuffer& buf = bufs.get_midi(0);
for (MidiBuffer::iterator e = buf.begin(); e != buf.end(); ) {
Evoral::MIDIEvent<framepos_t> ev(*e, false);
Evoral::Event<framepos_t> ev(*e, false);
if (ev.is_channel_event()) {
switch (mode) {

View File

@ -409,7 +409,7 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
Evoral::Event<MidiBuffer::TimeType> ev(*i, false);
if (ev.time() + rec_offset > rec_nframes) {
break;
}
@ -445,7 +445,7 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
}
if (!filter || !filter->filter(ev.buffer(), ev.size())) {
_capture_buf->write(event_time, ev.type(), ev.size(), ev.buffer());
_capture_buf->write(event_time, ev.event_type(), ev.size(), ev.buffer());
}
}
g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);

View File

@ -1498,7 +1498,7 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source,
for (Evoral::Sequence<TimeType>::const_iterator i = begin(TimeType(), true); i != end(); ++i) {
if (i->time() >= begin_time && i->time() < end_time) {
Evoral::MIDIEvent<TimeType> mev (*i, true); /* copy the event */
Evoral::Event<TimeType> mev (*i, true); /* copy the event */
if (offset_events) {
mev.set_time(mev.time() - begin_time);

View File

@ -92,7 +92,7 @@ MidiPlaylist::~MidiPlaylist ()
template<typename Time>
struct EventsSortByTimeAndType {
bool operator() (Evoral::Event<Time>* a, Evoral::Event<Time>* b) {
bool operator() (const Evoral::Event<Time>* a, const Evoral::Event<Time>* b) {
if (a->time() == b->time()) {
if (parameter_is_midi ((AutomationType)a->event_type()) &&
parameter_is_midi ((AutomationType)b->event_type())) {

View File

@ -230,7 +230,7 @@ MidiPort::flush_buffers (pframes_t nframes)
for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
const Evoral::MIDIEvent<MidiBuffer::TimeType> ev (*i, false);
const Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
if (sends_output() && _trace_on) {

View File

@ -17,7 +17,7 @@
*/
#include "evoral/MIDIEvent.hpp"
#include "evoral/Event.hpp"
#include "midi++/channel.h"
#include "midi++/parser.h"
#include "midi++/port.h"

View File

@ -195,8 +195,8 @@ MidiSource::midi_read (const Lock& lm,
MidiStateTracker* tracker,
MidiChannelFilter* filter,
const std::set<Evoral::Parameter>& filtered,
const double pulse,
const double start_beats) const
const double pulse,
const double start_beats) const
{
//BeatsFramesConverter converter(_session.tempo_map(), source_start);
@ -292,18 +292,28 @@ MidiSource::midi_read (const Lock& lm,
/* in range */
if (filter && filter->filter(i->buffer(), i->size())) {
DEBUG_TRACE (DEBUG::MidiSourceIO,
string_compose ("%1: filter event @ %2 type %3 size %4\n",
_name, time_frames, i->event_type(), i->size()));
continue;
}
if (loop_range) {
time_frames = loop_range->squish (time_frames);
}
dst.write (time_frames, i->event_type(), i->size(), i->buffer());
const uint8_t status = i->buffer()[0];
const bool is_channel_event = (0x80 <= (status & 0xF0)) && (status <= 0xE0);
if (filter && is_channel_event) {
/* Copy event so the filter can modify the channel. I'm not
sure if this is necessary here (channels are mapped later in
buffers anyway), but it preserves existing behaviour without
destroying events in the model during read. */
Evoral::Event<Evoral::Beats> ev(*i, true);
if (!filter->filter(ev.buffer(), ev.size())) {
dst.write(time_frames, ev.event_type(), ev.size(), ev.buffer());
} else {
DEBUG_TRACE (DEBUG::MidiSourceIO,
string_compose ("%1: filter event @ %2 type %3 size %4\n",
_name, time_frames, i->event_type(), i->size()));
}
} else {
dst.write (time_frames, i->event_type(), i->size(), i->buffer());
}
#ifndef NDEBUG
if (DEBUG_ENABLED(DEBUG::MidiSourceIO)) {

View File

@ -122,8 +122,8 @@ MidiStateTracker::resolve_notes (MidiBuffer &dst, framepos_t time)
for (int note = 0; note < 128; ++note) {
while (_active_notes[note + 128 * channel]) {
uint8_t buffer[3] = { ((uint8_t) (MIDI_CMD_NOTE_OFF | channel)), uint8_t (note), 0 };
Evoral::MIDIEvent<MidiBuffer::TimeType> noteoff
(MIDI_CMD_NOTE_OFF, time, 3, buffer, false);
Evoral::Event<MidiBuffer::TimeType> noteoff
(Evoral::MIDI_EVENT, time, 3, buffer, false);
/* note that we do not care about failure from
push_back() ... should we warn someone ?
*/
@ -157,7 +157,7 @@ MidiStateTracker::resolve_notes (Evoral::EventSink<framepos_t> &dst, framepos_t
/* note that we do not care about failure from
write() ... should we warn someone ?
*/
dst.write (time, midi_parameter_type (buf[0]), 3, buf);
dst.write (time, Evoral::MIDI_EVENT, 3, buf);
_active_notes[note + 128 * channel]--;
DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: EVS-resolved note %2/%3 at %4\n",
this, (int) note, (int) channel, time));
@ -181,7 +181,7 @@ MidiStateTracker::resolve_notes (MidiSource& src, const MidiSource::Lock& lock,
for (int channel = 0; channel < 16; ++channel) {
for (int note = 0; note < 128; ++note) {
while (_active_notes[note + 128 * channel]) {
Evoral::MIDIEvent<Evoral::Beats> ev ((MIDI_CMD_NOTE_OFF|channel), time, 3, 0, true);
Evoral::Event<Evoral::Beats> ev (Evoral::MIDI_EVENT, time, 3, 0, true);
ev.set_type (MIDI_CMD_NOTE_OFF);
ev.set_channel (channel);
ev.set_note (note);

View File

@ -339,7 +339,7 @@ MidiTrack::update_controls(const BufferSet& bufs)
{
const MidiBuffer& buf = bufs.get_midi(0);
for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
const Evoral::MIDIEvent<framepos_t>& ev = *e;
const Evoral::Event<framepos_t>& ev = *e;
const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size());
const boost::shared_ptr<Evoral::Control> control = this->control(param);
if (control) {
@ -549,7 +549,7 @@ MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
const Evoral::MIDIEvent<framepos_t> ev(*e, false);
const Evoral::Event<framepos_t> ev(*e, false);
/* note on, since for step edit, note length is determined
elsewhere
@ -557,7 +557,7 @@ MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
if (ev.is_note_on()) {
/* we don't care about the time for this purpose */
_step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
_step_edit_ring_buffer.write (0, ev.event_type(), ev.size(), ev.buffer());
}
}
}
@ -689,8 +689,7 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
return false;
}
const uint32_t type = midi_parameter_type(buf[0]);
return (_immediate_events.write (0, type, size, buf) == size);
return (_immediate_events.write (0, Evoral::MIDI_EVENT, size, buf) == size);
}
void

View File

@ -231,7 +231,6 @@ SMFSource::read_unlocked (const Lock& lock,
// Output parameters for read_event (which will allocate scratch in buffer as needed)
uint32_t ev_delta_t = 0;
uint32_t ev_type = 0;
uint32_t ev_size = 0;
uint8_t* ev_buffer = 0;
@ -277,10 +276,8 @@ SMFSource::read_unlocked (const Lock& lock,
continue;
}
ev_type = midi_parameter_type(ev_buffer[0]);
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked delta %1, time %2, buf[0] %3, type %4\n",
ev_delta_t, time, ev_buffer[0], ev_type));
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked delta %1, time %2, buf[0] %3\n",
ev_delta_t, time, ev_buffer[0]));
assert(time >= start_ticks);
@ -295,7 +292,7 @@ SMFSource::read_unlocked (const Lock& lock,
if (ev_frame_time < start + duration) {
if (!filter || !filter->filter(ev_buffer, ev_size)) {
destination.write (ev_frame_time, ev_type, ev_size, ev_buffer);
destination.write (ev_frame_time, Evoral::MIDI_EVENT, ev_size, ev_buffer);
if (tracker) {
tracker->track(ev_buffer);
}
@ -334,7 +331,7 @@ SMFSource::write_unlocked (const Lock& lock,
_model->start_write();
}
Evoral::MIDIEvent<framepos_t> ev;
Evoral::Event<framepos_t> ev;
while (true) {
/* Get the event time, in frames since session start but ignoring looping. */
bool ret;
@ -377,7 +374,7 @@ SMFSource::write_unlocked (const Lock& lock,
time -= position;
ev.set(buf, size, time);
ev.set_event_type(midi_parameter_type(ev.buffer()[0]));
ev.set_event_type(Evoral::MIDI_EVENT);
ev.set_id(Evoral::next_event_id());
if (!(ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex())) {
@ -604,8 +601,8 @@ SMFSource::safe_midi_file_extension (const string& file)
}
static bool compare_eventlist (
const std::pair< Evoral::Event<Evoral::Beats>*, gint >& a,
const std::pair< Evoral::Event<Evoral::Beats>*, gint >& b) {
const std::pair< const Evoral::Event<Evoral::Beats>*, gint >& a,
const std::pair< const Evoral::Event<Evoral::Beats>*, gint >& b) {
return ( a.first->time() < b.first->time() );
}
@ -674,7 +671,6 @@ SMFSource::load_model (const Glib::Threads::Mutex::Lock& lock, bool force_reload
if (!have_event_id) {
event_id = Evoral::next_event_id();
}
const uint32_t event_type = midi_parameter_type(buf[0]);
const Evoral::Beats event_time = Evoral::Beats::ticks_at_rate(time, ppqn());
#ifndef NDEBUG
std::string ss;
@ -685,13 +681,13 @@ SMFSource::load_model (const Glib::Threads::Mutex::Lock& lock, bool force_reload
ss += b;
}
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %7 load model delta %1, time %2, size %3 buf %4, type %5 id %6\n",
delta_t, time, size, ss , event_type, event_id, name()));
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %7 load model delta %1, time %2, size %3 buf %4, id %6\n",
delta_t, time, size, ss, event_id, name()));
#endif
eventlist.push_back(make_pair (
new Evoral::Event<Evoral::Beats> (
event_type, event_time,
Evoral::MIDI_EVENT, event_time,
size, buf, true)
, event_id));

View File

@ -62,7 +62,7 @@ URIMap::URIDs::init(URIMap& uri_map)
patch_Set = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#Set");
patch_property = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#property");
patch_value = uri_map.uri_to_id("http://lv2plug.in/ns/ext/patch#value");
state_Changed = uri_map.uri_to_id("http://lv2plug.in/ns/ext/state/#StateChanged"); // since LV2 1.15.1
state_StateChanged = uri_map.uri_to_id("http://lv2plug.in/ns/ext/state#StateChanged"); // since LV2 1.15.1
#ifdef LV2_EXTENDED
auto_event = uri_map.uri_to_id(LV2_AUTOMATE_URI__event);
auto_setup = uri_map.uri_to_id(LV2_AUTOMATE_URI__setup);

View File

@ -409,8 +409,7 @@ def build(bld):
'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
'LIBARDOUR="' + bld.env['lwrcase_dirname'] + '"',
'EVORAL_MIDI_XML=1',
'LIBARDOUR="' + bld.env['lwrcase_dirname'] + '"'
]
#obj.source += ' st_stretch.cc st_pitch.cc '

View File

@ -284,7 +284,7 @@
>
</File>
<File
RelativePath="..\src\MIDIEvent.cpp"
RelativePath="..\src\MIDIXML.cpp"
>
</File>
<File
@ -496,7 +496,7 @@
>
</File>
<File
RelativePath="..\evoral\MIDIEvent.hpp"
RelativePath="..\evoral\MIDIXML.hpp"
>
</File>
<File

View File

@ -1,5 +1,5 @@
/* This file is part of Evoral.
* Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2008-2016 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
@ -24,8 +24,9 @@
#include <sstream>
#include <stdint.h>
#include "evoral/visibility.h"
#include "evoral/midi_events.h"
#include "evoral/types.hpp"
#include "evoral/visibility.h"
/** If this is not defined, all methods of MidiEvent are RT safe
* but MidiEvent will never deep copy and (depending on the scenario)
@ -37,7 +38,7 @@ namespace Evoral {
LIBEVORAL_API event_id_t event_id_counter();
LIBEVORAL_API event_id_t next_event_id();
LIBEVORAL_API void init_event_id_counter(event_id_t n);
LIBEVORAL_API void init_event_id_counter(event_id_t n);
/** An event (much like a type generic jack_midi_event_t)
*
@ -47,9 +48,9 @@ template<typename Time>
class LIBEVORAL_API Event {
public:
#ifdef EVORAL_EVENT_ALLOC
Event (EventType type=0, Time time=Time(), uint32_t size=0, uint8_t* buf=NULL, bool alloc=false);
Event(EventType type=NO_EVENT, Time time=Time(), uint32_t size=0, uint8_t* buf=NULL, bool alloc=false);
Event (EventType type, Time time, uint32_t size, const uint8_t* buf);
Event(EventType type, Time time, uint32_t size, const uint8_t* buf);
/** Copy \a copy.
*
@ -59,33 +60,17 @@ public:
*/
Event(const Event& copy, bool alloc);
~Event();
~Event();
void assign (const Event& other);
void assign(const Event& other);
void set(const uint8_t* buf, uint32_t size, Time t);
inline bool operator==(const Event& other) const {
if (_type != other._type)
if (_type != other._type || _time != other._time || _size != other._size) {
return false;
if (_nominal_time != other._nominal_time)
return false;
if (_original_time != other._original_time)
return false;
if (_size != other._size)
return false;
if (_buf == other._buf)
return true;
for (uint32_t i=0; i < _size; ++i)
if (_buf[i] != other._buf[i])
return false;
return true;
}
return !memcmp(_buf, other._buf, _size);
}
inline bool operator!=(const Event& other) const { return ! operator==(other); }
@ -120,43 +105,96 @@ public:
}
inline void clear() {
_type = 0;
_original_time = Time();
_nominal_time = Time();
_size = 0;
_buf = NULL;
_type = NO_EVENT;
_time = Time();
_size = 0;
_buf = NULL;
}
#else
inline void set_buffer(uint8_t* buf) { _buf = buf; }
#endif // EVORAL_EVENT_ALLOC
inline EventType event_type() const { return _type; }
inline Time time() const { return _nominal_time; }
inline Time original_time() const { return _original_time; }
inline Time time() const { return _time; }
inline uint32_t size() const { return _size; }
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);
inline void set_time(Time t) { _time = t; }
inline event_id_t id() const { return _id; }
inline void set_id(event_id_t n) { _id = n; }
/* The following methods are type specific and only make sense for the
correct event type. It is the caller's responsibility to only call
methods which make sense for the given event type. Currently this means
they all only make sense for MIDI, but built-in support may be added for
other protocols in the future, or the internal representation may change
to be protocol agnostic. */
uint8_t type() const { return _buf[0] & 0xF0; }
uint8_t channel() const { return _buf[0] & 0x0F; }
bool is_note_on() const { return type() == MIDI_CMD_NOTE_ON; }
bool is_note_off() const { return type() == MIDI_CMD_NOTE_OFF; }
bool is_note() const { return is_note_on() || is_note_off(); }
bool is_poly_pressure() const { return type() == MIDI_CMD_NOTE_PRESSURE; }
bool is_channel_pressure() const { return type() == MIDI_CMD_CHANNEL_PRESSURE; }
bool is_cc() const { return type() == MIDI_CMD_CONTROL; }
bool is_pgm_change() const { return type() == MIDI_CMD_PGM_CHANGE; }
bool is_pitch_bender() const { return type() == MIDI_CMD_BENDER; }
bool is_channel_event() const { return (0x80 <= type()) && (type() <= 0xE0); }
bool is_smf_meta_event() const { return _buf[0] == 0xFF; }
bool is_sysex() const { return _buf[0] == 0xF0 || _buf[0] == 0xF7; }
bool is_spp() const { return _buf[0] == 0xF2 && size() == 1; }
bool is_mtc_quarter() const { return _buf[0] == 0xF1 && size() == 1; }
bool is_mtc_full() const { return (size() == 10 &&
_buf[0] == 0xF0 && _buf[1] == 0x7F &&
_buf[3] == 0x01 && _buf[4] == 0x01); }
uint8_t note() const { return _buf[1]; }
uint8_t velocity() const { return _buf[2]; }
uint8_t poly_note() const { return _buf[1]; }
uint8_t poly_pressure() const { return _buf[2]; }
uint8_t channel_pressure() const { return _buf[1]; }
uint8_t cc_number() const { return _buf[1]; }
uint8_t cc_value() const { return _buf[2]; }
uint8_t pgm_number() const { return _buf[1]; }
uint8_t pitch_bender_lsb() const { return _buf[1]; }
uint8_t pitch_bender_msb() const { return _buf[2]; }
uint16_t pitch_bender_value() const { return ((0x7F & _buf[2]) << 7 | (0x7F & _buf[1])); }
void set_channel(uint8_t channel) { _buf[0] = (0xF0 & _buf[0]) | (0x0F & channel); }
void set_type(uint8_t type) { _buf[0] = (0x0F & _buf[0]) | (0xF0 & type); }
void set_note(uint8_t num) { _buf[1] = num; }
void set_velocity(uint8_t val) { _buf[2] = val; }
void set_cc_number(uint8_t num) { _buf[1] = num; }
void set_cc_value(uint8_t val) { _buf[2] = val; }
void set_pgm_number(uint8_t num) { _buf[1] = num; }
uint16_t value() const {
switch (type()) {
case MIDI_CMD_CONTROL:
return cc_value();
case MIDI_CMD_BENDER:
return pitch_bender_value();
case MIDI_CMD_NOTE_PRESSURE:
return poly_pressure();
case MIDI_CMD_CHANNEL_PRESSURE:
return channel_pressure();
default:
return 0;
}
}
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 */
event_id_t _id; /** UUID for each event, should probably be 64bit or at least unsigned */
EventType _type; ///< Type of event (application relative, NOT MIDI 'type')
Time _time; ///< Time stamp of event
uint32_t _size; ///< Size of buffer in bytes
uint8_t* _buf; ///< Event contents (e.g. raw MIDI data)
event_id_t _id; ///< Unique event ID
#ifdef EVORAL_EVENT_ALLOC
bool _owns_buf; /**< Whether buffer is locally allocated */
bool _owns_buf; ///< Whether buffer is locally allocated
#endif
};

View File

@ -1,127 +0,0 @@
/* This file is part of Evoral.
* Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EVORAL_MIDI_EVENT_HPP
#define EVORAL_MIDI_EVENT_HPP
#include <cmath>
#include <boost/shared_ptr.hpp>
#include "evoral/visibility.h"
#include "evoral/Event.hpp"
#include "evoral/midi_events.h"
#ifdef EVORAL_MIDI_XML
class XMLNode;
#endif
namespace Evoral {
/** MIDI helper functions for an Event.
*
* This class contains no data, an Evoral::Event can be cast to a MIDIEvent
* but the application must make sure the Event actually contains
* valid MIDI data for these functions to make sense.
*/
template<typename Time>
class /*LIBEVORAL_API*/ MIDIEvent : public Event<Time> {
public:
MIDIEvent(EventType type=0, Time time=0, uint32_t size=0, uint8_t* buf=NULL, bool alloc=false)
: Event<Time>(type, time, size, buf, alloc)
{}
MIDIEvent(const Event<Time>& copy, bool alloc)
: Event<Time>(copy, alloc)
{}
#ifdef EVORAL_MIDI_XML
/** Event from XML ala http://www.midi.org/dtds/MIDIEvents10.dtd */
MIDIEvent(const XMLNode& event);
/** Event to XML ala http://www.midi.org/dtds/MIDIEvents10.dtd */
boost::shared_ptr<XMLNode> to_xml() const;
#endif
inline uint8_t type() const { return (this->_buf[0] & 0xF0); }
inline void set_type(uint8_t type) { this->_buf[0] = (0x0F & this->_buf[0])
| (0xF0 & type); }
inline uint8_t channel() const { return (this->_buf[0] & 0x0F); }
inline void set_channel(uint8_t channel) { this->_buf[0] = (0xF0 & this->_buf[0])
| (0x0F & channel); }
inline bool is_note_on() const { return (type() == MIDI_CMD_NOTE_ON); }
inline bool is_note_off() const { return (type() == MIDI_CMD_NOTE_OFF); }
inline bool is_cc() const { return (type() == MIDI_CMD_CONTROL); }
inline bool is_pitch_bender() const { return (type() == MIDI_CMD_BENDER); }
inline bool is_pgm_change() const { return (type() == MIDI_CMD_PGM_CHANGE); }
inline bool is_note() const { return (is_note_on() || is_note_off()); }
inline bool is_poly_pressure() const { return (type() == MIDI_CMD_NOTE_PRESSURE); }
inline bool is_channel_pressure() const { return (type() == MIDI_CMD_CHANNEL_PRESSURE); }
inline uint8_t note() const { return (this->_buf[1]); }
inline void set_note(uint8_t n) { this->_buf[1] = n; }
inline uint8_t velocity() const { return (this->_buf[2]); }
inline void set_velocity(uint8_t value) { this->_buf[2] = value; }
inline void scale_velocity(float factor) {
if (factor < 0) factor = 0;
this->_buf[2] = (uint8_t) lrintf (this->_buf[2]*factor);
if (this->_buf[2] > 127) this->_buf[2] = 127;
}
inline uint8_t cc_number() const { return (this->_buf[1]); }
inline void set_cc_number(uint8_t number) { this->_buf[1] = number; }
inline uint8_t cc_value() const { return (this->_buf[2]); }
inline void set_cc_value(uint8_t value) { this->_buf[2] = value; }
inline uint8_t pitch_bender_lsb() const { return (this->_buf[1]); }
inline uint8_t pitch_bender_msb() const { return (this->_buf[2]); }
inline uint16_t pitch_bender_value() const { return ( ((0x7F & this->_buf[2]) << 7)
| (0x7F & this->_buf[1]) ); }
inline uint8_t pgm_number() const { return (this->_buf[1]); }
inline void set_pgm_number(uint8_t number) { this->_buf[1] = number; }
inline uint8_t poly_note() const { return (this->_buf[1]); }
inline uint8_t poly_pressure() const { return (this->_buf[2]); }
inline uint8_t channel_pressure() const { return (this->_buf[1]); }
inline bool is_channel_event() const { return (0x80 <= type()) && (type() <= 0xE0); }
inline bool is_smf_meta_event() const { return this->_buf[0] == 0xFF; }
inline bool is_sysex() const { return this->_buf[0] == 0xF0
|| this->_buf[0] == 0xF7; }
inline bool is_spp() const { return this->_buf[0] == 0xF2 && this->size() == 1; }
inline bool is_mtc_quarter() const { return this->_buf[0] == 0xF1 && this->size() == 1; }
inline bool is_mtc_full() const {
return this->size() == 10 && this->_buf[0] == 0xf0 && this->_buf[1] == 0x7f &&
this->_buf[3] == 0x01 && this->_buf[4] == 0x01;
}
inline uint16_t value() const {
switch (type()) {
case MIDI_CMD_CONTROL:
return cc_value();
case MIDI_CMD_BENDER:
return pitch_bender_value();
case MIDI_CMD_NOTE_PRESSURE:
return poly_pressure();
case MIDI_CMD_CHANNEL_PRESSURE:
return channel_pressure();
default:
return 0;
}
}
};
} // namespace Evoral
#endif // EVORAL_MIDI_EVENT_HPP

View File

@ -0,0 +1,96 @@
/* This file is part of Evoral.
* Copyright (C) 2008-2016 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EVORAL_MIDI_XML_HPP
#define EVORAL_MIDI_XML_HPP
#include "evoral/Event.hpp"
#include "pbd/xml++.h"
namespace Evoral {
namespace MIDIXML {
template<typename Time>
bool
xml_to_midi(const XMLNode& node, Evoral::Event<Time>& ev)
{
if (node.name() == "ControlChange") {
ev.set_type(MIDI_CMD_CONTROL);
ev.set_cc_number(atoi(node.property("Control")->value().c_str()));
ev.set_cc_value(atoi(node.property("Value")->value().c_str()));
return true;
} else if (node.name() == "ProgramChange") {
ev.set_type(MIDI_CMD_PGM_CHANGE);
ev.set_pgm_number(atoi(node.property("Number")->value().c_str()));
return true;
}
return false;
}
template<typename Time>
boost::shared_ptr<XMLNode>
midi_to_xml(const Evoral::Event<Time>& ev)
{
XMLNode* result = 0;
switch (ev.type()) {
case MIDI_CMD_CONTROL:
result = new XMLNode("ControlChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Control", long(ev.cc_number()));
result->add_property("Value", long(ev.cc_value()));
break;
case MIDI_CMD_PGM_CHANGE:
result = new XMLNode("ProgramChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Number", long(ev.pgm_number()));
break;
case MIDI_CMD_NOTE_ON:
result = new XMLNode("NoteOn");
result->add_property("Channel", long(ev.channel()));
result->add_property("Note", long(ev.note()));
result->add_property("Velocity", long(ev.velocity()));
break;
case MIDI_CMD_NOTE_OFF:
result = new XMLNode("NoteOff");
result->add_property("Channel", long(ev.channel()));
result->add_property("Note", long(ev.note()));
result->add_property("Velocity", long(ev.velocity()));
break;
case MIDI_CMD_BENDER:
result = new XMLNode("PitchBendChange");
result->add_property("Channel", long(ev.channel()));
result->add_property("Value", long(ev.pitch_bender_value()));
break;
default:
return boost::shared_ptr<XMLNode>();
}
return boost::shared_ptr<XMLNode>(result);
}
} // namespace MIDIXML
} // namespace Evoral
#endif // EVORAL_MIDI_XML_HPP

View File

@ -24,7 +24,7 @@
#include <stdint.h>
#include "evoral/visibility.h"
#include "evoral/MIDIEvent.hpp"
#include "evoral/Event.hpp"
namespace Evoral {
@ -105,8 +105,8 @@ public:
private:
// Event buffers are self-contained
MIDIEvent<Time> _on_event;
MIDIEvent<Time> _off_event;
Event<Time> _on_event;
Event<Time> _off_event;
};
template<typename Time>

View File

@ -25,6 +25,7 @@
#include <boost/shared_ptr.hpp>
#include "evoral/visibility.h"
#include "evoral/types.hpp"
namespace Evoral {
@ -40,13 +41,13 @@ namespace Evoral {
class LIBEVORAL_API Parameter
{
public:
inline Parameter(uint32_t type, uint8_t channel=0, uint32_t id=0)
inline Parameter(ParameterType type, uint8_t channel=0, uint32_t id=0)
: _type(type), _id(id), _channel(channel)
{}
inline uint32_t type() const { return _type; }
inline uint8_t channel() const { return _channel; }
inline uint32_t id() const { return _id; }
inline ParameterType type() const { return _type; }
inline uint8_t channel() const { return _channel; }
inline uint32_t id() const { return _id; }
/** Equivalence operator
* It is obvious from the definition that this operator
@ -80,9 +81,9 @@ public:
inline operator bool() const { return (_type != 0); }
private:
uint32_t _type;
uint32_t _id;
uint8_t _channel;
ParameterType _type;
uint32_t _id;
uint8_t _channel;
};
} // namespace Evoral

View File

@ -22,7 +22,7 @@
#include "evoral/visibility.h"
#include "evoral/Event.hpp"
#include "evoral/MIDIEvent.hpp"
#include "evoral/Event.hpp"
namespace Evoral {
@ -39,9 +39,9 @@ public:
* @param b Bank number (counted from 0, 14-bit).
*/
PatchChange (Time t, uint8_t c, uint8_t p, int b)
: _bank_change_msb (0, t, 3, 0, true)
, _bank_change_lsb (0, t, 3, 0, true)
, _program_change (0, t, 2, 0, true)
: _bank_change_msb (MIDI_EVENT, t, 3, 0, true)
, _bank_change_lsb (MIDI_EVENT, t, 3, 0, true)
, _program_change (MIDI_EVENT, t, 2, 0, true)
{
_bank_change_msb.buffer()[0] = MIDI_CMD_CONTROL | c;
_bank_change_msb.buffer()[1] = MIDI_CTL_MSB_BANK;
@ -138,7 +138,7 @@ public:
/** The PatchChange is made up of messages() MIDI messages; this method returns them by index.
* @param i index of message to return.
*/
MIDIEvent<Time> const & message (int i) const {
Event<Time> const & message (int i) const {
switch (i) {
case 0:
return _bank_change_msb;
@ -158,9 +158,9 @@ public:
}
private:
MIDIEvent<Time> _bank_change_msb;
MIDIEvent<Time> _bank_change_lsb;
MIDIEvent<Time> _program_change;
Event<Time> _bank_change_msb;
Event<Time> _bank_change_lsb;
Event<Time> _program_change;
};
}

View File

@ -232,9 +232,8 @@ public:
void invalidate(std::set<WeakNotePtr>* notes);
const Event<Time>& operator*() const { return *_event; }
const boost::shared_ptr< Event<Time> > operator->() const { return _event; }
const boost::shared_ptr< Event<Time> > get_event_pointer() { return _event; }
const Event<Time>& operator*() const { return *_event; }
const boost::shared_ptr< const Event<Time> > operator->() const { return _event; }
const const_iterator& operator++(); // prefix only
@ -336,10 +335,10 @@ private:
bool overlaps_unlocked (const NotePtr& ev, const NotePtr& ignore_this_note) const;
bool contains_unlocked (const NotePtr& ev) const;
void append_note_on_unlocked(const MIDIEvent<Time>& event, Evoral::event_id_t);
void append_note_off_unlocked(const MIDIEvent<Time>& event);
void append_note_on_unlocked(const Event<Time>& event, Evoral::event_id_t);
void append_note_off_unlocked(const Event<Time>& event);
void append_control_unlocked(const Parameter& param, Time time, double value, Evoral::event_id_t);
void append_sysex_unlocked(const MIDIEvent<Time>& ev, Evoral::event_id_t);
void append_sysex_unlocked(const Event<Time>& ev, Evoral::event_id_t);
void append_patch_change_unlocked(const PatchChange<Time>&, Evoral::event_id_t);
void get_notes_by_pitch (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;

View File

@ -24,6 +24,7 @@
#include <string>
#include "evoral/visibility.h"
#include "evoral/types.hpp"
namespace Evoral {
@ -47,9 +48,8 @@ public:
*/
virtual uint8_t parameter_midi_type(const Parameter& param) const = 0;
/** The type ID for a MIDI event with the given status byte
*/
virtual uint32_t midi_event_type(uint8_t status) const = 0;
/** The parameter type for the given MIDI event. */
virtual ParameterType midi_parameter_type(const uint8_t* buf, uint32_t len) const = 0;
/** Return the description of a parameter. */
virtual ParameterDescriptor descriptor(const Parameter& param) const = 0;

View File

@ -1,5 +1,5 @@
/* This file is part of Evoral.
* Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2008-2016 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
@ -37,8 +37,23 @@ namespace Evoral {
*/
typedef int32_t event_id_t;
/** Type of an event (opaque, mapped by application) */
typedef uint32_t EventType;
/** Type of an event (opaque, mapped by application, e.g. MIDI).
*
* Event types are really an arbitrary integer provided by the type map, and it
* is safe to use values not in this enum, but this enum exists so the compiler
* can catch mistakes like setting the event type to a MIDI status byte. Event
* types come from the type map and describe a format/protocol like MIDI, and
* must not be confused with the payload (such as a note on or CC change).
* There is a static value for MIDI as this type is handled specially by
* various parts of Evoral.
*/
enum EventType {
NO_EVENT,
MIDI_EVENT
};
/** Type of a parameter (opaque, mapped by application, e.g. gain) */
typedef uint32_t ParameterType;
class Beats;

View File

@ -57,8 +57,7 @@ next_event_id ()
template<typename Timestamp>
Event<Timestamp>::Event(EventType type, Timestamp time, uint32_t size, uint8_t* buf, bool alloc)
: _type(type)
, _original_time(time)
, _nominal_time(time)
, _time(time)
, _size(size)
, _buf(buf)
, _id(-1)
@ -80,8 +79,7 @@ Event<Timestamp>::Event(EventType type,
uint32_t size,
const uint8_t* buf)
: _type(type)
, _original_time(time)
, _nominal_time(time)
, _time(time)
, _size(size)
, _buf((uint8_t*)malloc(size))
, _id(-1)
@ -93,8 +91,7 @@ Event<Timestamp>::Event(EventType type,
template<typename Timestamp>
Event<Timestamp>::Event(const Event& copy, bool owns_buf)
: _type(copy._type)
, _original_time(copy._original_time)
, _nominal_time(copy._nominal_time)
, _time(copy._time)
, _size(copy._size)
, _buf(copy._buf)
, _id (next_event_id ())
@ -123,8 +120,7 @@ Event<Timestamp>::assign(const Event& other)
{
_id = other._id;
_type = other._type;
_original_time = other._original_time;
_nominal_time = other._nominal_time;
_time = other._time;
_owns_buf = other._owns_buf;
if (_owns_buf) {
if (other._buf) {
@ -160,25 +156,10 @@ Event<Timestamp>::set (const uint8_t* buf, uint32_t size, Timestamp t)
_buf = const_cast<uint8_t*> (buf);
}
_original_time = t;
_nominal_time = t;
_time = t;
_size = size;
}
template<typename Timestamp>
void
Event<Timestamp>::set_time (Timestamp t)
{
_nominal_time = t;
}
template<typename Timestamp>
void
Event<Timestamp>::set_original_time (Timestamp t)
{
_original_time = t;
}
#endif // EVORAL_EVENT_ALLOC
template class Event<Evoral::Beats>;

View File

@ -1,109 +0,0 @@
/* This file is part of Evoral.
* Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include "evoral/Beats.hpp"
#include "evoral/MIDIEvent.hpp"
#ifdef EVORAL_MIDI_XML
#include "pbd/xml++.h"
#endif
using namespace std;
namespace Evoral {
#ifdef EVORAL_MIDI_XML
template<typename Time>
MIDIEvent<Time>::MIDIEvent(const XMLNode& event)
: Event<Time>()
{
string name = event.name();
if (name == "ControlChange") {
this->_buf = (uint8_t*) ::malloc(3);
this->_owns_buf = true;
set_type(MIDI_CMD_CONTROL);
set_cc_number(atoi(event.property("Control")->value().c_str()));
set_cc_value (atoi(event.property("Value")->value().c_str()));
} else if (name == "ProgramChange") {
this->_buf = (uint8_t*) ::malloc(2);
this->_owns_buf = true;
set_type(MIDI_CMD_PGM_CHANGE);
set_pgm_number(atoi(event.property("Number")->value().c_str()));
}
}
template<typename Time>
boost::shared_ptr<XMLNode>
MIDIEvent<Time>::to_xml() const
{
XMLNode *result = 0;
switch (type()) {
case MIDI_CMD_CONTROL:
result = new XMLNode("ControlChange");
result->add_property("Channel", long(channel()));
result->add_property("Control", long(cc_number()));
result->add_property("Value", long(cc_value()));
break;
case MIDI_CMD_PGM_CHANGE:
result = new XMLNode("ProgramChange");
result->add_property("Channel", long(channel()));
result->add_property("Number", long(pgm_number()));
break;
case MIDI_CMD_NOTE_ON:
result = new XMLNode("NoteOn");
result->add_property("Channel", long(channel()));
result->add_property("Note", long(note()));
result->add_property("Velocity", long(velocity()));
break;
case MIDI_CMD_NOTE_OFF:
result = new XMLNode("NoteOff");
result->add_property("Channel", long(channel()));
result->add_property("Note", long(note()));
result->add_property("Velocity", long(velocity()));
break;
case MIDI_CMD_BENDER:
result = new XMLNode("PitchBendChange");
result->add_property("Channel", long(channel()));
result->add_property("Value", long(pitch_bender_value()));
break;
default:
// The implementation is continued as needed
result = new XMLNode("NotImplemented");
break;
}
return boost::shared_ptr<XMLNode>(result);
}
#endif // EVORAL_MIDI_XML
template class MIDIEvent<Evoral::Beats>;
} // namespace Evoral

View File

@ -16,6 +16,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cassert>
#include <iostream>
#include <limits>
#include <glib.h>
@ -29,9 +30,8 @@ namespace Evoral {
template<typename Time>
Note<Time>::Note(uint8_t chan, Time t, Time l, uint8_t n, uint8_t v)
// FIXME: types?
: _on_event (0xDE, t, 3, NULL, true)
, _off_event (0xAD, t + l, 3, NULL, true)
: _on_event (MIDI_EVENT, t, 3, NULL, true)
, _off_event (MIDI_EVENT, t + l, 3, NULL, true)
{
assert(chan < 16);

View File

@ -63,7 +63,7 @@ template<typename Time>
Sequence<Time>::const_iterator::const_iterator()
: _seq(NULL)
, _event(boost::shared_ptr< Event<Time> >(new Event<Time>()))
, _active_patch_change_message (0)
, _active_patch_change_message (NO_EVENT)
, _type(NIL)
, _is_end(true)
, _control_iter(_control_iters.end())
@ -191,7 +191,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>&
// Allocate a new event for storing the current event in MIDI format
_event = boost::shared_ptr< Event<Time> >(
new Event<Time>(0, Time(), 4, NULL, true));
new Event<Time>(NO_EVENT, Time(), 4, NULL, true));
// Set event from chosen sub-iterator
set_event();
@ -203,7 +203,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>&
DEBUG_TRACE(DEBUG::Sequence,
string_compose("Starting at type 0x%1 : 0x%2 @ %3\n",
(int)_event->event_type(),
(int)((MIDIEvent<Time>*)_event.get())->type(),
(int)_event->buffer()[0],
_event->time()));
}
}
@ -330,7 +330,7 @@ Sequence<Time>::const_iterator::operator++()
assert(_event && _event->buffer() && _event->size() > 0);
const MIDIEvent<Time>& ev = *((MIDIEvent<Time>*)_event.get());
const Event<Time>& ev = *_event.get();
if (!( ev.is_note()
|| ev.is_cc()
@ -514,9 +514,8 @@ Sequence<Time>::Sequence(const Sequence<Time>& other)
assert(! _end_iter._lock);
}
/** Write the controller event pointed to by \a iter to \a ev.
* The buffer of \a ev will be allocated or resized as necessary.
* The event_type of \a ev should be set to the expected output type.
/** Write the controller event pointed to by `iter` to `ev`.
* The buffer of `ev` will be allocated or resized as necessary.
* \return true on success
*/
template<typename Time>
@ -526,15 +525,14 @@ Sequence<Time>::control_to_midi_event(
const ControlIterator& iter) const
{
assert(iter.list.get());
const uint32_t event_type = iter.list->parameter().type();
// initialize the event pointer with a new event, if necessary
if (!ev) {
ev = boost::shared_ptr< Event<Time> >(new Event<Time>(event_type, Time(), 3, NULL, true));
ev = boost::shared_ptr< Event<Time> >(new Event<Time>(NO_EVENT, Time(), 3, NULL, true));
}
uint8_t midi_type = _type_map.parameter_midi_type(iter.list->parameter());
ev->set_event_type(_type_map.midi_event_type(midi_type));
const uint8_t midi_type = _type_map.parameter_midi_type(iter.list->parameter());
ev->set_event_type(MIDI_EVENT);
ev->set_id(-1);
switch (midi_type) {
case MIDI_CMD_CONTROL:
@ -888,12 +886,10 @@ Sequence<Time>::remove_sysex_unlocked (const SysExPtr sysex)
*/
template<typename Time>
void
Sequence<Time>::append(const Event<Time>& event, event_id_t evid)
Sequence<Time>::append(const Event<Time>& ev, event_id_t evid)
{
WriteLock lock(write_lock());
const MIDIEvent<Time>& ev = (const MIDIEvent<Time>&)event;
assert(_notes.empty() || ev.time() >= (*_notes.rbegin())->time());
assert(_writing);
@ -921,23 +917,28 @@ Sequence<Time>::append(const Event<Time>& event, event_id_t evid)
_bank[ev.channel()] |= ev.cc_value();
}
} else if (ev.is_cc()) {
const ParameterType ptype = _type_map.midi_parameter_type(ev.buffer(), ev.size());
append_control_unlocked(
Parameter(ev.event_type(), ev.channel(), ev.cc_number()),
Parameter(ptype, ev.channel(), ev.cc_number()),
ev.time(), ev.cc_value(), evid);
} else if (ev.is_pgm_change()) {
/* write a patch change with this program change and any previously set-up bank number */
append_patch_change_unlocked (PatchChange<Time> (ev.time(), ev.channel(), ev.pgm_number(), _bank[ev.channel()]), evid);
append_patch_change_unlocked (
PatchChange<Time> (ev.time(), ev.channel(),
ev.pgm_number(), _bank[ev.channel()]), evid);
} else if (ev.is_pitch_bender()) {
const ParameterType ptype = _type_map.midi_parameter_type(ev.buffer(), ev.size());
append_control_unlocked(
Parameter(ev.event_type(), ev.channel()),
Parameter(ptype, ev.channel()),
ev.time(), double ((0x7F & ev.pitch_bender_msb()) << 7
| (0x7F & ev.pitch_bender_lsb())),
evid);
} else if (ev.is_poly_pressure()) {
append_control_unlocked (Parameter (ev.event_type(), ev.channel(), ev.poly_note()), ev.time(), ev.poly_pressure(), evid);
} else if (ev.is_channel_pressure()) {
const ParameterType ptype = _type_map.midi_parameter_type(ev.buffer(), ev.size());
append_control_unlocked(
Parameter(ev.event_type(), ev.channel()),
Parameter(ptype, ev.channel()),
ev.time(), ev.channel_pressure(), evid);
} else if (!_type_map.type_is_midi(ev.event_type())) {
printf("WARNING: Sequence: Unknown event type %X: ", ev.event_type());
@ -954,7 +955,7 @@ Sequence<Time>::append(const Event<Time>& event, event_id_t evid)
template<typename Time>
void
Sequence<Time>::append_note_on_unlocked (const MIDIEvent<Time>& ev, event_id_t evid)
Sequence<Time>::append_note_on_unlocked (const Event<Time>& ev, event_id_t evid)
{
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 c=%2 note %3 on @ %4 v=%5\n", this,
(int)ev.channel(), (int)ev.note(),
@ -986,7 +987,7 @@ Sequence<Time>::append_note_on_unlocked (const MIDIEvent<Time>& ev, event_id_t e
template<typename Time>
void
Sequence<Time>::append_note_off_unlocked (const MIDIEvent<Time>& ev)
Sequence<Time>::append_note_off_unlocked (const Event<Time>& ev)
{
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 c=%2 note %3 OFF @ %4 v=%5\n",
this, (int)ev.channel(),
@ -1053,7 +1054,7 @@ Sequence<Time>::append_control_unlocked(const Parameter& param, Time time, doubl
template<typename Time>
void
Sequence<Time>::append_sysex_unlocked(const MIDIEvent<Time>& ev, event_id_t /* evid */)
Sequence<Time>::append_sysex_unlocked(const Event<Time>& ev, event_id_t /* evid */)
{
#ifdef DEBUG_SEQUENCE
cerr << this << " SysEx @ " << ev.time() << " \t= \t [ " << hex;
@ -1062,7 +1063,7 @@ Sequence<Time>::append_sysex_unlocked(const MIDIEvent<Time>& ev, event_id_t /* e
} cerr << "]" << endl;
#endif
boost::shared_ptr<MIDIEvent<Time> > event(new MIDIEvent<Time>(ev, true));
boost::shared_ptr< Event<Time> > event(new Event<Time>(ev, true));
/* XXX sysex events should use IDs */
_sysexes.insert(event);
}
@ -1203,7 +1204,7 @@ template<typename Time>
typename Sequence<Time>::SysExes::const_iterator
Sequence<Time>::sysex_lower_bound (Time t) const
{
SysExPtr search (new Event<Time> (0, t));
SysExPtr search (new Event<Time> (NO_EVENT, t));
typename Sequence<Time>::SysExes::const_iterator i = _sysexes.lower_bound (search);
assert (i == _sysexes.end() || (*i)->time() >= t);
return i;
@ -1238,7 +1239,7 @@ template<typename Time>
typename Sequence<Time>::SysExes::iterator
Sequence<Time>::sysex_lower_bound (Time t)
{
SysExPtr search (new Event<Time> (0, t));
SysExPtr search (new Event<Time> (NO_EVENT, t));
typename Sequence<Time>::SysExes::iterator i = _sysexes.lower_bound (search);
assert (i == _sysexes.end() || (*i)->time() >= t);
return i;

View File

@ -59,7 +59,7 @@ SMFTest::takeFiveTest ()
if (ret > 0) { // didn't skip (meta) event
//cerr << "read smf event type " << hex << int(buf[0]) << endl;
ev.set_time(Evoral::Beats::ticks_at_rate(time, smf.ppqn()));
ev.set_event_type(type_map->midi_event_type(buf[0]));
ev.set_event_type(Evoral::MIDI_EVENT);
seq->append(ev, next_event_id ());
}
}

View File

@ -25,7 +25,7 @@ SequenceTest::preserveEventOrderingTest ()
for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
uint8_t buffer[3];
Event<Time>* event = new Event<Time>(
DummyTypeMap::CONTROL, (*i)->on_event().time(), 3, buffer, true
(Evoral::EventType)DummyTypeMap::CONTROL, (*i)->on_event().time(), 3, buffer, true
);
event->buffer()[0] = MIDI_CMD_CONTROL;
@ -77,12 +77,12 @@ SequenceTest::iteratorSeekTest ()
bool on = true;
for (Sequence<Time>::const_iterator i = seq->begin(Evoral::Beats(600)); i != seq->end(); ++i) {
if (on) {
CPPUNIT_ASSERT(((const MIDIEvent<Time>&)*i).is_note_on());
CPPUNIT_ASSERT(i->is_note_on());
CPPUNIT_ASSERT_EQUAL(i->time(), Time((num_notes + 6) * 100));
++num_notes;
on = false;
} else {
CPPUNIT_ASSERT(((const MIDIEvent<Time>&)*i).is_note_off());
CPPUNIT_ASSERT(i->is_note_off());
on = true;
}
}

View File

@ -31,13 +31,14 @@ public:
};
}
uint32_t midi_event_type(uint8_t status) const {
status &= 0xf0;
switch (status) {
case MIDI_CMD_CONTROL: return CONTROL;
case MIDI_CMD_COMMON_SYSEX: return SYSEX;
default: return 0;
};
virtual ParameterType midi_parameter_type(const uint8_t* buf, uint32_t len) const {
switch (buf[0] & 0xF0) {
case MIDI_CMD_CONTROL: return CONTROL;
case MIDI_CMD_COMMON_SYSEX: return SYSEX;
case MIDI_CMD_NOTE_ON: return NOTE;
case MIDI_CMD_NOTE_OFF: return NOTE;
default: return 0;
}
}
ParameterDescriptor descriptor(const Parameter& param) const {

View File

@ -82,7 +82,6 @@ def build(bld):
src/ControlSet.cpp
src/Curve.cpp
src/Event.cpp
src/MIDIEvent.cpp
src/Note.cpp
src/SMF.cpp
src/Sequence.cpp
@ -110,7 +109,7 @@ def build(bld):
obj.use = 'libsmf libpbd'
obj.vnum = EVORAL_LIB_VERSION
obj.install_path = bld.env['LIBDIR']
obj.defines += [ 'PACKAGE="libevoral"', 'EVORAL_MIDI_XML=1' ]
obj.defines += [ 'PACKAGE="libevoral"' ]
if bld.env['BUILD_TESTS'] and bld.is_defined('HAVE_CPPUNIT'):
# Static library (for unit test code coverage)
@ -129,7 +128,7 @@ def build(bld):
obj.linkflags = '-lgcov'
obj.cflags = [ '-fprofile-arcs', '-ftest-coverage' ]
obj.cxxflags = [ '-fprofile-arcs', '-ftest-coverage' ]
obj.defines = ['PACKAGE="libevoral"', 'EVORAL_MIDI_XML=1' ]
obj.defines = ['PACKAGE="libevoral"']
# Unit tests
obj = bld(features = 'cxx cxxprogram')

View File

@ -37,10 +37,6 @@
*/
#define EVORAL_EVENT_ALLOC 1
/** Support serialisation of MIDI events to/from XML */
#define EVORAL_MIDI_XML 1
#include "evoral/Event.hpp"
#include "evoral/MIDIEvent.hpp"
#endif /* __libmidipp_midi_event_h__ */

View File

@ -97,12 +97,12 @@ Patch::get_state (void)
node->add_property("Name", _name);
/*
typedef std::list< boost::shared_ptr< Evoral::MIDIEvent<Evoral::Beats> > > PatchMidiCommands;
typedef std::list< boost::shared_ptr< Evoral::Event<Evoral::Beats> > > PatchMidiCommands;
XMLNode* commands = node->add_child("PatchMIDICommands");
for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
event != _patch_midi_commands.end();
++event) {
commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
commands->add_child_copy(Evoral::MIDIXML::midi_to_xml(*event));
}
*/