changeset 188:90c962b68d7f

Merge pull request #2 from piper-audio/dev/step-and-block-size Pull step & block size out into framing struct, return in config
author Chris Cannam <cannam@all-day-breakfast.com>
date Mon, 06 Feb 2017 12:04:25 +0000
parents 150cfa0c71e1 (current diff) 3eb00e5c76c4 (diff)
children 6859f35cb4f8 458766b73e71
files
diffstat 14 files changed, 497 insertions(+), 148 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Feb 03 13:00:42 2017 +0000
+++ b/Makefile	Mon Feb 06 12:04:25 2017 +0000
@@ -24,9 +24,14 @@
 bin/piper-vamp-simple-server: o/simple-server.o o/json11.o o/piper.capnp.o
 	c++ $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
 
-o/piper.capnp.o:	vamp-capnp/piper.capnp.c++ vamp-capnp/piper.capnp.h
+o/piper.capnp.o:	vamp-capnp/piper.capnp.c++
 	c++ $(CXXFLAGS) $(INCFLAGS) -c $< -o $@
 
+vamp-capnp/piper.capnp.h:	vamp-capnp/piper.capnp.c++
+
+vamp-capnp/piper.capnp.c++: $(PIPER_DIR)/capnp/piper.capnp
+	capnpc --src-prefix=$(PIPER_DIR)/capnp -oc++:vamp-capnp $<
+
 o/json11.o:	ext/json11/json11.cpp
 	c++ $(CXXFLAGS) -c $< -o $@
 
--- a/test.sh	Fri Feb 03 13:00:42 2017 +0000
+++ b/test.sh	Mon Feb 06 12:04:25 2017 +0000
@@ -11,7 +11,7 @@
 echo
 echo "Building and running test client..."
 
-( cd "$mypath"/vamp-client/qt && qmake && make &&
+( cd "$mypath"/vamp-client/qt && qmake && make clean all test &&
       ./test ../../bin/piper-vamp-simple-server )
 
 echo
--- a/vamp-capnp/VampnProto.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-capnp/VampnProto.h	Mon Feb 06 12:04:25 2017 +0000
@@ -477,8 +477,10 @@
 
         b.setCurrentProgram(c.currentProgram);
         b.setChannelCount(c.channelCount);
-        b.setStepSize(c.stepSize);
-        b.setBlockSize(c.blockSize);
+
+        auto framing = b.initFraming();
+        framing.setStepSize(c.framing.stepSize);
+        framing.setBlockSize(c.framing.blockSize);
     }
 
     static void
@@ -492,8 +494,8 @@
 
         c.currentProgram = r.getCurrentProgram();
         c.channelCount = r.getChannelCount();
-        c.stepSize = r.getStepSize();
-        c.blockSize = r.getBlockSize();
+        c.framing.stepSize = r.getFraming().getStepSize();
+        c.framing.blockSize = r.getFraming().getBlockSize();
     }
     
     static void
@@ -642,6 +644,9 @@
             auto od = olist[i];
             buildOutputDescriptor(od, cr.outputs[i]);
         }
+        auto framing = b.initFraming();
+        framing.setStepSize(cr.framing.stepSize);
+        framing.setBlockSize(cr.framing.blockSize);
     }
 
     static void
@@ -657,6 +662,8 @@
             readOutputDescriptor(desc, o);
             cr.outputs.push_back(desc);
         }
+        cr.framing.stepSize = r.getFraming().getStepSize();
+        cr.framing.blockSize = r.getFraming().getBlockSize();
     }
 
     static void
--- a/vamp-capnp/piper.capnp.c++	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-capnp/piper.capnp.c++	Mon Feb 06 12:04:25 2017 +0000
@@ -1238,17 +1238,77 @@
   1, 2, i_ab2572c346316b24, nullptr, nullptr, { &s_ab2572c346316b24, nullptr, nullptr, 0, 0, nullptr }
 };
 #endif  // !CAPNP_LITE
