[SCM] calf/master: + LV2: updates/fixes to event support (still not enough) + Knob: requisition fix

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:03 UTC 2013


The following commit has been merged in the master branch:
commit 04663b3b410d7616d49c2883c239c8d1da3ea1de
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Sun Feb 3 23:13:51 2008 +0000

    + LV2: updates/fixes to event support (still not enough)
    + Knob: requisition fix
    
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@122 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/lv2_event.h b/src/calf/lv2_event.h
index bb8a6aa..bc81ed9 100644
--- a/src/calf/lv2_event.h
+++ b/src/calf/lv2_event.h
@@ -49,8 +49,7 @@
 static const uint32_t LV2_EVENT_PPQN = 3136573440U;
 
 
-
-/** An LV2 event.
+/** An LV2 event (header only).
  *
  * LV2 events are generic time-stamped containers for any type of event.
  * The type field defines the format of a given event's contents.
@@ -81,17 +80,17 @@ typedef struct {
 	/** The type of this event, as a number which represents some URI
 	 * defining an event type.  This value MUST be some value previously
 	 * returned from a call to the uri_to_id function defined in the LV2
-	 * URI map extension.
-	 * The type 0 is a special reserved value, meaning the event contains a
-	 * single pointer (of native machine size) to a dynamically allocated
-	 * LV2_Object.  This allows events to carry large non-POD payloads
-	 * (e.g. images, waveforms, large SYSEX dumps, etc.) without copying.
-	 * See the LV2 Object extension for details.
-	 * Plugins which do not support the LV2 Object extension MUST NOT store,
-	 * copy, or pass through to an output any event with type 0.
-	 * If the type is not 0, plugins may assume the event is POD and should
-	 * gracefully ignore or pass through (with a simple copy) any events
-	 * of a type the plugin does not recognize.
+	 * URI map extension (see lv2_uri_map.h).
+	 * There are special rules which must be followed depending on the type
+	 * of an event.  If the plugin recognizes an event type, the definition
+	 * of that event type will describe how to interpret the event, and
+	 * any required behaviour.  Otherwise (if the plugin does not understand
+	 * the event type), lv2_event_drop must be called if the event is 'dropped'
+	 * (see above).  Even if the plugin does not understand an event, it may
+	 * pass the event through to an output by simply copying (and NOT calling
+	 * lv2_event_drop).  These rules are designed to allow for generic event
+	 * handling plugins and large non-POD events, but with minimal hassle on
+	 * simple plugins that "don't care" about these more advanced features.
 	 */
 	uint16_t type;
 
@@ -106,7 +105,7 @@ typedef struct {
 
 
 
-/** A buffer of LV2 events.
+/** A buffer of LV2 events (header only).
  *
  * 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.
@@ -180,5 +179,49 @@ typedef struct {
 } LV2_Event_Buffer;
 
 
+/** Opaque pointer to host data. */
+typedef void* LV2_Event_Callback_Data;
+
+
+/** The data field of the LV2_Feature for this extension.
+ *
+ * To support this feature the host must pass an LV2_Feature struct to the
+ * plugin's instantiate method with URI "http://lv2plug.in/ns/ext/event"
+ * and data pointed to an instance of this struct.
+ */
+typedef struct {
+	
+	/** Opaque pointer to host data.
+	 *
+	 * The plugin MUST pass this to any call to functions in this struct.
+	 * Otherwise, it must not be interpreted in any way.
+	 */
+	LV2_Event_Callback_Data callback_data;
+	
+	/** Drop a reference to a non-POD event.
+	 *
+	 * If a plugin receives an event with type 0, it means the event is a
+	 * pointer to some object in memory and not a flat sequence of bytes
+	 * in the buffer.  If the plugin does not pass the event through to
+	 * an output or store it internally somehow, it MUST call this function
+	 * on the event (more information on using non-POD events below).
+	 *
+	 * @param event An event received at an input that will not be copied to
+	 *              an output or stored in any way.
+	 * @param context The calling context.  (Like event types) this is a mapped
+	 *                URI, see lv2_context.h. Simple plugin with just a run()
+	 *                method should pass 0 here (the ID of the 'standard' LV2
+	 *                run context).  The host guarantees that this function is
+	 *                realtime safe iff @a context is realtime safe.
+	 *
+	 * PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
+	 */
+	uint32_t (*lv2_event_drop)(LV2_Event_Callback_Data callback_data,
+	                           LV2_Event*              event,
+	                           uint32_t                context);
+
+} LV2_Event_Feature;
+
+
 #endif // LV2_EVENT_H
 
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index 587b538..33271fb 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -17,6 +17,7 @@ struct lv2_instance: public Module, public plugin_ctl_iface
     LV2_MIDI *midi_data;
     LV2_Event_Buffer *event_data;
     LV2_URI_Map_Feature *uri_map;
+    LV2_Event_Feature *event_feature;
     uint32_t midi_event_type;
     lv2_instance()
     {
@@ -131,6 +132,10 @@ struct lv2_wrapper
                     "http://lv2plug.in/ns/ext/event",
                     "http://lv2plug.in/ns/ext/midi#MidiEvent");
             }
