[SCM] calf/master: + Framework: separated midi_mixin into event_mixin and midi_mixin which is dependent on it + LV2: updated lv2_event.h + Small modules: removed notefilter_e and notefilter2_e, added a bunch of trivial inflexible MIDI filters for different classes of messages (plus some base class to make future, more complex filter easier to write), added a new utility category (MIDI)

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


The following commit has been merged in the master branch:
commit b298843d3b34cb603b7b4bdca848c959713d2da9
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Fri Oct 10 20:46:59 2008 +0000

    + Framework: separated midi_mixin into event_mixin and midi_mixin which is dependent on it
    + LV2: updated lv2_event.h
    + Small modules: removed notefilter_e and notefilter2_e, added a bunch of trivial inflexible MIDI filters for different classes of messages (plus some base class to make future, more complex filter easier to write), added a new utility category (MIDI)
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@327 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/lv2_event.h b/src/calf/lv2_event.h
index ed306f9..6ea90c8 100644
--- a/src/calf/lv2_event.h
+++ b/src/calf/lv2_event.h
@@ -84,13 +84,13 @@ typedef struct {
 	 * 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.
+	 * any required behaviour.  Otherwise, if the type is 0, this event is a
+	 * non-POD event and lv2_event_unref 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_unref).  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;
 