-static const ::capnp::_::AlignedData<105> b_db209a01f86fe045 = {
+static const ::capnp::_::AlignedData<49> b_fe907ebf410a65a4 = {
+  {   0,   0,   0,   0,   5,   0,   6,   0,
+    164, 101,  10,  65, 191, 126, 144, 254,
+     12,   0,   0,   0,   1,   0,   1,   0,
+      6, 146, 153,  76, 196, 198, 177, 196,
+      0,   0,   7,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     21,   0,   0,   0, 162,   0,   0,   0,
+     29,   0,   0,   0,   7,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     25,   0,   0,   0, 119,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+    112, 105, 112, 101, 114,  46,  99,  97,
+    112, 110, 112,  58,  70, 114,  97, 109,
+    105, 110, 103,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   1,   0,   1,   0,
+      8,   0,   0,   0,   3,   0,   4,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     41,   0,   0,   0,  74,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     40,   0,   0,   0,   3,   0,   1,   0,
+     52,   0,   0,   0,   2,   0,   1,   0,
+      1,   0,   0,   0,   1,   0,   0,   0,
+      0,   0,   1,   0,   1,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     49,   0,   0,   0,  82,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     48,   0,   0,   0,   3,   0,   1,   0,
+     60,   0,   0,   0,   2,   0,   1,   0,
+    115, 116, 101, 112,  83, 105, 122, 101,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      4,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      4,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     98, 108, 111,  99, 107,  83, 105, 122,
+    101,   0,   0,   0,   0,   0,   0,   0,
+      4,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      4,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0, }
+};
+::capnp::word const* const bp_fe907ebf410a65a4 = b_fe907ebf410a65a4.words;
+#if !CAPNP_LITE
+static const uint16_t m_fe907ebf410a65a4[] = {1, 0};
+static const uint16_t i_fe907ebf410a65a4[] = {0, 1};
+const ::capnp::_::RawSchema s_fe907ebf410a65a4 = {
+  0xfe907ebf410a65a4, b_fe907ebf410a65a4.words, 49, nullptr, m_fe907ebf410a65a4,
+  0, 2, i_fe907ebf410a65a4, nullptr, nullptr, { &s_fe907ebf410a65a4, nullptr, nullptr, 0, 0, nullptr }
+};
+#endif  // !CAPNP_LITE
+static const ::capnp::_::AlignedData<88> b_db209a01f86fe045 = {
   {   0,   0,   0,   0,   5,   0,   6,   0,
      69, 224, 111, 248,   1, 154,  32, 219,
-     12,   0,   0,   0,   1,   0,   2,   0,
+     12,   0,   0,   0,   1,   0,   1,   0,
       6, 146, 153,  76, 196, 198, 177, 196,
-      2,   0,   7,   0,   0,   0,   0,   0,
+      3,   0,   7,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
      21,   0,   0,   0, 210,   0,   0,   0,
      33,   0,   0,   0,  23,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-     41,   0,   0,   0,  31,   1,   0,   0,
+     41,   0,   0,   0, 231,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
     112, 105, 112, 101, 114,  46,  99,  97,
@@ -1259,42 +1319,35 @@
      55, 221,  34, 212, 254,  86,  11, 144,
       1,   0,   0,   0,  58,   0,   0,   0,
      80,  86,  80,  97, 105, 114,   0,   0,
-     20,   0,   0,   0,   3,   0,   4,   0,
+     16,   0,   0,   0,   3,   0,   4,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   1,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-    125,   0,   0,   0, 130,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    124,   0,   0,   0,   3,   0,   1,   0,
-    152,   0,   0,   0,   2,   0,   1,   0,
+     97,   0,   0,   0, 130,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     96,   0,   0,   0,   3,   0,   1,   0,
+    124,   0,   0,   0,   2,   0,   1,   0,
       1,   0,   0,   0,   1,   0,   0,   0,
       0,   0,   1,   0,   1,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-    149,   0,   0,   0, 122,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    148,   0,   0,   0,   3,   0,   1,   0,
-    160,   0,   0,   0,   2,   0,   1,   0,
+    121,   0,   0,   0, 122,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+    120,   0,   0,   0,   3,   0,   1,   0,
+    132,   0,   0,   0,   2,   0,   1,   0,
       2,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   1,   0,   2,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-    157,   0,   0,   0, 106,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    156,   0,   0,   0,   3,   0,   1,   0,
-    168,   0,   0,   0,   2,   0,   1,   0,
-      3,   0,   0,   0,   1,   0,   0,   0,
+    129,   0,   0,   0, 106,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+    128,   0,   0,   0,   3,   0,   1,   0,
+    140,   0,   0,   0,   2,   0,   1,   0,
+      3,   0,   0,   0,   2,   0,   0,   0,
       0,   0,   1,   0,   3,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-    165,   0,   0,   0,  74,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    164,   0,   0,   0,   3,   0,   1,   0,
-    176,   0,   0,   0,   2,   0,   1,   0,
-      4,   0,   0,   0,   2,   0,   0,   0,
-      0,   0,   1,   0,   4,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    173,   0,   0,   0,  82,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-    172,   0,   0,   0,   3,   0,   1,   0,
-    184,   0,   0,   0,   2,   0,   1,   0,
+    137,   0,   0,   0,  66,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+    132,   0,   0,   0,   3,   0,   1,   0,
+    144,   0,   0,   0,   2,   0,   1,   0,
     112,  97, 114,  97, 109, 101, 116, 101,
     114,  86,  97, 108, 117, 101, 115,   0,
      14,   0,   0,   0,   0,   0,   0,   0,
@@ -1326,22 +1379,12 @@
       4,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-    115, 116, 101, 112,  83, 105, 122, 101,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      4,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      4,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-     98, 108, 111,  99, 107,  83, 105, 122,
-    101,   0,   0,   0,   0,   0,   0,   0,
-      4,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-      4,   0,   0,   0,   0,   0,   0,   0,
+    102, 114,  97, 109, 105, 110, 103,   0,
+     16,   0,   0,   0,   0,   0,   0,   0,
+    164, 101,  10,  65, 191, 126, 144, 254,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     16,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0, }
 };
@@ -1349,12 +1392,13 @@
 #if !CAPNP_LITE
 static const ::capnp::_::RawSchema* const d_db209a01f86fe045[] = {
   &s_900b56fed422dd37,
+  &s_fe907ebf410a65a4,
 };
-static const uint16_t m_db209a01f86fe045[] = {4, 2, 1, 0, 3};
-static const uint16_t i_db209a01f86fe045[] = {0, 1, 2, 3, 4};
+static const uint16_t m_db209a01f86fe045[] = {2, 1, 3, 0};
+static const uint16_t i_db209a01f86fe045[] = {0, 1, 2, 3};
 const ::capnp::_::RawSchema s_db209a01f86fe045 = {
-  0xdb209a01f86fe045, b_db209a01f86fe045.words, 105, d_db209a01f86fe045, m_db209a01f86fe045,
-  1, 5, i_db209a01f86fe045, nullptr, nullptr, { &s_db209a01f86fe045, nullptr, nullptr, 0, 0, nullptr }
+  0xdb209a01f86fe045, b_db209a01f86fe045.words, 88, d_db209a01f86fe045, m_db209a01f86fe045,
+  2, 4, i_db209a01f86fe045, nullptr, nullptr, { &s_db209a01f86fe045, nullptr, nullptr, 0, 0, nullptr }
 };
 #endif  // !CAPNP_LITE
 static const ::capnp::_::AlignedData<50> b_900b56fed422dd37 = {
@@ -1864,17 +1908,17 @@
   1, 2, i_fcf72b478bbe9d02, nullptr, nullptr, { &s_fcf72b478bbe9d02, nullptr, nullptr, 0, 0, nullptr }
 };
 #endif  // !CAPNP_LITE
-static const ::capnp::_::AlignedData<53> b_c433db5864bf6d56 = {
+static const ::capnp::_::AlignedData<68> b_c433db5864bf6d56 = {
   {   0,   0,   0,   0,   5,   0,   6,   0,
      86, 109, 191, 100,  88, 219,  51, 196,
      12,   0,   0,   0,   1,   0,   1,   0,
       6, 146, 153,  76, 196, 198, 177, 196,
-      1,   0,   7,   0,   0,   0,   0,   0,
+      2,   0,   7,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
      21,   0,   0,   0,  18,   1,   0,   0,
      37,   0,   0,   0,   7,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-     33,   0,   0,   0, 119,   0,   0,   0,
+     33,   0,   0,   0, 175,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
     112, 105, 112, 101, 114,  46,  99,  97,
@@ -1883,21 +1927,28 @@
     110,  82, 101, 115, 112, 111, 110, 115,
     101,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   1,   0,   1,   0,
-      8,   0,   0,   0,   3,   0,   4,   0,
+     12,   0,   0,   0,   3,   0,   4,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   1,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-     41,   0,   0,   0,  58,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-     36,   0,   0,   0,   3,   0,   1,   0,
-     48,   0,   0,   0,   2,   0,   1,   0,
+     69,   0,   0,   0,  58,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     64,   0,   0,   0,   3,   0,   1,   0,
+     76,   0,   0,   0,   2,   0,   1,   0,
       1,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   1,   0,   1,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
-     45,   0,   0,   0,  66,   0,   0,   0,
-      0,   0,   0,   0,   0,   0,   0,   0,
-     40,   0,   0,   0,   3,   0,   1,   0,
-     68,   0,   0,   0,   2,   0,   1,   0,
+     73,   0,   0,   0,  66,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     68,   0,   0,   0,   3,   0,   1,   0,
+     96,   0,   0,   0,   2,   0,   1,   0,
+      2,   0,   0,   0,   1,   0,   0,   0,
+      0,   0,   1,   0,   2,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     93,   0,   0,   0,  66,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     88,   0,   0,   0,   3,   0,   1,   0,
+    100,   0,   0,   0,   2,   0,   1,   0,
     104,  97, 110, 100, 108, 101,   0,   0,
       4,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
@@ -1917,18 +1968,27 @@
       0,   0,   0,   0,   0,   0,   0,   0,
      14,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+    102, 114,  97, 109, 105, 110, 103,   0,
+     16,   0,   0,   0,   0,   0,   0,   0,
+    164, 101,  10,  65, 191, 126, 144, 254,
+      0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
+     16,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0, }
 };
 ::capnp::word const* const bp_c433db5864bf6d56 = b_c433db5864bf6d56.words;
 #if !CAPNP_LITE
 static const ::capnp::_::RawSchema* const d_c433db5864bf6d56[] = {
   &s_902c6065e1be824a,
+  &s_fe907ebf410a65a4,
 };
-static const uint16_t m_c433db5864bf6d56[] = {0, 1};
-static const uint16_t i_c433db5864bf6d56[] = {0, 1};
+static const uint16_t m_c433db5864bf6d56[] = {2, 0, 1};
+static const uint16_t i_c433db5864bf6d56[] = {0, 1, 2};
 const ::capnp::_::RawSchema s_c433db5864bf6d56 = {
-  0xc433db5864bf6d56, b_c433db5864bf6d56.words, 53, d_c433db5864bf6d56, m_c433db5864bf6d56,
-  1, 2, i_c433db5864bf6d56, nullptr, nullptr, { &s_c433db5864bf6d56, nullptr, nullptr, 0, 0, nullptr }
+  0xc433db5864bf6d56, b_c433db5864bf6d56.words, 68, d_c433db5864bf6d56, m_c433db5864bf6d56,
+  2, 3, i_c433db5864bf6d56, nullptr, nullptr, { &s_c433db5864bf6d56, nullptr, nullptr, 0, 0, nullptr }
 };
 #endif  // !CAPNP_LITE
 static const ::capnp::_::AlignedData<49> b_ea87c8bff474ddce = {
@@ -2829,6 +2889,17 @@
 constexpr ::capnp::_::RawBrandedSchema const* FeatureSet::FSPair::_capnpPrivate::brand;
 #endif  // !CAPNP_LITE
 
+// Framing
+#ifndef _MSC_VER
+constexpr uint16_t Framing::_capnpPrivate::dataWordSize;
+constexpr uint16_t Framing::_capnpPrivate::pointerCount;
+#endif
+#if !CAPNP_LITE
+constexpr ::capnp::Kind Framing::_capnpPrivate::kind;
+constexpr ::capnp::_::RawSchema const* Framing::_capnpPrivate::schema;
+constexpr ::capnp::_::RawBrandedSchema const* Framing::_capnpPrivate::brand;
+#endif  // !CAPNP_LITE
+
 // Configuration
 #ifndef _MSC_VER
 constexpr uint16_t Configuration::_capnpPrivate::dataWordSize;
--- a/vamp-capnp/piper.capnp.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-capnp/piper.capnp.h	Mon Feb 06 12:04:25 2017 +0000
@@ -37,6 +37,7 @@
 CAPNP_DECLARE_SCHEMA(d6a172208c9a1760);
 CAPNP_DECLARE_SCHEMA(ffa3fccceb684869);
 CAPNP_DECLARE_SCHEMA(ab2572c346316b24);
+CAPNP_DECLARE_SCHEMA(fe907ebf410a65a4);
 CAPNP_DECLARE_SCHEMA(db209a01f86fe045);
 CAPNP_DECLARE_SCHEMA(900b56fed422dd37);
 CAPNP_DECLARE_SCHEMA(b5edf73eb2e79c4e);
@@ -226,6 +227,21 @@
   };
 };
 
+struct Framing {
+  Framing() = delete;
+
+  class Reader;
+  class Builder;
+  class Pipeline;
+
+  struct _capnpPrivate {
+    CAPNP_DECLARE_STRUCT_HEADER(fe907ebf410a65a4, 1, 0)
+    #if !CAPNP_LITE
+    static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;
+    #endif  // !CAPNP_LITE
+  };
+};
+
 struct Configuration {
   Configuration() = delete;
 
@@ -235,7 +251,7 @@
   struct PVPair;
 
   struct _capnpPrivate {
-    CAPNP_DECLARE_STRUCT_HEADER(db209a01f86fe045, 2, 2)
+    CAPNP_DECLARE_STRUCT_HEADER(db209a01f86fe045, 1, 3)
     #if !CAPNP_LITE
     static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;
     #endif  // !CAPNP_LITE
@@ -344,7 +360,7 @@
   class Pipeline;
 
   struct _capnpPrivate {
-    CAPNP_DECLARE_STRUCT_HEADER(c433db5864bf6d56, 1, 1)
+    CAPNP_DECLARE_STRUCT_HEADER(c433db5864bf6d56, 1, 2)
     #if !CAPNP_LITE
     static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand;
     #endif  // !CAPNP_LITE
@@ -1655,9 +1671,9 @@
 };
 #endif  // !CAPNP_LITE
 
-class Configuration::Reader {
+class Framing::Reader {
 public:
-  typedef Configuration Reads;
+  typedef Framing Reads;
 
   Reader() = default;
   inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
@@ -1672,14 +1688,6 @@
   }
 #endif  // !CAPNP_LITE
 
-  inline bool hasParameterValues() const;
-  inline  ::capnp::List< ::piper::Configuration::PVPair>::Reader getParameterValues() const;
-
-  inline bool hasCurrentProgram() const;
-  inline  ::capnp::Text::Reader getCurrentProgram() const;
-
-  inline  ::int32_t getChannelCount() const;
-
   inline  ::int32_t getStepSize() const;
 
   inline  ::int32_t getBlockSize() const;
@@ -1696,9 +1704,9 @@
   friend class ::capnp::Orphanage;
 };
 
-class Configuration::Builder {
+class Framing::Builder {
 public:
-  typedef Configuration Builds;
+  typedef Framing Builds;
 
   Builder() = delete;  // Deleted to discourage incorrect usage.
                        // You can explicitly initialize to nullptr instead.
@@ -1712,6 +1720,94 @@
   inline ::kj::StringTree toString() const { return asReader().toString(); }
 #endif  // !CAPNP_LITE
 
+  inline  ::int32_t getStepSize();
+  inline void setStepSize( ::int32_t value);
+
+  inline  ::int32_t getBlockSize();
+  inline void setBlockSize( ::int32_t value);
+
+private:
+  ::capnp::_::StructBuilder _builder;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::ToDynamic_;
+  friend class ::capnp::Orphanage;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::_::PointerHelpers;
+};
+
+#if !CAPNP_LITE
+class Framing::Pipeline {
+public:
+  typedef Framing Pipelines;
+
+  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
+  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
+      : _typeless(kj::mv(typeless)) {}
+
+private:
+  ::capnp::AnyPointer::Pipeline _typeless;
+  friend class ::capnp::PipelineHook;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::ToDynamic_;
+};
+#endif  // !CAPNP_LITE
+
+class Configuration::Reader {
+public:
+  typedef Configuration Reads;
+
+  Reader() = default;
+  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
+
+  inline ::capnp::MessageSize totalSize() const {
+    return _reader.totalSize().asPublic();
+  }
+
+#if !CAPNP_LITE
+  inline ::kj::StringTree toString() const {
+    return ::capnp::_::structString(_reader, *_capnpPrivate::brand);
+  }
+#endif  // !CAPNP_LITE
+
+  inline bool hasParameterValues() const;
+  inline  ::capnp::List< ::piper::Configuration::PVPair>::Reader getParameterValues() const;
+
+  inline bool hasCurrentProgram() const;
+  inline  ::capnp::Text::Reader getCurrentProgram() const;
+
+  inline  ::int32_t getChannelCount() const;
+
+  inline bool hasFraming() const;
+  inline  ::piper::Framing::Reader getFraming() const;
+
+private:
+  ::capnp::_::StructReader _reader;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::ToDynamic_;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::_::PointerHelpers;
+  template <typename, ::capnp::Kind>
+  friend struct ::capnp::List;
+  friend class ::capnp::MessageBuilder;
+  friend class ::capnp::Orphanage;
+};
+
+class Configuration::Builder {
+public:
+  typedef Configuration Builds;
+
+  Builder() = delete;  // Deleted to discourage incorrect usage.
+                       // You can explicitly initialize to nullptr instead.
+  inline Builder(decltype(nullptr)) {}
+  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
+  inline operator Reader() const { return Reader(_builder.asReader()); }
+  inline Reader asReader() const { return *this; }
+
+  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
+#if !CAPNP_LITE
+  inline ::kj::StringTree toString() const { return asReader().toString(); }
+#endif  // !CAPNP_LITE
+
   inline bool hasParameterValues();
   inline  ::capnp::List< ::piper::Configuration::PVPair>::Builder getParameterValues();
   inline void setParameterValues( ::capnp::List< ::piper::Configuration::PVPair>::Reader value);
@@ -1729,11 +1825,12 @@
   inline  ::int32_t getChannelCount();
   inline void setChannelCount( ::int32_t value);
 
-  inline  ::int32_t getStepSize();
-  inline void setStepSize( ::int32_t value);
-
-  inline  ::int32_t getBlockSize();
-  inline void setBlockSize( ::int32_t value);
+  inline bool hasFraming();
+  inline  ::piper::Framing::Builder getFraming();
+  inline void setFraming( ::piper::Framing::Reader value);
+  inline  ::piper::Framing::Builder initFraming();
+  inline void adoptFraming(::capnp::Orphan< ::piper::Framing>&& value);
+  inline ::capnp::Orphan< ::piper::Framing> disownFraming();
 
 private:
   ::capnp::_::StructBuilder _builder;
@@ -1753,6 +1850,7 @@
   inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
       : _typeless(kj::mv(typeless)) {}
 
+  inline  ::piper::Framing::Pipeline getFraming();
 private:
   ::capnp::AnyPointer::Pipeline _typeless;
   friend class ::capnp::PipelineHook;
@@ -2314,6 +2412,9 @@
   inline bool hasOutputs() const;
   inline  ::capnp::List< ::piper::OutputDescriptor>::Reader getOutputs() const;
 
+  inline bool hasFraming() const;
+  inline  ::piper::Framing::Reader getFraming() const;
+
 private:
   ::capnp::_::StructReader _reader;
   template <typename, ::capnp::Kind>
@@ -2352,6 +2453,13 @@
   inline void adoptOutputs(::capnp::Orphan< ::capnp::List< ::piper::OutputDescriptor>>&& value);
   inline ::capnp::Orphan< ::capnp::List< ::piper::OutputDescriptor>> disownOutputs();
 
+  inline bool hasFraming();
+  inline  ::piper::Framing::Builder getFraming();
+  inline void setFraming( ::piper::Framing::Reader value);
+  inline  ::piper::Framing::Builder initFraming();
+  inline void adoptFraming(::capnp::Orphan< ::piper::Framing>&& value);
+  inline ::capnp::Orphan< ::piper::Framing> disownFraming();
+
 private:
   ::capnp::_::StructBuilder _builder;
   template <typename, ::capnp::Kind>
@@ -2370,6 +2478,7 @@
   inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
       : _typeless(kj::mv(typeless)) {}
 
+  inline  ::piper::Framing::Pipeline getFraming();
 private:
   ::capnp::AnyPointer::Pipeline _typeless;
   friend class ::capnp::PipelineHook;
@@ -4698,6 +4807,34 @@
       _builder.getPointerField(1 * ::capnp::POINTERS));
 }
 
+inline  ::int32_t Framing::Reader::getStepSize() const {
+  return _reader.getDataField< ::int32_t>(
+      0 * ::capnp::ELEMENTS);
+}
+
+inline  ::int32_t Framing::Builder::getStepSize() {
+  return _builder.getDataField< ::int32_t>(
+      0 * ::capnp::ELEMENTS);
+}
+inline void Framing::Builder::setStepSize( ::int32_t value) {
+  _builder.setDataField< ::int32_t>(
+      0 * ::capnp::ELEMENTS, value);
+}
+
+inline  ::int32_t Framing::Reader::getBlockSize() const {
+  return _reader.getDataField< ::int32_t>(
+      1 * ::capnp::ELEMENTS);
+}
+
+inline  ::int32_t Framing::Builder::getBlockSize() {
+  return _builder.getDataField< ::int32_t>(
+      1 * ::capnp::ELEMENTS);
+}
+inline void Framing::Builder::setBlockSize( ::int32_t value) {
+  _builder.setDataField< ::int32_t>(
+      1 * ::capnp::ELEMENTS, value);
+}
+
 inline bool Configuration::Reader::hasParameterValues() const {
   return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
 }
@@ -4776,32 +4913,41 @@
       0 * ::capnp::ELEMENTS, value);
 }
 
-inline  ::int32_t Configuration::Reader::getStepSize() const {
-  return _reader.getDataField< ::int32_t>(
-      1 * ::capnp::ELEMENTS);
-}
-
-inline  ::int32_t Configuration::Builder::getStepSize() {
-  return _builder.getDataField< ::int32_t>(
-      1 * ::capnp::ELEMENTS);
-}
-inline void Configuration::Builder::setStepSize( ::int32_t value) {
-  _builder.setDataField< ::int32_t>(
-      1 * ::capnp::ELEMENTS, value);
-}
-
-inline  ::int32_t Configuration::Reader::getBlockSize() const {
-  return _reader.getDataField< ::int32_t>(
-      2 * ::capnp::ELEMENTS);
-}
-
-inline  ::int32_t Configuration::Builder::getBlockSize() {
-  return _builder.getDataField< ::int32_t>(
-      2 * ::capnp::ELEMENTS);
-}
-inline void Configuration::Builder::setBlockSize( ::int32_t value) {
-  _builder.setDataField< ::int32_t>(
-      2 * ::capnp::ELEMENTS, value);
+inline bool Configuration::Reader::hasFraming() const {
+  return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull();
+}
+inline bool Configuration::Builder::hasFraming() {
+  return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull();
+}
+inline  ::piper::Framing::Reader Configuration::Reader::getFraming() const {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::get(
+      _reader.getPointerField(2 * ::capnp::POINTERS));
+}
+inline  ::piper::Framing::Builder Configuration::Builder::getFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::get(
+      _builder.getPointerField(2 * ::capnp::POINTERS));
+}
+#if !CAPNP_LITE
+inline  ::piper::Framing::Pipeline Configuration::Pipeline::getFraming() {
+  return  ::piper::Framing::Pipeline(_typeless.getPointerField(2));
+}
+#endif  // !CAPNP_LITE
+inline void Configuration::Builder::setFraming( ::piper::Framing::Reader value) {
+  ::capnp::_::PointerHelpers< ::piper::Framing>::set(
+      _builder.getPointerField(2 * ::capnp::POINTERS), value);
+}
+inline  ::piper::Framing::Builder Configuration::Builder::initFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::init(
+      _builder.getPointerField(2 * ::capnp::POINTERS));
+}
+inline void Configuration::Builder::adoptFraming(
+    ::capnp::Orphan< ::piper::Framing>&& value) {
+  ::capnp::_::PointerHelpers< ::piper::Framing>::adopt(
+      _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value));
+}
+inline ::capnp::Orphan< ::piper::Framing> Configuration::Builder::disownFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::disown(
+      _builder.getPointerField(2 * ::capnp::POINTERS));
 }
 
 inline bool Configuration::PVPair::Reader::hasParameter() const {
@@ -5185,6 +5331,43 @@
       _builder.getPointerField(0 * ::capnp::POINTERS));
 }
 