+            else if (!strcmp((*features)->URI, LV2_EVENT_URI))
+            {
+                mod->event_feature = (LV2_Event_Feature *)((*features)->data);
+            }
             features++;
         }
         return mod;
@@ -163,35 +168,7 @@ struct lv2_wrapper
         }
         mod->params_changed();
         uint32_t offset = 0;
-        if (mod->midi_data)
-        {
-            struct MIDI_ITEM {
-                double timestamp;
-                uint32_t size;
-                unsigned char data[1];
-            };
-            unsigned char *data = (unsigned char *)mod->midi_data->data;
-            for (uint32_t i = 0; i < mod->midi_data->event_count; i++) {
-                MIDI_ITEM *item = (MIDI_ITEM *)data;
-                uint32_t ts = (int)item->timestamp;
-                if (ts > offset)
-                {
-                    process_slice(mod, offset, ts);
-                    offset = ts;
-                }
-                switch(item->data[0] >> 4)
-                {
-                case 8: mod->note_off(item->data[1], item->data[2]); break;
-                case 9: mod->note_on(item->data[1], item->data[2]); break;
-                case 10: mod->program_change(item->data[1]); break;
-                case 11: mod->control_change(item->data[1], item->data[2]); break;
-                case 14: mod->pitch_bend(item->data[1] + 128 * item->data[2] - 8192); break;
-                }
-                // printf("timestamp %f item size %d first byte %x\n", item->timestamp, item->size, item->data[0]);
-                data += 12 + item->size;
-            }
-        }
-        else if (mod->event_data)
+        if (mod->event_data)
         {
             // printf("Event data: count %d\n", mod->event_data->event_count);
             struct LV2_Midi_Event: public LV2_Event {
@@ -202,7 +179,6 @@ struct lv2_wrapper
                 LV2_Midi_Event *item = (LV2_Midi_Event *)data;
                 uint32_t ts = item->frames;
                 // printf("Event: timestamp %d subframes %d type %d vs %d\n", item->frames, item->subframes, item->type, mod->midi_event_type);
-                fflush(stdout);
                 if (ts > offset)
                 {
                     process_slice(mod, offset, ts);
@@ -220,10 +196,42 @@ struct lv2_wrapper
                     case 14: mod->pitch_bend(item->data[1] + 128 * item->data[2] - 8192); break;
                     }
                 }
+                else
+                if (item->type == 0 && mod->event_feature)
+                    mod->event_feature->lv2_event_drop(mod->event_feature->callback_data, item, 0);
                 // printf("timestamp %f item size %d first byte %x\n", item->timestamp, item->size, item->data[0]);
                 data += ((sizeof(LV2_Event) + item->size + 7))&~7;
             }
         }
