summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-01-21 15:14:53 +0000
committerDavid Robillard <d@drobilla.net>2008-01-21 15:14:53 +0000
commitd6b87aa26ef482a8952437f7472b81a2240f01fd (patch)
tree620d233b902c78413dc17ee5f921633251239695 /src/common
parent2356f96fbd6c9d70dedcd0d64bf0d72786ea36bb (diff)
downloadingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.tar.gz
ingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.tar.bz2
ingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.zip
Work on generic LV2 events.
git-svn-id: http://svn.drobilla.net/lad/ingen@1090 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/common')
-rw-r--r--src/common/interface/DataType.hpp15
-rw-r--r--src/common/interface/EventType.hpp79
-rw-r--r--src/common/interface/Makefile.am1
-rw-r--r--src/common/lv2ext/Makefile.am2
-rw-r--r--src/common/lv2ext/lv2-midiport.h179
-rw-r--r--src/common/lv2ext/lv2_event.h178
l---------src/common/lv2ext/lv2_osc.h1
7 files changed, 264 insertions, 191 deletions
diff --git a/src/common/interface/DataType.hpp b/src/common/interface/DataType.hpp
index 60056d2b..7ce76be1 100644
--- a/src/common/interface/DataType.hpp
+++ b/src/common/interface/DataType.hpp
@@ -35,8 +35,7 @@ public:
UNKNOWN = 0,
AUDIO = 1,
CONTROL = 2,
- MIDI = 3,
- OSC = 4
+ EVENT = 3
};
DataType(const std::string& uri)
@@ -46,10 +45,8 @@ public:
_symbol = AUDIO;
} else if (uri == type_uri(CONTROL)) {
_symbol = CONTROL;
- } else if (uri == type_uri(MIDI)) {
- _symbol = MIDI;
- } else if (uri == type_uri(OSC)) {
- _symbol = OSC;
+ } else if (uri == type_uri(EVENT)) {
+ _symbol = EVENT;
}
}
@@ -66,8 +63,7 @@ public:
inline bool is_audio() { return _symbol == AUDIO; }
inline bool is_control() { return _symbol == CONTROL; }
- inline bool is_midi() { return _symbol == MIDI; }
- inline bool is_osc() { return _symbol == OSC; }
+ inline bool is_event() { return _symbol == EVENT; }
private:
@@ -75,8 +71,7 @@ private:
switch (symbol_num) {
case 1: return "ingen:AudioPort";
case 2: return "ingen:ControlPort";
- case 3: return "ingen:MIDIPort";
- case 4: return "ingen:OSCPort";
+ case 3: return "ingen:EventPort";
default: return "";
}
}
diff --git a/src/common/interface/EventType.hpp b/src/common/interface/EventType.hpp
new file mode 100644
index 00000000..d74835e6
--- /dev/null
+++ b/src/common/interface/EventType.hpp
@@ -0,0 +1,79 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen 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.
+ *
+ * Ingen 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 EVENTTYPE_H
+#define EVENTTYPE_H
+
+namespace Ingen {
+namespace Shared {
+
+
+/** A type of event (that can live in an EventBuffer).
+ */
+class EventType {
+public:
+
+ enum Symbol {
+ UNKNOWN = 0,
+ MIDI = 1,
+ OSC = 2
+ };
+
+ EventType(const std::string& uri)
+ : _symbol(UNKNOWN)
+ {
+ if (uri == type_uri(MIDI)) {
+ _symbol = MIDI;
+ } else if (uri == type_uri(OSC)) {
+ _symbol = OSC;
+ }
+ }
+
+ EventType(Symbol symbol)
+ : _symbol(symbol)
+ {}
+
+ inline const char* uri() const { return type_uri(_symbol); }
+
+ inline bool operator==(const Symbol& symbol) const { return (_symbol == symbol); }
+ inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); }
+ inline bool operator==(const EventType& type) const { return (_symbol == type._symbol); }
+ inline bool operator!=(const EventType& type) const { return (_symbol != type._symbol); }
+
+ inline bool is_midi() { return _symbol == MIDI; }
+ inline bool is_osc() { return _symbol == OSC; }
+
+private:
+
+ static inline const char* type_uri(unsigned symbol_num) {
+ switch (symbol_num) {
+ case 1: return "ingen:MidiEvent";
+ case 2: return "ingen:OSCEvent";
+ default: return "";
+ }
+ }
+
+ Symbol _symbol;
+};
+
+
+} // namespace Shared
+} // namespace Ingen
+
+using Ingen::Shared::EventType;
+
+#endif // EVENTTYPE_H
diff --git a/src/common/interface/Makefile.am b/src/common/interface/Makefile.am
index b23e2583..9f56791d 100644
--- a/src/common/interface/Makefile.am
+++ b/src/common/interface/Makefile.am
@@ -3,6 +3,7 @@ EXTRA_DIST = \
Connection.hpp \
DataType.hpp \
EngineInterface.hpp \
+ EventType.hpp \
GraphObject.hpp \
Node.hpp \
Patch.hpp \
diff --git a/src/common/lv2ext/Makefile.am b/src/common/lv2ext/Makefile.am
index a4dceb45..ecbde5dd 100644
--- a/src/common/lv2ext/Makefile.am
+++ b/src/common/lv2ext/Makefile.am
@@ -1 +1 @@
-noinst_HEADERS = lv2-midiport.h
+noinst_HEADERS = lv2_event.h
diff --git a/src/common/lv2ext/lv2-midiport.h b/src/common/lv2ext/lv2-midiport.h
deleted file mode 100644
index 63980f64..00000000
--- a/src/common/lv2ext/lv2-midiport.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-
- lv2-midiport.h - header file for using MIDI in LV2 plugins
-
- Copyright (C) 2006 Lars Luthman <lars.luthman@gmail.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
-
-****************************************************************************/
-
-#include <stdint.h>
-
-/** @file
- This file contains the specification for an LV2 MIDI port extension.
-*/
-
-#ifndef LV2_MIDIPORT_H
-#define LV2_MIDIPORT_H
-
-
-/** This data structure is used to contain the MIDI events for one run()
- cycle. The port buffer for an LV2 port of the type
- <http://ll-plugins.nongnu.org/lv2/ext/MidiPort> should be a pointer
- to an instance of this struct.
-
- To store two Note On events on MIDI channel 0 in a buffer, with timestamps
- 12 and 35.5, you could use something like this code (assuming that
- midi_data is a variable of type LV2_MIDI):
- @code
-
- uint32_t buffer_offset = 0;
- *(double*)(midi_data->data + buffer_offset) = 12;
- buffer_offset += sizeof(double);
- *(uint32_t*)(midi_data->data + buffer_offset) = 3;
- buffer_offset += sizeof(uint32_t);
- midi_data->data[buffer_offset++] = 0x90;
- midi_data->data[buffer_offset++] = 0x48;
- midi_data->data[buffer_offset++] = 0x64;
- ++midi_data->event_count;
-
- *(double*)(midi_data->data + buffer_offset) = 35.5;
- buffer_offset += sizeof(double);
- *(uint32_t*)(midi_data->data + buffer_offset) = 3;
- buffer_offset += sizeof(uint32_t);
- midi_data->data[buffer_offset++] = 0x90;
- midi_data->data[buffer_offset++] = 0x55;
- midi_data->data[buffer_offset++] = 0x64;
- ++midi_data->event_count;
-
- midi_data->size = buffer_offset;
-
- @endcode
-
- This would be done by the host in the case of an input port, and by the
- plugin in the case of an output port. Whoever is writing events to the
- buffer must also take care not to exceed the capacity of the data buffer.
-
- To read events from a buffer, you could do something like this:
- @code
-
- uint32_t buffer_offset = 0;
- uint32_t i;
- for (i = 0; i < midi_data->event_count; ++i) {
- double timestamp = *(double*)(midi_data->data + buffer_offset);
- buffer_offset += sizeof(double);
- uint32_t size = *(uint32_t*)(midi_data->data + buffer_offset);
- buffer_offset += sizeof(uint32_t);
- do_something_with_event(timestamp, size,
- midi_data->data + buffer_offset);
- buffer_offset += size;
- }
-
- @endcode
-
- If you think this looks like too much code to simply read and write MIDI
- events, take a look at the helper functions in lv2-midifunctions.h. They
- are not an official part of this extension, but they can be convenient.
-*/
-typedef struct {
-
- /** The number of MIDI events in the data buffer.
- INPUT PORTS: It's the host's responsibility to set this field to the
- number of MIDI events contained in the data buffer before calling the
- plugin's run() function. The plugin may not change this field.
- OUTPUT PORTS: It's the plugin's responsibility to set this field to the
- number of MIDI events it has stored in the data buffer before returning
- from the run() function. Any initial value should be ignored by the
- plugin.
- */
- uint32_t event_count;
-
- /** The size of the data buffer in bytes. It is set by the host and may not
- be changed by the plugin. The host is allowed to change this between
- run() calls.
- */
- uint32_t capacity;
-
- /** The size of the initial part of the data buffer that actually contains
- data.
- INPUT PORTS: It's the host's responsibility to set this field to the
- number of bytes used by all MIDI events it has written to the buffer
- (including timestamps and size fields) before calling the plugin's
- run() function. The plugin may not change this field.
- OUTPUT PORTS: It's the plugin's responsibility to set this field to
- the number of bytes used by all MIDI events it has written to the
- buffer (including timestamps and size fields) before returning from
- the run() function. Any initial value should be ignored by the plugin.
- */
- uint32_t size;
-
- /** The data buffer that is used to store MIDI events. The events are packed
- after each other, and the format of each event is as follows:
-
- First there is a timestamp, which should have the type "double",
- i.e. have the same bit size as a double and the same bit layout as a
- double (whatever that is on the current platform). This timestamp gives
- the offset from the beginning of the current cycle, in frames, that
- the MIDI event occurs on. It must be strictly smaller than the 'nframes'
- parameter to the current run() call. The MIDI events in the buffer must
- be ordered by their timestamp, e.g. an event with a timestamp of 123.23
- must be stored after an event with a timestamp of 65.0.
-
- The second part of the event is a size field, which should have the type
- "uint32_t" (as defined in the standard C header stddef.h). It should
- contain the size of the MIDI data for this event, i.e. the number of
- bytes used to store the actual MIDI event. The bytes used by the
- timestamp and the size field should not be counted.
-
- The third part of the event is the actual MIDI data. There are some
- requirements that must be followed:
-
- * Running status is not allowed. Every event must have its own status
- byte.
- * Note On events with velocity 0 are not allowed. These events are
- equivalent to Note Off in standard MIDI streams, but in order to make
- plugins and hosts easier to write, as well as more efficient, only
- proper Note Off events are allowed as Note Off.
- * "Realtime events" (status bytes 0xF8 to 0xFF) are allowed, but may not
- occur inside other events like they are allowed to in hardware MIDI
- streams.
- * All events must be fully contained in a single data buffer, i.e. events
- may not "wrap around" by storing the first few bytes in one buffer and
- then wait for the next run() call to store the rest of the event. If
- there isn't enough space in the current data buffer to store an event,
- the event will either have to wait until next run() call, be ignored,
- or compensated for in some more clever way.
- * All events must be valid MIDI events. This means for example that
- only the first byte in each event (the status byte) may have the eighth
- bit set, that Note On and Note Off events are always 3 bytes long etc.
- The MIDI writer (host or plugin) is responsible for writing valid MIDI
- events to the buffer, and the MIDI reader (plugin or host) can assume
- that all events are valid.
-
- On a platform where double is 8 bytes the data buffer layout for a
- 3-byte event followed by a 4-byte event may look something like this:
- _______________________________________________________________
- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ...
- |TIMESTAMP 1 |SIZE 1 |DATA |TIMESTAMP 2 |SIZE 2 |DATA | ...
-
- */
- unsigned char* data;
-
-} LV2_MIDI;
-
-
-
-#endif
diff --git a/src/common/lv2ext/lv2_event.h b/src/common/lv2ext/lv2_event.h
new file mode 100644
index 00000000..266ba180
--- /dev/null
+++ b/src/common/lv2ext/lv2_event.h
@@ -0,0 +1,178 @@
+/* lv2_events.h - C header file for the LV2 events extension.
+ *
+ * Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
+ * Copyright (C) 2008 Dave Robillard <dave@drobilla.net>
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This header 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
+ */
+
+#ifndef LV2_EVENTS_H
+#define LV2_EVENTS_H
+
+#include <stdint.h>
+
+/** @file
+ * This header defines the code portion of the LV2 events extension with URI
+ * <http://lv2plug.in/ns/ext/events> (preferred prefix 'lv2ev').
+ *
+ * This extension is a generic transport mechanism for time stamped events
+ * of any type (e.g. MIDI, OSC, ramps, etc). Each port can transport mixed
+ * events of any type; the type of events is defined by a URI (in some other
+ * extension) which is mapped to an integer by the host for performance
+ * reasons.
+ */
+
+
+/** The PPQN (pulses per quarter note) of tempo-based LV2 event time stamps.
+ * Equal to (2^5 * 3^4 * 5 * 7 * 11 * 13 * 17 * 19), which is evenly divisuble
+ * by all integers from 1 through 22 inclusive. */
+static const uint32_t LV2_EVENT_PPQN = 4190266080;
+
+
+
+/** Opaque host data passed to LV2_Event_Feature.
+ */
+typedef void* LV2_Event_Callback_Data;
+
+
+
+/** The data part of the LV2_Feature for the LV2 events extension.
+ *
+ * The host MUST pass an LV2_Feature struct to the plugin's instantiate
+ * method with URI set to "http://lv2plug.in/ns/ext/events" and data
+ * set to an instance of this struct.
+ *
+ * The plugin MUST pass callback_data to any invocation of the functions
+ * defined in this struct. Otherwise, callback_data is opaque and the
+ * plugin MUST NOT interpret its value in any way.
+ */
+typedef struct {
+
+ /** Get the numeric version of an event type from the host.
+ *
+ * The returned value is 0 if there is no type by that URI.
+ * The returned value correlates to the type field of LV2_Event, and is
+ * guaranteed never to change over the course of the plugin's
+ * instantiation, unless the returned value is 0 (i.e. new event types
+ * can be added, but existing ones can never be changed/removed).
+ */
+ uint16_t (*uri_to_event_type)(LV2_Event_Callback_Data callback_data,
+ char const* uri);
+
+ LV2_Event_Callback_Data callback_data;
+
+} LV2_Event_Feature;
+
+
+
+/** An LV2 event.
+ *
+ * LV2 events are generic time-stamped containers for any type of event.
+ * The type field defines the format of a given event's contents.
+ *
+ * This struct defined the header of an LV2 event. An LV2 event is a single
+ * chunk of POD (plain old data), usually contained in a flat buffer
+ * (see LV2_EventBuffer below). Unless a required feature says otherwise,
+ * hosts may assume a deep copy of an LV2 event can be created safely
+ * using a simple:
+ *
+ * memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size); (or equivalent)
+ */
+typedef struct {
+
+ /** The frames portion of timestamp. The units used here can optionally be
+ * set for a port (with the lv2ev:timeUnits property), otherwise this
+ * is audio frames, corresponding to the sample_count parameter of the
+ * LV2 run method (e.g. frame 0 is the first frame for that call to run).
+ */
+ uint32_t frames;
+
+ /** The sub-frames portion of timestamp. The units used here can
+ * optionally be set for a port (with the lv2ev:timeUnits property),
+ * otherwise this is 1/(2^32) of an audio frame.
+ */
+ uint32_t subframes;
+
+ /** The type of this event, where this numeric value refers to some URI
+ * defining an event type. The LV2_Event_Feature passed from the host
+ * provides a function to map URIs to event types for this field.
+ * The type 0 is a special nil value, meaning the event has no type and
+ * should be ignored or passed through without interpretation.
+ * Plugins MUST gracefully ignore or pass through any events of a type
+ * which the plugin does not recognize.
+ */
+ uint16_t type;
+
+ /** The size of the data portion of this event in bytes, which immediately
+ * follows. The header size (12 bytes) is not included in this value.
+ */
+ uint16_t size;
+
+ /* size bytes of data follow here */
+
+} LV2_Event;
+
+
+
+/** A buffer of LV2 events.
+ *
+ * Like events (which this contains) an event buffer is a single chunk of POD:
+ * the entire buffer (including contents) can be copied with a single memcpy.
+ * The first contained event begins sizeof(LV2_EventBuffer) bytes after
+ * the start of this struct.
+ *
+ * After this header, the buffer contains an event header (defined by struct
+ * LV2_Event), followed by that event's contents (padded to 64 bits), followed by
+ * another header, etc:
+ *
+ * | | | | | | |
+ * | | | | | | | | | | | | | | | | | | | | | | | | |
+ * |FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ...
+ */
+typedef struct {
+
+ /** The number of events in this buffer.
+ * INPUT PORTS: The host must set this field to the number of events
+ * contained in the data buffer before calling run().
+ * The plugin must not change this field.
+ * OUTPUT PORTS: The plugin must set this field to the number of events it
+ * has written to the buffer before returning from run().
+ * Any initial value should be ignored by the plugin.
+ */
+ uint32_t event_count;
+
+ /** The size of the data buffer in bytes.
+ * This is set by the host and must not be changed by the plugin.
+ * The host is allowed to change this between run() calls.
+ */
+ uint32_t capacity;
+
+ /** The size of the initial portion of the data buffer containing data.
+ * INPUT PORTS: The host must set this field to the number of bytes used
+ * by all events it has written to the buffer (including headers)
+ * before calling the plugin's run().
+ * The plugin must not change this field.
+ * OUTPUT PORTS: The plugin must set this field to the number of bytes
+ * used by all events it has written to the buffer (including headers)
+ * before returning from run().
+ * Any initial value should be ignored by the plugin.
+ */
+ uint32_t size;
+
+} LV2_Event_Buffer;
+
+
+#endif // LV2_EVENTS_H
+
diff --git a/src/common/lv2ext/lv2_osc.h b/src/common/lv2ext/lv2_osc.h
deleted file mode 120000
index 8c97f7b8..00000000
--- a/src/common/lv2ext/lv2_osc.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../lv2/extensions/osc/lv2_osc.h \ No newline at end of file