+inline bool ConfigurationResponse::Reader::hasFraming() const {
+  return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull();
+}
+inline bool ConfigurationResponse::Builder::hasFraming() {
+  return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull();
+}
+inline  ::piper::Framing::Reader ConfigurationResponse::Reader::getFraming() const {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::get(
+      _reader.getPointerField(1 * ::capnp::POINTERS));
+}
+inline  ::piper::Framing::Builder ConfigurationResponse::Builder::getFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::get(
+      _builder.getPointerField(1 * ::capnp::POINTERS));
+}
+#if !CAPNP_LITE
+inline  ::piper::Framing::Pipeline ConfigurationResponse::Pipeline::getFraming() {
+  return  ::piper::Framing::Pipeline(_typeless.getPointerField(1));
+}
+#endif  // !CAPNP_LITE
+inline void ConfigurationResponse::Builder::setFraming( ::piper::Framing::Reader value) {
+  ::capnp::_::PointerHelpers< ::piper::Framing>::set(
+      _builder.getPointerField(1 * ::capnp::POINTERS), value);
+}
+inline  ::piper::Framing::Builder ConfigurationResponse::Builder::initFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::init(
+      _builder.getPointerField(1 * ::capnp::POINTERS));
+}
+inline void ConfigurationResponse::Builder::adoptFraming(
+    ::capnp::Orphan< ::piper::Framing>&& value) {
+  ::capnp::_::PointerHelpers< ::piper::Framing>::adopt(
+      _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value));
+}
+inline ::capnp::Orphan< ::piper::Framing> ConfigurationResponse::Builder::disownFraming() {
+  return ::capnp::_::PointerHelpers< ::piper::Framing>::disown(
+      _builder.getPointerField(1 * ::capnp::POINTERS));
+}
+
 inline  ::int32_t ProcessRequest::Reader::getHandle() const {
   return _reader.getDataField< ::int32_t>(
       0 * ::capnp::ELEMENTS);
--- a/vamp-client/CapnpRRClient.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-client/CapnpRRClient.h	Mon Feb 06 12:04:25 2017 +0000
@@ -199,7 +199,7 @@
     // PluginClient methods:
     
     virtual
-    Vamp::Plugin::OutputList
+    ConfigurationResponse
     configure(PluginStub *plugin,
               PluginConfiguration config) override {
 
@@ -232,7 +232,7 @@
 
         LOG_E("CapnpRRClient::configure returning");
         
-        return cr.outputs;
+        return cr;
     };
     
     virtual
--- a/vamp-client/PluginClient.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-client/PluginClient.h	Mon Feb 06 12:04:25 2017 +0000
@@ -47,7 +47,7 @@
 {
 public:
     virtual
-    Vamp::Plugin::OutputList
+    ConfigurationResponse
     configure(PluginStub *plugin,
               PluginConfiguration config) = 0;
     
--- a/vamp-client/PluginStub.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-client/PluginStub.h	Mon Feb 06 12:04:25 2017 +0000
@@ -163,11 +163,21 @@
         }
         
         m_config.channelCount = int(inputChannels);
-        m_config.stepSize = int(stepSize);
-        m_config.blockSize = int(blockSize);
+        m_config.framing.stepSize = int(stepSize);
+        m_config.framing.blockSize = int(blockSize);
 
         try {
-            m_outputs = m_client->configure(this, m_config);
+            auto response = m_client->configure(this, m_config);
+            m_outputs = response.outputs;
+
+            // Update with the new preferred step and block size now
+            // that the plugin has taken into account its parameter
+            // settings. If the values passed in to initialise()
+            // weren't suitable, then this ensures that a subsequent
+            // call to getPreferredStepSize/BlockSize on this plugin
+            // object will at least get acceptable values from now on
+            m_config.framing = response.framing;
+            
         } catch (const std::exception &e) {
             m_state = Failed;
             throw;
@@ -206,11 +216,17 @@
     }
 
     virtual size_t getPreferredBlockSize() const {
-        return m_defaultConfig.blockSize;
+        // Return this from m_config instead of m_defaultConfig, so
+        // that it gets updated in the event of an initialise() call
+        // that fails for the wrong value
+        return m_config.framing.blockSize;
     }
 
     virtual size_t getPreferredStepSize() const {
-        return m_defaultConfig.stepSize;
+        // Return this from m_config instead of m_defaultConfig, so
+        // that it gets updated in the event of an initialise() call
+        // that fails for the wrong value
+        return m_config.framing.stepSize;
     }
 
     virtual size_t getMinChannelCount() const {
@@ -265,7 +281,7 @@
         for (int c = 0; c < m_config.channelCount; ++c) {
             vecbuf.push_back(std::vector<float>
                              (inputBuffers[c],
-                              inputBuffers[c] + m_config.blockSize));
+                              inputBuffers[c] + m_config.framing.blockSize));
         }
 
         try {
--- a/vamp-json/VampJson.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-json/VampJson.h	Mon Feb 06 12:04:25 2017 +0000
@@ -694,8 +694,11 @@
         }
 
         jo["channelCount"] = c.channelCount;