+        else
+        if (mod->midi_data)
+        {
+            struct MIDI_ITEM {
+                double timestamp;
+                uint32_t size;
+                unsigned char data[1];
+            };
+            unsigned char *data = (unsigned char *)mod->midi_data->data;
+            for (uint32_t i = 0; i < mod->midi_data->event_count; i++) {
+                MIDI_ITEM *item = (MIDI_ITEM *)data;
+                uint32_t ts = (int)item->timestamp;
+                if (ts > offset)
+                {
+                    process_slice(mod, offset, ts);
+                    offset = ts;
+                }
+                switch(item->data[0] >> 4)
+                {
+                case 8: mod->note_off(item->data[1], item->data[2]); break;
+                case 9: mod->note_on(item->data[1], item->data[2]); break;
+                case 10: mod->program_change(item->data[1]); break;
+                case 11: mod->control_change(item->data[1], item->data[2]); break;
+                case 14: mod->pitch_bend(item->data[1] + 128 * item->data[2] - 8192); break;
+                }
+                // printf("timestamp %f item size %d first byte %x\n", item->timestamp, item->size, item->data[0]);
+                data += 12 + item->size;
+            }
+        }
         process_slice(mod, offset, SampleCount);
     }
     static void cb_cleanup(LV2_Handle Instance) {
diff --git a/src/custom_ctl.cpp b/src/custom_ctl.cpp
index d5afd1b..f95d7ae 100644
--- a/src/custom_ctl.cpp
+++ b/src/custom_ctl.cpp
@@ -213,6 +213,8 @@ calf_knob_size_request (GtkWidget *widget,
     g_assert(CALF_IS_KNOB(widget));
     
     CalfKnob *self = CALF_KNOB(widget);
+    requisition->width = 40;
+    requisition->height = 40;
 }
 
 static void
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index 806ebaf..d9689d9 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -58,7 +58,7 @@ void make_rdf()
     printf("%s\n", rdf.c_str());
 }
 
-static void add_port(string &ports, const char *symbol, const char *name, const char *direction, int pidx, const char *type = "lv2:AudioPort")
+static void add_port(string &ports, const char *symbol, const char *name, const char *direction, int pidx, const char *type = "lv2:AudioPort", bool optional = false)
 {
     stringstream ss;
     const char *ind = "        ";
@@ -71,6 +71,13 @@ static void add_port(string &ports, const char *symbol, const char *name, const
     ss << ind << "lv2:index " << pidx << " ;\n";
     ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
     ss << ind << "lv2:name \"" << name << "\" ;\n";
+    if (optional)
+        ss << ind << "lv2:portProperty lv2:connectionOptional ;\n";
+    if (!strcmp(type, "lv2ev:EventPort")) {
+        ss << ind << "lv2ev:supportsEvent lv2midi:midiEvent ;\n";
+        // XXXKF add a correct timestamp type here
+        ss << ind << "lv2ev:supportsTimestamp <lv2ev:TimeStamp> ;\n";
+    }
     ss << "    ]";
     ports += ss.str();
 }
@@ -118,6 +125,7 @@ void make_ttl(string path_prefix)
         "@prefix midiext: <http://ll-plugins.nongnu.org/lv2/ext/MidiPort> .\n"
         "@prefix uiext: <http://ll-plugins.nongnu.org/lv2/ext/ui#> .\n"
         "@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .\n"
+        "@prefix lv2midi: <http://lv2plug.in/ns/ext/midi#> .\n"
 
         "\n"
     ;
@@ -180,8 +188,8 @@ void make_ttl(string path_prefix)
         for (int i = 0; i < pi.params; i++)
             add_ctl_port(ports, pi.param_props[i], pn++);
         if (pi.midi_in_capable) {
-            add_port(ports, "midi_in", "MIDI", "Input", pn++, "<http://ll-plugins.nongnu.org/lv2/ext/MidiPort>");
-            add_port(ports, "event_in", "Event", "Input", pn++, "lv2ev:EventPort");
+            add_port(ports, "midi_in", "MIDI", "Input", pn++, "<http://ll-plugins.nongnu.org/lv2/ext/MidiPort>", true);
+            add_port(ports, "event_in", "Event", "Input", pn++, "lv2ev:EventPort", true);
         }
         if (!ports.empty())
             ttl += "    lv2:port " + ports + "\n";

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list