@@ -209,6 +209,29 @@ typedef struct {
 	 */
 	LV2_Event_Callback_Data callback_data;
 	
+	/** Take 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.  When receiving a non-POD event, the plugin already
+	 * has an implicit reference to the event.  If the event is stored AND
+	 * passed to an output, lv2_event_ref MUST be called on that event.
+	 * If the event is only stored OR passed through, this is not necessary
+	 * (as the plugin already has 1 implicit reference).
+	 *
+	 * @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_ref)(LV2_Event_Callback_Data callback_data,
+	                          LV2_Event*              event);
+	
 	/** Drop a reference to a non-POD event.
 	 *
 	 * If a plugin receives an event with type 0, it means the event is a
@@ -227,9 +250,8 @@ typedef struct {
 	 *
 	 * 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);
+	uint32_t (*lv2_event_unref)(LV2_Event_Callback_Data callback_data,
+	                            LV2_Event*              event);
 
 } LV2_Event_Feature;
 
diff --git a/src/calf/lv2helpers.h b/src/calf/lv2helpers.h
index 565e8de..deae345 100644
--- a/src/calf/lv2helpers.h
+++ b/src/calf/lv2helpers.h
@@ -23,15 +23,35 @@
 
 #if USE_LV2
 
-/// A mixin for adding the event feature, URI map and MIDI event type retrieval to small plugins
-/// @todo refactor into separate event feature, URI map and MIDI event type mixins some day
+/// A mixin for adding the event feature to the small plugin
 template<class T>
-class midi_mixin: public T
+class event_mixin: public T
 {
 public:
+    /// Event feature pointer
+    LV2_Event_Feature *event_feature;
+    virtual void use_feature(const char *URI, void *data) {
+        if (!strcmp(URI, LV2_EVENT_URI))
+        {
+            event_feature = (LV2_Event_Feature *)data;
+        }
+        T::use_feature(URI, data);
+    }
+    /// Create a reference
+    inline void ref_event(LV2_Event *event) { event_feature->lv2_event_ref(event_feature->callback_data, event); }
+    /// Destroy a reference
+    inline void unref_event(LV2_Event *event) { event_feature->lv2_event_unref(event_feature->callback_data, event); }
+};
+
+/// A mixin for adding the URI map and MIDI event type retrieval to small plugins
+template<class T>
+class midi_mixin: public event_mixin<T>
+{
+public:
+    /// URI map feature pointer
     LV2_URI_Map_Feature *uri_map;
+    /// MIDI event ID, as resolved using the URI map feature
     uint32_t midi_event_type;
-    LV2_Event_Feature *event_feature;
     virtual void use_feature(const char *URI, void *data) {
         if (!strcmp(URI, LV2_URI_MAP_URI))
         {
@@ -40,11 +60,7 @@ public:
                 "http://lv2plug.in/ns/ext/event",
                 "http://lv2plug.in/ns/ext/midi#MidiEvent");
         }
-        else if (!strcmp(URI, LV2_EVENT_URI))
-        {
-            event_feature = (LV2_Event_Feature *)data;
-        }
-        T::use_feature(URI, data);
+        event_mixin<T>::use_feature(URI, data);
     }
 };
 
diff --git a/src/calf/modulelist.h b/src/calf/modulelist.h
index b7e2dae..bd2eda0 100644
--- a/src/calf/modulelist.h
+++ b/src/calf/modulelist.h
@@ -40,8 +40,12 @@
     PER_SMALL_MODULE_ITEM(print_e, "print_e")
     PER_SMALL_MODULE_ITEM(print_em, "print_em")
     PER_SMALL_MODULE_ITEM(copy_em, "copy_em")
-    PER_SMALL_MODULE_ITEM(notefilter_e, "notefilter_e")
-    PER_SMALL_MODULE_ITEM(notefilter2_e, "notefilter2_e")
+    PER_SMALL_MODULE_ITEM(notefilter_m, "notefilter_m")
+    PER_SMALL_MODULE_ITEM(ccfilter_m, "ccfilter_m")
+    PER_SMALL_MODULE_ITEM(pcfilter_m, "pcfilter_m")
+    PER_SMALL_MODULE_ITEM(pressurefilter_m, "pressurefilter_m")
+    PER_SMALL_MODULE_ITEM(pitchbendfilter_m, "pitchbendfilter_m")
+    PER_SMALL_MODULE_ITEM(systemfilter_m, "systemfilter_m")
     PER_SMALL_MODULE_ITEM(eventmerge_e, "eventmerge_e")
     PER_SMALL_MODULE_ITEM(quadpower_a, "quadpower_a")
     PER_SMALL_MODULE_ITEM(quadpower_c, "quadpower_c")
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index c3cfa70..c947540 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -491,9 +491,10 @@ void make_manifest()
         "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"
         "@prefix kf: <http://foltman.com/ns/> .\n"
         "\n"
-        "kf:BooleanPlugin a rdfs:Class ; rdfs:label \"Boolean-oriented\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Modules heavily inspired by digital electronics (gates, flip-flops)\"\"\" .\n"
+        "kf:BooleanPlugin a rdfs:Class ; rdfs:label \"Boolean-oriented\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Modules heavily inspired by digital electronics (gates, flip-flops etc.)\"\"\" .\n"
         "kf:MathOperatorPlugin a rdfs:Class ; rdfs:label \"Math operators\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Mathematical operators and utility functions\"\"\" .\n"
-        "kf:IntegerPlugin a rdfs:Class ; rdfs:label \"Integer-oriented\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Operations using integer values (counters, multiplexers)\"\"\" .\n"
+        "kf:IntegerPlugin a rdfs:Class ; rdfs:label \"Integer-oriented\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Operations using integer values (counters, multiplexers etc.)\"\"\" .\n"
+        "kf:MIDIPlugin a rdfs:Class ; rdfs:label \"MIDI\" ; rdfs:subClassOf lv2:UtilityPlugin ; rdfs:comment \"\"\"Operations on MIDI streams (filters, transposers, mappers etc.)\"\"\" .\n"
     ;
     
     vector<synth::giface_plugin_info> plugins;
diff --git a/src/modules_small.cpp b/src/modules_small.cpp
index 3e05d5d..fcabfb7 100644
--- a/src/modules_small.cpp
+++ b/src/modules_small.cpp
@@ -1306,36 +1306,23 @@ public:
     }
 };
 
-class notefilter_e_audio_module: public midi_mixin<small_audio_module_base<1, 1> >
+template<class Range>
+class miditypefilter_m_audio_module: public midi_mixin<small_audio_module_base<1, 2> >
 {
 public:    
-    static void plugin_info(plugin_info_iface *pii)
+    static inline void extra_inputs(plugin_info_iface *pii)
     {
-        pii->names("notefilter_e", "Note Filter (M)", "lv2:UtilityPlugin");
-        pii->event_port("in", "In").input();
-        pii->event_port("out", "Out").output();
     }
-    void process(uint32_t)
-    {
-        event_port_read_iterator ri((LV2_Event_Buffer *)ins[0]);
-        event_port_write_iterator wi((LV2_Event_Buffer *)outs[0]);
-        while(ri)
-        {
-            const lv2_event &event = *ri++;
-            if (event.type == midi_event_type && event.size && event.data[0] >= 0x80 && event.data[0] <= 0x9F)
-                *wi++ = event;
-        }
-    }
-};
-
-class notefilter2_e_audio_module: public midi_mixin<small_audio_module_base<1, 2> >
-{
-public:    
+    static inline const char *plugin_symbol() { return Range::strings()[0]; }
+    static inline const char *plugin_name() { return Range::strings()[1]; }
+    static inline const char *port_symbol() { return Range::strings()[2]; }
+    static inline const char *port_name() { return Range::strings()[3]; }
     static void plugin_info(plugin_info_iface *pii)
     {
-        pii->names("notefilter2_e", "Note Filter 2 (M)", "lv2:UtilityPlugin");
+        pii->names(Range::plugin_symbol(), Range::plugin_name(), "kf:MIDIPlugin");
         pii->event_port("in", "In").input();
-        pii->event_port("notes", "Notes").output();
+        Range::extra_inputs(pii);
+        pii->event_port(Range::port_symbol(), Range::port_name()).output();
         pii->event_port("others", "Others").output();
     }
     void process(uint32_t)
@@ -1346,7 +1333,7 @@ public:
         while(ri)
         {
             const lv2_event &event = *ri++;
-            if (event.type == midi_event_type && event.size && event.data[0] >= 0x80 && event.data[0] <= 0x9F)
+            if (event.type == midi_event_type && event.size && Range::is_in_range(event.data, ins))
                 *wi++ = event;
             else 
                 *wi2++ = event;
@@ -1354,14 +1341,56 @@ public:
     }
 };
 
-class eventmerge_e_audio_module: public midi_mixin<small_audio_module_base<2, 1> >
+class notefilter_m_audio_module: public miditypefilter_m_audio_module<notefilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0x80 && data[0] <= 0x9F; }
+    static inline const char **strings() { static const char *s[] = { "notefilter_m", "Note Filter", "note", "Note" }; return s;}
+};
+
+class pcfilter_m_audio_module: public miditypefilter_m_audio_module<pcfilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xA0 && data[0] <= 0xAF; }
+    static inline const char **strings() { static const char *s[] = { "pcfilter_m", "Program Change Filter", "pc", "PC" }; return s;}
+};
+
+class ccfilter_m_audio_module: public miditypefilter_m_audio_module<ccfilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xB0 && data[0] <= 0xBF; }
+    static inline const char **strings() { static const char *s[] = { "ccfilter_m", "Control Change Filter", "cc", "CC" }; return s;}
+};
+
+class pressurefilter_m_audio_module: public miditypefilter_m_audio_module<pressurefilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xC0 && data[0] <= 0xDF; }
+    static inline const char **strings() { static const char *s[] = { "pressurefilter_m", "Pressure Filter", "pressure", "Pressure" }; return s;}
+};
+
+class pitchbendfilter_m_audio_module: public miditypefilter_m_audio_module<pitchbendfilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xE0 && data[0] <= 0xEF; }
+    static inline const char **strings() { static const char *s[] = { "pitchbendfilter_m", "Pitch Bend Filter", "pbend", "Pitch Bend" }; return s;}
+};
+
+class systemfilter_m_audio_module: public miditypefilter_m_audio_module<systemfilter_m_audio_module>
+{
+public:
+    static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xF0 && data[0] <= 0xFF; }
+    static inline const char **strings() { static const char *s[] = { "systemfilter_m", "System Msg Filter", "system", "System" }; return s;}
+};
+
+class eventmerge_e_audio_module: public event_mixin<small_audio_module_base<2, 1> >
 {
 public:    
     static void plugin_info(plugin_info_iface *pii)
     {
-        pii->names("eventmerge_e", "Event Merge (M)", "lv2:UtilityPlugin");
-        pii->event_port("in_1", "In").input();
-        pii->event_port("in_2", "In").input();
+        pii->names("eventmerge_e", "Event Merge (E)", "lv2:UtilityPlugin");
+        pii->event_port("in_1", "In 1").input();
+        pii->event_port("in_2", "In 2").input();
         pii->event_port("out", "Out").output();
     }
     void process(uint32_t)
@@ -1369,10 +1398,7 @@ public:
         event_port_merge_iterator<event_port_read_iterator, event_port_read_iterator> ri((const LV2_Event_Buffer *)ins[0], (const LV2_Event_Buffer *)ins[1]);
         event_port_write_iterator wi((LV2_Event_Buffer *)outs[0]);
         while(ri)
-        {
-            const lv2_event &event = *ri++;
-            *wi++ = event;
-        }
+            *wi++ = *ri++;
     }
 };
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list