-        jo["stepSize"] = c.stepSize;
-        jo["blockSize"] = c.blockSize;
+
+        json11::Json::object framing;
+        framing["stepSize"] = c.framing.stepSize;
+        framing["blockSize"] = c.framing.blockSize;
+        jo["framing"] = framing;
     
         return json11::Json(jo);
     }
@@ -704,13 +707,18 @@
     toPluginConfiguration(json11::Json j, std::string &err) {
         
         if (!j.has_shape({
-                    { "channelCount", json11::Json::NUMBER },
-                    { "stepSize", json11::Json::NUMBER },
-                    { "blockSize", json11::Json::NUMBER } }, err)) {
+                    { "channelCount", json11::Json::NUMBER } }, err)) {
             err = "malformed plugin configuration: " + err;
             return {};
         }
 
+        if (!j["framing"].has_shape({
+                    { "stepSize", json11::Json::NUMBER },
+                    { "blockSize", json11::Json::NUMBER } }, err)) {
+            err = "malformed framing: " + err;
+            return {};
+        }
+                    
         if (!j["parameterValues"].is_null() &&
             !j["parameterValues"].is_object()) {
             err = "object expected for parameter values";
@@ -733,8 +741,8 @@
         PluginConfiguration config;
 
         config.channelCount = int(round(j["channelCount"].number_value()));
-        config.stepSize = int(round(j["stepSize"].number_value()));
-        config.blockSize = int(round(j["blockSize"].number_value()));
+        config.framing.stepSize = int(round(j["framing"]["stepSize"].number_value()));
+        config.framing.blockSize = int(round(j["framing"]["blockSize"].number_value()));
         
         for (auto &pv : j["parameterValues"].object_items()) {
             config.parameterValues[pv.first] = float(pv.second.number_value());
@@ -963,6 +971,11 @@
             outs.push_back(fromOutputDescriptor(d));
         }
         jo["outputList"] = outs;
+
+        json11::Json::object framing;
+        framing["stepSize"] = cr.framing.stepSize;
+        framing["blockSize"] = cr.framing.blockSize;
+        jo["framing"] = framing;
         
         return json11::Json(jo);
     }
