changeset 139:aa96f69e2f14

Add support for process timestamp method to low-level api
author Chris Cannam
date Wed, 08 Jul 2015 11:37:06 +0100
parents d3126719b094
children 1a494598ee2b
files native/PyPluginObject.cpp native/vampyhost.cpp test/test_plugin_metadata.py
diffstat 3 files changed, 68 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/native/PyPluginObject.cpp	Wed Jul 08 11:36:42 2015 +0100
+++ b/native/PyPluginObject.cpp	Wed Jul 08 11:37:06 2015 +0100
@@ -54,6 +54,9 @@
 #include "StringConversion.h"
 #include "PyRealTime.h"
 
+#include "vamp-hostsdk/PluginWrapper.h"
+#include "vamp-hostsdk/PluginInputDomainAdapter.h"
+
 #include <string>
 #include <vector>
 #include <cstddef>
@@ -61,6 +64,7 @@
 
 using namespace std;
 using namespace Vamp;
+using namespace Vamp::HostExt;
 
 static
 PyPluginObject *
@@ -309,6 +313,38 @@
 }
 
 static PyObject *
+set_process_timestamp_method(PyObject *self, PyObject *args)
+{
+    ssize_t method;
+
+    if (!PyArg_ParseTuple(args,
+                          "n",
+                          &method)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "set_process_timestamp_method() takes method (int) argument");
+        return 0; }
+
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    PluginWrapper *wrapper = dynamic_cast<PluginWrapper *>(pd->plugin);
+    if (!wrapper) {
+        PyErr_SetString(PyExc_Exception,
+                        "Plugin was not loaded with ADAPT_INPUT_DOMAIN flag (no wrapper present)");
+        return 0;
+    }
+
+    PluginInputDomainAdapter *adapter = wrapper->getWrapper<PluginInputDomainAdapter>();
+    if (!adapter) {
+        Py_RETURN_FALSE;
+    }
+
+    adapter->setProcessTimestampMethod
+        (PluginInputDomainAdapter::ProcessTimestampMethod(method));
+    Py_RETURN_TRUE;
+}
+
+static PyObject *
 initialise(PyObject *self, PyObject *args)
 {
     ssize_t channels, blockSize, stepSize;
@@ -770,7 +806,7 @@
 
     {"set_parameter_values", set_parameter_values, METH_VARARGS,
      "set_parameter_values(dict) -> Set multiple parameters to values corresponding to the key/value pairs in the dict. Any parameters not mentioned in the dict are unchanged."},
-
+    
     {"select_program", select_program, METH_VARARGS,
      "select_program(name) -> Select the processing program with the given name."},
     
@@ -785,6 +821,9 @@
 
     {"get_max_channel_count", get_max_channel_count, METH_VARARGS,
      "get_max_channel_count() -> Return the maximum number of channels of audio data the plugin accepts as input."},
+
+    {"set_process_timestamp_method", set_process_timestamp_method, METH_VARARGS,
+     "set_process_timestamp_method(method) -> Set the method used for timestamp adjustment in plugins using frequency-domain input, where that input is being automatically converted for a plugin loaded with the ADAPT_INPUT_DOMAIN flag set (or one of ADAPT_ALL_SAFE or ADAPT_ALL). The method must be one of SHIFT_TIMESTAMP, SHIFT_DATA, or NO_SHIFT. The default is SHIFT_TIMESTAMP."},
     
     {"initialise", initialise, METH_VARARGS,
      "initialise(channels, stepSize, blockSize) -> Initialise the plugin for the given number of channels and processing frame sizes. This must be called before process_block() can be used."},
--- a/native/vampyhost.cpp	Wed Jul 08 11:36:42 2015 +0100
+++ b/native/vampyhost.cpp	Wed Jul 08 11:37:06 2015 +0100
@@ -260,16 +260,16 @@
      "get_plugin_path() -> Return a list of directories which will be searched for Vamp plugins. This may be changed by setting the VAMP_PATH environment variable."},
 
     {"get_category_of", get_category_of, METH_VARARGS,
-     "get_category_of(pluginKey) -> Return the category of a Vamp plugin given its key, if known. The category is expressed as a list of nested types from least to most specific."},
+     "get_category_of(plugin_key) -> Return the category of a Vamp plugin given its key, if known. The category is expressed as a list of nested types from least to most specific."},
 
     {"get_library_for", get_library_for, METH_VARARGS,
-     "get_library_for(pluginKey) -> Return the file path of the Vamp plugin library in which the given plugin key is found, or an empty string if the plugin is not installed."},
+     "get_library_for(plugin_key) -> Return the file path of the Vamp plugin library in which the given plugin key is found, or an empty string if the plugin is not installed."},
 
     {"get_outputs_of", get_outputs_of, METH_VARARGS,
-     "get_outputs_of(pluginKey) -> Return a list of the output identifiers of the plugin with the given key, if installed."},
+     "get_outputs_of(plugin_key) -> Return a list of the output identifiers of the plugin with the given key, if installed."},
 
     {"load_plugin", load_plugin, METH_VARARGS,
-     "load_plugin(pluginKey, samplerate) -> Load the plugin that has the given key, if installed, and return the plugin object."},
+     "load_plugin(plugin_key, sample_rate, adapter_flags) -> Load the plugin that has the given key, if installed, and return the plugin object. The adapter_flags may be ADAPT_NONE, any additive combination of ADAPT_INPUT_DOMAIN, ADAPT_CHANNEL_COUNT, ADAPT_BUFFER_SIZE, or one of the special flags ADAPT_ALL_SAFE or ADAPT_ALL. If in doubt, pass ADAPT_ALL_SAFE. See the Vamp SDK documentation for the PluginLoader class for more details."},
 
     {"frame_to_realtime", frame_to_realtime, METH_VARARGS,
      "frame_to_realtime() -> Convert sample frame number and sample rate to a RealTime object." },
