From d6b87aa26ef482a8952437f7472b81a2240f01fd Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 21 Jan 2008 15:14:53 +0000 Subject: Work on generic LV2 events. git-svn-id: http://svn.drobilla.net/lad/ingen@1090 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/lv2ext/Makefile.am | 2 +- src/common/lv2ext/lv2-midiport.h | 179 --------------------------------------- src/common/lv2ext/lv2_event.h | 178 ++++++++++++++++++++++++++++++++++++++ src/common/lv2ext/lv2_osc.h | 1 - 4 files changed, 179 insertions(+), 181 deletions(-) delete mode 100644 src/common/lv2ext/lv2-midiport.h create mode 100644 src/common/lv2ext/lv2_event.h delete mode 120000 src/common/lv2ext/lv2_osc.h (limited to 'src/common/lv2ext') 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 - - 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 - -/** @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 - 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 + * Copyright (C) 2008 Dave Robillard + * + * 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 + +/** @file + * This header defines the code portion of the LV2 events extension with URI + * (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 -- cgit v1.2.1