@@ -973,18 +986,28 @@
         
         ConfigurationResponse cr;
 
-        cr.plugin = pmapper.handleToPlugin(j["handle"].int_value());
+        if (!j["framing"].has_shape({
+                    { "stepSize", json11::Json::NUMBER },
+                    { "blockSize", json11::Json::NUMBER } }, err)) {
+            err = "malformed framing: " + err;
+            return {};
+        }
         
         if (!j["outputList"].is_array()) {
             err = "array expected for output list";
             return {};
         }
+        
+        cr.plugin = pmapper.handleToPlugin(j["handle"].int_value());
 
         for (const auto &o: j["outputList"].array_items()) {
             cr.outputs.push_back(toOutputDescriptor(o, err));
             if (failed(err)) return {};
         }
 
+        cr.framing.stepSize = int(round(j["framing"]["stepSize"].number_value()));
+        cr.framing.blockSize = int(round(j["framing"]["blockSize"].number_value()));
+        
         return cr;
     }
 
--- a/vamp-server/simple-server.cpp	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-server/simple-server.cpp	Mon Feb 06 12:04:25 2017 +0000
@@ -484,11 +484,18 @@
             throw runtime_error("plugin has already been configured");
         }
 
+        if (creq.configuration.framing.stepSize == 0 ||
+            creq.configuration.framing.blockSize == 0) {
+            throw runtime_error("step and block size must be non-zero");
+        }
+
         response.configurationResponse = LoaderRequests().configurePlugin(creq);
         
         if (!response.configurationResponse.outputs.empty()) {
             mapper.markConfigured
-                (h, creq.configuration.channelCount, creq.configuration.blockSize);
+                (h,
+                 creq.configuration.channelCount,
+                 creq.configuration.framing.blockSize);
             response.success = true;
         }
         break;