@@ -372,7 +372,13 @@
         setint(dict, "ADAPT_ALL_SAFE",
                PluginLoader::ADAPT_ALL_SAFE) < 0 ||
         setint(dict, "ADAPT_ALL",
-               PluginLoader::ADAPT_ALL) < 0) {
+               PluginLoader::ADAPT_ALL) < 0 ||
+        setint(dict, "SHIFT_TIMESTAMP",
+               PluginInputDomainAdapter::ShiftTimestamp) < 0 ||
+        setint(dict, "SHIFT_DATA",
+               PluginInputDomainAdapter::ShiftData) < 0 ||
+        setint(dict, "NO_SHIFT",
+               PluginInputDomainAdapter::NoShift) < 0) {
         cerr << "ERROR: initvampyhost: Failed to add enums to module dictionary" << endl;
         return BAD_RETURN;
     }
--- a/test/test_plugin_metadata.py	Wed Jul 08 11:36:42 2015 +0100
+++ b/test/test_plugin_metadata.py	Wed Jul 08 11:37:06 2015 +0100
@@ -79,6 +79,23 @@
 def test_parameterdescriptors():
     plug = vh.load_plugin(plugin_key, rate, vh.ADAPT_NONE)
     assert plug.parameters[0]["identifier"] == "produce_output"
+
+def test_timestamp_method_fail():
+    plug = vh.load_plugin(plugin_key, rate, vh.ADAPT_NONE)
+    try:
+        plug.set_process_timestamp_method(vh.SHIFT_DATA)
+        assert False
+    except Exception:
+        pass
+
+def test_timestamp_method_fail2():
+    plug = vh.load_plugin(plugin_key, rate, vh.ADAPT_INPUT_DOMAIN)
+    # Not a freq-domain plugin: shouldn't throw, but should return false
+    assert (not plug.set_process_timestamp_method(vh.SHIFT_DATA))
+
+def test_timestamp_method_succeed():
+    plug = vh.load_plugin(plugin_key_freq, rate, vh.ADAPT_INPUT_DOMAIN)
+    assert plug.set_process_timestamp_method(vh.SHIFT_DATA)
     
 def test_setparameter():
     plug = vh.load_plugin(plugin_key, rate, vh.ADAPT_NONE)