--- a/vamp-server/test.sh	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-server/test.sh	Mon Feb 06 12:04:25 2017 +0000
@@ -64,8 +64,8 @@
 {"method":"list","params": {"from":["something-nonexistent"]}}
 {"method":"load","id":6,"params": {"key":"vamp-example-plugins:percussiononsets","inputSampleRate":44100,"adapterFlags":["AdaptInputDomain","AdaptBufferSize"]}}
 {"method":"process","params": {"handle": 1, "processInput": { "timestamp": {"s": 0, "n": 0}, "inputBuffers": [ [1,2,3,4,5,6,7,8] ]}}}
-{"method":"configure","id":"weevil","params":{"handle":1,"configuration":{"blockSize": 8, "channelCount": 1, "parameterValues": {"sensitivity": 40, "threshold": 3}, "stepSize": 8}}}
-{"method":"configure","id":9,"params":{"handle":-9999,"configuration":{"blockSize": 8, "channelCount": 1, "parameterValues": {"sensitivity": 40, "threshold": 3}, "stepSize": 8}}}
+{"method":"configure","id":"weevil","params":{"handle":1,"configuration":{"framing":{"blockSize": 8,"stepSize":8}, "channelCount": 1, "parameterValues": {"sensitivity": 40, "threshold": 3}}}}
+{"method":"configure","id":9,"params":{"handle":-9999,"configuration":{"framing":{"blockSize": 8,"stepSize":8}, "channelCount": 1, "parameterValues": {"sensitivity": 40, "threshold": 3}}}}
 {"method":"process","params": {"handle": 1, "processInput": { "timestamp": {"s": 0, "n": 0}, "inputBuffers": [ [1,2,3,4,5,6,7,8] ]}}}
 {"method":"finish","params": {"handle": 1}}
 {"method":"finish","id":"blah","params": {"handle": 1}}
@@ -74,9 +74,9 @@
 # Expected output, apart from the plugin list which seems a bit
 # fragile to check here
 cat > "$expected" <<EOF
-{"id": 6, "jsonrpc": "2.0", "method": "load", "result": {"defaultConfiguration": {"blockSize": 1024, "channelCount": 1, "parameterValues": {"sensitivity": 40, "threshold": 3}, "stepSize": 1024}, "handle": 1, "staticData": {"basic": {"description": "Detect percussive note onsets by identifying broadband energy rises", "identifier": "percussiononsets", "name": "Simple Percussion Onset Detector"}, "basicOutputInfo": [{"description": "Percussive note onset locations", "identifier": "onsets", "name": "Onsets"}, {"description": "Broadband energy rise detection function", "identifier": "detectionfunction", "name": "Detection Function"}], "category": ["Time", "Onsets"], "copyright": "Code copyright 2006 Queen Mary, University of London, after Dan Barry et al 2005.  Freely redistributable (BSD license)", "inputDomain": "TimeDomain", "key": "vamp-example-plugins:percussiononsets", "maker": "Vamp SDK Example Plugins", "maxChannelCount": 1, "minChannelCount": 1, "parameters": [{"basic": {"description": "Energy rise within a frequency bin necessary to count toward broadband total", "identifier": "threshold", "name": "Energy rise threshold"}, "defaultValue": 3, "extents": {"max": 20, "min": 0}, "unit": "dB", "valueNames": []}, {"basic": {"description": "Sensitivity of peak detector applied to broadband detection function", "identifier": "sensitivity", "name": "Sensitivity"}, "defaultValue": 40, "extents": {"max": 100, "min": 0}, "unit": "%", "valueNames": []}], "programs": [], "version": 2}}}
+{"id": 6, "jsonrpc": "2.0", "method": "load", "result": {"defaultConfiguration": {"channelCount": 1, "framing": {"blockSize": 1024, "stepSize": 1024}, "parameterValues": {"sensitivity": 40, "threshold": 3}}, "handle": 1, "staticData": {"basic": {"description": "Detect percussive note onsets by identifying broadband energy rises", "identifier": "percussiononsets", "name": "Simple Percussion Onset Detector"}, "basicOutputInfo": [{"description": "Percussive note onset locations", "identifier": "onsets", "name": "Onsets"}, {"description": "Broadband energy rise detection function", "identifier": "detectionfunction", "name": "Detection Function"}], "category": ["Time", "Onsets"], "copyright": "Code copyright 2006 Queen Mary, University of London, after Dan Barry et al 2005.  Freely redistributable (BSD license)", "inputDomain": "TimeDomain", "key": "vamp-example-plugins:percussiononsets", "maker": "Vamp SDK Example Plugins", "maxChannelCount": 1, "minChannelCount": 1, "parameters": [{"basic": {"description": "Energy rise within a frequency bin necessary to count toward broadband total", "identifier": "threshold", "name": "Energy rise threshold"}, "defaultValue": 3, "extents": {"max": 20, "min": 0}, "unit": "dB", "valueNames": []}, {"basic": {"description": "Sensitivity of peak detector applied to broadband detection function", "identifier": "sensitivity", "name": "Sensitivity"}, "defaultValue": 40, "extents": {"max": 100, "min": 0}, "unit": "%", "valueNames": []}], "programs": [], "version": 2}}}
 {"error": {"code": 0, "message": "error in process request: plugin has not been configured"}, "jsonrpc": "2.0", "method": "process"}
-{"id": "weevil", "jsonrpc": "2.0", "method": "configure", "result": {"handle": 1, "outputList": [{"basic": {"description": "Percussive note onset locations", "identifier": "onsets", "name": "Onsets"}, "configured": {"binCount": 0, "binNames": [], "hasDuration": false, "sampleRate": 44100, "sampleType": "VariableSampleRate", "unit": ""}}, {"basic": {"description": "Broadband energy rise detection function", "identifier": "detectionfunction", "name": "Detection Function"}, "configured": {"binCount": 1, "binNames": [""], "hasDuration": false, "quantizeStep": 1, "sampleRate": 86.1328125, "sampleType": "FixedSampleRate", "unit": ""}}]}}
+{"id": "weevil", "jsonrpc": "2.0", "method": "configure", "result": {"framing": {"blockSize": 8, "stepSize": 8}, "handle": 1, "outputList": [{"basic": {"description": "Percussive note onset locations", "identifier": "onsets", "name": "Onsets"}, "configured": {"binCount": 0, "binNames": [], "hasDuration": false, "sampleRate": 44100, "sampleType": "VariableSampleRate", "unit": ""}}, {"basic": {"description": "Broadband energy rise detection function", "identifier": "detectionfunction", "name": "Detection Function"}, "configured": {"binCount": 1, "binNames": [""], "hasDuration": false, "quantizeStep": 1, "sampleRate": 86.1328125, "sampleType": "FixedSampleRate", "unit": ""}}]}}
 {"error": {"code": 0, "message": "error in configure request: unknown plugin handle supplied to configure"}, "id": 9, "jsonrpc": "2.0", "method": "configure"}
 {"jsonrpc": "2.0", "method": "process", "result": {"features": {}, "handle": 1}}
 {"jsonrpc": "2.0", "method": "finish", "result": {"features": {"detectionfunction": [{"featureValues": [0], "timestamp": {"n": 11609977, "s": 0}}]}, "handle": 1}}
--- a/vamp-support/LoaderRequests.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-support/LoaderRequests.h	Mon Feb 06 12:04:25 2017 +0000
@@ -130,12 +130,32 @@
 	ConfigurationResponse response;
 
 	response.plugin = req.plugin;
-    
+
+        if (req.configuration.framing.stepSize == 0 ||
+            req.configuration.framing.blockSize == 0) {
+            return response;
+        }
+
 	if (req.plugin->initialise(req.configuration.channelCount,
-				   req.configuration.stepSize,
-				   req.configuration.blockSize)) {
+				   req.configuration.framing.stepSize,
+				   req.configuration.framing.blockSize)) {
+
 	    response.outputs = req.plugin->getOutputDescriptors();
-	}
+
+            // If the Vamp plugin initialise() call succeeds, then by
+            // definition it is accepting the step and block size
+            // passed in
+            response.framing = req.configuration.framing;
+
+	} else {
+
+            // If initialise() fails, one reason could be that it
+            // didn't like the passed-in step and block size. If we
+            // return its current preferred values here, the
+            // host/client can retry with these (if they differ)
+            response.framing.stepSize = req.plugin->getPreferredStepSize();
+            response.framing.blockSize = req.plugin->getPreferredBlockSize();
+        }
 
 	return response;
     }
--- a/vamp-support/PluginConfiguration.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-support/PluginConfiguration.h	Mon Feb 06 12:04:25 2017 +0000
@@ -45,6 +45,20 @@
 namespace piper_vamp {
 
 /**
+ * \struct Framing
+ * 
+ * A structure bundling the processing step and block size.
+ */
+struct Framing
+{
+    Framing() : // invalid by default 
+        stepSize(0), blockSize(0) { }
+    
+    int stepSize;
+    int blockSize;
+};
+
+/**
  * \class PluginConfiguration
  * 
  * PluginConfiguration is a structure bundling together data that
@@ -59,11 +73,10 @@
 struct PluginConfiguration
 {
     PluginConfiguration() : // invalid configuration by default
-	channelCount(0), stepSize(0), blockSize(0) { }
+	channelCount(0) { }
 	
     int channelCount;
-    int stepSize;
-    int blockSize;
+    Framing framing;
     typedef std::map<std::string, float> ParameterMap;
     ParameterMap parameterValues;
     std::string currentProgram;
@@ -77,8 +90,8 @@
 	PluginConfiguration c;
 	
 	c.channelCount = channelCount;
-	c.stepSize = stepSize;
-	c.blockSize = blockSize;
+	c.framing.stepSize = stepSize;
+	c.framing.blockSize = blockSize;
 
 	Vamp::PluginBase::ParameterList params = p->getParameterDescriptors();
 	for (Vamp::PluginBase::ParameterList::const_iterator i = params.begin();
--- a/vamp-support/RequestResponse.h	Fri Feb 03 13:00:42 2017 +0000
+++ b/vamp-support/RequestResponse.h	Mon Feb 06 12:04:25 2017 +0000
@@ -187,7 +187,10 @@
  * The return value from a configuration request (i.e. setting the
  * parameters and initialising the plugin). If the configuration was
  * successful, the output list will contain the final
- * post-initialisation output descriptors. If configuration failed,
+ * post-initialisation output descriptors and the required step and
+ * block size. (The step and block size will usually match those
+ * passed to configure, but may differ if the parameter settings
+ * turned out to be incompatible with those.) If configuration failed,
  * the output list will be empty.
  *
  * \see PluginConfiguration, ConfigurationRequest, LoadRequest, LoadResponse
@@ -200,6 +203,7 @@
 
     Vamp::Plugin *plugin;
     Vamp::Plugin::OutputList outputs;
+    Framing framing;
 };
 
 /**